diff --git a/examples/org.eclipse.nebula.examples/.classpath b/examples/org.eclipse.nebula.examples/.classpath index ca3785c41..e801ebfb4 100644 --- a/examples/org.eclipse.nebula.examples/.classpath +++ b/examples/org.eclipse.nebula.examples/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/examples/org.eclipse.nebula.examples/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.nebula.examples/.settings/org.eclipse.jdt.core.prefs index e2e9c66d8..f2525a8b9 100644 --- a/examples/org.eclipse.nebula.examples/.settings/org.eclipse.jdt.core.prefs +++ b/examples/org.eclipse.nebula.examples/.settings/org.eclipse.jdt.core.prefs @@ -1,14 +1,14 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/examples/org.eclipse.nebula.examples/build.properties b/examples/org.eclipse.nebula.examples/build.properties index 58b5d42dc..2398cbab9 100644 --- a/examples/org.eclipse.nebula.examples/build.properties +++ b/examples/org.eclipse.nebula.examples/build.properties @@ -1,8 +1,8 @@ -source.. = src/ -output.. = bin/ -bin.includes = icons/,\ - plugin.xml,\ - META-INF/,\ - plugin.properties,\ - . -src.includes = about.html +source.. = src/ +output.. = bin/ +bin.includes = icons/,\ + plugin.xml,\ + META-INF/,\ + plugin.properties,\ + . +src.includes = about.html diff --git a/examples/org.eclipse.nebula.examples/schema/examples.exsd b/examples/org.eclipse.nebula.examples/schema/examples.exsd index b414edeaf..df1c2a40f 100644 --- a/examples/org.eclipse.nebula.examples/schema/examples.exsd +++ b/examples/org.eclipse.nebula.examples/schema/examples.exsd @@ -1,154 +1,154 @@ - - - - - - - - - Provides an extension point to hook in the Nebula Examples View. - - - - - - - - - - This extension point enables extenders to hook into the Nebula Examples view. Each contribution will be displayed in a separate tab in the view. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The tab element is used to point to an implementation of AbstractExampleTab - - - - - - - The name attribute will be used as the title of the tab. Provide a short name like "ChartTable" which describes the widget that is exposed on the tab. - - - - - - - - - - Provide a class that extends org.eclipse.nebula.examples.AbstractExampleTab. - - - - - - - - - - - - - - - The value of the class attribute in the describer element must represent an implementor of org.eclipse.nebula.examples.AbstractExampleTab - - - - - - - - - 1.0 - - - - - - - - - <pre> -<extension - point="org.eclipse.nebula.examples.examples"> - <tab - class="org.eclipse.nebula.widgets.oscilloscope.example.OscilloscopeExampleTab" - name="Oscilloscope"> - </tab> -</extension> - - -<extension - point="org.eclipse.nebula.examples.examples"> - <tab - class="org.eclipse.nebula.widgets.ganttchart.example.GanttExampleTab" - name="Ganttchart"> - </tab> -</extension> -</pre> - - - - - - - - - No information is supplied by the provider of this extension point but all Nebula widgets must use this extension point. Please look at any of the Nebula widgets for a variety of implementation examples. - - - - - - - - - Copyright (c) 2007,2012 IBM, Remain Software 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: - Chris Gross - IBM - Creation - Wim jongman <wim.jongman@remainsoftware.com> Documentation - - - - - + + + + + + + + + Provides an extension point to hook in the Nebula Examples View. + + + + + + + + + + This extension point enables extenders to hook into the Nebula Examples view. Each contribution will be displayed in a separate tab in the view. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The tab element is used to point to an implementation of AbstractExampleTab + + + + + + + The name attribute will be used as the title of the tab. Provide a short name like "ChartTable" which describes the widget that is exposed on the tab. + + + + + + + + + + Provide a class that extends org.eclipse.nebula.examples.AbstractExampleTab. + + + + + + + + + + + + + + + The value of the class attribute in the describer element must represent an implementor of org.eclipse.nebula.examples.AbstractExampleTab + + + + + + + + + 1.0 + + + + + + + + + <pre> +<extension + point="org.eclipse.nebula.examples.examples"> + <tab + class="org.eclipse.nebula.widgets.oscilloscope.example.OscilloscopeExampleTab" + name="Oscilloscope"> + </tab> +</extension> + + +<extension + point="org.eclipse.nebula.examples.examples"> + <tab + class="org.eclipse.nebula.widgets.ganttchart.example.GanttExampleTab" + name="Ganttchart"> + </tab> +</extension> +</pre> + + + + + + + + + No information is supplied by the provider of this extension point but all Nebula widgets must use this extension point. Please look at any of the Nebula widgets for a variety of implementation examples. + + + + + + + + + Copyright (c) 2007,2012 IBM, Remain Software 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: + Chris Gross - IBM - Creation + Wim jongman <wim.jongman@remainsoftware.com> Documentation + + + + + diff --git a/examples/org.eclipse.nebula.snippets/.classpath b/examples/org.eclipse.nebula.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/examples/org.eclipse.nebula.snippets/.classpath +++ b/examples/org.eclipse.nebula.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/examples/org.eclipse.nebula.snippets/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.nebula.snippets/.settings/org.eclipse.jdt.core.prefs index 27656b34c..9d6b57d79 100644 --- a/examples/org.eclipse.nebula.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/examples/org.eclipse.nebula.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.8 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/compositetable/SnippetCompositeTableDataBinding.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/compositetable/SnippetCompositeTableDataBinding.java index a2fa188ff..e4c1d23ad 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/compositetable/SnippetCompositeTableDataBinding.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/compositetable/SnippetCompositeTableDataBinding.java @@ -1,558 +1,558 @@ -package org.eclipse.nebula.snippets.compositetable; - -/* - * Text example snippet: verify input (only allow digits) - * - * For a list of all SWT example snippets see - * http://www.eclipse.org/swt/snippets/ - */ -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.databinding.Binding; -import org.eclipse.core.databinding.DataBindingContext; -import org.eclipse.core.databinding.UpdateValueStrategy; -import org.eclipse.core.databinding.beans.BeansObservables; -import org.eclipse.core.databinding.beans.PojoObservables; -import org.eclipse.core.databinding.observable.Realm; -import org.eclipse.jface.databinding.swt.SWTObservables; -import org.eclipse.jface.dialogs.TitleAreaDialog; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.window.Window; -import org.eclipse.nebula.widgets.compositetable.CompositeTable; -import org.eclipse.nebula.widgets.compositetable.IRowContentProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.FormAttachment; -import org.eclipse.swt.layout.FormData; -import org.eclipse.swt.layout.FormLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -@SuppressWarnings("deprecation") -public class SnippetCompositeTableDataBinding { - - /** - * A Model class representing a hero - * - * @author sylvere.richard@sogeti.lu - * - */ - private static class Hero { - private String name; - - private String firstname; - - public Hero() { - } - - /** - * copy constructor - * - * @param hero - */ - public Hero(Hero hero) { - this.firstname = hero.firstname; - this.name = hero.name; - } - - public void setName(String name) { - this.name = name; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - } - - /** - * A model class containing a list of persons. - * - * @author sylvere.richard@sogeti.lu - * - */ - private static class MyModel { - private final PropertyChangeSupport support = new PropertyChangeSupport(this); - - /** - * @param listener - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { - support.addPropertyChangeListener(listener); - } - - /** - * @param propertyName - * @param listener - */ - public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - support.addPropertyChangeListener(propertyName, listener); - } - - /** - * @param listener - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { - support.removePropertyChangeListener(listener); - } - - /** - * @param propertyName - * @param listener - */ - public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - support.removePropertyChangeListener(propertyName, listener); - } - - /** - * - * @param propertyName - * @param oldValue - * @param newValue - */ - protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { - support.firePropertyChange(propertyName, oldValue, newValue); - } - - private final List heroes = new LinkedList(); - - public List getHeroes() { - return heroes; - } - - /** - * Returns how many heroes the model contains. - * - * @return - */ - public int getHeroesListSize() { - return getHeroes().size(); - } - - /** - * Adds a new hero to the list of people - * - * @param p - */ - public void addHero(Hero p) { - getHeroes().add(p); - // notify whenever the hero list size changes - support.firePropertyChange("heroesListSize", getHeroesListSize() - 1, getHeroesListSize()); - } - - public void removePerson(Hero person) { - getHeroes().remove(person); - // notify whenever the hero list size changes - support.firePropertyChange("heroesListSize", getHeroesListSize() + 1, getHeroesListSize()); - } - } - - /** - * contains size of table columns - */ - private static int[] cols = new int[] { 0, 30, 60, 75 }; - - /** - * Header of my table - * - * @author sylvere.richard@sogeti.lu - * - */ - private static class Header extends Composite { - public Header(Composite parent, int style) { - super(parent, style); - - doLayout(); - } - - private void doLayout() { - setLayout(new FormLayout()); - Label lblName = new Label(this, SWT.CENTER); - lblName.setText("Name"); - - int index = 0; - FormData data = new FormData(); - data.left = new FormAttachment(cols[index], 100, 5); - data.right = new FormAttachment(cols[index + 1], 100, 0); - data.top = new FormAttachment(0, 100, 5); - - lblName.setLayoutData(data); - index++; - - Label lblFirstname = new Label(this, SWT.CENTER); - lblFirstname.setText("Firstname"); - - data = new FormData(); - data.left = new FormAttachment(cols[index], 100, 5); - data.right = new FormAttachment(cols[index + 1], 100, 0); - data.top = new FormAttachment(0, 100, 5); - - lblFirstname.setLayoutData(data); - index++; - - Label lblAction = new Label(this, SWT.CENTER); - lblAction.setText("Action"); - - data = new FormData(); - data.left = new FormAttachment(cols[index], 100, 5); - data.right = new FormAttachment(cols[index + 1], 100, 0); - data.top = new FormAttachment(0, 100, 5); - - lblAction.setLayoutData(data); - - } - } - - /** - * A row of my table - * - * @author sylvere.richard@sogeti.lu - * - */ - private static class Row extends Composite { - - private DataBindingContext dbcRow; - - private Text lastname; - - private Text firstname; - - private Button action; - - public Row(Composite parent, int style) { - super(parent, style); - doLayout(); - - addListener(SWT.Dispose, e -> { - // in case the row is bound, we unbind it - unbind(); - }); - } - - private void doLayout() { - lastname = new Text(this, SWT.BORDER); - firstname = new Text(this, SWT.BORDER); - action = new Button(this, SWT.NONE); - action.setText("Delete"); - - setLayout(new FormLayout()); - - // column index - int index = 0; - FormData data = new FormData(); - data.top = new FormAttachment(0, 100, 5); - data.left = new FormAttachment(cols[index], 100, 5); - data.right = new FormAttachment(cols[index + 1], 100, 0); - lastname.setLayoutData(data); - index++; - - data = new FormData(); - data.top = new FormAttachment(0, 100, 5); - data.left = new FormAttachment(cols[index], 100, 5); - data.right = new FormAttachment(cols[index + 1], 100, 0); - firstname.setLayoutData(data); - index++; - - data = new FormData(); - data.top = new FormAttachment(0, 100, 5); - data.left = new FormAttachment(cols[index], 100, 5); - data.right = new FormAttachment(cols[index + 1], 100, 0); - action.setLayoutData(data); - index++; - } - - /** - * Unbind the current row. Be sure to call this method before any call - * to bind. - */ - public void unbind() { - if (dbcRow != null) { - dbcRow.dispose(); - dbcRow = null; - } - } - - /** - * Binds the current ro with the given Person - * - * @param p - * The Person bean to bind. - */ - public void bind(Hero p) { - dbcRow = new DataBindingContext(); - Binding b = dbcRow.bindValue(SWTObservables.observeText(lastname, SWT.Modify), PojoObservables.observeValue(p, "name"), null, null); - b = dbcRow.bindValue(SWTObservables.observeText(firstname, SWT.Modify), PojoObservables.observeValue(p, "firstname"), null, null); - } - - } - - /** - * A simple dialog to create a new person. - * - * @author sylvere.richard@sogeti.lu - * - */ - private static final class PersonTitleAreaDialog extends TitleAreaDialog { - private Text txName; - private Text txFirstname; - private final Hero hero = new Hero(); - - private DataBindingContext dbc = new DataBindingContext(); - - private PersonTitleAreaDialog(Shell parentShell) { - super(parentShell); - - } - - @Override - protected Control createContents(Composite parent) { - Control ret = super.createContents(parent); - setTitle("Add new Hero"); - setMessage("Enter here your favorite hero :"); - return ret; - } - - protected Control createDialogArea(Composite parent) { - Composite composite = (Composite) super.createDialogArea(parent); - - Label lbName = new Label(composite, SWT.NONE); - lbName.setText("Name :"); - - txName = new Text(composite, SWT.BORDER); - - Label lbFirstname = new Label(composite, SWT.NONE); - lbFirstname.setText("Firstname :"); - - txFirstname = new Text(composite, SWT.BORDER); - - GridLayoutFactory.fillDefaults().generateLayout(composite); - - // binding - Binding b = dbc.bindValue(SWTObservables.observeText(txFirstname, SWT.FocusOut), PojoObservables.observeValue(hero, "firstname"), null, null); - b = dbc.bindValue(SWTObservables.observeText(txName, SWT.FocusOut), PojoObservables.observeValue(hero, "name"), null, null); - return composite; - } - - @Override - public int open() { - return super.open(); - } - - @Override - public boolean close() { - dbc.dispose(); - return super.close(); - } - - public Hero getHero() { - // returns a copy - return new Hero(hero); - } - } - - /** - * This composite contains the CompositeTable and a button to add new rows - * - * @author sylvere.richard@sogeti.lu - * - */ - private static class MainCompo extends Composite { - - private CompositeTable table; - private Button addNew; - private final MyModel model = new MyModel(); - - private final DataBindingContext dbc = new DataBindingContext(); - - public MainCompo(Composite parent, int style) { - super(parent, style); - - doLayout(); - } - - private void doLayout() { - setLayout(new FormLayout()); - - table = new CompositeTable(this, SWT.NULL); - table.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - new Header(table, SWT.NULL); - new Row(table, SWT.NULL); - - addNew = new Button(this, SWT.NONE); - addNew.setText("Add new Hero"); - addNew.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(SelectionEvent e) { - PersonTitleAreaDialog d = new PersonTitleAreaDialog(getShell()); - d.open(); - final int result = d.getReturnCode(); - if (result == Window.OK) { - Hero p = d.getHero(); - getModel().addHero(p); - } - } - }); - - FormData data = new FormData(); - data.left = new FormAttachment(0, 100, 5); - data.right = new FormAttachment(100, 100, -5); - data.top = new FormAttachment(0, 100, 5); - data.bottom = new FormAttachment(addNew, -5, SWT.TOP); - table.setLayoutData(data); - table.setRunTime(true); - - data = new FormData(); - data.right = new FormAttachment(100, 100, -5); - data.bottom = new FormAttachment(100, 100, -5); - addNew.setLayoutData(data); - } - - /** - * In this method, we bind the heroes list size with the - * compositetable's property 'numRowsInCollection'. - * - */ - public void binding() { - - // table.setNumRowsInCollection(model.getPeople().size()); - Binding b = dbc.bindValue(PojoObservables.observeValue(table, "numRowsInCollection"), BeansObservables.observeValue(model, "heroesListSize"), new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), new UpdateValueStrategy()); - - table.addRowContentProvider(new IRowContentProvider() { - - /** - * Keeps a reference of each delete listener for each row, so we can - * remove a listener when compositetable associate the row to another hero. - */ - private Map map = new HashMap(); - - /** - * * Since the compositetable has its own pool of Row elements, - * we must first ensure to unbind if necessary the row before - * rebinding it with the Hero given as parameter. - * - * In the same way, we remove and add selectionlistener. - */ - public void refresh(CompositeTable sender, int currentObjectOffset, Control rowControl) { - Row row = (Row) rowControl; - final Hero p = model.getHeroes().get(currentObjectOffset); - - // unbind previous hero - row.unbind(); - - // remove previous listener if nay - if (map.get(row) != null) { - row.action.removeSelectionListener(map.get(row)); - } - - // bind the new hero - row.bind(p); - - // add selectionlistener - SelectionListener listen = new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - getModel().removePerson(p); - } - }; - row.action.addSelectionListener(listen); - // keep a reference to this listener to be able to remove it - // during the next refresh - map.put(row, listen); - } - }); - } - - public MyModel getModel() { - return model; - } - } - - /** - * Main entry point. - * - * @param args - */ - public static void main(String[] args) { - final Display display = new Display(); - - Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { - public void run() { - Shell shell = new Shell(display); - shell.setText("Jules Verne's Heroes"); - shell.setBounds(0, 0, 400, 200); - shell.setLayout(new FormLayout()); - - // creation of the composite containing the table - MainCompo compo = new MainCompo(shell, SWT.NONE); - - // position it on the shell - FormData data = new FormData(); - data.left = new FormAttachment(0, 100, 5); - data.right = new FormAttachment(100, 100, -5); - data.top = new FormAttachment(0, 100, 5); - data.bottom = new FormAttachment(100, 100, -5); - compo.setLayoutData(data); - - // add some data to the model - populateModel(compo.getModel()); - - // binding the UI with the model - compo.binding(); - - // start the UI - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - } - }); - display.dispose(); - } - - /** - * populates the given model with some data - * - * @param md - */ - private static void populateModel(MyModel md) { - Hero p = new Hero(); - p.setName("Fogg"); - p.setFirstname("Phileas"); - md.getHeroes().add(p); - - p = new Hero(); - p.setName("Aronnax"); - p.setFirstname("Pierre"); - md.getHeroes().add(p); - - p = new Hero(); - p.setName("Strogoff"); - p.setFirstname("Michel"); - md.getHeroes().add(p); - - p = new Hero(); - p.setName("Nemo"); - p.setFirstname("Captain"); - md.getHeroes().add(p); - - p = new Hero(); - p.setName("Barbicane"); - p.setFirstname("Impey"); - md.getHeroes().add(p); - } -} +package org.eclipse.nebula.snippets.compositetable; + +/* + * Text example snippet: verify input (only allow digits) + * + * For a list of all SWT example snippets see + * http://www.eclipse.org/swt/snippets/ + */ +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.databinding.Binding; +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.UpdateValueStrategy; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.beans.PojoObservables; +import org.eclipse.core.databinding.observable.Realm; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.window.Window; +import org.eclipse.nebula.widgets.compositetable.CompositeTable; +import org.eclipse.nebula.widgets.compositetable.IRowContentProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +@SuppressWarnings("deprecation") +public class SnippetCompositeTableDataBinding { + + /** + * A Model class representing a hero + * + * @author sylvere.richard@sogeti.lu + * + */ + private static class Hero { + private String name; + + private String firstname; + + public Hero() { + } + + /** + * copy constructor + * + * @param hero + */ + public Hero(Hero hero) { + this.firstname = hero.firstname; + this.name = hero.name; + } + + public void setName(String name) { + this.name = name; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + } + + /** + * A model class containing a list of persons. + * + * @author sylvere.richard@sogeti.lu + * + */ + private static class MyModel { + private final PropertyChangeSupport support = new PropertyChangeSupport(this); + + /** + * @param listener + */ + public void addPropertyChangeListener(PropertyChangeListener listener) { + support.addPropertyChangeListener(listener); + } + + /** + * @param propertyName + * @param listener + */ + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + support.addPropertyChangeListener(propertyName, listener); + } + + /** + * @param listener + */ + public void removePropertyChangeListener(PropertyChangeListener listener) { + support.removePropertyChangeListener(listener); + } + + /** + * @param propertyName + * @param listener + */ + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + support.removePropertyChangeListener(propertyName, listener); + } + + /** + * + * @param propertyName + * @param oldValue + * @param newValue + */ + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + support.firePropertyChange(propertyName, oldValue, newValue); + } + + private final List heroes = new LinkedList(); + + public List getHeroes() { + return heroes; + } + + /** + * Returns how many heroes the model contains. + * + * @return + */ + public int getHeroesListSize() { + return getHeroes().size(); + } + + /** + * Adds a new hero to the list of people + * + * @param p + */ + public void addHero(Hero p) { + getHeroes().add(p); + // notify whenever the hero list size changes + support.firePropertyChange("heroesListSize", getHeroesListSize() - 1, getHeroesListSize()); + } + + public void removePerson(Hero person) { + getHeroes().remove(person); + // notify whenever the hero list size changes + support.firePropertyChange("heroesListSize", getHeroesListSize() + 1, getHeroesListSize()); + } + } + + /** + * contains size of table columns + */ + private static int[] cols = new int[] { 0, 30, 60, 75 }; + + /** + * Header of my table + * + * @author sylvere.richard@sogeti.lu + * + */ + private static class Header extends Composite { + public Header(Composite parent, int style) { + super(parent, style); + + doLayout(); + } + + private void doLayout() { + setLayout(new FormLayout()); + Label lblName = new Label(this, SWT.CENTER); + lblName.setText("Name"); + + int index = 0; + FormData data = new FormData(); + data.left = new FormAttachment(cols[index], 100, 5); + data.right = new FormAttachment(cols[index + 1], 100, 0); + data.top = new FormAttachment(0, 100, 5); + + lblName.setLayoutData(data); + index++; + + Label lblFirstname = new Label(this, SWT.CENTER); + lblFirstname.setText("Firstname"); + + data = new FormData(); + data.left = new FormAttachment(cols[index], 100, 5); + data.right = new FormAttachment(cols[index + 1], 100, 0); + data.top = new FormAttachment(0, 100, 5); + + lblFirstname.setLayoutData(data); + index++; + + Label lblAction = new Label(this, SWT.CENTER); + lblAction.setText("Action"); + + data = new FormData(); + data.left = new FormAttachment(cols[index], 100, 5); + data.right = new FormAttachment(cols[index + 1], 100, 0); + data.top = new FormAttachment(0, 100, 5); + + lblAction.setLayoutData(data); + + } + } + + /** + * A row of my table + * + * @author sylvere.richard@sogeti.lu + * + */ + private static class Row extends Composite { + + private DataBindingContext dbcRow; + + private Text lastname; + + private Text firstname; + + private Button action; + + public Row(Composite parent, int style) { + super(parent, style); + doLayout(); + + addListener(SWT.Dispose, e -> { + // in case the row is bound, we unbind it + unbind(); + }); + } + + private void doLayout() { + lastname = new Text(this, SWT.BORDER); + firstname = new Text(this, SWT.BORDER); + action = new Button(this, SWT.NONE); + action.setText("Delete"); + + setLayout(new FormLayout()); + + // column index + int index = 0; + FormData data = new FormData(); + data.top = new FormAttachment(0, 100, 5); + data.left = new FormAttachment(cols[index], 100, 5); + data.right = new FormAttachment(cols[index + 1], 100, 0); + lastname.setLayoutData(data); + index++; + + data = new FormData(); + data.top = new FormAttachment(0, 100, 5); + data.left = new FormAttachment(cols[index], 100, 5); + data.right = new FormAttachment(cols[index + 1], 100, 0); + firstname.setLayoutData(data); + index++; + + data = new FormData(); + data.top = new FormAttachment(0, 100, 5); + data.left = new FormAttachment(cols[index], 100, 5); + data.right = new FormAttachment(cols[index + 1], 100, 0); + action.setLayoutData(data); + index++; + } + + /** + * Unbind the current row. Be sure to call this method before any call + * to bind. + */ + public void unbind() { + if (dbcRow != null) { + dbcRow.dispose(); + dbcRow = null; + } + } + + /** + * Binds the current ro with the given Person + * + * @param p + * The Person bean to bind. + */ + public void bind(Hero p) { + dbcRow = new DataBindingContext(); + Binding b = dbcRow.bindValue(SWTObservables.observeText(lastname, SWT.Modify), PojoObservables.observeValue(p, "name"), null, null); + b = dbcRow.bindValue(SWTObservables.observeText(firstname, SWT.Modify), PojoObservables.observeValue(p, "firstname"), null, null); + } + + } + + /** + * A simple dialog to create a new person. + * + * @author sylvere.richard@sogeti.lu + * + */ + private static final class PersonTitleAreaDialog extends TitleAreaDialog { + private Text txName; + private Text txFirstname; + private final Hero hero = new Hero(); + + private DataBindingContext dbc = new DataBindingContext(); + + private PersonTitleAreaDialog(Shell parentShell) { + super(parentShell); + + } + + @Override + protected Control createContents(Composite parent) { + Control ret = super.createContents(parent); + setTitle("Add new Hero"); + setMessage("Enter here your favorite hero :"); + return ret; + } + + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + + Label lbName = new Label(composite, SWT.NONE); + lbName.setText("Name :"); + + txName = new Text(composite, SWT.BORDER); + + Label lbFirstname = new Label(composite, SWT.NONE); + lbFirstname.setText("Firstname :"); + + txFirstname = new Text(composite, SWT.BORDER); + + GridLayoutFactory.fillDefaults().generateLayout(composite); + + // binding + Binding b = dbc.bindValue(SWTObservables.observeText(txFirstname, SWT.FocusOut), PojoObservables.observeValue(hero, "firstname"), null, null); + b = dbc.bindValue(SWTObservables.observeText(txName, SWT.FocusOut), PojoObservables.observeValue(hero, "name"), null, null); + return composite; + } + + @Override + public int open() { + return super.open(); + } + + @Override + public boolean close() { + dbc.dispose(); + return super.close(); + } + + public Hero getHero() { + // returns a copy + return new Hero(hero); + } + } + + /** + * This composite contains the CompositeTable and a button to add new rows + * + * @author sylvere.richard@sogeti.lu + * + */ + private static class MainCompo extends Composite { + + private CompositeTable table; + private Button addNew; + private final MyModel model = new MyModel(); + + private final DataBindingContext dbc = new DataBindingContext(); + + public MainCompo(Composite parent, int style) { + super(parent, style); + + doLayout(); + } + + private void doLayout() { + setLayout(new FormLayout()); + + table = new CompositeTable(this, SWT.NULL); + table.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + new Header(table, SWT.NULL); + new Row(table, SWT.NULL); + + addNew = new Button(this, SWT.NONE); + addNew.setText("Add new Hero"); + addNew.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + PersonTitleAreaDialog d = new PersonTitleAreaDialog(getShell()); + d.open(); + final int result = d.getReturnCode(); + if (result == Window.OK) { + Hero p = d.getHero(); + getModel().addHero(p); + } + } + }); + + FormData data = new FormData(); + data.left = new FormAttachment(0, 100, 5); + data.right = new FormAttachment(100, 100, -5); + data.top = new FormAttachment(0, 100, 5); + data.bottom = new FormAttachment(addNew, -5, SWT.TOP); + table.setLayoutData(data); + table.setRunTime(true); + + data = new FormData(); + data.right = new FormAttachment(100, 100, -5); + data.bottom = new FormAttachment(100, 100, -5); + addNew.setLayoutData(data); + } + + /** + * In this method, we bind the heroes list size with the + * compositetable's property 'numRowsInCollection'. + * + */ + public void binding() { + + // table.setNumRowsInCollection(model.getPeople().size()); + Binding b = dbc.bindValue(PojoObservables.observeValue(table, "numRowsInCollection"), BeansObservables.observeValue(model, "heroesListSize"), new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), new UpdateValueStrategy()); + + table.addRowContentProvider(new IRowContentProvider() { + + /** + * Keeps a reference of each delete listener for each row, so we can + * remove a listener when compositetable associate the row to another hero. + */ + private Map map = new HashMap(); + + /** + * * Since the compositetable has its own pool of Row elements, + * we must first ensure to unbind if necessary the row before + * rebinding it with the Hero given as parameter. + * + * In the same way, we remove and add selectionlistener. + */ + public void refresh(CompositeTable sender, int currentObjectOffset, Control rowControl) { + Row row = (Row) rowControl; + final Hero p = model.getHeroes().get(currentObjectOffset); + + // unbind previous hero + row.unbind(); + + // remove previous listener if nay + if (map.get(row) != null) { + row.action.removeSelectionListener(map.get(row)); + } + + // bind the new hero + row.bind(p); + + // add selectionlistener + SelectionListener listen = new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + getModel().removePerson(p); + } + }; + row.action.addSelectionListener(listen); + // keep a reference to this listener to be able to remove it + // during the next refresh + map.put(row, listen); + } + }); + } + + public MyModel getModel() { + return model; + } + } + + /** + * Main entry point. + * + * @param args + */ + public static void main(String[] args) { + final Display display = new Display(); + + Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { + public void run() { + Shell shell = new Shell(display); + shell.setText("Jules Verne's Heroes"); + shell.setBounds(0, 0, 400, 200); + shell.setLayout(new FormLayout()); + + // creation of the composite containing the table + MainCompo compo = new MainCompo(shell, SWT.NONE); + + // position it on the shell + FormData data = new FormData(); + data.left = new FormAttachment(0, 100, 5); + data.right = new FormAttachment(100, 100, -5); + data.top = new FormAttachment(0, 100, 5); + data.bottom = new FormAttachment(100, 100, -5); + compo.setLayoutData(data); + + // add some data to the model + populateModel(compo.getModel()); + + // binding the UI with the model + compo.binding(); + + // start the UI + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + } + }); + display.dispose(); + } + + /** + * populates the given model with some data + * + * @param md + */ + private static void populateModel(MyModel md) { + Hero p = new Hero(); + p.setName("Fogg"); + p.setFirstname("Phileas"); + md.getHeroes().add(p); + + p = new Hero(); + p.setName("Aronnax"); + p.setFirstname("Pierre"); + md.getHeroes().add(p); + + p = new Hero(); + p.setName("Strogoff"); + p.setFirstname("Michel"); + md.getHeroes().add(p); + + p = new Hero(); + p.setName("Nemo"); + p.setFirstname("Captain"); + md.getHeroes().add(p); + + p = new Hero(); + p.setName("Barbicane"); + p.setFirstname("Impey"); + md.getHeroes().add(p); + } +} diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/gallery/SnippetHScroll.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/gallery/SnippetHScroll.java index 6367200d2..a3892b802 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/gallery/SnippetHScroll.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/gallery/SnippetHScroll.java @@ -1,89 +1,89 @@ -package org.eclipse.nebula.snippets.gallery; - -/******************************************************************************* - * Copyright (c) 2006-2007 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation - *******************************************************************************/ - -import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; -import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; -import org.eclipse.nebula.widgets.gallery.Gallery; -import org.eclipse.nebula.widgets.gallery.GalleryItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * This widget displays a simple gallery with some content.
- * Scrolling is vertical.
- *
- * - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A - * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE - * VERSIONS. - *

- * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - */ - -public class SnippetHScroll { - - public static void main(String[] args) { - Display display = new Display(); - Image itemImage = new Image(display, Program - .findProgram("jpg").getImageData()); //$NON-NLS-1$ - - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - Gallery gallery = new Gallery(shell, SWT.H_SCROLL | SWT.MULTI); - - // Renderers - DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer(); - gr.setMinMargin(10); - gr.setItemHeight(56); - gr.setItemWidth(72); - gr.setAutoMargin(true); - gallery.setGroupRenderer(gr); - - DefaultGalleryItemRenderer ir = new DefaultGalleryItemRenderer(); - gallery.setItemRenderer(ir); - - for (int g = 0; g < 2; g++) { - GalleryItem group = new GalleryItem(gallery, SWT.NONE); - group.setText("Really Long Group Name " + g); //$NON-NLS-1$ - group.setExpanded(true); - - for (int i = 0; i < 10; i++) { - GalleryItem item = new GalleryItem(group, SWT.NONE); - if (itemImage != null) { - item.setImage(itemImage); - } - item.setText("Item " + i); //$NON-NLS-1$ - } - } - - shell.pack(); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - if (itemImage != null) - itemImage.dispose(); - display.dispose(); - } -} +package org.eclipse.nebula.snippets.gallery; + +/******************************************************************************* + * Copyright (c) 2006-2007 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation + *******************************************************************************/ + +import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; +import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; +import org.eclipse.nebula.widgets.gallery.Gallery; +import org.eclipse.nebula.widgets.gallery.GalleryItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * This widget displays a simple gallery with some content.
+ * Scrolling is vertical.
+ *
+ * + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A + * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE + * VERSIONS. + *

+ * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + */ + +public class SnippetHScroll { + + public static void main(String[] args) { + Display display = new Display(); + Image itemImage = new Image(display, Program + .findProgram("jpg").getImageData()); //$NON-NLS-1$ + + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + Gallery gallery = new Gallery(shell, SWT.H_SCROLL | SWT.MULTI); + + // Renderers + DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer(); + gr.setMinMargin(10); + gr.setItemHeight(56); + gr.setItemWidth(72); + gr.setAutoMargin(true); + gallery.setGroupRenderer(gr); + + DefaultGalleryItemRenderer ir = new DefaultGalleryItemRenderer(); + gallery.setItemRenderer(ir); + + for (int g = 0; g < 2; g++) { + GalleryItem group = new GalleryItem(gallery, SWT.NONE); + group.setText("Really Long Group Name " + g); //$NON-NLS-1$ + group.setExpanded(true); + + for (int i = 0; i < 10; i++) { + GalleryItem item = new GalleryItem(group, SWT.NONE); + if (itemImage != null) { + item.setImage(itemImage); + } + item.setText("Item " + i); //$NON-NLS-1$ + } + } + + shell.pack(); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + if (itemImage != null) + itemImage.dispose(); + display.dispose(); + } +} diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/gallery/SnippetVScroll.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/gallery/SnippetVScroll.java index 7bdc21a3f..71be56a5a 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/gallery/SnippetVScroll.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/gallery/SnippetVScroll.java @@ -1,88 +1,88 @@ -package org.eclipse.nebula.snippets.gallery; - -/******************************************************************************* - * Copyright (c) 2006-2007 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation - *******************************************************************************/ - - -import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; -import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; -import org.eclipse.nebula.widgets.gallery.Gallery; -import org.eclipse.nebula.widgets.gallery.GalleryItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * This widget displays a simple gallery with some content.
Scrolling is - * vertical.

- * - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A - * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE - * VERSIONS. - *

- * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - */ - -public class SnippetVScroll { - - public static void main(String[] args) { - Display display = new Display(); - Image itemImage = new Image(display, Program.findProgram("jpg").getImageData()); //$NON-NLS-1$ - - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - Gallery gallery = new Gallery(shell, SWT.V_SCROLL | SWT.MULTI); - - // Renderers - DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer(); - gr.setMinMargin(10); - gr.setItemHeight(56); - gr.setItemWidth(72); - gr.setAutoMargin(true); - gallery.setGroupRenderer(gr); - - DefaultGalleryItemRenderer ir = new DefaultGalleryItemRenderer(); - gallery.setItemRenderer(ir); - - for (int g = 0; g < 2; g++) { - GalleryItem group = new GalleryItem(gallery, SWT.NONE); - group.setText("Really Long Group Name " + g); //$NON-NLS-1$ - group.setExpanded(true); - - for (int i = 0; i < 10; i++) { - GalleryItem item = new GalleryItem(group, SWT.NONE); - if (itemImage != null) { - item.setImage(itemImage); - } - item.setText("Item " + i); //$NON-NLS-1$ - } - } - - shell.pack(); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - if (itemImage != null) - itemImage.dispose(); - display.dispose(); - } -} +package org.eclipse.nebula.snippets.gallery; + +/******************************************************************************* + * Copyright (c) 2006-2007 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation + *******************************************************************************/ + + +import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; +import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; +import org.eclipse.nebula.widgets.gallery.Gallery; +import org.eclipse.nebula.widgets.gallery.GalleryItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * This widget displays a simple gallery with some content.
Scrolling is + * vertical.

+ * + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A + * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE + * VERSIONS. + *

+ * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + */ + +public class SnippetVScroll { + + public static void main(String[] args) { + Display display = new Display(); + Image itemImage = new Image(display, Program.findProgram("jpg").getImageData()); //$NON-NLS-1$ + + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + Gallery gallery = new Gallery(shell, SWT.V_SCROLL | SWT.MULTI); + + // Renderers + DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer(); + gr.setMinMargin(10); + gr.setItemHeight(56); + gr.setItemWidth(72); + gr.setAutoMargin(true); + gallery.setGroupRenderer(gr); + + DefaultGalleryItemRenderer ir = new DefaultGalleryItemRenderer(); + gallery.setItemRenderer(ir); + + for (int g = 0; g < 2; g++) { + GalleryItem group = new GalleryItem(gallery, SWT.NONE); + group.setText("Really Long Group Name " + g); //$NON-NLS-1$ + group.setExpanded(true); + + for (int i = 0; i < 10; i++) { + GalleryItem item = new GalleryItem(group, SWT.NONE); + if (itemImage != null) { + item.setImage(itemImage); + } + item.setText("Item " + i); //$NON-NLS-1$ + } + } + + shell.pack(); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + if (itemImage != null) + itemImage.dispose(); + display.dispose(); + } +} diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/GridSnippet10.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/GridSnippet10.java index 13c2f7957..a8396213d 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/GridSnippet10.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/GridSnippet10.java @@ -1,79 +1,79 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.snippets.grid; - - -import org.eclipse.nebula.widgets.grid.Grid; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.GridItem; -import org.eclipse.nebula.widgets.grid.Win7RendererSupport; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/* - * Create a simple grid with Win7 column header rendering - * - * For a list of all Nebula Grid example snippets see - * http://www.eclipse.org/nebula/widgets/grid/snippets.php - */ -public class GridSnippet10 { - -public static void main (String [] args) { - Display display = new Display (); - Shell shell = new Shell (display); - shell.setLayout(new FillLayout()); - - Grid grid = new Grid(shell,SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); - grid.setHeaderVisible(true); - GridColumn column = new GridColumn(grid,SWT.NONE); - column.setTree(true); - column.setText("Column 1"); - column.setWidth(100); - GridColumn column2 = new GridColumn(grid,SWT.NONE); - column2.setTree(true); - column2.setText("Column 1"); - column2.setWidth(100); - GridColumn column3 = new GridColumn(grid,SWT.NONE); - column3.setTree(true); - column3.setText("Column 3"); - column3.setWidth(100); - - GridItem item1 = new GridItem(grid,SWT.NONE); - item1.setText(0,"Root Item1"); - item1.setText(1,"Root Item2"); - item1.setText(2,"Root Item3"); - GridItem item2 = new GridItem(item1,SWT.NONE); - item2.setText(0,"Second item1"); - item2.setText(1,"Second item2"); - item2.setText(2,"Second item3"); - GridItem item3 = new GridItem(item2,SWT.NONE); - item3.setText(0,"Third Item1"); - item3.setText(1,"Third Item2"); - item3.setText(2,"Third Item3"); - - grid.setCellSelectionEnabled(true); - - //add the "win7" column header rendering - Win7RendererSupport.create(grid).decorate(); - - shell.setSize(200,200); - shell.open (); - while (!shell.isDisposed()) { - if (!display.readAndDispatch ()) display.sleep (); - } - display.dispose (); -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.snippets.grid; + + +import org.eclipse.nebula.widgets.grid.Grid; +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.nebula.widgets.grid.GridItem; +import org.eclipse.nebula.widgets.grid.Win7RendererSupport; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/* + * Create a simple grid with Win7 column header rendering + * + * For a list of all Nebula Grid example snippets see + * http://www.eclipse.org/nebula/widgets/grid/snippets.php + */ +public class GridSnippet10 { + +public static void main (String [] args) { + Display display = new Display (); + Shell shell = new Shell (display); + shell.setLayout(new FillLayout()); + + Grid grid = new Grid(shell,SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + grid.setHeaderVisible(true); + GridColumn column = new GridColumn(grid,SWT.NONE); + column.setTree(true); + column.setText("Column 1"); + column.setWidth(100); + GridColumn column2 = new GridColumn(grid,SWT.NONE); + column2.setTree(true); + column2.setText("Column 1"); + column2.setWidth(100); + GridColumn column3 = new GridColumn(grid,SWT.NONE); + column3.setTree(true); + column3.setText("Column 3"); + column3.setWidth(100); + + GridItem item1 = new GridItem(grid,SWT.NONE); + item1.setText(0,"Root Item1"); + item1.setText(1,"Root Item2"); + item1.setText(2,"Root Item3"); + GridItem item2 = new GridItem(item1,SWT.NONE); + item2.setText(0,"Second item1"); + item2.setText(1,"Second item2"); + item2.setText(2,"Second item3"); + GridItem item3 = new GridItem(item2,SWT.NONE); + item3.setText(0,"Third Item1"); + item3.setText(1,"Third Item2"); + item3.setText(2,"Third Item3"); + + grid.setCellSelectionEnabled(true); + + //add the "win7" column header rendering + Win7RendererSupport.create(grid).decorate(); + + shell.setSize(200,200); + shell.open (); + while (!shell.isDisposed()) { + if (!display.readAndDispatch ()) display.sleep (); + } + display.dispose (); +} } \ No newline at end of file diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/GridSnippet11.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/GridSnippet11.java index fdab6912a..f8f12a4bc 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/GridSnippet11.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/GridSnippet11.java @@ -1,81 +1,81 @@ -/******************************************************************************* - * Copyright (c) 2019 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron@gmail.com) - initial API and - * implementation - *******************************************************************************/ - -package org.eclipse.nebula.snippets.grid; - -import org.eclipse.nebula.widgets.grid.Grid; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.GridItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * This snippet show custom header font - */ -public class GridSnippet11 { - - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - - Grid grid = new Grid(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); - grid.setHeaderVisible(true); - grid.setCellSelectionEnabled(true); - grid.setRowHeaderVisible(true); - - Font[] fonts = new Font[4]; - fonts[0] = new Font(display, "Consolas", 11, SWT.NONE); - fonts[1] = new Font(display, "Arial", 12, SWT.ITALIC); - fonts[2] = new Font(display, "Calibri", 10, SWT.BOLD); - fonts[3] = new Font(display, "Courier New", 13, SWT.BOLD | SWT.ITALIC); - - int fontIndex = 0; - for (int colCount = 0; colCount < 4; colCount++) { - GridColumn column = new GridColumn(grid, SWT.NONE); - column.setText("Column " + (colCount + 1)); - column.setWidth(100); - for (int rowCount = 0; rowCount < 50; rowCount++) { - final GridItem item; - if (colCount == 0) { - item = new GridItem(grid, SWT.NONE); - item.setHeaderFont(fonts[fontIndex % 4]); - fontIndex++; - } else { - item = grid.getItem(rowCount); - } - item.setText(colCount, (rowCount + 1) + "." + (colCount + 1)); - } - } - - // Need to call it after items has been created, because the size has to be recomputed. - grid.setRowHeaderVisible(true); - - - shell.setSize(500, 500); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - for (Font f : fonts) { - f.dispose(); - } - - display.dispose(); - } +/******************************************************************************* + * Copyright (c) 2019 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron@gmail.com) - initial API and + * implementation + *******************************************************************************/ + +package org.eclipse.nebula.snippets.grid; + +import org.eclipse.nebula.widgets.grid.Grid; +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.nebula.widgets.grid.GridItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * This snippet show custom header font + */ +public class GridSnippet11 { + + public static void main(String[] args) { + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + + Grid grid = new Grid(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + grid.setHeaderVisible(true); + grid.setCellSelectionEnabled(true); + grid.setRowHeaderVisible(true); + + Font[] fonts = new Font[4]; + fonts[0] = new Font(display, "Consolas", 11, SWT.NONE); + fonts[1] = new Font(display, "Arial", 12, SWT.ITALIC); + fonts[2] = new Font(display, "Calibri", 10, SWT.BOLD); + fonts[3] = new Font(display, "Courier New", 13, SWT.BOLD | SWT.ITALIC); + + int fontIndex = 0; + for (int colCount = 0; colCount < 4; colCount++) { + GridColumn column = new GridColumn(grid, SWT.NONE); + column.setText("Column " + (colCount + 1)); + column.setWidth(100); + for (int rowCount = 0; rowCount < 50; rowCount++) { + final GridItem item; + if (colCount == 0) { + item = new GridItem(grid, SWT.NONE); + item.setHeaderFont(fonts[fontIndex % 4]); + fontIndex++; + } else { + item = grid.getItem(rowCount); + } + item.setText(colCount, (rowCount + 1) + "." + (colCount + 1)); + } + } + + // Need to call it after items has been created, because the size has to be recomputed. + grid.setRowHeaderVisible(true); + + + shell.setSize(500, 500); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + for (Font f : fonts) { + f.dispose(); + } + + display.dispose(); + } } \ No newline at end of file diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/TestBug351227.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/TestBug351227.java index b047454dc..82e646ac2 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/TestBug351227.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/TestBug351227.java @@ -1,46 +1,46 @@ -package org.eclipse.nebula.snippets.grid; - -import org.eclipse.nebula.widgets.grid.Grid; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.GridItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -public class TestBug351227 { - - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - - Grid grid = new Grid(shell, SWT.BORDER | SWT.V_SCROLL); - grid.setHeaderVisible(true); - grid.setCellSelectionEnabled(true); - - for (int colCount = 0; colCount < 4; colCount++) { - GridColumn column = new GridColumn(grid, SWT.NONE); - column.setText("Column " + (colCount + 1)); - column.setWidth(100); - for (int rowCount = 0; rowCount < 50; rowCount++) { - final GridItem item; - if (colCount == 0) { - item = new GridItem(grid, SWT.NONE); - } else { - item = grid.getItem(rowCount); - } - item.setText(colCount, (rowCount + 1) + "." + (colCount + 1)); - } - } - - - shell.setSize(500, 500); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - display.dispose(); - } +package org.eclipse.nebula.snippets.grid; + +import org.eclipse.nebula.widgets.grid.Grid; +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.nebula.widgets.grid.GridItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class TestBug351227 { + + public static void main(String[] args) { + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + + Grid grid = new Grid(shell, SWT.BORDER | SWT.V_SCROLL); + grid.setHeaderVisible(true); + grid.setCellSelectionEnabled(true); + + for (int colCount = 0; colCount < 4; colCount++) { + GridColumn column = new GridColumn(grid, SWT.NONE); + column.setText("Column " + (colCount + 1)); + column.setWidth(100); + for (int rowCount = 0; rowCount < 50; rowCount++) { + final GridItem item; + if (colCount == 0) { + item = new GridItem(grid, SWT.NONE); + } else { + item = grid.getItem(rowCount); + } + item.setText(colCount, (rowCount + 1) + "." + (colCount + 1)); + } + } + + + shell.setSize(500, 500); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } } \ No newline at end of file diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/TestBug387468.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/TestBug387468.java index e68675c91..97641298d 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/TestBug387468.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/TestBug387468.java @@ -1,84 +1,84 @@ -package org.eclipse.nebula.snippets.grid; - -import org.eclipse.nebula.widgets.grid.Grid; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.GridItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Create a grid with an item that spans rows. - * - * For a list of all Nebula Grid example snippets see - * http://www.eclipse.org/nebula/widgets/grid/snippets.php - */ -public class TestBug387468 { - - /** - * - * @param args - */ - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - - Grid grid = new Grid(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); - - grid.setHeaderVisible(true); - GridColumn column = new GridColumn(grid, SWT.NONE); - column.setText("Employee"); - column.setWidth(100); - - GridColumn column2 = new GridColumn(grid, SWT.NONE); - column2.setText("Company"); - column2.setWidth(100); - - GridItem item1 = new GridItem(grid, SWT.NONE); - item1.setText("Anne"); - item1.setText(1, "Company A"); - item1.setRowSpan(1, 2); - - GridItem item2 = new GridItem(grid, SWT.NONE); - item2.setText("Jim"); - item1.setText(1, "Company A"); - item2.setRowSpan(1, 2); - - GridItem item3 = new GridItem(grid, SWT.NONE); - item3.setText("Sara"); - item3.setText(1, "Company A"); - item3.setRowSpan(1, 2); - - GridItem item4 = new GridItem(grid, SWT.NONE); - item4.setText("Tom"); - item4.setText(1, "Company B"); - item4.setRowSpan(1, 1); - - GridItem item5 = new GridItem(grid, SWT.NONE); - item5.setText("Nathalie"); - item5.setText(1, "Company B"); - item5.setRowSpan(1, 1); - - GridItem item6 = new GridItem(grid, SWT.NONE); - item6.setText("Wim"); - item6.setText(1, "Company C"); - item6.setRowSpan(1, 1); - - GridItem item7 = new GridItem(grid, SWT.NONE); - item7.setText("Pauline"); - item7.setText(1, "Company C"); - item7.setRowSpan(1, 1); - - shell.setSize(300, 300); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - display.dispose(); - } +package org.eclipse.nebula.snippets.grid; + +import org.eclipse.nebula.widgets.grid.Grid; +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.nebula.widgets.grid.GridItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Create a grid with an item that spans rows. + * + * For a list of all Nebula Grid example snippets see + * http://www.eclipse.org/nebula/widgets/grid/snippets.php + */ +public class TestBug387468 { + + /** + * + * @param args + */ + public static void main(String[] args) { + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + + Grid grid = new Grid(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + + grid.setHeaderVisible(true); + GridColumn column = new GridColumn(grid, SWT.NONE); + column.setText("Employee"); + column.setWidth(100); + + GridColumn column2 = new GridColumn(grid, SWT.NONE); + column2.setText("Company"); + column2.setWidth(100); + + GridItem item1 = new GridItem(grid, SWT.NONE); + item1.setText("Anne"); + item1.setText(1, "Company A"); + item1.setRowSpan(1, 2); + + GridItem item2 = new GridItem(grid, SWT.NONE); + item2.setText("Jim"); + item1.setText(1, "Company A"); + item2.setRowSpan(1, 2); + + GridItem item3 = new GridItem(grid, SWT.NONE); + item3.setText("Sara"); + item3.setText(1, "Company A"); + item3.setRowSpan(1, 2); + + GridItem item4 = new GridItem(grid, SWT.NONE); + item4.setText("Tom"); + item4.setText(1, "Company B"); + item4.setRowSpan(1, 1); + + GridItem item5 = new GridItem(grid, SWT.NONE); + item5.setText("Nathalie"); + item5.setText(1, "Company B"); + item5.setRowSpan(1, 1); + + GridItem item6 = new GridItem(grid, SWT.NONE); + item6.setText("Wim"); + item6.setText(1, "Company C"); + item6.setRowSpan(1, 1); + + GridItem item7 = new GridItem(grid, SWT.NONE); + item7.setText("Pauline"); + item7.setText(1, "Company C"); + item7.setRowSpan(1, 1); + + shell.setSize(300, 300); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + display.dispose(); + } } \ No newline at end of file diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerShortTextPerformance.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerShortTextPerformance.java index ad7335890..724f5cb17 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerShortTextPerformance.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerShortTextPerformance.java @@ -1,250 +1,250 @@ -package org.eclipse.nebula.snippets.grid.viewer; - -import java.io.StringWriter; - -/******************************************************************************* - * Copyright (c) 2016 Mirko Paturzo (Exeura srl). - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Mirko Paturzo - improve Grid Export, dispose, fonts and background - * functional changes - *******************************************************************************/ - -import org.eclipse.jface.resource.FontRegistry; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.ITableColorProvider; -import org.eclipse.jface.viewers.ITableFontProvider; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.nebula.jface.gridviewer.GridTableViewer; -import org.eclipse.nebula.jface.gridviewer.GridViewerEditor; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * - * Test of the grid with long text. - * - * @author Mirko Paturzo - */ -public class GridViewerShortTextPerformance -{ - - private static final int NUM_COLUMNS = 2; - private static final int NUM_MODELS = 10; - private static final int HOW_MANY_TEXT_LINE = 100000; - - private static final String LINE = "Ground Control to Major Tom.."; - - private class MyContentProvider implements IStructuredContentProvider - { - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) - */ - public Object[] getElements(Object inputElement) - { - return (MyModel[]) inputElement; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IContentProvider#dispose() - */ - public void dispose() - { - - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, - * java.lang.Object, java.lang.Object) - */ - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) - { - - } - - } - - public static boolean flag = true; - - public class MyModel - { - public int counter; - - public MyModel(int counter) - { - this.counter = counter; - } - - @Override - public String toString() - { - return "Item " + this.counter; - } - } - - private static String doBigText() - { - StringWriter writer = new StringWriter(); - for (int i = 0; i < HOW_MANY_TEXT_LINE; i++) - { - writer.append(LINE); - } -// writer.append("\n"); - return writer.toString(); - } - - public class MyLabelProvider extends LabelProvider - implements ITableLabelProvider, ITableFontProvider, ITableColorProvider - { - FontRegistry registry = new FontRegistry(); - - public Image getColumnImage(Object element, int columnIndex) - { - return null; - } - - public String getColumnText(Object element, int columnIndex) - { - if (columnIndex == 0) - return "Row " + element.toString(); - - return doBigText(); - } - - public Font getFont(Object element, int columnIndex) - { - if (((MyModel) element).counter % 2 == 0) - { - return registry.getBold(Display.getCurrent().getSystemFont().getFontData()[0].getName()); - } - return null; - } - - public Color getBackground(Object element, int columnIndex) - { - if (((MyModel) element).counter % 2 == 0) - { - return Display.getCurrent().getSystemColor(SWT.COLOR_RED); - } - return null; - } - - public Color getForeground(Object element, int columnIndex) - { - if (((MyModel) element).counter % 2 == 1) - { - return Display.getCurrent().getSystemColor(SWT.COLOR_RED); - } - return null; - } - - } - - public GridViewerShortTextPerformance(Shell shell) - { - final GridTableViewer v = new GridTableViewer(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); - v.setLabelProvider(new MyLabelProvider()); - v.setContentProvider(new MyContentProvider()); - v.getGrid().setCellSelectionEnabled(true); - - v.setCellEditors(new CellEditor[] { new TextCellEditor(v.getGrid()), new TextCellEditor(v.getGrid()) }); - - v.setColumnProperties(new String[] { "1", "2" }); - - ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(v) - { - - @Override - protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) - { - return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL - || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION - || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED - && event.keyCode == SWT.CR); - } - }; - - GridViewerEditor.create(v, actSupport, - ColumnViewerEditor.TABBING_HORIZONTAL | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR - | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION); - - for (int i = 0; i < NUM_COLUMNS; i++) - { - createColumn(v, "Column " + i); - } - - MyModel[] model = createModel(); - v.setInput(model); - v.getGrid().setLinesVisible(true); - v.getGrid().setHeaderVisible(true); - } - - private void createColumn(final GridTableViewer v, String name) - { - GridColumn column = new GridColumn(v.getGrid(), SWT.NONE); - column.setWidth(200); - column.setText(name); - } - - private MyModel[] createModel() - { - MyModel[] elements = new MyModel[NUM_MODELS]; - - for (int i = 0; i < NUM_MODELS; i++) - { - elements[i] = new MyModel(i); - } - - return elements; - } - - /** - * @param args - */ - public static void main(String[] args) - { - Display display = new Display(); - - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - new GridViewerShortTextPerformance(shell); - shell.open(); - - while (!shell.isDisposed()) - { - if (!display.readAndDispatch()) - display.sleep(); - } - - display.dispose(); - - } - -} +package org.eclipse.nebula.snippets.grid.viewer; + +import java.io.StringWriter; + +/******************************************************************************* + * Copyright (c) 2016 Mirko Paturzo (Exeura srl). + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Mirko Paturzo - improve Grid Export, dispose, fonts and background + * functional changes + *******************************************************************************/ + +import org.eclipse.jface.resource.FontRegistry; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.nebula.jface.gridviewer.GridTableViewer; +import org.eclipse.nebula.jface.gridviewer.GridViewerEditor; +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * + * Test of the grid with long text. + * + * @author Mirko Paturzo + */ +public class GridViewerShortTextPerformance +{ + + private static final int NUM_COLUMNS = 2; + private static final int NUM_MODELS = 10; + private static final int HOW_MANY_TEXT_LINE = 100000; + + private static final String LINE = "Ground Control to Major Tom.."; + + private class MyContentProvider implements IStructuredContentProvider + { + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) + { + return (MyModel[]) inputElement; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() + { + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) + { + + } + + } + + public static boolean flag = true; + + public class MyModel + { + public int counter; + + public MyModel(int counter) + { + this.counter = counter; + } + + @Override + public String toString() + { + return "Item " + this.counter; + } + } + + private static String doBigText() + { + StringWriter writer = new StringWriter(); + for (int i = 0; i < HOW_MANY_TEXT_LINE; i++) + { + writer.append(LINE); + } +// writer.append("\n"); + return writer.toString(); + } + + public class MyLabelProvider extends LabelProvider + implements ITableLabelProvider, ITableFontProvider, ITableColorProvider + { + FontRegistry registry = new FontRegistry(); + + public Image getColumnImage(Object element, int columnIndex) + { + return null; + } + + public String getColumnText(Object element, int columnIndex) + { + if (columnIndex == 0) + return "Row " + element.toString(); + + return doBigText(); + } + + public Font getFont(Object element, int columnIndex) + { + if (((MyModel) element).counter % 2 == 0) + { + return registry.getBold(Display.getCurrent().getSystemFont().getFontData()[0].getName()); + } + return null; + } + + public Color getBackground(Object element, int columnIndex) + { + if (((MyModel) element).counter % 2 == 0) + { + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + } + return null; + } + + public Color getForeground(Object element, int columnIndex) + { + if (((MyModel) element).counter % 2 == 1) + { + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + } + return null; + } + + } + + public GridViewerShortTextPerformance(Shell shell) + { + final GridTableViewer v = new GridTableViewer(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + v.setLabelProvider(new MyLabelProvider()); + v.setContentProvider(new MyContentProvider()); + v.getGrid().setCellSelectionEnabled(true); + + v.setCellEditors(new CellEditor[] { new TextCellEditor(v.getGrid()), new TextCellEditor(v.getGrid()) }); + + v.setColumnProperties(new String[] { "1", "2" }); + + ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(v) + { + + @Override + protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) + { + return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL + || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION + || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED + && event.keyCode == SWT.CR); + } + }; + + GridViewerEditor.create(v, actSupport, + ColumnViewerEditor.TABBING_HORIZONTAL | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR + | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION); + + for (int i = 0; i < NUM_COLUMNS; i++) + { + createColumn(v, "Column " + i); + } + + MyModel[] model = createModel(); + v.setInput(model); + v.getGrid().setLinesVisible(true); + v.getGrid().setHeaderVisible(true); + } + + private void createColumn(final GridTableViewer v, String name) + { + GridColumn column = new GridColumn(v.getGrid(), SWT.NONE); + column.setWidth(200); + column.setText(name); + } + + private MyModel[] createModel() + { + MyModel[] elements = new MyModel[NUM_MODELS]; + + for (int i = 0; i < NUM_MODELS; i++) + { + elements[i] = new MyModel(i); + } + + return elements; + } + + /** + * @param args + */ + public static void main(String[] args) + { + Display display = new Display(); + + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + new GridViewerShortTextPerformance(shell); + shell.open(); + + while (!shell.isDisposed()) + { + if (!display.readAndDispatch()) + display.sleep(); + } + + display.dispose(); + + } + +} diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithAdaptedDataVisualizer.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithAdaptedDataVisualizer.java index b3892e432..73a7dfdff 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithAdaptedDataVisualizer.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithAdaptedDataVisualizer.java @@ -1,274 +1,274 @@ -package org.eclipse.nebula.snippets.grid.viewer; - -/******************************************************************************* - * Copyright (c) 2006 Tom Schindl and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Tom Schindl - initial API and implementation - * Mirko Paturzo - adapt the example for AdaptedDataVisualizer - *******************************************************************************/ - -import org.eclipse.jface.resource.FontRegistry; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; -import org.eclipse.jface.viewers.ICellModifier; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.ITableColorProvider; -import org.eclipse.jface.viewers.ITableFontProvider; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.nebula.jface.gridviewer.GridTableViewer; -import org.eclipse.nebula.jface.gridviewer.GridViewerEditor; -import org.eclipse.nebula.widgets.grid.AdaptedDataVisualizer; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.GridItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Example usage of none mandatory interfaces of ITableFontProvider and - * ITableColorProvider - * - * @author Tom Schindl - * @author Mirko Paturzo - * - * Example with {@link AdaptedDataVisualizer} - */ -public class GridViewerSnippetWithAdaptedDataVisualizer { - - private static final int NUM_COLUMNS = 1000; - private static final int NUM_MODELS = 1000; - - private class MyContentProvider implements IStructuredContentProvider { - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) - */ - public Object[] getElements(Object inputElement) { - return (MyModel[]) inputElement; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IContentProvider#dispose() - */ - public void dispose() { - - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, - * java.lang.Object, java.lang.Object) - */ - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - - } - - } - - public static boolean flag = true; - - public class MyModel { - public int counter; - - public MyModel(int counter) { - this.counter = counter; - } - - @Override - public String toString() { - return "Item " + this.counter; - } - } - - public class MyLabelProvider extends LabelProvider implements ITableLabelProvider, ITableFontProvider, - ITableColorProvider { - FontRegistry registry = new FontRegistry(); - - public Image getColumnImage(Object element, int columnIndex) { - return null; - } - - public String getColumnText(Object element, int columnIndex) { - return "Column " + columnIndex + " => " + element.toString(); - } - - public Font getFont(Object element, int columnIndex) { - if (((MyModel) element).counter % 2 == 0) { - return registry.getBold(Display.getCurrent().getSystemFont().getFontData()[0].getName()); - } - return null; - } - - public Color getBackground(Object element, int columnIndex) { - if (((MyModel) element).counter % 2 == 0) { - return Display.getCurrent().getSystemColor(SWT.COLOR_RED); - } - return null; - } - - public Color getForeground(Object element, int columnIndex) { - if (((MyModel) element).counter % 2 == 1) { - return Display.getCurrent().getSystemColor(SWT.COLOR_RED); - } - return null; - } - - } - - /** - * Below myown AdaptedDataVisualizer - * @author Mirko Paturzo - * - */ - private static class MyOwnDataVisualizer extends AdaptedDataVisualizer { - FontRegistry registry = new FontRegistry(); - - private final MyModel models[]; - - public MyOwnDataVisualizer(MyModel models[]) { - this.models = models; - } - - @Override - public Image getImage(GridItem gridItem, int columnIndex) { - return null; - } - - @Override - public String getText(GridItem gridItem, int columnIndex) { - return "Column " + columnIndex + " => " + models[gridItem.getRowIndex()].toString(); - } - - @Override - public Font getFont(GridItem gridItem, int columnIndex) { - if ((models[gridItem.getRowIndex()]).counter % 2 == 0) { - return registry.getBold(Display.getCurrent().getSystemFont().getFontData()[0].getName()); - } - return null; - } - - @Override - public Color getBackground(GridItem gridItem, int columnIndex) { - if ((models[gridItem.getRowIndex()]).counter % 2 == 0) { - return Display.getCurrent().getSystemColor(SWT.COLOR_RED); - } - return Display.getCurrent().getSystemColor(SWT.COLOR_WHITE); - } - - @Override - public Color getForeground(GridItem gridItem, int columnIndex) { - if ((models[gridItem.getRowIndex()]).counter % 2 == 1) { - return Display.getCurrent().getSystemColor(SWT.COLOR_RED); - } - return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); - } - } - - public GridViewerSnippetWithAdaptedDataVisualizer(Shell shell) { - MyModel[] models = createModel(); - final GridTableViewer v = new GridTableViewer(new MyOwnDataVisualizer(models), shell, SWT.BORDER | SWT.V_SCROLL - | SWT.H_SCROLL); - v.setLabelProvider(new MyLabelProvider()); - v.setContentProvider(new MyContentProvider()); - v.getGrid().setCellSelectionEnabled(true); - - v.setCellEditors(new CellEditor[] { new TextCellEditor(v.getGrid()), new TextCellEditor(v.getGrid()) }); - v.setCellModifier(new ICellModifier() { - - public boolean canModify(Object element, String property) { - return true; - } - - public Object getValue(Object element, String property) { - return "Column " + property + " => " + element.toString(); - } - - public void modify(Object element, String property, Object value) { - - } - - }); - - v.setColumnProperties(new String[] { "1", "2" }); - - ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(v) { - @Override - protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) { - return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL - || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION - || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR); - } - }; - - GridViewerEditor.create(v, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL - | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL - | ColumnViewerEditor.KEYBOARD_ACTIVATION); - - for (int i = 0; i < NUM_COLUMNS; i++) { - createColumn(v, "Column " + i); - } - - v.setInput(models); - v.getGrid().setLinesVisible(true); - v.getGrid().setHeaderVisible(true); - } - - private void createColumn(final GridTableViewer v, String name) { - GridColumn column = new GridColumn(v.getGrid(), SWT.NONE); - column.setWidth(200); - column.setText(name); - } - - private MyModel[] createModel() { - MyModel[] elements = new MyModel[NUM_MODELS]; - - for (int i = 0; i < NUM_MODELS; i++) { - elements[i] = new MyModel(i); - } - - return elements; - } - - /** - * @param args - */ - public static void main(String[] args) { - Display display = new Display(); - - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - new GridViewerSnippetWithAdaptedDataVisualizer(shell); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - display.dispose(); - - } - -} +package org.eclipse.nebula.snippets.grid.viewer; + +/******************************************************************************* + * Copyright (c) 2006 Tom Schindl and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Tom Schindl - initial API and implementation + * Mirko Paturzo - adapt the example for AdaptedDataVisualizer + *******************************************************************************/ + +import org.eclipse.jface.resource.FontRegistry; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.nebula.jface.gridviewer.GridTableViewer; +import org.eclipse.nebula.jface.gridviewer.GridViewerEditor; +import org.eclipse.nebula.widgets.grid.AdaptedDataVisualizer; +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.nebula.widgets.grid.GridItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Example usage of none mandatory interfaces of ITableFontProvider and + * ITableColorProvider + * + * @author Tom Schindl + * @author Mirko Paturzo + * + * Example with {@link AdaptedDataVisualizer} + */ +public class GridViewerSnippetWithAdaptedDataVisualizer { + + private static final int NUM_COLUMNS = 1000; + private static final int NUM_MODELS = 1000; + + private class MyContentProvider implements IStructuredContentProvider { + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return (MyModel[]) inputElement; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + + } + + } + + public static boolean flag = true; + + public class MyModel { + public int counter; + + public MyModel(int counter) { + this.counter = counter; + } + + @Override + public String toString() { + return "Item " + this.counter; + } + } + + public class MyLabelProvider extends LabelProvider implements ITableLabelProvider, ITableFontProvider, + ITableColorProvider { + FontRegistry registry = new FontRegistry(); + + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + public String getColumnText(Object element, int columnIndex) { + return "Column " + columnIndex + " => " + element.toString(); + } + + public Font getFont(Object element, int columnIndex) { + if (((MyModel) element).counter % 2 == 0) { + return registry.getBold(Display.getCurrent().getSystemFont().getFontData()[0].getName()); + } + return null; + } + + public Color getBackground(Object element, int columnIndex) { + if (((MyModel) element).counter % 2 == 0) { + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + } + return null; + } + + public Color getForeground(Object element, int columnIndex) { + if (((MyModel) element).counter % 2 == 1) { + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + } + return null; + } + + } + + /** + * Below myown AdaptedDataVisualizer + * @author Mirko Paturzo + * + */ + private static class MyOwnDataVisualizer extends AdaptedDataVisualizer { + FontRegistry registry = new FontRegistry(); + + private final MyModel models[]; + + public MyOwnDataVisualizer(MyModel models[]) { + this.models = models; + } + + @Override + public Image getImage(GridItem gridItem, int columnIndex) { + return null; + } + + @Override + public String getText(GridItem gridItem, int columnIndex) { + return "Column " + columnIndex + " => " + models[gridItem.getRowIndex()].toString(); + } + + @Override + public Font getFont(GridItem gridItem, int columnIndex) { + if ((models[gridItem.getRowIndex()]).counter % 2 == 0) { + return registry.getBold(Display.getCurrent().getSystemFont().getFontData()[0].getName()); + } + return null; + } + + @Override + public Color getBackground(GridItem gridItem, int columnIndex) { + if ((models[gridItem.getRowIndex()]).counter % 2 == 0) { + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + } + return Display.getCurrent().getSystemColor(SWT.COLOR_WHITE); + } + + @Override + public Color getForeground(GridItem gridItem, int columnIndex) { + if ((models[gridItem.getRowIndex()]).counter % 2 == 1) { + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + } + return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); + } + } + + public GridViewerSnippetWithAdaptedDataVisualizer(Shell shell) { + MyModel[] models = createModel(); + final GridTableViewer v = new GridTableViewer(new MyOwnDataVisualizer(models), shell, SWT.BORDER | SWT.V_SCROLL + | SWT.H_SCROLL); + v.setLabelProvider(new MyLabelProvider()); + v.setContentProvider(new MyContentProvider()); + v.getGrid().setCellSelectionEnabled(true); + + v.setCellEditors(new CellEditor[] { new TextCellEditor(v.getGrid()), new TextCellEditor(v.getGrid()) }); + v.setCellModifier(new ICellModifier() { + + public boolean canModify(Object element, String property) { + return true; + } + + public Object getValue(Object element, String property) { + return "Column " + property + " => " + element.toString(); + } + + public void modify(Object element, String property, Object value) { + + } + + }); + + v.setColumnProperties(new String[] { "1", "2" }); + + ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(v) { + @Override + protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) { + return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL + || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION + || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR); + } + }; + + GridViewerEditor.create(v, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL + | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL + | ColumnViewerEditor.KEYBOARD_ACTIVATION); + + for (int i = 0; i < NUM_COLUMNS; i++) { + createColumn(v, "Column " + i); + } + + v.setInput(models); + v.getGrid().setLinesVisible(true); + v.getGrid().setHeaderVisible(true); + } + + private void createColumn(final GridTableViewer v, String name) { + GridColumn column = new GridColumn(v.getGrid(), SWT.NONE); + column.setWidth(200); + column.setText(name); + } + + private MyModel[] createModel() { + MyModel[] elements = new MyModel[NUM_MODELS]; + + for (int i = 0; i < NUM_MODELS; i++) { + elements[i] = new MyModel(i); + } + + return elements; + } + + /** + * @param args + */ + public static void main(String[] args) { + Display display = new Display(); + + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + new GridViewerSnippetWithAdaptedDataVisualizer(shell); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + display.dispose(); + + } + +} diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithGridItemDataVisualizer.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithGridItemDataVisualizer.java index 8c2717cca..5472bbb6c 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithGridItemDataVisualizer.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithGridItemDataVisualizer.java @@ -1,238 +1,238 @@ -package org.eclipse.nebula.snippets.grid.viewer; - -/******************************************************************************* - * Copyright (c) 2006 Tom Schindl and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Tom Schindl - initial API and implementation - * Mirko Paturzo - improve Grid Export, dispose, fonts and background - * functional changes - *******************************************************************************/ - - -import org.eclipse.jface.resource.FontRegistry; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; -import org.eclipse.jface.viewers.ICellModifier; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.ITableColorProvider; -import org.eclipse.jface.viewers.ITableFontProvider; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.nebula.jface.gridviewer.GridTableViewer; -import org.eclipse.nebula.jface.gridviewer.GridViewerEditor; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Example usage of none mandatory interfaces of ITableFontProvider and - * ITableColorProvider - * - * @author Tom Schindl - * @author Mirko Paturzo - * - * Original example, with something else (NUM_COLUMNS, NUM_MODELS) - * Using {@link ColumnRowBigDataVisualizer} - * - */ -public class GridViewerSnippetWithGridItemDataVisualizer { - - private static final int NUM_COLUMNS = 1000; - private static final int NUM_MODELS = 1000; - - private class MyContentProvider implements IStructuredContentProvider { - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) - */ - public Object[] getElements(Object inputElement) { - return (MyModel[]) inputElement; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IContentProvider#dispose() - */ - public void dispose() { - - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, - * java.lang.Object, java.lang.Object) - */ - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - - } - - } - - public static boolean flag = true; - - public class MyModel { - public int counter; - - public MyModel(int counter) { - this.counter = counter; - } - - - @Override - public String toString() { - return "Item " + this.counter; - } - } - - public class MyLabelProvider extends LabelProvider implements - ITableLabelProvider, ITableFontProvider, ITableColorProvider { - FontRegistry registry = new FontRegistry(); - - - public Image getColumnImage(Object element, int columnIndex) { - return null; - } - - - public String getColumnText(Object element, int columnIndex) { - return "Column " + columnIndex + " => " + element.toString(); - } - - - public Font getFont(Object element, int columnIndex) { - if (((MyModel) element).counter % 2 == 0) { - return registry.getBold(Display.getCurrent().getSystemFont() - .getFontData()[0].getName()); - } - return null; - } - - - public Color getBackground(Object element, int columnIndex) { - if (((MyModel) element).counter % 2 == 0) { - return Display.getCurrent().getSystemColor(SWT.COLOR_RED); - } - return null; - } - - - public Color getForeground(Object element, int columnIndex) { - if (((MyModel) element).counter % 2 == 1) { - return Display.getCurrent().getSystemColor(SWT.COLOR_RED); - } - return null; - } - - } - - public GridViewerSnippetWithGridItemDataVisualizer(Shell shell) { - final GridTableViewer v = new GridTableViewer(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); - v.setLabelProvider(new MyLabelProvider()); - v.setContentProvider(new MyContentProvider()); - v.getGrid().setCellSelectionEnabled(true); - - v.setCellEditors(new CellEditor[] { new TextCellEditor(v.getGrid()), new TextCellEditor(v.getGrid()) }); - v.setCellModifier(new ICellModifier() { - - - public boolean canModify(Object element, String property) { - return true; - } - - - public Object getValue(Object element, String property) { - return "Column " + property + " => " + element.toString(); - } - - - public void modify(Object element, String property, Object value) { - - } - - }); - - v.setColumnProperties(new String[] {"1","2"}); - - ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(v) { - - @Override - protected boolean isEditorActivationEvent( - ColumnViewerEditorActivationEvent event) { - return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL - || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION - || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR); - } - }; - - GridViewerEditor.create(v, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL - | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR - | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION); - - for(int i = 0; i < NUM_COLUMNS; i++) { - createColumn(v, "Column " + i); - } - - MyModel[] model = createModel(); - v.setInput(model); - v.getGrid().setLinesVisible(true); - v.getGrid().setHeaderVisible(true); - } - - private void createColumn(final GridTableViewer v, String name) { - GridColumn column = new GridColumn(v.getGrid(), SWT.NONE); - column.setWidth(200); - column.setText(name); - } - - private MyModel[] createModel() { - MyModel[] elements = new MyModel[NUM_MODELS]; - - for (int i = 0; i < NUM_MODELS; i++) { - elements[i] = new MyModel(i); - } - - return elements; - } - - /** - * @param args - */ - public static void main(String[] args) { - Display display = new Display(); - - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - new GridViewerSnippetWithGridItemDataVisualizer(shell); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - display.dispose(); - - } - -} +package org.eclipse.nebula.snippets.grid.viewer; + +/******************************************************************************* + * Copyright (c) 2006 Tom Schindl and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Tom Schindl - initial API and implementation + * Mirko Paturzo - improve Grid Export, dispose, fonts and background + * functional changes + *******************************************************************************/ + + +import org.eclipse.jface.resource.FontRegistry; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.nebula.jface.gridviewer.GridTableViewer; +import org.eclipse.nebula.jface.gridviewer.GridViewerEditor; +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Example usage of none mandatory interfaces of ITableFontProvider and + * ITableColorProvider + * + * @author Tom Schindl + * @author Mirko Paturzo + * + * Original example, with something else (NUM_COLUMNS, NUM_MODELS) + * Using {@link ColumnRowBigDataVisualizer} + * + */ +public class GridViewerSnippetWithGridItemDataVisualizer { + + private static final int NUM_COLUMNS = 1000; + private static final int NUM_MODELS = 1000; + + private class MyContentProvider implements IStructuredContentProvider { + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return (MyModel[]) inputElement; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + + } + + } + + public static boolean flag = true; + + public class MyModel { + public int counter; + + public MyModel(int counter) { + this.counter = counter; + } + + + @Override + public String toString() { + return "Item " + this.counter; + } + } + + public class MyLabelProvider extends LabelProvider implements + ITableLabelProvider, ITableFontProvider, ITableColorProvider { + FontRegistry registry = new FontRegistry(); + + + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + + public String getColumnText(Object element, int columnIndex) { + return "Column " + columnIndex + " => " + element.toString(); + } + + + public Font getFont(Object element, int columnIndex) { + if (((MyModel) element).counter % 2 == 0) { + return registry.getBold(Display.getCurrent().getSystemFont() + .getFontData()[0].getName()); + } + return null; + } + + + public Color getBackground(Object element, int columnIndex) { + if (((MyModel) element).counter % 2 == 0) { + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + } + return null; + } + + + public Color getForeground(Object element, int columnIndex) { + if (((MyModel) element).counter % 2 == 1) { + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + } + return null; + } + + } + + public GridViewerSnippetWithGridItemDataVisualizer(Shell shell) { + final GridTableViewer v = new GridTableViewer(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + v.setLabelProvider(new MyLabelProvider()); + v.setContentProvider(new MyContentProvider()); + v.getGrid().setCellSelectionEnabled(true); + + v.setCellEditors(new CellEditor[] { new TextCellEditor(v.getGrid()), new TextCellEditor(v.getGrid()) }); + v.setCellModifier(new ICellModifier() { + + + public boolean canModify(Object element, String property) { + return true; + } + + + public Object getValue(Object element, String property) { + return "Column " + property + " => " + element.toString(); + } + + + public void modify(Object element, String property, Object value) { + + } + + }); + + v.setColumnProperties(new String[] {"1","2"}); + + ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(v) { + + @Override + protected boolean isEditorActivationEvent( + ColumnViewerEditorActivationEvent event) { + return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL + || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION + || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR); + } + }; + + GridViewerEditor.create(v, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL + | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR + | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION); + + for(int i = 0; i < NUM_COLUMNS; i++) { + createColumn(v, "Column " + i); + } + + MyModel[] model = createModel(); + v.setInput(model); + v.getGrid().setLinesVisible(true); + v.getGrid().setHeaderVisible(true); + } + + private void createColumn(final GridTableViewer v, String name) { + GridColumn column = new GridColumn(v.getGrid(), SWT.NONE); + column.setWidth(200); + column.setText(name); + } + + private MyModel[] createModel() { + MyModel[] elements = new MyModel[NUM_MODELS]; + + for (int i = 0; i < NUM_MODELS; i++) { + elements[i] = new MyModel(i); + } + + return elements; + } + + /** + * @param args + */ + public static void main(String[] args) { + Display display = new Display(); + + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + new GridViewerSnippetWithGridItemDataVisualizer(shell); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + display.dispose(); + + } + +} diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridVirtualTableViewer.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridVirtualTableViewer.java index eec8bec52..2b9b36243 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridVirtualTableViewer.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridVirtualTableViewer.java @@ -1,153 +1,153 @@ -package org.eclipse.nebula.snippets.grid.viewer; - -/******************************************************************************* - * Copyright (c) 2014 Mirko Paturzo (Exeura srl). - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Mirko Paturzo - realize example - *******************************************************************************/ - -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.nebula.jface.gridviewer.GridTableViewer; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple TableViewer to demonstrate the usage of a lazy content provider - * with a virtual table - */ -public class GridVirtualTableViewer { - - private static final int ROWS = 1000000; - private static final int COLUMNS = 10; - - private class MyContentProvider implements IStructuredContentProvider { - public MyContentProvider(GridTableViewer viewer) { - - } - public void dispose() { - // TODO Auto-generated method stub - - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // TODO Auto-generated method stub - - } - - public Object[] getElements(Object inputElement) { - return (Object[]) inputElement; - } - - } - - public class MyModel { - public int counter; - - public MyModel(int counter) { - this.counter = counter; - } - - @Override - public String toString() { - return "Item " + this.counter; - } - } - - public GridVirtualTableViewer(Shell shell) { - LabelProvider labelProvider = new LabelProvider(); - final GridTableViewer v = new GridTableViewer(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.VIRTUAL); - - v.setLabelProvider(labelProvider); - v.setContentProvider(new MyContentProvider(v)); - v.setUseHashlookup(true); - v.getGrid().setLinesVisible(true); - v.getGrid().setHeaderVisible(true); - v.getGrid().setVisibleLinesColumnPack(true); -// v.getGrid().setRowHeaderVisible(true); -// v.setRowHeaderLabelProvider(new ColumnLabelProvider() { -// @Override -// public String getText(Object element) { -// return "xyz"; -// } -// }); - v.getGrid().setLayoutData(new GridData(GridData.FILL_BOTH)); - - for (int i = 0; i < COLUMNS; i++) - { - createColumn(v, "Column"); - } - - MyModel[] model = createModel(); - v.setInput(model); - - Button b = new Button(shell, SWT.PUSH); - b.setText("Filter items without 0"); - b.addSelectionListener(new SelectionListener() { - - public void widgetSelected(SelectionEvent arg0) { - v.addFilter(new ViewerFilter() { - - @Override - public boolean select(Viewer viewer, Object parentElement, Object element) { - return element.toString().contains("0"); - } - }); - } - - public void widgetDefaultSelected(SelectionEvent arg0) { - } - }); - } - private void createColumn(final GridTableViewer v, String name) { - GridColumn column = new GridColumn(v.getGrid(), SWT.NONE); - column.setWidth(200); - column.setText(name); - } - private MyModel[] createModel() { - MyModel[] elements = new MyModel[ROWS]; - - for (int i = 0; i < ROWS; i++) { - elements[i] = new MyModel(i); - } - - return elements; - } - - /** - * @param args - */ - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setLayout(new GridLayout()); - new GridVirtualTableViewer(shell); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - display.dispose(); - - } - +package org.eclipse.nebula.snippets.grid.viewer; + +/******************************************************************************* + * Copyright (c) 2014 Mirko Paturzo (Exeura srl). + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Mirko Paturzo - realize example + *******************************************************************************/ + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.nebula.jface.gridviewer.GridTableViewer; +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple TableViewer to demonstrate the usage of a lazy content provider + * with a virtual table + */ +public class GridVirtualTableViewer { + + private static final int ROWS = 1000000; + private static final int COLUMNS = 10; + + private class MyContentProvider implements IStructuredContentProvider { + public MyContentProvider(GridTableViewer viewer) { + + } + public void dispose() { + // TODO Auto-generated method stub + + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // TODO Auto-generated method stub + + } + + public Object[] getElements(Object inputElement) { + return (Object[]) inputElement; + } + + } + + public class MyModel { + public int counter; + + public MyModel(int counter) { + this.counter = counter; + } + + @Override + public String toString() { + return "Item " + this.counter; + } + } + + public GridVirtualTableViewer(Shell shell) { + LabelProvider labelProvider = new LabelProvider(); + final GridTableViewer v = new GridTableViewer(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.VIRTUAL); + + v.setLabelProvider(labelProvider); + v.setContentProvider(new MyContentProvider(v)); + v.setUseHashlookup(true); + v.getGrid().setLinesVisible(true); + v.getGrid().setHeaderVisible(true); + v.getGrid().setVisibleLinesColumnPack(true); +// v.getGrid().setRowHeaderVisible(true); +// v.setRowHeaderLabelProvider(new ColumnLabelProvider() { +// @Override +// public String getText(Object element) { +// return "xyz"; +// } +// }); + v.getGrid().setLayoutData(new GridData(GridData.FILL_BOTH)); + + for (int i = 0; i < COLUMNS; i++) + { + createColumn(v, "Column"); + } + + MyModel[] model = createModel(); + v.setInput(model); + + Button b = new Button(shell, SWT.PUSH); + b.setText("Filter items without 0"); + b.addSelectionListener(new SelectionListener() { + + public void widgetSelected(SelectionEvent arg0) { + v.addFilter(new ViewerFilter() { + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + return element.toString().contains("0"); + } + }); + } + + public void widgetDefaultSelected(SelectionEvent arg0) { + } + }); + } + private void createColumn(final GridTableViewer v, String name) { + GridColumn column = new GridColumn(v.getGrid(), SWT.NONE); + column.setWidth(200); + column.setText(name); + } + private MyModel[] createModel() { + MyModel[] elements = new MyModel[ROWS]; + + for (int i = 0; i < ROWS; i++) { + elements[i] = new MyModel(i); + } + + return elements; + } + + /** + * @param args + */ + public static void main(String[] args) { + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new GridLayout()); + new GridVirtualTableViewer(shell); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + display.dispose(); + + } + } \ No newline at end of file diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/pshelf/PShelfViewerSnippet1.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/pshelf/PShelfViewerSnippet1.java index e41123f46..e74599090 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/pshelf/PShelfViewerSnippet1.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/pshelf/PShelfViewerSnippet1.java @@ -1,150 +1,150 @@ -package org.eclipse.nebula.snippets.pshelf; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.ListViewer; -import org.eclipse.jface.viewers.StructuredViewer; -import org.eclipse.jface.viewers.TreeNode; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.nebula.jface.pshelfviewer.IShelfViewerFactory; -import org.eclipse.nebula.jface.pshelfviewer.PShelfViewer; -import org.eclipse.nebula.widgets.pshelf.RedmondShelfRenderer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -public class PShelfViewerSnippet1 { - - private MyTreeNode myModel; - private MyContentProvider myContentProvider; - private MyLabelProvider myLabelProvider; - - private class MyViewerFactory implements IShelfViewerFactory { - - public Viewer createViewerForContent(Composite parent, Object content) { - TreeNode node = (TreeNode) content; - StructuredViewer viewer; - if (node.getValue().equals("List")) { - viewer = new ListViewer(parent); - } else { - viewer = new TreeViewer(parent); - } - - viewer.setContentProvider(myContentProvider); - viewer.setLabelProvider(myLabelProvider); - return viewer; - } - - } - - private class MyContentProvider implements ITreeContentProvider { - - public Object[] getChildren(Object parentElement) { - return ((TreeNode) parentElement).getChildren(); - } - - public Object getParent(Object element) { - return ((TreeNode) element).getParent(); - } - - public boolean hasChildren(Object element) { - return ((TreeNode) element).hasChildren(); - } - - public Object[] getElements(Object inputElement) { - if (inputElement instanceof Object[]) { - // elements for ListViewer - return (Object[]) inputElement; - } else { - // elements for PShelf - Object[] children = getChildren(inputElement); - // prepend "All" node to children - Object[] elements = new Object[children.length + 1]; - elements[0] = myModel; - System.arraycopy(children, 0, elements, 1, children.length); - return elements; - } - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - } - - private class MyLabelProvider extends LabelProvider { - - public String getText(Object element) { - return ((TreeNode) element).getValue().toString(); - } - } - - private class MyTreeNode extends TreeNode { - - public MyTreeNode(Object value) { - super(value); - } - - public void setChildren(TreeNode[] children) { - super.setChildren(children); - for (int i = 0; i < children.length; i++) { - children[i].setParent(this); - } - } - - } - - public PShelfViewerSnippet1(Shell shell) { - PShelfViewer viewer = new PShelfViewer(shell, SWT.NONE, - new MyViewerFactory()); - - // Optionally, change the renderer - viewer.getPShelf().setRenderer(new RedmondShelfRenderer()); - - // Optionally, transfer selection between viewers - viewer.setTransferSelection(true); - - myContentProvider = new MyContentProvider(); - viewer.setContentProvider(myContentProvider); - myLabelProvider = new MyLabelProvider(); - viewer.setLabelProvider(myLabelProvider); - createModel(); - viewer.setInput(myModel); - } - - private void createModel() { - myModel = new MyTreeNode("All"); - TreeNode list = new MyTreeNode("List"); - TreeNode tree = new MyTreeNode("Tree"); - myModel.setChildren(new TreeNode[] { list, tree }); - - list.setChildren(new TreeNode[] { - new MyTreeNode("List item 1"), new MyTreeNode("List item 2") - }); - - MyTreeNode treeNode1 = new MyTreeNode("Tree item 1"); - tree.setChildren(new TreeNode[] { treeNode1, new MyTreeNode("Tree item 2") }); - treeNode1.setChildren(new TreeNode[] { new MyTreeNode("Sub item 1.1") }); - } - - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - - new PShelfViewerSnippet1(shell); - - shell.setSize(200, 400); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - display.dispose(); - } -} +package org.eclipse.nebula.snippets.pshelf; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TreeNode; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.nebula.jface.pshelfviewer.IShelfViewerFactory; +import org.eclipse.nebula.jface.pshelfviewer.PShelfViewer; +import org.eclipse.nebula.widgets.pshelf.RedmondShelfRenderer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class PShelfViewerSnippet1 { + + private MyTreeNode myModel; + private MyContentProvider myContentProvider; + private MyLabelProvider myLabelProvider; + + private class MyViewerFactory implements IShelfViewerFactory { + + public Viewer createViewerForContent(Composite parent, Object content) { + TreeNode node = (TreeNode) content; + StructuredViewer viewer; + if (node.getValue().equals("List")) { + viewer = new ListViewer(parent); + } else { + viewer = new TreeViewer(parent); + } + + viewer.setContentProvider(myContentProvider); + viewer.setLabelProvider(myLabelProvider); + return viewer; + } + + } + + private class MyContentProvider implements ITreeContentProvider { + + public Object[] getChildren(Object parentElement) { + return ((TreeNode) parentElement).getChildren(); + } + + public Object getParent(Object element) { + return ((TreeNode) element).getParent(); + } + + public boolean hasChildren(Object element) { + return ((TreeNode) element).hasChildren(); + } + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof Object[]) { + // elements for ListViewer + return (Object[]) inputElement; + } else { + // elements for PShelf + Object[] children = getChildren(inputElement); + // prepend "All" node to children + Object[] elements = new Object[children.length + 1]; + elements[0] = myModel; + System.arraycopy(children, 0, elements, 1, children.length); + return elements; + } + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + } + + private class MyLabelProvider extends LabelProvider { + + public String getText(Object element) { + return ((TreeNode) element).getValue().toString(); + } + } + + private class MyTreeNode extends TreeNode { + + public MyTreeNode(Object value) { + super(value); + } + + public void setChildren(TreeNode[] children) { + super.setChildren(children); + for (int i = 0; i < children.length; i++) { + children[i].setParent(this); + } + } + + } + + public PShelfViewerSnippet1(Shell shell) { + PShelfViewer viewer = new PShelfViewer(shell, SWT.NONE, + new MyViewerFactory()); + + // Optionally, change the renderer + viewer.getPShelf().setRenderer(new RedmondShelfRenderer()); + + // Optionally, transfer selection between viewers + viewer.setTransferSelection(true); + + myContentProvider = new MyContentProvider(); + viewer.setContentProvider(myContentProvider); + myLabelProvider = new MyLabelProvider(); + viewer.setLabelProvider(myLabelProvider); + createModel(); + viewer.setInput(myModel); + } + + private void createModel() { + myModel = new MyTreeNode("All"); + TreeNode list = new MyTreeNode("List"); + TreeNode tree = new MyTreeNode("Tree"); + myModel.setChildren(new TreeNode[] { list, tree }); + + list.setChildren(new TreeNode[] { + new MyTreeNode("List item 1"), new MyTreeNode("List item 2") + }); + + MyTreeNode treeNode1 = new MyTreeNode("Tree item 1"); + tree.setChildren(new TreeNode[] { treeNode1, new MyTreeNode("Tree item 2") }); + treeNode1.setChildren(new TreeNode[] { new MyTreeNode("Sub item 1.1") }); + } + + public static void main(String[] args) { + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + + new PShelfViewerSnippet1(shell); + + shell.setSize(200, 400); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } +} diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/tablecombo/TableComboSnippet1.java b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/tablecombo/TableComboSnippet1.java index 09439e1af..786df1da9 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/tablecombo/TableComboSnippet1.java +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/tablecombo/TableComboSnippet1.java @@ -1,510 +1,510 @@ -/******************************************************************************* - * Copyright (c) 2009 Marty Jones - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Marty Jones - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.snippets.tablecombo; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.nebula.widgets.tablecombo.TableCombo; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableItem; -import org.eclipse.swt.widgets.Text; - -/** - * Show basic features of TableCombo - * - */ -public class TableComboSnippet1 { - - private static Font boldFont; - private static Image testImage; - private static Image test2Image; - private static Image test3Image; - private static Color darkRed; - private static Color darkBlue; - private static Color darkGreen; - private static List modelList; - private static Text listenerResults; - private static Group listenerGroup; - - /** - * @param args - */ - public static void main(String[] args) { - - // get display. - Display display = new Display (); - - // create bold and italic font. - boldFont = new Font(display,"Arial",8, SWT.BOLD | SWT.ITALIC); - - // create images - testImage = ImageDescriptor.createFromFile(TableComboSnippet1.class, - "in_ec_ov_success_16x16.gif").createImage(); - test2Image = ImageDescriptor.createFromFile(TableComboSnippet1.class, - "in_ec_ov_warning_16x16.gif").createImage(); - test3Image = ImageDescriptor.createFromFile(TableComboSnippet1.class, - "invalid_build_tool_16x16.gif").createImage(); - - // create colors - darkRed = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED); - darkBlue = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE); - darkGreen = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN); - - // load the model list. - modelList = loadModel(); - - // create a new shell. - Shell shell = new Shell (display); - shell.setText("TableCombo Snippet 1"); - shell.setSize(600, 400); - shell.setLayout(new GridLayout()); - - // create group - Group group = new Group(shell, SWT.NONE); - group.setLayout(new GridLayout(2, false)); - group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - group.setText("Sample Group"); - - // create group - listenerGroup = new Group(shell, SWT.NONE); - listenerGroup.setLayout(new GridLayout(1, false)); - listenerGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - listenerGroup.setText("Listener Results"); - - listenerResults = new Text(listenerGroup, SWT.BORDER | SWT.MULTI); - GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - gd.heightHint = 30; - listenerResults.setLayoutData(gd); - - //////////////////////////////////////////////////////////////////////// - // Sample #1 - //////////////////////////////////////////////////////////////////////// - Label label = new Label(group, SWT.NONE); - label.setText("Single Column (Mimics Normal Combo Field):"); - - // create TableCombo - TableCombo tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); - tc.setLayoutData(new GridData(125, SWT.DEFAULT)); - - // load the dataset. - loadSingleDataset(tc.getTable()); - - // add listener - tc.addSelectionListener(new ItemSelected(tc, "Sample1")); - - //////////////////////////////////////////////////////////////////////// - // Sample #2 - //////////////////////////////////////////////////////////////////////// - - label = new Label(group, SWT.NONE); - label.setText("Single Column (With Images)"); - - // create TableCombo - tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); - tc.setLayoutData(new GridData(125, SWT.DEFAULT)); - - // load the dataset. - loadSingleDatasetWithImages(tc.getTable()); - - // add listener - tc.addSelectionListener(new ItemSelected(tc, "Sample2")); - //////////////////////////////////////////////////////////////////////// - // Sample #3 - //////////////////////////////////////////////////////////////////////// - // create label - label = new Label(group, SWT.NONE); - label.setText("Two Columns:"); - - // create TableCombo - tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); - tc.setLayoutData(new GridData(125, SWT.DEFAULT)); - - // tell the TableCombo that I want 2 blank columns auto sized. - tc.defineColumns(2); - - // set which column will be used for the selected item. - tc.setDisplayColumnIndex(1); - - tc.setToolTipText("This is a tool tip."); - - // load the dataset. - loadTwoColumnDataset(tc.getTable()); - - // add listener - tc.addSelectionListener(new ItemSelected(tc, "Sample3")); - - //////////////////////////////////////////////////////////////////////// - // Sample #4 - //////////////////////////////////////////////////////////////////////// - // create label - label = new Label(group, SWT.NONE); - label.setText("Two Columns (With Colors && Fonts):"); - - // create TableCombo - tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); - tc.setLayoutData(new GridData(125, SWT.DEFAULT)); - - // tell the TableCombo that I want 2 blank columns auto sized. - tc.defineColumns(2); - - // set which column will be used for the selected item. - tc.setDisplayColumnIndex(1); - - // load the dataset. - loadTwoColumnDatasetWithColorsAndFonts(tc.getTable()); - - // add listener - tc.addSelectionListener(new ItemSelected(tc, "Sample4")); - - //////////////////////////////////////////////////////////////////////// - // Sample #5 - //////////////////////////////////////////////////////////////////////// - // create label - label = new Label(group, SWT.NONE); - label.setText("Three Columns (With Colors && Fonts && Header):"); - - // create TableCombo - tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); - tc.setLayoutData(new GridData(125, SWT.DEFAULT)); - - // tell the TableCombo that I want 3 columns autosized with the following column headers. - tc.defineColumns(new String[] { "Id", "Description", "Computed"}); - - // set which column will be used for the selected item. - tc.setDisplayColumnIndex(2); - - // turn on the table header. - tc.setShowTableHeader(true); - - // load the dataset. - loadThreeColumnDatasetWithColorsAndFonts(tc.getTable()); - - // add listener - tc.addSelectionListener(new ItemSelected(tc, "Sample5")); - - //////////////////////////////////////////////////////////////////////// - // Sample #6 - //////////////////////////////////////////////////////////////////////// - // create label - label = new Label(group, SWT.NONE); - label.setText("Three Columns (First Column, Fixed Width):"); - - // create TableCombo - tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); - tc.setLayoutData(new GridData(125, SWT.DEFAULT)); - - // tell the TableCombo that I want 3 columns autosized with the following column headers. - tc.defineColumns(new String[] { "Id", "Description", "Computed"}, - new int[] { 50 , SWT.DEFAULT, SWT.DEFAULT}); - - // set which column will be used for the selected item. - tc.setDisplayColumnIndex(2); - - // turn on the table header. - tc.setShowTableHeader(true); - - // load the dataset. - loadThreeColumnDatasetWithColorsAndFonts(tc.getTable()); - - // add listener - tc.addSelectionListener(new ItemSelected(tc, "Sample6")); - - //////////////////////////////////////////////////////////////////////// - // Sample #7 - //////////////////////////////////////////////////////////////////////// - // create label - label = new Label(group, SWT.NONE); - label.setText("Three Columns (With Table Width 75%):"); - - // create TableCombo - tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); - tc.setLayoutData(new GridData(125, SWT.DEFAULT)); - - // tell the TableCombo that I want 3 columns autosized with the following column headers. - tc.defineColumns(new String[] { "Id", "Description", "Computed"}); - - // set which column will be used for the selected item. - tc.setDisplayColumnIndex(2); - - // turn on the table header. - tc.setShowTableHeader(true); - - // load the dataset. - loadThreeColumnDatasetWithColorsAndFonts(tc.getTable()); - - // set the table width % to 75% - tc.setTableWidthPercentage(75); - - // add listener - tc.addSelectionListener(new ItemSelected(tc, "Sample7")); - - //////////////////////////////////////////////////////////////////////// - // Sample #8 - //////////////////////////////////////////////////////////////////////// - // create label - label = new Label(group, SWT.NONE); - label.setText("Keep popup open"); - - // create TableCombo - tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); - tc.setLayoutData(new GridData(125, SWT.DEFAULT)); - - // tell the TableCombo that I want 3 columns autosized with the following column headers. - tc.defineColumns(new String[] { "Id", "Description", "Computed"}); - - // set which column will be used for the selected item. - tc.setDisplayColumnIndex(2); - - // turn on the table header. - tc.setShowTableHeader(true); - - // load the dataset. - loadThreeColumnDatasetWithColorsAndFonts(tc.getTable()); - - // add listener - tc.addSelectionListener(new ItemSelected(tc, "Sample8")); - - // keep popup open after selecting an element - tc.setClosePopupAfterSelection(false); - - // open the shell. - shell.open(); - - while (!shell.isDisposed ()) { - if (!display.readAndDispatch ()) display.sleep (); - } - - // dispose of the font - boldFont.dispose(); - - // dispose images - testImage.dispose(); - test2Image.dispose(); - test3Image.dispose(); - - // dispose colors - darkRed.dispose(); - darkBlue.dispose(); - darkGreen.dispose(); - - // dispose display - display.dispose (); - } - - /** - * load a list of rows with a single column - * @return - */ - private static List loadSingleDataset(Table table) { - List rowList = new ArrayList(); - - int total = (modelList == null ? 0 : modelList.size()); - - for (int index=0; index < total; index++) { - TableItem ti = new TableItem(table, SWT.NONE); - Model model = (Model)modelList.get(index); - ti.setText(model.getDescription()); - rowList.add(ti); - } - - return rowList; - } - - /** - * load a list of rows with a single column that includes images - * @return - */ - private static List loadSingleDatasetWithImages(Table table) { - List list = loadSingleDataset(table); - - int total = (list == null ? 0 : list.size()); - - for (int index=0; index < total; index++) { - TableItem ti = ((TableItem)(list.get(index))); - - if (index == 1 || index == 7 || index == 13 || index == 19) { - ti.setImage(0, testImage); - } - else if (index == 3 || index == 9 || index == 15) { - ti.setImage(0, test2Image); - } - else if (index == 5 || index == 11 || index == 17) { - ti.setImage(0, test3Image); - } - } - - return list; - } - - /** - * load a list of rows with 2 columns in each row. - * @return - */ - private static List loadTwoColumnDataset(Table table) { - List rowList = new ArrayList(); - - int total = (modelList == null ? 0 : modelList.size()); - - for (int index=0; index < total; index++) { - TableItem ti = new TableItem(table, SWT.NONE); - Model model = (Model)modelList.get(index); - ti.setText(new String[] { String.valueOf(model.getId()), model.getDescription() }); - rowList.add(ti); - } - - return rowList; - } - - /** - * load a list of rows with 2 columns that includes colors and fonts. - * @return - */ - private static List loadTwoColumnDatasetWithColorsAndFonts(Table table) { - List list = loadTwoColumnDataset(table); - - int total = (list == null ? 0 : list.size()); - - for (int index=0; index < total; index++) { - TableItem ti = ((TableItem)(list.get(index))); - - if (index == 0 || index == 14) { - ti.setForeground(darkRed); - ti.setFont(boldFont); - } - else if (index == 4 || index == 19) { - ti.setForeground(darkBlue); - ti.setFont(boldFont); - } - else if (index == 9) { - ti.setForeground(darkGreen); - ti.setFont(boldFont); - } - } - - return list; - } - - /** - * load a list of rows with 3 columns - * @return - */ - private static List loadThreeColumnDataset(Table table) { - List rowList = new ArrayList(); - - int total = (modelList == null ? 0 : modelList.size()); - - for (int index=0; index < total; index++) { - TableItem ti = new TableItem(table, SWT.NONE); - Model model = (Model)modelList.get(index); - ti.setText(new String[] { String.valueOf(model.getId()), model.getDescription(), - String.valueOf(model.getId()) + " - " + model.getDescription() }); - rowList.add(ti); - } - - return rowList; - } - - /** - * load a list of rows with 3 columns that includes colors and fonts. - * @return - */ - private static List loadThreeColumnDatasetWithColorsAndFonts(Table table) { - List list = loadThreeColumnDataset(table); - - int total = (list == null ? 0 : list.size()); - - for (int index=0; index < total; index++) { - TableItem ti = ((TableItem)(list.get(index))); - - if (index == 0 || index == 14) { - ti.setForeground(darkRed); - ti.setFont(boldFont); - } - else if (index == 4 || index == 19) { - ti.setForeground(darkBlue); - ti.setFont(boldFont); - } else if (index==6) { - ti.setForeground(table.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - ti.setBackground(table.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - } else if (index == 9) { - ti.setForeground(darkGreen); - ti.setFont(boldFont); - } - } - - return list; - } - - /** - * load the Model data. - * @return - */ - private static List loadModel() { - List items = new ArrayList(); - items.add(new Model(1, "One")); - items.add(new Model(2, "Two")); - items.add(new Model(3, "Three")); - items.add(new Model(4, "Four")); - items.add(new Model(5, "Five")); - items.add(new Model(6, "Six")); - items.add(new Model(7, "Seven")); - items.add(new Model(8, "Eight")); - items.add(new Model(9, "Nine")); - items.add(new Model(10, "Ten")); - items.add(new Model(11, "Eleven")); - items.add(new Model(12, "Twelve")); - items.add(new Model(13, "Thirteen")); - items.add(new Model(14, "Fourteen")); - items.add(new Model(15, "Fiveteen")); - items.add(new Model(16, "Sixteen")); - items.add(new Model(17, "Seventeen")); - items.add(new Model(18, "Eighteen")); - items.add(new Model(19, "Nineteen")); - items.add(new Model(20, "Twenty")); - - return items; - } - - private static class ItemSelected extends SelectionAdapter { - - private TableCombo tc; - private String text; - - public ItemSelected(TableCombo tc, String text) { - this.tc = tc; - this.text = text; - } - - public void widgetSelected(SelectionEvent e) { - listenerGroup.setText("Listener Results - (" + text + ")"); - listenerResults.setText(tc.getText() == null ? "null" : tc.getText()); - } - } -} - +/******************************************************************************* + * Copyright (c) 2009 Marty Jones + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Marty Jones - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.snippets.tablecombo; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.nebula.widgets.tablecombo.TableCombo; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +/** + * Show basic features of TableCombo + * + */ +public class TableComboSnippet1 { + + private static Font boldFont; + private static Image testImage; + private static Image test2Image; + private static Image test3Image; + private static Color darkRed; + private static Color darkBlue; + private static Color darkGreen; + private static List modelList; + private static Text listenerResults; + private static Group listenerGroup; + + /** + * @param args + */ + public static void main(String[] args) { + + // get display. + Display display = new Display (); + + // create bold and italic font. + boldFont = new Font(display,"Arial",8, SWT.BOLD | SWT.ITALIC); + + // create images + testImage = ImageDescriptor.createFromFile(TableComboSnippet1.class, + "in_ec_ov_success_16x16.gif").createImage(); + test2Image = ImageDescriptor.createFromFile(TableComboSnippet1.class, + "in_ec_ov_warning_16x16.gif").createImage(); + test3Image = ImageDescriptor.createFromFile(TableComboSnippet1.class, + "invalid_build_tool_16x16.gif").createImage(); + + // create colors + darkRed = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED); + darkBlue = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE); + darkGreen = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN); + + // load the model list. + modelList = loadModel(); + + // create a new shell. + Shell shell = new Shell (display); + shell.setText("TableCombo Snippet 1"); + shell.setSize(600, 400); + shell.setLayout(new GridLayout()); + + // create group + Group group = new Group(shell, SWT.NONE); + group.setLayout(new GridLayout(2, false)); + group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + group.setText("Sample Group"); + + // create group + listenerGroup = new Group(shell, SWT.NONE); + listenerGroup.setLayout(new GridLayout(1, false)); + listenerGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + listenerGroup.setText("Listener Results"); + + listenerResults = new Text(listenerGroup, SWT.BORDER | SWT.MULTI); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + gd.heightHint = 30; + listenerResults.setLayoutData(gd); + + //////////////////////////////////////////////////////////////////////// + // Sample #1 + //////////////////////////////////////////////////////////////////////// + Label label = new Label(group, SWT.NONE); + label.setText("Single Column (Mimics Normal Combo Field):"); + + // create TableCombo + TableCombo tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); + tc.setLayoutData(new GridData(125, SWT.DEFAULT)); + + // load the dataset. + loadSingleDataset(tc.getTable()); + + // add listener + tc.addSelectionListener(new ItemSelected(tc, "Sample1")); + + //////////////////////////////////////////////////////////////////////// + // Sample #2 + //////////////////////////////////////////////////////////////////////// + + label = new Label(group, SWT.NONE); + label.setText("Single Column (With Images)"); + + // create TableCombo + tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); + tc.setLayoutData(new GridData(125, SWT.DEFAULT)); + + // load the dataset. + loadSingleDatasetWithImages(tc.getTable()); + + // add listener + tc.addSelectionListener(new ItemSelected(tc, "Sample2")); + //////////////////////////////////////////////////////////////////////// + // Sample #3 + //////////////////////////////////////////////////////////////////////// + // create label + label = new Label(group, SWT.NONE); + label.setText("Two Columns:"); + + // create TableCombo + tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); + tc.setLayoutData(new GridData(125, SWT.DEFAULT)); + + // tell the TableCombo that I want 2 blank columns auto sized. + tc.defineColumns(2); + + // set which column will be used for the selected item. + tc.setDisplayColumnIndex(1); + + tc.setToolTipText("This is a tool tip."); + + // load the dataset. + loadTwoColumnDataset(tc.getTable()); + + // add listener + tc.addSelectionListener(new ItemSelected(tc, "Sample3")); + + //////////////////////////////////////////////////////////////////////// + // Sample #4 + //////////////////////////////////////////////////////////////////////// + // create label + label = new Label(group, SWT.NONE); + label.setText("Two Columns (With Colors && Fonts):"); + + // create TableCombo + tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); + tc.setLayoutData(new GridData(125, SWT.DEFAULT)); + + // tell the TableCombo that I want 2 blank columns auto sized. + tc.defineColumns(2); + + // set which column will be used for the selected item. + tc.setDisplayColumnIndex(1); + + // load the dataset. + loadTwoColumnDatasetWithColorsAndFonts(tc.getTable()); + + // add listener + tc.addSelectionListener(new ItemSelected(tc, "Sample4")); + + //////////////////////////////////////////////////////////////////////// + // Sample #5 + //////////////////////////////////////////////////////////////////////// + // create label + label = new Label(group, SWT.NONE); + label.setText("Three Columns (With Colors && Fonts && Header):"); + + // create TableCombo + tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); + tc.setLayoutData(new GridData(125, SWT.DEFAULT)); + + // tell the TableCombo that I want 3 columns autosized with the following column headers. + tc.defineColumns(new String[] { "Id", "Description", "Computed"}); + + // set which column will be used for the selected item. + tc.setDisplayColumnIndex(2); + + // turn on the table header. + tc.setShowTableHeader(true); + + // load the dataset. + loadThreeColumnDatasetWithColorsAndFonts(tc.getTable()); + + // add listener + tc.addSelectionListener(new ItemSelected(tc, "Sample5")); + + //////////////////////////////////////////////////////////////////////// + // Sample #6 + //////////////////////////////////////////////////////////////////////// + // create label + label = new Label(group, SWT.NONE); + label.setText("Three Columns (First Column, Fixed Width):"); + + // create TableCombo + tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); + tc.setLayoutData(new GridData(125, SWT.DEFAULT)); + + // tell the TableCombo that I want 3 columns autosized with the following column headers. + tc.defineColumns(new String[] { "Id", "Description", "Computed"}, + new int[] { 50 , SWT.DEFAULT, SWT.DEFAULT}); + + // set which column will be used for the selected item. + tc.setDisplayColumnIndex(2); + + // turn on the table header. + tc.setShowTableHeader(true); + + // load the dataset. + loadThreeColumnDatasetWithColorsAndFonts(tc.getTable()); + + // add listener + tc.addSelectionListener(new ItemSelected(tc, "Sample6")); + + //////////////////////////////////////////////////////////////////////// + // Sample #7 + //////////////////////////////////////////////////////////////////////// + // create label + label = new Label(group, SWT.NONE); + label.setText("Three Columns (With Table Width 75%):"); + + // create TableCombo + tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); + tc.setLayoutData(new GridData(125, SWT.DEFAULT)); + + // tell the TableCombo that I want 3 columns autosized with the following column headers. + tc.defineColumns(new String[] { "Id", "Description", "Computed"}); + + // set which column will be used for the selected item. + tc.setDisplayColumnIndex(2); + + // turn on the table header. + tc.setShowTableHeader(true); + + // load the dataset. + loadThreeColumnDatasetWithColorsAndFonts(tc.getTable()); + + // set the table width % to 75% + tc.setTableWidthPercentage(75); + + // add listener + tc.addSelectionListener(new ItemSelected(tc, "Sample7")); + + //////////////////////////////////////////////////////////////////////// + // Sample #8 + //////////////////////////////////////////////////////////////////////// + // create label + label = new Label(group, SWT.NONE); + label.setText("Keep popup open"); + + // create TableCombo + tc = new TableCombo(group, SWT.BORDER | SWT.READ_ONLY); + tc.setLayoutData(new GridData(125, SWT.DEFAULT)); + + // tell the TableCombo that I want 3 columns autosized with the following column headers. + tc.defineColumns(new String[] { "Id", "Description", "Computed"}); + + // set which column will be used for the selected item. + tc.setDisplayColumnIndex(2); + + // turn on the table header. + tc.setShowTableHeader(true); + + // load the dataset. + loadThreeColumnDatasetWithColorsAndFonts(tc.getTable()); + + // add listener + tc.addSelectionListener(new ItemSelected(tc, "Sample8")); + + // keep popup open after selecting an element + tc.setClosePopupAfterSelection(false); + + // open the shell. + shell.open(); + + while (!shell.isDisposed ()) { + if (!display.readAndDispatch ()) display.sleep (); + } + + // dispose of the font + boldFont.dispose(); + + // dispose images + testImage.dispose(); + test2Image.dispose(); + test3Image.dispose(); + + // dispose colors + darkRed.dispose(); + darkBlue.dispose(); + darkGreen.dispose(); + + // dispose display + display.dispose (); + } + + /** + * load a list of rows with a single column + * @return + */ + private static List loadSingleDataset(Table table) { + List rowList = new ArrayList(); + + int total = (modelList == null ? 0 : modelList.size()); + + for (int index=0; index < total; index++) { + TableItem ti = new TableItem(table, SWT.NONE); + Model model = (Model)modelList.get(index); + ti.setText(model.getDescription()); + rowList.add(ti); + } + + return rowList; + } + + /** + * load a list of rows with a single column that includes images + * @return + */ + private static List loadSingleDatasetWithImages(Table table) { + List list = loadSingleDataset(table); + + int total = (list == null ? 0 : list.size()); + + for (int index=0; index < total; index++) { + TableItem ti = ((TableItem)(list.get(index))); + + if (index == 1 || index == 7 || index == 13 || index == 19) { + ti.setImage(0, testImage); + } + else if (index == 3 || index == 9 || index == 15) { + ti.setImage(0, test2Image); + } + else if (index == 5 || index == 11 || index == 17) { + ti.setImage(0, test3Image); + } + } + + return list; + } + + /** + * load a list of rows with 2 columns in each row. + * @return + */ + private static List loadTwoColumnDataset(Table table) { + List rowList = new ArrayList(); + + int total = (modelList == null ? 0 : modelList.size()); + + for (int index=0; index < total; index++) { + TableItem ti = new TableItem(table, SWT.NONE); + Model model = (Model)modelList.get(index); + ti.setText(new String[] { String.valueOf(model.getId()), model.getDescription() }); + rowList.add(ti); + } + + return rowList; + } + + /** + * load a list of rows with 2 columns that includes colors and fonts. + * @return + */ + private static List loadTwoColumnDatasetWithColorsAndFonts(Table table) { + List list = loadTwoColumnDataset(table); + + int total = (list == null ? 0 : list.size()); + + for (int index=0; index < total; index++) { + TableItem ti = ((TableItem)(list.get(index))); + + if (index == 0 || index == 14) { + ti.setForeground(darkRed); + ti.setFont(boldFont); + } + else if (index == 4 || index == 19) { + ti.setForeground(darkBlue); + ti.setFont(boldFont); + } + else if (index == 9) { + ti.setForeground(darkGreen); + ti.setFont(boldFont); + } + } + + return list; + } + + /** + * load a list of rows with 3 columns + * @return + */ + private static List loadThreeColumnDataset(Table table) { + List rowList = new ArrayList(); + + int total = (modelList == null ? 0 : modelList.size()); + + for (int index=0; index < total; index++) { + TableItem ti = new TableItem(table, SWT.NONE); + Model model = (Model)modelList.get(index); + ti.setText(new String[] { String.valueOf(model.getId()), model.getDescription(), + String.valueOf(model.getId()) + " - " + model.getDescription() }); + rowList.add(ti); + } + + return rowList; + } + + /** + * load a list of rows with 3 columns that includes colors and fonts. + * @return + */ + private static List loadThreeColumnDatasetWithColorsAndFonts(Table table) { + List list = loadThreeColumnDataset(table); + + int total = (list == null ? 0 : list.size()); + + for (int index=0; index < total; index++) { + TableItem ti = ((TableItem)(list.get(index))); + + if (index == 0 || index == 14) { + ti.setForeground(darkRed); + ti.setFont(boldFont); + } + else if (index == 4 || index == 19) { + ti.setForeground(darkBlue); + ti.setFont(boldFont); + } else if (index==6) { + ti.setForeground(table.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + ti.setBackground(table.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + } else if (index == 9) { + ti.setForeground(darkGreen); + ti.setFont(boldFont); + } + } + + return list; + } + + /** + * load the Model data. + * @return + */ + private static List loadModel() { + List items = new ArrayList(); + items.add(new Model(1, "One")); + items.add(new Model(2, "Two")); + items.add(new Model(3, "Three")); + items.add(new Model(4, "Four")); + items.add(new Model(5, "Five")); + items.add(new Model(6, "Six")); + items.add(new Model(7, "Seven")); + items.add(new Model(8, "Eight")); + items.add(new Model(9, "Nine")); + items.add(new Model(10, "Ten")); + items.add(new Model(11, "Eleven")); + items.add(new Model(12, "Twelve")); + items.add(new Model(13, "Thirteen")); + items.add(new Model(14, "Fourteen")); + items.add(new Model(15, "Fiveteen")); + items.add(new Model(16, "Sixteen")); + items.add(new Model(17, "Seventeen")); + items.add(new Model(18, "Eighteen")); + items.add(new Model(19, "Nineteen")); + items.add(new Model(20, "Twenty")); + + return items; + } + + private static class ItemSelected extends SelectionAdapter { + + private TableCombo tc; + private String text; + + public ItemSelected(TableCombo tc, String text) { + this.tc = tc; + this.text = text; + } + + public void widgetSelected(SelectionEvent e) { + listenerGroup.setText("Listener Results - (" + text + ")"); + listenerResults.setText(tc.getText() == null ? "null" : tc.getText()); + } + } +} + diff --git a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/visualization/Readme b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/visualization/Readme index 8dec9311b..dae76bf52 100644 --- a/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/visualization/Readme +++ b/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/visualization/Readme @@ -1,3 +1,3 @@ -Please don't modify code here! -The snippets here are copied from visualization plugins, which will overwritten regularly by coping them from visualization plugins. +Please don't modify code here! +The snippets here are copied from visualization plugins, which will overwritten regularly by coping them from visualization plugins. \ No newline at end of file diff --git a/releng/org.eclipse.nebula.examples.release.feature/feature.xml b/releng/org.eclipse.nebula.examples.release.feature/feature.xml index 0f5f191e3..8c083e497 100644 --- a/releng/org.eclipse.nebula.examples.release.feature/feature.xml +++ b/releng/org.eclipse.nebula.examples.release.feature/feature.xml @@ -1,496 +1,496 @@ - - - - - This feature contains the examples for the examples view. - - - - Copyright 2015, Weltevree beheer B.V. and others - - - - %license - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + This feature contains the examples for the examples view. + + + + Copyright 2015, Weltevree beheer B.V. and others + + + + %license + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/releng/org.eclipse.nebula.examples.webstart/rootfiles/nebula.jnlp b/releng/org.eclipse.nebula.examples.webstart/rootfiles/nebula.jnlp index 1427f91ac..46f34aacb 100644 --- a/releng/org.eclipse.nebula.examples.webstart/rootfiles/nebula.jnlp +++ b/releng/org.eclipse.nebula.examples.webstart/rootfiles/nebula.jnlp @@ -1,49 +1,49 @@ - - - - Nebula Examples - Eclipse Nebula Project - - - - - - - - -nosplash - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Nebula Examples + Eclipse Nebula Project + + + + + + + + -nosplash + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/releng/org.eclipse.nebula.feature/feature.xml b/releng/org.eclipse.nebula.feature/feature.xml index 2373b7598..77271623e 100644 --- a/releng/org.eclipse.nebula.feature/feature.xml +++ b/releng/org.eclipse.nebula.feature/feature.xml @@ -1,264 +1,264 @@ - - - - - This feature contains the Eclipse Nebula widgets. - - - - %license - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + This feature contains the Eclipse Nebula widgets. + + + + %license + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/releng/org.eclipse.nebula.feature/javadoc.xml b/releng/org.eclipse.nebula.feature/javadoc.xml index 8be72946e..fa16b7fbc 100644 --- a/releng/org.eclipse.nebula.feature/javadoc.xml +++ b/releng/org.eclipse.nebula.feature/javadoc.xml @@ -1,6 +1,6 @@ - - - - - - + + + + + + diff --git a/releng/org.eclipse.nebula.nebula-parent/pom.xml b/releng/org.eclipse.nebula.nebula-parent/pom.xml index ad3f5bd8c..09f50993f 100644 --- a/releng/org.eclipse.nebula.nebula-parent/pom.xml +++ b/releng/org.eclipse.nebula.nebula-parent/pom.xml @@ -1,464 +1,464 @@ - - - - 4.0.0 - org.eclipse.nebula - nebula-parent - 1.0.0-SNAPSHOT - pom - - - 4.0.4 - ${tycho-version} - 5.10.0 - 3.0.5 - 3.6.0 - 3.6.3 - 3.3.1 - 1.3.3 - 3.9.0 - 4.13.2 - 0.8.9 - 5.2.0 - - https://download.eclipse.org/releases/latest - - 11 - 11 - - - jacoco - reuseReports - - ../target/jacoco.exec - - scm:git:https://github.com/eclipse/nebula/ - - - https://download.eclipse.org/releases/latest - https://download.eclipse.org/justj/tools/updates/nightly/latest - genie.nebula - - - updates - yyyyMMddHHmm - http://www.example.com/ - nightly - - - - - - - org.eclipse.tycho - tycho-packaging-plugin - ${tycho-version} - - - true - - - - - org.eclipse.tycho.extras - tycho-sourceref-jgit - ${tycho-extras-version} - - - - - - org.eclipse.tycho - tycho-maven-plugin - ${tycho-version} - true - - - - org.eclipse.tycho - target-platform-configuration - ${tycho-version} - - JavaSE-17 - consider - - - linux - gtk - x86_64 - - - win32 - win32 - x86_64 - - - macosx - cocoa - x86_64 - - - - - - - org.jacoco - jacoco-maven-plugin - ${jacoco-version} - - - - prepare-agent - - - - ${sonar.jacoco.reportPath} - - *.nebula.* - - - true - - - - - - - - org.eclipse.tycho - tycho-surefire-plugin - ${tycho-version} - - true - ${tycho.testArgLine} -Xmx512m -Djava.awt.headless=true ${tests.vmargs} - - - - - org.eclipse.tycho - tycho-source-plugin - - - plugin-source - - plugin-source - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${mjd-version} - - - - - - - org.eclipse.tycho - tycho-compiler-plugin - ${tycho-version} - - UTF-8 - - - - org.eclipse.tycho - tycho-source-plugin - ${tycho-version} - - - org.apache.maven.plugins - maven-resources-plugin - ${mrp-version} - - ISO-8859-1 - - - - org.codehaus.mojo - findbugs-maven-plugin - ${findbugs-version} - - true - false - - - - - check - - - - - - org.apache.maven.plugins - maven-pmd-plugin - ${pmd-version} - - utf-8 - 100 - 1.5 - xml - false - - - - - cpd-check - - - - - - org.apache.maven.plugins - maven-assembly-plugin - ${map-version} - - - - - - - - - org.mockito - mockito-core - ${mockito-version} - - - - - - - junit - junit - ${junit-version} - test - - - - - - - tycho-snapshots - https://oss.sonatype.org/content/groups/public/ - - false - - - true - - - - - - - projects - p2 - ${target-platform} - - - - - - - nebula-dev Mailing List - nebula-dev@eclipse.org - https://dev.eclipse.org/mailman/listinfo/nebula-dev - https://dev.eclipse.org/mailman/listinfo/nebula-dev - https://dev.eclipse.org/mhonarc/lists/nebula-dev - - - - - https://github.com/eclipse/nebula/issues - Github - - - - https://github.com/eclipse/nebula - - - - - Eclipse Public License 2.0 - - All rights reserved. - - This program and the accompanying materials - are made available under the terms of the Eclipse Public License - 2.0 - which accompanies this distribution, and is available at - https://www.eclipse.org/legal/epl-2.0/ - - SPDX-License-Identifier: EPL-2.0 - - https://www.eclipse.org/legal/epl-2.0/ - - - - - - - - ../../widgets/badgedlabel - ../../widgets/carousel - ../../widgets/cdatetime - ../../widgets/chips - ../../widgets/compositetable - ../../widgets/ctreecombo - ../../widgets/cwt - ../../widgets/effects - ../../widgets/floatingtext - ../../widgets/fontawesome - ../../widgets/formattedtext - ../../widgets/gallery - ../../widgets/ganttchart - ../../widgets/geomap - ../../widgets/grid - ../../widgets/led - ../../widgets/nebulaslider - ../../widgets/opal/breadcrumb - ../../widgets/opal/calculator - ../../widgets/opal/checkboxgroup - ../../widgets/opal/columnbrowser - ../../widgets/opal/commons - ../../widgets/opal/dialog - ../../widgets/opal/duallist - ../../widgets/opal/header - ../../widgets/opal/heapmanager - ../../widgets/opal/horizontalspinner - ../../widgets/opal/launcher - ../../widgets/opal/logindialog - ../../widgets/opal/multichoice - ../../widgets/opal/notifier - ../../widgets/opal/panels - ../../widgets/opal/preferencewindow - ../../widgets/opal/promptsupport - ../../widgets/opal/propertytable - ../../widgets/opal/rangeslider - ../../widgets/opal/roundedtoolbar - ../../widgets/opal/starrating - ../../widgets/opal/switchbutton - ../../widgets/opal/textassist - ../../widgets/opal/tipoftheday - ../../widgets/opal/titledseparator - ../../widgets/oscilloscope - ../../widgets/paperclips - ../../widgets/passwordrevealer - ../../widgets/pgroup - ../../widgets/progresscircle - ../../widgets/pshelf - ../../widgets/richtext - ../../widgets/roundedcheckbox - ../../widgets/roundedswitch - ../../widgets/segmentedbar - ../../widgets/splitbutton - ../../widgets/stepbar - ../../widgets/tablecombo - ../../widgets/tiles - ../../widgets/treemapper - ../../widgets/visualization - ../../widgets/xviewer - - - - ../../widgets/calendarcombo - ../../widgets/collapsiblebuttons - ../../widgets/datechooser - ../../widgets/pagination - ../../widgets/picture - ../../widgets/radiogroup - ../../widgets/timeline - - ../../examples/org.eclipse.nebula.examples - ../../examples/org.eclipse.nebula.examples.feature - - - - ../org.eclipse.nebula.feature - ../org.eclipse.nebula.examples.release.feature - - ../org.eclipse.nebula.incubation.feature - ../org.eclipse.nebula.examples.incubation.feature - - ../org.eclipse.nebula.site - - - - - promote - - ../org.eclipse.nebula.site/promotion - - - - - static-checks - - - - org.codehaus.mojo - findbugs-maven-plugin - - - org.apache.maven.plugins - maven-pmd-plugin - - - - - - - build-server - - - - org.eclipse.cbi.maven.plugins - eclipse-jarsigner-plugin - ${ejp-version} - - - sign - verify - - sign - - - - - - - - - - cbi - https://repo.eclipse.org/content/repositories/cbi-releases/ - - true - - - false - - - - - - - - + + + + 4.0.0 + org.eclipse.nebula + nebula-parent + 1.0.0-SNAPSHOT + pom + + + 4.0.4 + ${tycho-version} + 5.10.0 + 3.0.5 + 3.6.0 + 3.6.3 + 3.3.1 + 1.3.3 + 3.9.0 + 4.13.2 + 0.8.9 + 5.2.0 + + https://download.eclipse.org/releases/latest + + 11 + 11 + + + jacoco + reuseReports + + ../target/jacoco.exec + + scm:git:https://github.com/eclipse/nebula/ + + + https://download.eclipse.org/releases/latest + https://download.eclipse.org/justj/tools/updates/nightly/latest + genie.nebula + + + updates + yyyyMMddHHmm + http://www.example.com/ + nightly + + + + + + + org.eclipse.tycho + tycho-packaging-plugin + ${tycho-version} + + + true + + + + + org.eclipse.tycho.extras + tycho-sourceref-jgit + ${tycho-extras-version} + + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + JavaSE-17 + consider + + + linux + gtk + x86_64 + + + win32 + win32 + x86_64 + + + macosx + cocoa + x86_64 + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-version} + + + + prepare-agent + + + + ${sonar.jacoco.reportPath} + + *.nebula.* + + + true + + + + + + + + org.eclipse.tycho + tycho-surefire-plugin + ${tycho-version} + + true + ${tycho.testArgLine} -Xmx512m -Djava.awt.headless=true ${tests.vmargs} + + + + + org.eclipse.tycho + tycho-source-plugin + + + plugin-source + + plugin-source + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${mjd-version} + + + + + + + org.eclipse.tycho + tycho-compiler-plugin + ${tycho-version} + + UTF-8 + + + + org.eclipse.tycho + tycho-source-plugin + ${tycho-version} + + + org.apache.maven.plugins + maven-resources-plugin + ${mrp-version} + + ISO-8859-1 + + + + org.codehaus.mojo + findbugs-maven-plugin + ${findbugs-version} + + true + false + + + + + check + + + + + + org.apache.maven.plugins + maven-pmd-plugin + ${pmd-version} + + utf-8 + 100 + 1.5 + xml + false + + + + + cpd-check + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${map-version} + + + + + + + + + org.mockito + mockito-core + ${mockito-version} + + + + + + + junit + junit + ${junit-version} + test + + + + + + + tycho-snapshots + https://oss.sonatype.org/content/groups/public/ + + false + + + true + + + + + + + projects + p2 + ${target-platform} + + + + + + + nebula-dev Mailing List + nebula-dev@eclipse.org + https://dev.eclipse.org/mailman/listinfo/nebula-dev + https://dev.eclipse.org/mailman/listinfo/nebula-dev + https://dev.eclipse.org/mhonarc/lists/nebula-dev + + + + + https://github.com/eclipse/nebula/issues + Github + + + + https://github.com/eclipse/nebula + + + + + Eclipse Public License 2.0 + + All rights reserved. + + This program and the accompanying materials + are made available under the terms of the Eclipse Public License + 2.0 + which accompanies this distribution, and is available at + https://www.eclipse.org/legal/epl-2.0/ + + SPDX-License-Identifier: EPL-2.0 + + https://www.eclipse.org/legal/epl-2.0/ + + + + + + + + ../../widgets/badgedlabel + ../../widgets/carousel + ../../widgets/cdatetime + ../../widgets/chips + ../../widgets/compositetable + ../../widgets/ctreecombo + ../../widgets/cwt + ../../widgets/effects + ../../widgets/floatingtext + ../../widgets/fontawesome + ../../widgets/formattedtext + ../../widgets/gallery + ../../widgets/ganttchart + ../../widgets/geomap + ../../widgets/grid + ../../widgets/led + ../../widgets/nebulaslider + ../../widgets/opal/breadcrumb + ../../widgets/opal/calculator + ../../widgets/opal/checkboxgroup + ../../widgets/opal/columnbrowser + ../../widgets/opal/commons + ../../widgets/opal/dialog + ../../widgets/opal/duallist + ../../widgets/opal/header + ../../widgets/opal/heapmanager + ../../widgets/opal/horizontalspinner + ../../widgets/opal/launcher + ../../widgets/opal/logindialog + ../../widgets/opal/multichoice + ../../widgets/opal/notifier + ../../widgets/opal/panels + ../../widgets/opal/preferencewindow + ../../widgets/opal/promptsupport + ../../widgets/opal/propertytable + ../../widgets/opal/rangeslider + ../../widgets/opal/roundedtoolbar + ../../widgets/opal/starrating + ../../widgets/opal/switchbutton + ../../widgets/opal/textassist + ../../widgets/opal/tipoftheday + ../../widgets/opal/titledseparator + ../../widgets/oscilloscope + ../../widgets/paperclips + ../../widgets/passwordrevealer + ../../widgets/pgroup + ../../widgets/progresscircle + ../../widgets/pshelf + ../../widgets/richtext + ../../widgets/roundedcheckbox + ../../widgets/roundedswitch + ../../widgets/segmentedbar + ../../widgets/splitbutton + ../../widgets/stepbar + ../../widgets/tablecombo + ../../widgets/tiles + ../../widgets/treemapper + ../../widgets/visualization + ../../widgets/xviewer + + + + ../../widgets/calendarcombo + ../../widgets/collapsiblebuttons + ../../widgets/datechooser + ../../widgets/pagination + ../../widgets/picture + ../../widgets/radiogroup + ../../widgets/timeline + + ../../examples/org.eclipse.nebula.examples + ../../examples/org.eclipse.nebula.examples.feature + + + + ../org.eclipse.nebula.feature + ../org.eclipse.nebula.examples.release.feature + + ../org.eclipse.nebula.incubation.feature + ../org.eclipse.nebula.examples.incubation.feature + + ../org.eclipse.nebula.site + + + + + promote + + ../org.eclipse.nebula.site/promotion + + + + + static-checks + + + + org.codehaus.mojo + findbugs-maven-plugin + + + org.apache.maven.plugins + maven-pmd-plugin + + + + + + + build-server + + + + org.eclipse.cbi.maven.plugins + eclipse-jarsigner-plugin + ${ejp-version} + + + sign + verify + + sign + + + + + + + + + + cbi + https://repo.eclipse.org/content/repositories/cbi-releases/ + + true + + + false + + + + + + + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/.project b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/.project index e26ed04f5..cb225ebc7 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/.project +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.badgedlabel.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.badgedlabel.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/build.properties b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/build.properties +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/feature.properties b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/feature.properties +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/feature.xml b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/feature.xml index 8eca18a81..eb6a16fa7 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/feature.xml +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/feature.xml @@ -1,34 +1,34 @@ - - - - - Badged Label - - - - %license - - - - - - - - - - - + + + + + Badged Label + + + + %license + + + + + + + + + + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/pom.xml b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/pom.xml index 8740227b8..837a9df63 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/pom.xml +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - badgedlabel - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.badgedlabel.feature - eclipse-feature - 1.0.0-SNAPSHOT - - Nebula Badged Label Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + badgedlabel + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.badgedlabel.feature + eclipse-feature + 1.0.0-SNAPSHOT + + Nebula Badged Label Feature + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.classpath b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.classpath +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.project b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.project index f3ba63d25..d3f3631f6 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.project +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.badgedlabel.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.badgedlabel.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/META-INF/MANIFEST.MF b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/META-INF/MANIFEST.MF index 97317c446..0cf457036 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/META-INF/MANIFEST.MF +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Badge Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.badgedlabel.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.badgedlabel;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.badgedlabel.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Badge Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.badgedlabel.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.badgedlabel;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.badgedlabel.snippets diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/build.properties b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/build.properties +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/pom.xml b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/pom.xml index a7395eb2a..1f98f8b99 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/pom.xml +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - badgedlabel - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.badgedlabel.snippets - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + badgedlabel + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.badgedlabel.snippets + eclipse-plugin + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/src/org/eclipse/nebula/widgets/badgedlabel/BadgedLabelSnippet.java b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/src/org/eclipse/nebula/widgets/badgedlabel/BadgedLabelSnippet.java index aeaabf929..4f4aeefaf 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/src/org/eclipse/nebula/widgets/badgedlabel/BadgedLabelSnippet.java +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel.snippets/src/org/eclipse/nebula/widgets/badgedlabel/BadgedLabelSnippet.java @@ -1,114 +1,114 @@ -/******************************************************************************* - * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.badgedlabel; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * Snippet for the BadgedLabel widget - */ -public class BadgedLabelSnippet { - private static Shell shell; - private static Image icon; - - /** - * @param args - */ - public static void main(final String[] args) { - final Display display = new Display(); - shell = new Shell(display); - shell.setText("BadgedLabel Snippet"); - shell.setLayout(new GridLayout(5, false)); - shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); - - icon = new Image(display, BadgedLabelSnippet.class.getClassLoader() - .getResourceAsStream("org/eclipse/nebula/widgets/badgedlabel/user.png")); - - createButtons("Blue :", SWT.COLOR_BLUE, SWT.TOP | SWT.LEFT); - createButtons("Grey:", SWT.COLOR_GRAY, SWT.TOP | SWT.RIGHT); - createButtons("Green:", SWT.COLOR_GREEN, SWT.BOTTOM | SWT.LEFT); - createButtons("Red:", SWT.COLOR_RED, SWT.BOTTOM | SWT.RIGHT); - createButtons("Yellow:", SWT.COLOR_YELLOW, SWT.TOP | SWT.RIGHT); - createButtons("Cyan:", SWT.COLOR_CYAN, SWT.TOP | SWT.LEFT); - createButtons("Black:", SWT.COLOR_BLACK, SWT.BOTTOM | SWT.RIGHT); - - shell.pack(); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - icon.dispose(); - display.dispose(); - - } - - private static void createButtons(final String text, int color, int location) { - final Label label = new Label(shell, SWT.NONE); - label.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - String locationText; - if (location == (SWT.BOTTOM | SWT.LEFT)) { - locationText = "Bottom left"; - } else if (location == (SWT.BOTTOM | SWT.RIGHT)) { - locationText = "Bottom right"; - } else if (location == (SWT.TOP | SWT.LEFT)) { - locationText = "Top left"; - } else { - locationText = "Top right"; - } - - label.setText(text + " " + locationText); - label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - final BadgedLabel button1 = new BadgedLabel(shell, location); - button1.setText("Notification"); - final GridData gd = new GridData(GridData.FILL, GridData.CENTER, false, false); - gd.widthHint = 200; - gd.heightHint = 100; - button1.setLayoutData(gd); - button1.setBadgeValue("1"); - button1.setPredefinedColor(color); - button1.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final BadgedLabel button2 = new BadgedLabel(shell, location); - button2.setText("Text & image"); - button2.setImage(icon); - button2.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false)); - button2.setPredefinedColor(color); - button2.setBadgeValue("2"); - button2.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final BadgedLabel button3 = new BadgedLabel(shell, location); - button3.setImage(icon); - button3.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false)); - button3.setPredefinedColor(color); - button3.setBadgeValue("99+"); - button3.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final BadgedLabel button4 = new BadgedLabel(shell, location); - button4.setText("Disabled"); - button4.setEnabled(false); - button4.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false)); - button4.setPredefinedColor(color); - button4.setBadgeValue("New"); - button4.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - } -} +/******************************************************************************* + * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.badgedlabel; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * Snippet for the BadgedLabel widget + */ +public class BadgedLabelSnippet { + private static Shell shell; + private static Image icon; + + /** + * @param args + */ + public static void main(final String[] args) { + final Display display = new Display(); + shell = new Shell(display); + shell.setText("BadgedLabel Snippet"); + shell.setLayout(new GridLayout(5, false)); + shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); + + icon = new Image(display, BadgedLabelSnippet.class.getClassLoader() + .getResourceAsStream("org/eclipse/nebula/widgets/badgedlabel/user.png")); + + createButtons("Blue :", SWT.COLOR_BLUE, SWT.TOP | SWT.LEFT); + createButtons("Grey:", SWT.COLOR_GRAY, SWT.TOP | SWT.RIGHT); + createButtons("Green:", SWT.COLOR_GREEN, SWT.BOTTOM | SWT.LEFT); + createButtons("Red:", SWT.COLOR_RED, SWT.BOTTOM | SWT.RIGHT); + createButtons("Yellow:", SWT.COLOR_YELLOW, SWT.TOP | SWT.RIGHT); + createButtons("Cyan:", SWT.COLOR_CYAN, SWT.TOP | SWT.LEFT); + createButtons("Black:", SWT.COLOR_BLACK, SWT.BOTTOM | SWT.RIGHT); + + shell.pack(); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + icon.dispose(); + display.dispose(); + + } + + private static void createButtons(final String text, int color, int location) { + final Label label = new Label(shell, SWT.NONE); + label.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + String locationText; + if (location == (SWT.BOTTOM | SWT.LEFT)) { + locationText = "Bottom left"; + } else if (location == (SWT.BOTTOM | SWT.RIGHT)) { + locationText = "Bottom right"; + } else if (location == (SWT.TOP | SWT.LEFT)) { + locationText = "Top left"; + } else { + locationText = "Top right"; + } + + label.setText(text + " " + locationText); + label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + + final BadgedLabel button1 = new BadgedLabel(shell, location); + button1.setText("Notification"); + final GridData gd = new GridData(GridData.FILL, GridData.CENTER, false, false); + gd.widthHint = 200; + gd.heightHint = 100; + button1.setLayoutData(gd); + button1.setBadgeValue("1"); + button1.setPredefinedColor(color); + button1.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final BadgedLabel button2 = new BadgedLabel(shell, location); + button2.setText("Text & image"); + button2.setImage(icon); + button2.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false)); + button2.setPredefinedColor(color); + button2.setBadgeValue("2"); + button2.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final BadgedLabel button3 = new BadgedLabel(shell, location); + button3.setImage(icon); + button3.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false)); + button3.setPredefinedColor(color); + button3.setBadgeValue("99+"); + button3.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final BadgedLabel button4 = new BadgedLabel(shell, location); + button4.setText("Disabled"); + button4.setEnabled(false); + button4.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false)); + button4.setPredefinedColor(color); + button4.setBadgeValue("New"); + button4.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + } +} diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.classpath b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.classpath +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.project b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.project index 8b09a97b3..639f3376e 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.project +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.badgedlabel - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.badgedlabel + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.settings/org.eclipse.jdt.core.prefs b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/META-INF/MANIFEST.MF b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/META-INF/MANIFEST.MF index aa6904b5d..b8727b241 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/META-INF/MANIFEST.MF +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Badged Label Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.badgedlabel -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Export-Package: org.eclipse.nebula.widgets.badgedlabel -Require-Bundle: org.eclipse.nebula.widgets.opal.commons, - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.badgedlabel +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Badged Label Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.badgedlabel +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Export-Package: org.eclipse.nebula.widgets.badgedlabel +Require-Bundle: org.eclipse.nebula.widgets.opal.commons, + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.badgedlabel diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/build.properties b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/build.properties +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/pom.xml b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/pom.xml index 7e14f017e..337c4fa21 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/pom.xml +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - badgedlabel - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.badgedlabel - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + badgedlabel + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.badgedlabel + eclipse-plugin + + diff --git a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/src/org/eclipse/nebula/widgets/badgedlabel/BadgedLabel.java b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/src/org/eclipse/nebula/widgets/badgedlabel/BadgedLabel.java index 5e3e78107..4aa3c89b5 100644 --- a/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/src/org/eclipse/nebula/widgets/badgedlabel/BadgedLabel.java +++ b/widgets/badgedlabel/org.eclipse.nebula.widgets.badgedlabel/src/org/eclipse/nebula/widgets/badgedlabel/BadgedLabel.java @@ -1,772 +1,772 @@ -/******************************************************************************* - * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.badgedlabel; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -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.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; - -/** - * Instances of this class represent a non-selectable user interface object that - * displays a string or image. A badge is displayed on this label, so you can - * add extra information (the most common used is a notification label that - * shows the number of unread notifications). - * - *
- *
Styles:
- *
SWT.BORDER
- *
SWT.LEFT or SWT.RIGHT (horizontal location)
- *
SWT.TOP or SWT.BOTTOM (vertical location)
- *
Events:
- *
(none)
- *
- */ -public class BadgedLabel extends Canvas { - private static final int PADDING = 8; - private static final int MARGIN = 7; - private static final int CIRCLE_DIAMETER = 18; - private static final int MAX_BADGE_TEXT_SIZE = 11; - private Image image; - private String text; - private String badgeValue; - private Color textColor, backgroundColor, borderColor, badgeForeground, badgeBackground; - private final Font badgeFont; - private Font boldFont; - private int horizontalLocation, verticalLocation; - private GC gc; - private int left; - private int top; - private Point buttonSize; - private Point textSizeCache; - private Point badgeTextSizeCache; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent - * a composite control which will be the parent of the new instance - * (cannot be null) - * @param style - * the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - */ - public BadgedLabel(Composite parent, int style) { - super(parent, checkStyle(style) | SWT.DOUBLE_BUFFERED); - badgeFont = SWTGraphicUtil.buildFontFrom(this, SWT.NONE, 8); - SWTGraphicUtil.addDisposer(this, badgeFont); - boldFont = SWTGraphicUtil.buildFontFrom(this, SWT.BOLD); - SWTGraphicUtil.addDisposer(this, boldFont); - horizontalLocation = (getStyle() & SWT.LEFT) != 0 ? SWT.LEFT : SWT.RIGHT; - verticalLocation = (getStyle() & SWT.TOP) != 0 ? SWT.TOP : SWT.BOTTOM; - initDefaultColors(); - addListener(SWT.Paint, e -> onPaint(e)); - } - - private static int checkStyle(final int style) { - final int mask = SWT.BORDER | SWT.LEFT | SWT.RIGHT | SWT.TOP | SWT.BOTTOM; - int newStyle = style & mask; - newStyle |= SWT.DOUBLE_BUFFERED; - return newStyle; - } - - private void initDefaultColors() { - textColor = getDisplay().getSystemColor(SWT.COLOR_BLACK); - SWTGraphicUtil.addDisposer(this, textColor); - - backgroundColor = new Color(getDisplay(), 247, 247, 247); - SWTGraphicUtil.addDisposer(this, backgroundColor); - - borderColor = new Color(getDisplay(), 204, 204, 204); - SWTGraphicUtil.addDisposer(this, borderColor); - - badgeForeground = getDisplay().getSystemColor(SWT.COLOR_WHITE); - badgeBackground = new Color(getDisplay(), 0, 123, 255); - SWTGraphicUtil.addDisposer(this, badgeBackground); - } - - private void onPaint(Event e) { - gc = e.gc; - gc.setAntialias(SWT.ON); - gc.setAdvanced(true); - final Color previousForeground = getForeground(); - final Color previousBackground = getBackground(); - - drawButton(); - drawBadge(); - - gc.setForeground(previousForeground); - gc.setBackground(previousBackground); - } - - private void drawButton() { - drawShape(); - drawImageAndText(); - } - - private void drawShape() { - buttonSize = computeButtonSize(); - final Rectangle area = getClientArea(); - left = MARGIN; - if (horizontalLocation == SWT.LEFT) { - left += MARGIN; - } - - top = MARGIN; - if (verticalLocation == SWT.TOP) { - top += MARGIN; - } - - // Background - gc.setBackground(backgroundColor); - gc.fillRoundRectangle(left, top, // - Math.max(buttonSize.x, area.width - 2 * MARGIN) - left, // - Math.max(buttonSize.y, area.height - 2 * MARGIN) - top, 3, 3); - - // Foreground - gc.setForeground(borderColor); - gc.drawRoundRectangle(left, top, // - Math.max(buttonSize.x, area.width - 2 * MARGIN) - left, // - Math.max(buttonSize.y, area.height - 2 * MARGIN) - top, 3, 3); - } - - private void drawImageAndText() { - final int textWidth = getTextSizeInPixels().x; - int textDelta = 0; - final Rectangle area = getClientArea(); - final int width = Math.max(buttonSize.x, area.width - 2 * MARGIN) - left; - final int height = Math.max(buttonSize.y, area.height - 2 * MARGIN) - top; - if (image != null) { - final Point imageSize = new Point(image.getBounds().width, image.getBounds().height); - int wholeLength = imageSize.x; - if (textWidth != 0) { - wholeLength += PADDING / 2 + getTextSizeInPixels().x; - } - - final int x = left + (width - wholeLength) / 2; - gc.drawImage(image, x, top + (height - imageSize.y) / 2); - textDelta = x + imageSize.x + PADDING / 2; - } - - if (textWidth == 0) { - return; - } - - final int x = textDelta == 0 ? left + (width - textWidth) / 2 : textDelta; - gc.setFont(boldFont); - gc.setForeground(isEnabled() ? textColor : getDisplay().getSystemColor(SWT.COLOR_GRAY)); - gc.drawText(text, x, top + (height - getTextSizeInPixels().y) / 2, false); - } - - private Point getTextSizeInPixels() { - if (text == null || text.equals("")) { - return new Point(0, 0); - } - - if (textSizeCache != null) { - return textSizeCache; - } - - final GC gc = new GC(this); - gc.setFont(boldFont); - textSizeCache = gc.stringExtent(text); - gc.dispose(); - return textSizeCache; - } - - private void drawBadge() { - if (badgeValue == null || badgeValue.equals("")) { - return; - } - - gc.setForeground(badgeForeground); - gc.setBackground(badgeBackground); - - final Point textSize = getBadgeTextSizeInPixels(); - final Rectangle area = getClientArea(); - final int width = Math.max(buttonSize.x, area.width - 2 * MARGIN) - left; - final int height = Math.max(buttonSize.y, area.height - 2 * MARGIN) - top; - int badgeWith; - if (textSize.x > MAX_BADGE_TEXT_SIZE) { - // Draw a round rectangle - badgeWith = textSize.x + MAX_BADGE_TEXT_SIZE / 2; - } else { - // Draw a circle - badgeWith = CIRCLE_DIAMETER; - } - - int x; - switch (horizontalLocation) { - case SWT.RIGHT: - x = left + width - badgeWith / 2; - break; - case SWT.LEFT: - x = left - badgeWith / 2; - break; - default: - return; - } - - int y; - switch (verticalLocation) { - case SWT.TOP: - y = top - CIRCLE_DIAMETER / 2; - break; - case SWT.BOTTOM: - y = top + height - CIRCLE_DIAMETER / 2; - break; - default: - return; - } - if (textSize.x > MAX_BADGE_TEXT_SIZE) { - // Draw a round rectangle - gc.fillRoundRectangle(x, y, badgeWith, CIRCLE_DIAMETER, 3, 3); - } else { - // Draw a circle - gc.fillOval(x, y, CIRCLE_DIAMETER, CIRCLE_DIAMETER); - } - gc.setFont(badgeFont); - gc.drawText(badgeValue, x + (badgeWith - textSize.x) / 2, y + (CIRCLE_DIAMETER - textSize.y) / 2, true); - } - - private Point getBadgeTextSizeInPixels() { - if (badgeTextSizeCache != null) { - return badgeTextSizeCache; - } - final GC gc = new GC(this); - gc.setFont(badgeFont); - badgeTextSizeCache = gc.stringExtent(badgeValue); - gc.dispose(); - return badgeTextSizeCache; - - } - - /** - * Sets the badge's color theme to the theme specified by the argument - * - * @param color - * the new color, can pick one of the following value: - * SWT.COLOR_BLUE, SWT.COLOR_GRAY, SWT.COLOR_GREEN, SWT.COLOR_RED, - * SWT.COLOR_YELLOW, SWT.COLOR_CYAN, SWT.COLOR_BLACK - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setPredefinedColor(int color) { - checkWidget(); - - badgeForeground = getDisplay().getSystemColor(SWT.COLOR_WHITE); - switch (color) { - case SWT.COLOR_BLUE: - badgeBackground = new Color(getDisplay(), 0, 123, 255); - break; - case SWT.COLOR_GRAY: - badgeBackground = new Color(getDisplay(), 108, 117, 125); - break; - case SWT.COLOR_GREEN: - badgeBackground = new Color(getDisplay(), 40, 167, 69); - break; - case SWT.COLOR_RED: - badgeBackground = new Color(getDisplay(), 220, 53, 69); - break; - case SWT.COLOR_YELLOW: - badgeForeground = getDisplay().getSystemColor(SWT.COLOR_BLACK); - badgeBackground = new Color(getDisplay(), 255, 193, 7); - break; - case SWT.COLOR_CYAN: - badgeBackground = new Color(getDisplay(), 23, 162, 184); - break; - default: // BLACK - badgeBackground = new Color(getDisplay(), 52, 58, 64); - } - - SWTGraphicUtil.addDisposer(this, badgeBackground); - } - - /** - * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - checkWidget(); - - if (image == null && text == null) { - return super.computeSize(wHint, hHint, changed); - } - - // Button - final Point buttonSize = computeButtonSize(); - int width = buttonSize.x; - int height = buttonSize.y; - - // Margin - width += 3 * MARGIN; - height += 3 * MARGIN; - return new Point(Math.max(width, wHint), Math.max(height, hHint)); - } - - private Point computeButtonSize() { - int width = 2 * PADDING, height = 2 * PADDING; - if (image != null && text == null) { - final Rectangle bounds = image.getBounds(); - width += bounds.width; - height = Math.max(height, bounds.height + 2 * PADDING); - } else if (text != null && image == null) { - final Point extent = getTextSizeInPixels(); - width = Math.max(width, extent.x + 2 * PADDING); - height = height + extent.y; - } else { - final Rectangle bounds = image.getBounds(); - final Point extent = getTextSizeInPixels(); - width += bounds.width + PADDING + extent.x + 2 * PADDING; - final int maxTextAndImageHeight = Math.max(extent.y, bounds.y); - height = Math.max(height, maxTextAndImageHeight + 2 * PADDING); - } - return new Point(width, height); - } - - /** - * Returns the background color that the receiver will use to draw. - * - * @return the receiver's background color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getBackgroundColor() { - checkWidget(); - return backgroundColor; - } - - /** - * Returns the background color that the badge will use to draw. - * - * @return the badge's backdground color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getBadgeBackground() { - checkWidget(); - return badgeBackground; - } - - /** - * Returns the foreground color that the badge will use to draw. - * - * @return the badge's foreground color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getBadgeForeground() { - checkWidget(); - return badgeForeground; - } - - /** - * Returns the text of the badge - * - * @return the badge's text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public String getBadgeValue() { - checkWidget(); - return badgeValue; - } - - /** - * Returns the border color that the receiver will use to draw. - * - * @return the receiver's border color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getBorderColor() { - checkWidget(); - return borderColor; - } - - /** - * Returns the receiver's image if it has one, or null if it does not. - * - * @return the receiver's image - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Image getImage() { - checkWidget(); - return image; - } - - /** - * Returns the receiver's text, which will be an empty string if it has never - * been set or if the receiver is a SEPARATOR label. - * - * @return the receiver's text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public String getText() { - checkWidget(); - return text; - } - - /** - * Returns the text color that the receiver will use to draw. - * - * @return the receiver's text color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getTextColor() { - checkWidget(); - return textColor; - } - - /** - * Sets the receiver's background color to the color specified by the argument - * - * @param color - * the new color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setBackgroundColor(Color backgroundColor) { - checkWidget(); - checkColor(backgroundColor); - this.backgroundColor = backgroundColor; - } - - private void checkColor(Color color) { - if (color == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - - /** - * Sets the badge's background color to the color specified by the argument - * - * @param color - * the new color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setBadgeBackground(Color badgeBackground) { - checkWidget(); - checkColor(badgeBackground); - this.badgeBackground = badgeBackground; - } - - /** - * Sets the badge's foreground color to the color specified by the argument - * - * @param color - * the new color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setBadgeForeground(Color badgeForeground) { - checkWidget(); - checkColor(badgeForeground); - this.badgeForeground = badgeForeground; - } - - /** - * Sets the badge's value (text) to the text specified by the argument - * - * @param value - * the new text value - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setBadgeValue(String value) { - checkWidget(); - if (value == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - badgeValue = value; - badgeTextSizeCache = null; - } - - /** - * Sets the receiver's border color to the color specified by the argument - * - * @param color - * the new color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setBorderColor(Color borderColor) { - checkWidget(); - checkColor(borderColor); - this.borderColor = borderColor; - } - - /** - * @see org.eclipse.swt.widgets.Control#setEnabled(boolean) - */ - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - redraw(); - } - - /** - * @see org.eclipse.swt.widgets.Canvas#setFont(org.eclipse.swt.graphics.Font) - */ - @Override - public void setFont(Font font) { - super.setFont(font); - textSizeCache = null; - boldFont.dispose(); - boldFont = SWTGraphicUtil.buildFontFrom(this, SWT.BOLD); - } - - /** - * Sets the receiver's image to the argument, which may be null indicating that - * no image should be displayed. - * - * @param image - * the image to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setImage(Image image) { - checkWidget(); - this.image = image; - } - - /** - * Sets the receiver's text. - *

- * This method sets the widget label. The label may include the mnemonic - * character and line delimiters. - *

- *

- * Mnemonics are indicated by an '&' that causes the next character to be - * the mnemonic. When the user presses a key sequence that matches the mnemonic, - * focus is assigned to the control that follows the label. On most platforms, - * the mnemonic appears underlined but may be emphasised in a platform specific - * manner. The mnemonic indicator character '&' can be escaped by doubling - * it in the string, causing a single '&' to be displayed. - *

- *

- * Note: If control characters like '\n', '\t' etc. are used in the string, then - * the behavior is platform dependent. - *

- * - * @param string - * the new text - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the text is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setText(String text) { - checkWidget(); - textSizeCache = null; - this.text = text; - } - - /** - * Sets the receiver's text color to the color specified by the argument - * - * @param color - * the new color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setTextColor(Color textColor) { - checkWidget(); - checkColor(textColor); - this.textColor = textColor; - } - -} +/******************************************************************************* + * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.badgedlabel; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +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.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class represent a non-selectable user interface object that + * displays a string or image. A badge is displayed on this label, so you can + * add extra information (the most common used is a notification label that + * shows the number of unread notifications). + * + *
+ *
Styles:
+ *
SWT.BORDER
+ *
SWT.LEFT or SWT.RIGHT (horizontal location)
+ *
SWT.TOP or SWT.BOTTOM (vertical location)
+ *
Events:
+ *
(none)
+ *
+ */ +public class BadgedLabel extends Canvas { + private static final int PADDING = 8; + private static final int MARGIN = 7; + private static final int CIRCLE_DIAMETER = 18; + private static final int MAX_BADGE_TEXT_SIZE = 11; + private Image image; + private String text; + private String badgeValue; + private Color textColor, backgroundColor, borderColor, badgeForeground, badgeBackground; + private final Font badgeFont; + private Font boldFont; + private int horizontalLocation, verticalLocation; + private GC gc; + private int left; + private int top; + private Point buttonSize; + private Point textSizeCache; + private Point badgeTextSizeCache; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent + * a composite control which will be the parent of the new instance + * (cannot be null) + * @param style + * the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + */ + public BadgedLabel(Composite parent, int style) { + super(parent, checkStyle(style) | SWT.DOUBLE_BUFFERED); + badgeFont = SWTGraphicUtil.buildFontFrom(this, SWT.NONE, 8); + SWTGraphicUtil.addDisposer(this, badgeFont); + boldFont = SWTGraphicUtil.buildFontFrom(this, SWT.BOLD); + SWTGraphicUtil.addDisposer(this, boldFont); + horizontalLocation = (getStyle() & SWT.LEFT) != 0 ? SWT.LEFT : SWT.RIGHT; + verticalLocation = (getStyle() & SWT.TOP) != 0 ? SWT.TOP : SWT.BOTTOM; + initDefaultColors(); + addListener(SWT.Paint, e -> onPaint(e)); + } + + private static int checkStyle(final int style) { + final int mask = SWT.BORDER | SWT.LEFT | SWT.RIGHT | SWT.TOP | SWT.BOTTOM; + int newStyle = style & mask; + newStyle |= SWT.DOUBLE_BUFFERED; + return newStyle; + } + + private void initDefaultColors() { + textColor = getDisplay().getSystemColor(SWT.COLOR_BLACK); + SWTGraphicUtil.addDisposer(this, textColor); + + backgroundColor = new Color(getDisplay(), 247, 247, 247); + SWTGraphicUtil.addDisposer(this, backgroundColor); + + borderColor = new Color(getDisplay(), 204, 204, 204); + SWTGraphicUtil.addDisposer(this, borderColor); + + badgeForeground = getDisplay().getSystemColor(SWT.COLOR_WHITE); + badgeBackground = new Color(getDisplay(), 0, 123, 255); + SWTGraphicUtil.addDisposer(this, badgeBackground); + } + + private void onPaint(Event e) { + gc = e.gc; + gc.setAntialias(SWT.ON); + gc.setAdvanced(true); + final Color previousForeground = getForeground(); + final Color previousBackground = getBackground(); + + drawButton(); + drawBadge(); + + gc.setForeground(previousForeground); + gc.setBackground(previousBackground); + } + + private void drawButton() { + drawShape(); + drawImageAndText(); + } + + private void drawShape() { + buttonSize = computeButtonSize(); + final Rectangle area = getClientArea(); + left = MARGIN; + if (horizontalLocation == SWT.LEFT) { + left += MARGIN; + } + + top = MARGIN; + if (verticalLocation == SWT.TOP) { + top += MARGIN; + } + + // Background + gc.setBackground(backgroundColor); + gc.fillRoundRectangle(left, top, // + Math.max(buttonSize.x, area.width - 2 * MARGIN) - left, // + Math.max(buttonSize.y, area.height - 2 * MARGIN) - top, 3, 3); + + // Foreground + gc.setForeground(borderColor); + gc.drawRoundRectangle(left, top, // + Math.max(buttonSize.x, area.width - 2 * MARGIN) - left, // + Math.max(buttonSize.y, area.height - 2 * MARGIN) - top, 3, 3); + } + + private void drawImageAndText() { + final int textWidth = getTextSizeInPixels().x; + int textDelta = 0; + final Rectangle area = getClientArea(); + final int width = Math.max(buttonSize.x, area.width - 2 * MARGIN) - left; + final int height = Math.max(buttonSize.y, area.height - 2 * MARGIN) - top; + if (image != null) { + final Point imageSize = new Point(image.getBounds().width, image.getBounds().height); + int wholeLength = imageSize.x; + if (textWidth != 0) { + wholeLength += PADDING / 2 + getTextSizeInPixels().x; + } + + final int x = left + (width - wholeLength) / 2; + gc.drawImage(image, x, top + (height - imageSize.y) / 2); + textDelta = x + imageSize.x + PADDING / 2; + } + + if (textWidth == 0) { + return; + } + + final int x = textDelta == 0 ? left + (width - textWidth) / 2 : textDelta; + gc.setFont(boldFont); + gc.setForeground(isEnabled() ? textColor : getDisplay().getSystemColor(SWT.COLOR_GRAY)); + gc.drawText(text, x, top + (height - getTextSizeInPixels().y) / 2, false); + } + + private Point getTextSizeInPixels() { + if (text == null || text.equals("")) { + return new Point(0, 0); + } + + if (textSizeCache != null) { + return textSizeCache; + } + + final GC gc = new GC(this); + gc.setFont(boldFont); + textSizeCache = gc.stringExtent(text); + gc.dispose(); + return textSizeCache; + } + + private void drawBadge() { + if (badgeValue == null || badgeValue.equals("")) { + return; + } + + gc.setForeground(badgeForeground); + gc.setBackground(badgeBackground); + + final Point textSize = getBadgeTextSizeInPixels(); + final Rectangle area = getClientArea(); + final int width = Math.max(buttonSize.x, area.width - 2 * MARGIN) - left; + final int height = Math.max(buttonSize.y, area.height - 2 * MARGIN) - top; + int badgeWith; + if (textSize.x > MAX_BADGE_TEXT_SIZE) { + // Draw a round rectangle + badgeWith = textSize.x + MAX_BADGE_TEXT_SIZE / 2; + } else { + // Draw a circle + badgeWith = CIRCLE_DIAMETER; + } + + int x; + switch (horizontalLocation) { + case SWT.RIGHT: + x = left + width - badgeWith / 2; + break; + case SWT.LEFT: + x = left - badgeWith / 2; + break; + default: + return; + } + + int y; + switch (verticalLocation) { + case SWT.TOP: + y = top - CIRCLE_DIAMETER / 2; + break; + case SWT.BOTTOM: + y = top + height - CIRCLE_DIAMETER / 2; + break; + default: + return; + } + if (textSize.x > MAX_BADGE_TEXT_SIZE) { + // Draw a round rectangle + gc.fillRoundRectangle(x, y, badgeWith, CIRCLE_DIAMETER, 3, 3); + } else { + // Draw a circle + gc.fillOval(x, y, CIRCLE_DIAMETER, CIRCLE_DIAMETER); + } + gc.setFont(badgeFont); + gc.drawText(badgeValue, x + (badgeWith - textSize.x) / 2, y + (CIRCLE_DIAMETER - textSize.y) / 2, true); + } + + private Point getBadgeTextSizeInPixels() { + if (badgeTextSizeCache != null) { + return badgeTextSizeCache; + } + final GC gc = new GC(this); + gc.setFont(badgeFont); + badgeTextSizeCache = gc.stringExtent(badgeValue); + gc.dispose(); + return badgeTextSizeCache; + + } + + /** + * Sets the badge's color theme to the theme specified by the argument + * + * @param color + * the new color, can pick one of the following value: + * SWT.COLOR_BLUE, SWT.COLOR_GRAY, SWT.COLOR_GREEN, SWT.COLOR_RED, + * SWT.COLOR_YELLOW, SWT.COLOR_CYAN, SWT.COLOR_BLACK + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setPredefinedColor(int color) { + checkWidget(); + + badgeForeground = getDisplay().getSystemColor(SWT.COLOR_WHITE); + switch (color) { + case SWT.COLOR_BLUE: + badgeBackground = new Color(getDisplay(), 0, 123, 255); + break; + case SWT.COLOR_GRAY: + badgeBackground = new Color(getDisplay(), 108, 117, 125); + break; + case SWT.COLOR_GREEN: + badgeBackground = new Color(getDisplay(), 40, 167, 69); + break; + case SWT.COLOR_RED: + badgeBackground = new Color(getDisplay(), 220, 53, 69); + break; + case SWT.COLOR_YELLOW: + badgeForeground = getDisplay().getSystemColor(SWT.COLOR_BLACK); + badgeBackground = new Color(getDisplay(), 255, 193, 7); + break; + case SWT.COLOR_CYAN: + badgeBackground = new Color(getDisplay(), 23, 162, 184); + break; + default: // BLACK + badgeBackground = new Color(getDisplay(), 52, 58, 64); + } + + SWTGraphicUtil.addDisposer(this, badgeBackground); + } + + /** + * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + checkWidget(); + + if (image == null && text == null) { + return super.computeSize(wHint, hHint, changed); + } + + // Button + final Point buttonSize = computeButtonSize(); + int width = buttonSize.x; + int height = buttonSize.y; + + // Margin + width += 3 * MARGIN; + height += 3 * MARGIN; + return new Point(Math.max(width, wHint), Math.max(height, hHint)); + } + + private Point computeButtonSize() { + int width = 2 * PADDING, height = 2 * PADDING; + if (image != null && text == null) { + final Rectangle bounds = image.getBounds(); + width += bounds.width; + height = Math.max(height, bounds.height + 2 * PADDING); + } else if (text != null && image == null) { + final Point extent = getTextSizeInPixels(); + width = Math.max(width, extent.x + 2 * PADDING); + height = height + extent.y; + } else { + final Rectangle bounds = image.getBounds(); + final Point extent = getTextSizeInPixels(); + width += bounds.width + PADDING + extent.x + 2 * PADDING; + final int maxTextAndImageHeight = Math.max(extent.y, bounds.y); + height = Math.max(height, maxTextAndImageHeight + 2 * PADDING); + } + return new Point(width, height); + } + + /** + * Returns the background color that the receiver will use to draw. + * + * @return the receiver's background color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getBackgroundColor() { + checkWidget(); + return backgroundColor; + } + + /** + * Returns the background color that the badge will use to draw. + * + * @return the badge's backdground color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getBadgeBackground() { + checkWidget(); + return badgeBackground; + } + + /** + * Returns the foreground color that the badge will use to draw. + * + * @return the badge's foreground color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getBadgeForeground() { + checkWidget(); + return badgeForeground; + } + + /** + * Returns the text of the badge + * + * @return the badge's text + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getBadgeValue() { + checkWidget(); + return badgeValue; + } + + /** + * Returns the border color that the receiver will use to draw. + * + * @return the receiver's border color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getBorderColor() { + checkWidget(); + return borderColor; + } + + /** + * Returns the receiver's image if it has one, or null if it does not. + * + * @return the receiver's image + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Image getImage() { + checkWidget(); + return image; + } + + /** + * Returns the receiver's text, which will be an empty string if it has never + * been set or if the receiver is a SEPARATOR label. + * + * @return the receiver's text + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getText() { + checkWidget(); + return text; + } + + /** + * Returns the text color that the receiver will use to draw. + * + * @return the receiver's text color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getTextColor() { + checkWidget(); + return textColor; + } + + /** + * Sets the receiver's background color to the color specified by the argument + * + * @param color + * the new color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setBackgroundColor(Color backgroundColor) { + checkWidget(); + checkColor(backgroundColor); + this.backgroundColor = backgroundColor; + } + + private void checkColor(Color color) { + if (color == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + + /** + * Sets the badge's background color to the color specified by the argument + * + * @param color + * the new color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setBadgeBackground(Color badgeBackground) { + checkWidget(); + checkColor(badgeBackground); + this.badgeBackground = badgeBackground; + } + + /** + * Sets the badge's foreground color to the color specified by the argument + * + * @param color + * the new color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setBadgeForeground(Color badgeForeground) { + checkWidget(); + checkColor(badgeForeground); + this.badgeForeground = badgeForeground; + } + + /** + * Sets the badge's value (text) to the text specified by the argument + * + * @param value + * the new text value + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setBadgeValue(String value) { + checkWidget(); + if (value == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + badgeValue = value; + badgeTextSizeCache = null; + } + + /** + * Sets the receiver's border color to the color specified by the argument + * + * @param color + * the new color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setBorderColor(Color borderColor) { + checkWidget(); + checkColor(borderColor); + this.borderColor = borderColor; + } + + /** + * @see org.eclipse.swt.widgets.Control#setEnabled(boolean) + */ + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + redraw(); + } + + /** + * @see org.eclipse.swt.widgets.Canvas#setFont(org.eclipse.swt.graphics.Font) + */ + @Override + public void setFont(Font font) { + super.setFont(font); + textSizeCache = null; + boldFont.dispose(); + boldFont = SWTGraphicUtil.buildFontFrom(this, SWT.BOLD); + } + + /** + * Sets the receiver's image to the argument, which may be null indicating that + * no image should be displayed. + * + * @param image + * the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setImage(Image image) { + checkWidget(); + this.image = image; + } + + /** + * Sets the receiver's text. + *

+ * This method sets the widget label. The label may include the mnemonic + * character and line delimiters. + *

+ *

+ * Mnemonics are indicated by an '&' that causes the next character to be + * the mnemonic. When the user presses a key sequence that matches the mnemonic, + * focus is assigned to the control that follows the label. On most platforms, + * the mnemonic appears underlined but may be emphasised in a platform specific + * manner. The mnemonic indicator character '&' can be escaped by doubling + * it in the string, causing a single '&' to be displayed. + *

+ *

+ * Note: If control characters like '\n', '\t' etc. are used in the string, then + * the behavior is platform dependent. + *

+ * + * @param string + * the new text + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the text is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setText(String text) { + checkWidget(); + textSizeCache = null; + this.text = text; + } + + /** + * Sets the receiver's text color to the color specified by the argument + * + * @param color + * the new color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTextColor(Color textColor) { + checkWidget(); + checkColor(textColor); + this.textColor = textColor; + } + +} diff --git a/widgets/badgedlabel/pom.xml b/widgets/badgedlabel/pom.xml index a003247a3..e874ae13f 100644 --- a/widgets/badgedlabel/pom.xml +++ b/widgets/badgedlabel/pom.xml @@ -1,23 +1,23 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - nebula-parent - ../../releng/org.eclipse.nebula.nebula-parent - - - badgedlabel - pom - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.badgedlabel - org.eclipse.nebula.widgets.badgedlabel.feature - org.eclipse.nebula.widgets.badgedlabel.snippets - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + nebula-parent + ../../releng/org.eclipse.nebula.nebula-parent + + + badgedlabel + pom + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.badgedlabel + org.eclipse.nebula.widgets.badgedlabel.feature + org.eclipse.nebula.widgets.badgedlabel.snippets + + + diff --git a/widgets/calendarcombo/org.eclipse.nebula.widgets.calendarcombo.example/.project b/widgets/calendarcombo/org.eclipse.nebula.widgets.calendarcombo.example/.project index 78c10f40d..3913de68c 100644 --- a/widgets/calendarcombo/org.eclipse.nebula.widgets.calendarcombo.example/.project +++ b/widgets/calendarcombo/org.eclipse.nebula.widgets.calendarcombo.example/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.calendarcombo.example - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.calendarcombo.example + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/.project b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/.project index 154d3d9c0..47d6830ee 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/.project +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.carousel.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.carousel.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/build.properties b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/build.properties +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/feature.properties b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/feature.properties +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/feature.xml b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/feature.xml index 3d184bd8b..867f8172e 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/feature.xml +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/feature.xml @@ -1,34 +1,34 @@ - - - - - Chips Widget - - - - %license - - - - - - - - - - - + + + + + Chips Widget + + + + %license + + + + + + + + + + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/pom.xml b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/pom.xml index 051bde005..1863acf4b 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/pom.xml +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - carousel - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.carousel.feature - eclipse-feature - 1.0.0-SNAPSHOT - - Nebula Carousel Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + carousel + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.carousel.feature + eclipse-feature + 1.0.0-SNAPSHOT + + Nebula Carousel Feature + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.classpath b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.classpath +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.project b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.project index 0cbf56274..392342958 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.project +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.carousel.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.carousel.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/META-INF/MANIFEST.MF b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/META-INF/MANIFEST.MF index 87219ffdd..51a6cacf3 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/META-INF/MANIFEST.MF +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Carousel Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.carousel.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.carousel;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.carousel.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Carousel Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.carousel.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.carousel;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.carousel.snippets diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/build.properties b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/build.properties +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/pom.xml b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/pom.xml index 981682fa7..f5430b5af 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/pom.xml +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - carousel - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.carousel.snippets - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + carousel + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.carousel.snippets + eclipse-plugin + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/src/org/eclipse/nebula/widgets/chips/CarouselSnippet.java b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/src/org/eclipse/nebula/widgets/chips/CarouselSnippet.java index 8ec50de2e..4f3843efe 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/src/org/eclipse/nebula/widgets/chips/CarouselSnippet.java +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel.snippets/src/org/eclipse/nebula/widgets/chips/CarouselSnippet.java @@ -1,66 +1,66 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.chips; - -import org.eclipse.nebula.widgets.carousel.Carousel; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; - -/** - * Snippet for the Carousel widget - */ -public class CarouselSnippet { - - private static Shell shell; - - /** - * @param args - */ - public static void main(final String[] args) { - final Display display = new Display(); - shell = new Shell(display); - shell.setText("Carousel Snippet"); - shell.setLayout(new FillLayout()); - shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); - - final Carousel carousel = new Carousel(shell, SWT.NONE); - carousel.addImage(loadImage("images/first.png")); - carousel.addImage(loadImage("images/second.jpg")); - carousel.addImage(loadImage("images/third.png")); - - final Listener listener = event -> { - System.out.println("Click on " + carousel.getSelection()); - }; - carousel.addListener(SWT.Selection, listener); - - shell.pack(); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - display.dispose(); - - } - - private static Image loadImage(final String img) { - return new Image(shell.getDisplay(), CarouselSnippet.class.getResourceAsStream(img)); - } - +/******************************************************************************* + * Copyright (c) 2020 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.chips; + +import org.eclipse.nebula.widgets.carousel.Carousel; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; + +/** + * Snippet for the Carousel widget + */ +public class CarouselSnippet { + + private static Shell shell; + + /** + * @param args + */ + public static void main(final String[] args) { + final Display display = new Display(); + shell = new Shell(display); + shell.setText("Carousel Snippet"); + shell.setLayout(new FillLayout()); + shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); + + final Carousel carousel = new Carousel(shell, SWT.NONE); + carousel.addImage(loadImage("images/first.png")); + carousel.addImage(loadImage("images/second.jpg")); + carousel.addImage(loadImage("images/third.png")); + + final Listener listener = event -> { + System.out.println("Click on " + carousel.getSelection()); + }; + carousel.addListener(SWT.Selection, listener); + + shell.pack(); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + display.dispose(); + + } + + private static Image loadImage(final String img) { + return new Image(shell.getDisplay(), CarouselSnippet.class.getResourceAsStream(img)); + } + } \ No newline at end of file diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel/.classpath b/widgets/carousel/org.eclipse.nebula.widgets.carousel/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel/.classpath +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel/.project b/widgets/carousel/org.eclipse.nebula.widgets.carousel/.project index 7761b0ded..36ddd0982 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel/.project +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.carousel - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.carousel + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel/.settings/org.eclipse.jdt.core.prefs b/widgets/carousel/org.eclipse.nebula.widgets.carousel/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel/META-INF/MANIFEST.MF b/widgets/carousel/org.eclipse.nebula.widgets.carousel/META-INF/MANIFEST.MF index c999e53fe..53c431024 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel/META-INF/MANIFEST.MF +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Carousel Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.carousel -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Export-Package: org.eclipse.nebula.widgets.carousel -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;visibility:=reexport, - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.carousel +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Carousel Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.carousel +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Export-Package: org.eclipse.nebula.widgets.carousel +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;visibility:=reexport, + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.carousel diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel/build.properties b/widgets/carousel/org.eclipse.nebula.widgets.carousel/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel/build.properties +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel/pom.xml b/widgets/carousel/org.eclipse.nebula.widgets.carousel/pom.xml index b4adae8e9..9ae8c8020 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel/pom.xml +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - carousel - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.carousel - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + carousel + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.carousel + eclipse-plugin + + diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/Carousel.java b/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/Carousel.java index b735fe698..29e6f1b6e 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/Carousel.java +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/Carousel.java @@ -1,487 +1,487 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.carousel; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; - -/** - * Instances of this class represent a "Carousel". This is a component that displays numerous images, and ones can navigate through images. - * - *
- *
Styles:
- *
(none)
- *
Events:
- *
SWT.Selection
- *
- */ -public class Carousel extends Composite { - - int selection = 0; - final ImageContainer imageContainer; - final ImageSelector imageSelector; - private List images = new ArrayList<>(); - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - */ - public Carousel(final Composite parent, final int style) { - super(parent, checkStyle(style)); - setLayout(new GridLayout()); - imageContainer = new ImageContainer(this, SWT.NONE); - imageContainer.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - imageSelector = new ImageSelector(this, SWT.NONE); - imageSelector.setLayoutData(new GridData(GridData.END, GridData.FILL, false, false)); - - initDefaultColors(); - addListener(SWT.KeyUp, e -> { - if (e.keyCode == SWT.ARROW_LEFT) { - imageContainer.movePrevious(); - } - if (e.keyCode == SWT.ARROW_RIGHT) { - imageContainer.moveNext(); - } - }); - } - - private static int checkStyle(final int style) { - final int mask = SWT.BORDER; - final int newStyle = style & mask; - return newStyle; - } - - private void initDefaultColors() { - setArrowColor(getDisplay().getSystemColor(SWT.COLOR_BLACK)); - setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - setCircleBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); - setCircleForeground(SWTGraphicUtil.getColorSafely(153, 153, 153)); - setCircleHoverColor(SWTGraphicUtil.getColorSafely(102, 102, 102)); - } - - /** - * Adds the image to the collection of images - * - * @param image the image to add - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if image is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see Image - * @see #removeImage - */ - public void addImage(final Image image) { - checkWidget(); - if (image == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - images.add(image); - imageContainer.setImage(images.get(selection)); - layout(); - } - - - - /** - * Adds the listener to the collection of listeners who will be notified when - * the control is selected by the user, by sending it one of the messages - * defined in the SelectionListener interface. - *

- * widgetDefaultSelected is not called. - *

- * - * @param listener the listener which should be notified when the control is - * selected by the user, - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.addSelectionListener(this, listener); - } - - /** - * Remove the image to the collection of images - * - * @param image the image to remove - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if image is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see Image - * @see #removeImage - */ - public void removeImage(final Image image) { - checkWidget(); - if (image == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - images.remove(image); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the control is selected by the user. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.removeSelectionListener(this, listener); - } - - // ---- Getters & Setters - - /** - * Returns the receiver's arrow color. - * - * @return the arrow color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getArrowColor() { - checkWidget(); - return imageSelector.arrowColor; - } - - /** - * Returns the receiver's circle background (when selected). - * - * @return the circle background color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getCircleBackground() { - checkWidget(); - return imageSelector.circleBackground; - } - - /** - * Returns the receiver's circle foreground color. - * - * @return the circle foreground color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getCircleForeground() { - checkWidget(); - return imageSelector.circleForeground; - } - - /** - * Returns the receiver's circle foreground color when mouse is over. - * - * @return the circle foreground color when mouse is over - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getCircleHoverColor() { - checkWidget(); - return imageSelector.circleHoverColor; - } - - /** - * Returns the receiver's list of images. - * - * @return the list of images - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public List getImages() { - checkWidget(); - return images; - } - - /** - * Returns true if the receiver is selected, - * and false otherwise. - *

- * Note: This operation is only available if the SWT.CHECK or the SWT.PUSH flag is set. - *

- * - * @return the selection state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getSelection() { - checkWidget(); - return selection; - } - - /** - * Sets the receiver's arrow color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setArrowColor(final Color arrowColor) { - checkWidget(); - imageSelector.arrowColor = arrowColor; - imageSelector.redraw(); - } - - /** - * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) - */ - @Override - public void setBackground(final Color color) { - super.setBackground(color); - imageContainer.setBackground(color); - imageSelector.setBackground(color); - } - - /** - * Sets the receiver's circle selection color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setCircleBackground(final Color circleBackground) { - checkWidget(); - imageSelector.circleBackground = circleBackground; - imageSelector.redraw(); - } - - /** - * Sets the circle's foreground color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setCircleForeground(final Color circleForeground) { - checkWidget(); - imageSelector.circleForeground = circleForeground; - imageSelector.redraw(); - } - - /** - * Sets the circle's foreground color (when mouse hover) to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setCircleHoverColor(final Color circleHoverColor) { - checkWidget(); - imageSelector.circleHoverColor = circleHoverColor; - imageSelector.redraw(); - } - - /** - * Sets the receiver's list of images. - * - * @param images the new list of images - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setImages(final List images) { - checkWidget(); - if (images == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - this.images = images; - selection = 0; - imageContainer.setImage(images.get(selection)); - layout(); - } - - /** - * Sets the selection state of the receiver, if it is of type CHECK or - * PUSH. - * - *

- * When the receiver is of type CHECK or RADIO, - * it is selected when it is checked. When it is of type TOGGLE, - * it is selected when it is pushed in. - * - * @param selected the new selection state - * - * @exception IllegalArgumentException - *

    - *
  • ERROR_INVALID_ARGUMENT - if the argument is lower than 0 or greater or equals to the number of images
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setSelection(final int selected) { - checkWidget(); - if (selected < 0 || selected >= images.size()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - selection = selected; - imageContainer.setImage(images.get(selection)); - redraw(); - } - -} +/******************************************************************************* + * Copyright (c) 2020 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.carousel; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; + +/** + * Instances of this class represent a "Carousel". This is a component that displays numerous images, and ones can navigate through images. + * + *
+ *
Styles:
+ *
(none)
+ *
Events:
+ *
SWT.Selection
+ *
+ */ +public class Carousel extends Composite { + + int selection = 0; + final ImageContainer imageContainer; + final ImageSelector imageSelector; + private List images = new ArrayList<>(); + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + */ + public Carousel(final Composite parent, final int style) { + super(parent, checkStyle(style)); + setLayout(new GridLayout()); + imageContainer = new ImageContainer(this, SWT.NONE); + imageContainer.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + imageSelector = new ImageSelector(this, SWT.NONE); + imageSelector.setLayoutData(new GridData(GridData.END, GridData.FILL, false, false)); + + initDefaultColors(); + addListener(SWT.KeyUp, e -> { + if (e.keyCode == SWT.ARROW_LEFT) { + imageContainer.movePrevious(); + } + if (e.keyCode == SWT.ARROW_RIGHT) { + imageContainer.moveNext(); + } + }); + } + + private static int checkStyle(final int style) { + final int mask = SWT.BORDER; + final int newStyle = style & mask; + return newStyle; + } + + private void initDefaultColors() { + setArrowColor(getDisplay().getSystemColor(SWT.COLOR_BLACK)); + setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + setCircleBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); + setCircleForeground(SWTGraphicUtil.getColorSafely(153, 153, 153)); + setCircleHoverColor(SWTGraphicUtil.getColorSafely(102, 102, 102)); + } + + /** + * Adds the image to the collection of images + * + * @param image the image to add + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if image is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see Image + * @see #removeImage + */ + public void addImage(final Image image) { + checkWidget(); + if (image == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + images.add(image); + imageContainer.setImage(images.get(selection)); + layout(); + } + + + + /** + * Adds the listener to the collection of listeners who will be notified when + * the control is selected by the user, by sending it one of the messages + * defined in the SelectionListener interface. + *

+ * widgetDefaultSelected is not called. + *

+ * + * @param listener the listener which should be notified when the control is + * selected by the user, + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.addSelectionListener(this, listener); + } + + /** + * Remove the image to the collection of images + * + * @param image the image to remove + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if image is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see Image + * @see #removeImage + */ + public void removeImage(final Image image) { + checkWidget(); + if (image == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + images.remove(image); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.removeSelectionListener(this, listener); + } + + // ---- Getters & Setters + + /** + * Returns the receiver's arrow color. + * + * @return the arrow color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getArrowColor() { + checkWidget(); + return imageSelector.arrowColor; + } + + /** + * Returns the receiver's circle background (when selected). + * + * @return the circle background color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getCircleBackground() { + checkWidget(); + return imageSelector.circleBackground; + } + + /** + * Returns the receiver's circle foreground color. + * + * @return the circle foreground color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getCircleForeground() { + checkWidget(); + return imageSelector.circleForeground; + } + + /** + * Returns the receiver's circle foreground color when mouse is over. + * + * @return the circle foreground color when mouse is over + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getCircleHoverColor() { + checkWidget(); + return imageSelector.circleHoverColor; + } + + /** + * Returns the receiver's list of images. + * + * @return the list of images + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public List getImages() { + checkWidget(); + return images; + } + + /** + * Returns true if the receiver is selected, + * and false otherwise. + *

+ * Note: This operation is only available if the SWT.CHECK or the SWT.PUSH flag is set. + *

+ * + * @return the selection state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getSelection() { + checkWidget(); + return selection; + } + + /** + * Sets the receiver's arrow color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setArrowColor(final Color arrowColor) { + checkWidget(); + imageSelector.arrowColor = arrowColor; + imageSelector.redraw(); + } + + /** + * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) + */ + @Override + public void setBackground(final Color color) { + super.setBackground(color); + imageContainer.setBackground(color); + imageSelector.setBackground(color); + } + + /** + * Sets the receiver's circle selection color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setCircleBackground(final Color circleBackground) { + checkWidget(); + imageSelector.circleBackground = circleBackground; + imageSelector.redraw(); + } + + /** + * Sets the circle's foreground color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setCircleForeground(final Color circleForeground) { + checkWidget(); + imageSelector.circleForeground = circleForeground; + imageSelector.redraw(); + } + + /** + * Sets the circle's foreground color (when mouse hover) to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setCircleHoverColor(final Color circleHoverColor) { + checkWidget(); + imageSelector.circleHoverColor = circleHoverColor; + imageSelector.redraw(); + } + + /** + * Sets the receiver's list of images. + * + * @param images the new list of images + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setImages(final List images) { + checkWidget(); + if (images == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + this.images = images; + selection = 0; + imageContainer.setImage(images.get(selection)); + layout(); + } + + /** + * Sets the selection state of the receiver, if it is of type CHECK or + * PUSH. + * + *

+ * When the receiver is of type CHECK or RADIO, + * it is selected when it is checked. When it is of type TOGGLE, + * it is selected when it is pushed in. + * + * @param selected the new selection state + * + * @exception IllegalArgumentException + *

    + *
  • ERROR_INVALID_ARGUMENT - if the argument is lower than 0 or greater or equals to the number of images
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setSelection(final int selected) { + checkWidget(); + if (selected < 0 || selected >= images.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + selection = selected; + imageContainer.setImage(images.get(selection)); + redraw(); + } + +} diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/ImageContainer.java b/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/ImageContainer.java index 6d8a00207..953fe39a4 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/ImageContainer.java +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/ImageContainer.java @@ -1,208 +1,208 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.carousel; - -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; -import org.eclipse.swt.SWT; -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.Canvas; - -class ImageContainer extends Canvas { - - private Image image, scrollImage; - private Carousel carousel; - private int slider; - - public ImageContainer(final Carousel parent, final int style) { - super(parent, SWT.DOUBLE_BUFFERED); - carousel = parent; - slider = -1; - addListener(SWT.Paint, e -> { - final GC gc = e.gc; - gc.setAntialias(SWT.ON); - gc.setInterpolation(SWT.HIGH); - - if (image == null) { - return; - } - - final Rectangle clientArea = getClientArea(); - if (slider == -1) { - final Rectangle imageBounds = image.getBounds(); - if (imageBounds.width > clientArea.width || imageBounds.height > clientArea.height) { - // Image is too big - final Point point = reduceImageSoItFits(image); - final int newWidth = point.x; - final int newHeight = point.y; - - gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, (clientArea.width - newWidth) / 2, (clientArea.height - newHeight) / 2, newWidth, newHeight); - } else { - gc.drawImage(image, (clientArea.width - imageBounds.width) / 2, (clientArea.height - imageBounds.height) / 2); - } - return; - } - - // Animation - if (!scrollImage.isDisposed()) { - gc.drawImage(scrollImage, slider, 0, clientArea.width, clientArea.height, 0, 0, clientArea.width, clientArea.height); - } - }); - } - - private Point reduceImageSoItFits(final Image img) { - final Rectangle clientArea = getClientArea(); - final Rectangle imageBounds = img.getBounds(); - final float ratio = imageBounds.width * 1f / imageBounds.height * 1f; - - int newWidth = imageBounds.width; - int newHeight = imageBounds.height; - while (newWidth > clientArea.width - 5 || newHeight > clientArea.height - 5) { - newWidth = (int) (newWidth * .9f); - newHeight = (int) (newWidth / ratio); - } - return new Point(newWidth, newHeight); - } - - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - final Point superSize = super.computeSize(wHint, hHint, changed); - - int width = 0, height = 0; - final List images = ((Carousel) getParent()).getImages(); - for (final Image image : images) { - final Rectangle rect = image.getBounds(); - width = Math.max(width, rect.width); - height = Math.max(height, rect.height); - } - return new Point(Math.max(superSize.x, width), Math.max(superSize.y, height)); - } - - void setImage(final Image image) { - this.image = image; - } - - void moveTo(final int newSelection) { - final int direction = newSelection > carousel.getSelection() ? SWT.LEFT : SWT.RIGHT; - slide(newSelection, direction); - carousel.selection = newSelection; - SelectionListenerUtil.fireSelectionListeners(carousel,null); - carousel.imageSelector.redraw(); - } - - void moveNext() { - int newSelection = carousel.selection + 1; - if (newSelection == carousel.getImages().size()) { - newSelection = 0; - } - slide(newSelection, SWT.LEFT); - carousel.selection = newSelection; - SelectionListenerUtil.fireSelectionListeners(carousel,null); - carousel.imageSelector.redraw(); - } - - private void slide(final int target, final int direction) { - final int width = getClientArea().width; - slider = direction == SWT.LEFT ? 0 : width; - if (direction == SWT.LEFT) { - createScrolledImage(image, carousel.getImages().get(target)); - } else { - createScrolledImage(carousel.getImages().get(target), image); - } - - getDisplay().timerExec(200, new Runnable() { - - @Override - public void run() { - ImageContainer.this.redraw(); - final int step = width / 5; - if (direction == SWT.LEFT) { - slider += step; - if (slider >= width) { - slider = -1; - scrollImage.dispose(); - return; - } - } else { - slider -= step; - if (slider <= 0) { - slider = -1; - scrollImage.dispose(); - return; - } - } - getDisplay().timerExec(50, this); - } - }); - - image = carousel.getImages().get(target); - redraw(); - } - - private void createScrolledImage(final Image left, final Image right) { - final Rectangle clientArea = getClientArea(); - - scrollImage = new Image(getDisplay(), clientArea.width * 2, clientArea.height); - final GC gc = new GC(scrollImage); - gc.setInterpolation(SWT.HIGH); - - gc.setBackground(carousel.getBackground()); - gc.fillRectangle(0, 0, clientArea.width * 2, clientArea.height); - - final Rectangle leftImageBounds = left.getBounds(); - if (leftImageBounds.width > clientArea.width || leftImageBounds.height > clientArea.height) { - // Image is too big - final Point point = reduceImageSoItFits(left); - final int newWidth = point.x; - final int newHeight = point.y; - - gc.drawImage(left, 0, 0, leftImageBounds.width, leftImageBounds.height, // - (clientArea.width - newWidth) / 2, (clientArea.height - newHeight) / 2, newWidth, newHeight); - } else { - gc.drawImage(left, (clientArea.width - leftImageBounds.width) / 2, (clientArea.height - leftImageBounds.height) / 2); - } - - final Rectangle rightImageBounds = right.getBounds(); - if (rightImageBounds.width > clientArea.width || rightImageBounds.height > clientArea.height) { - // Image is too big - final Point point = reduceImageSoItFits(right); - final int newWidth = point.x; - final int newHeight = point.y; - - gc.drawImage(right, 0, 0, rightImageBounds.width, rightImageBounds.height, // - clientArea.width + (clientArea.width - newWidth) / 2, (clientArea.height - newHeight) / 2, newWidth, newHeight); - } else { - gc.drawImage(right, clientArea.width + (clientArea.width - rightImageBounds.width) / 2, (clientArea.height - rightImageBounds.height) / 2); - } - - gc.dispose(); - } - - - void movePrevious() { - final Carousel carousel = (Carousel) getParent(); - int newSelection = carousel.selection - 1; - if (newSelection == -1) { - newSelection = carousel.getImages().size() - 1; - } - slide(newSelection, SWT.RIGHT); - carousel.selection = newSelection; - SelectionListenerUtil.fireSelectionListeners(carousel,null); - carousel.imageSelector.redraw(); - } - -} +/******************************************************************************* + * Copyright (c) 2020 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.carousel; + +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; +import org.eclipse.swt.SWT; +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.Canvas; + +class ImageContainer extends Canvas { + + private Image image, scrollImage; + private Carousel carousel; + private int slider; + + public ImageContainer(final Carousel parent, final int style) { + super(parent, SWT.DOUBLE_BUFFERED); + carousel = parent; + slider = -1; + addListener(SWT.Paint, e -> { + final GC gc = e.gc; + gc.setAntialias(SWT.ON); + gc.setInterpolation(SWT.HIGH); + + if (image == null) { + return; + } + + final Rectangle clientArea = getClientArea(); + if (slider == -1) { + final Rectangle imageBounds = image.getBounds(); + if (imageBounds.width > clientArea.width || imageBounds.height > clientArea.height) { + // Image is too big + final Point point = reduceImageSoItFits(image); + final int newWidth = point.x; + final int newHeight = point.y; + + gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, (clientArea.width - newWidth) / 2, (clientArea.height - newHeight) / 2, newWidth, newHeight); + } else { + gc.drawImage(image, (clientArea.width - imageBounds.width) / 2, (clientArea.height - imageBounds.height) / 2); + } + return; + } + + // Animation + if (!scrollImage.isDisposed()) { + gc.drawImage(scrollImage, slider, 0, clientArea.width, clientArea.height, 0, 0, clientArea.width, clientArea.height); + } + }); + } + + private Point reduceImageSoItFits(final Image img) { + final Rectangle clientArea = getClientArea(); + final Rectangle imageBounds = img.getBounds(); + final float ratio = imageBounds.width * 1f / imageBounds.height * 1f; + + int newWidth = imageBounds.width; + int newHeight = imageBounds.height; + while (newWidth > clientArea.width - 5 || newHeight > clientArea.height - 5) { + newWidth = (int) (newWidth * .9f); + newHeight = (int) (newWidth / ratio); + } + return new Point(newWidth, newHeight); + } + + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + final Point superSize = super.computeSize(wHint, hHint, changed); + + int width = 0, height = 0; + final List images = ((Carousel) getParent()).getImages(); + for (final Image image : images) { + final Rectangle rect = image.getBounds(); + width = Math.max(width, rect.width); + height = Math.max(height, rect.height); + } + return new Point(Math.max(superSize.x, width), Math.max(superSize.y, height)); + } + + void setImage(final Image image) { + this.image = image; + } + + void moveTo(final int newSelection) { + final int direction = newSelection > carousel.getSelection() ? SWT.LEFT : SWT.RIGHT; + slide(newSelection, direction); + carousel.selection = newSelection; + SelectionListenerUtil.fireSelectionListeners(carousel,null); + carousel.imageSelector.redraw(); + } + + void moveNext() { + int newSelection = carousel.selection + 1; + if (newSelection == carousel.getImages().size()) { + newSelection = 0; + } + slide(newSelection, SWT.LEFT); + carousel.selection = newSelection; + SelectionListenerUtil.fireSelectionListeners(carousel,null); + carousel.imageSelector.redraw(); + } + + private void slide(final int target, final int direction) { + final int width = getClientArea().width; + slider = direction == SWT.LEFT ? 0 : width; + if (direction == SWT.LEFT) { + createScrolledImage(image, carousel.getImages().get(target)); + } else { + createScrolledImage(carousel.getImages().get(target), image); + } + + getDisplay().timerExec(200, new Runnable() { + + @Override + public void run() { + ImageContainer.this.redraw(); + final int step = width / 5; + if (direction == SWT.LEFT) { + slider += step; + if (slider >= width) { + slider = -1; + scrollImage.dispose(); + return; + } + } else { + slider -= step; + if (slider <= 0) { + slider = -1; + scrollImage.dispose(); + return; + } + } + getDisplay().timerExec(50, this); + } + }); + + image = carousel.getImages().get(target); + redraw(); + } + + private void createScrolledImage(final Image left, final Image right) { + final Rectangle clientArea = getClientArea(); + + scrollImage = new Image(getDisplay(), clientArea.width * 2, clientArea.height); + final GC gc = new GC(scrollImage); + gc.setInterpolation(SWT.HIGH); + + gc.setBackground(carousel.getBackground()); + gc.fillRectangle(0, 0, clientArea.width * 2, clientArea.height); + + final Rectangle leftImageBounds = left.getBounds(); + if (leftImageBounds.width > clientArea.width || leftImageBounds.height > clientArea.height) { + // Image is too big + final Point point = reduceImageSoItFits(left); + final int newWidth = point.x; + final int newHeight = point.y; + + gc.drawImage(left, 0, 0, leftImageBounds.width, leftImageBounds.height, // + (clientArea.width - newWidth) / 2, (clientArea.height - newHeight) / 2, newWidth, newHeight); + } else { + gc.drawImage(left, (clientArea.width - leftImageBounds.width) / 2, (clientArea.height - leftImageBounds.height) / 2); + } + + final Rectangle rightImageBounds = right.getBounds(); + if (rightImageBounds.width > clientArea.width || rightImageBounds.height > clientArea.height) { + // Image is too big + final Point point = reduceImageSoItFits(right); + final int newWidth = point.x; + final int newHeight = point.y; + + gc.drawImage(right, 0, 0, rightImageBounds.width, rightImageBounds.height, // + clientArea.width + (clientArea.width - newWidth) / 2, (clientArea.height - newHeight) / 2, newWidth, newHeight); + } else { + gc.drawImage(right, clientArea.width + (clientArea.width - rightImageBounds.width) / 2, (clientArea.height - rightImageBounds.height) / 2); + } + + gc.dispose(); + } + + + void movePrevious() { + final Carousel carousel = (Carousel) getParent(); + int newSelection = carousel.selection - 1; + if (newSelection == -1) { + newSelection = carousel.getImages().size() - 1; + } + slide(newSelection, SWT.RIGHT); + carousel.selection = newSelection; + SelectionListenerUtil.fireSelectionListeners(carousel,null); + carousel.imageSelector.redraw(); + } + +} diff --git a/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/ImageSelector.java b/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/ImageSelector.java index 023a417fc..8939a1a0b 100644 --- a/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/ImageSelector.java +++ b/widgets/carousel/org.eclipse.nebula.widgets.carousel/src/org/eclipse/nebula/widgets/carousel/ImageSelector.java @@ -1,158 +1,158 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.carousel; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; - -class ImageSelector extends Canvas { - private static final int CIRCLE_DIAMETER = 20; - private static final int ARROW_SIZE = 12; - - Color arrowColor, circleBackground, circleForeground, circleHoverColor; - private final List rects = new ArrayList<>(); - private int indexHover = -1; - private Rectangle arrowLeftArea, arrowRightArea; - private boolean hoverLeftArrow, hoverRightArrow; - private final Carousel carousel; - - public ImageSelector(final Carousel parent, final int none) { - super(parent, SWT.DOUBLE_BUFFERED); - carousel = parent; - - addListener(SWT.Paint, e -> { - final GC gc = e.gc; - gc.setFont(getFont()); - gc.setAdvanced(true); - gc.setTextAntialias(SWT.ON); - gc.setAntialias(SWT.ON); - final Color previousForeground = gc.getForeground(); - final Color previousBackground = gc.getBackground(); - - drawContent(gc); - - gc.setBackground(previousBackground); - gc.setForeground(previousForeground); - }); - - addListener(SWT.MouseExit, e -> { - indexHover = -1; - setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); - }); - - addListener(SWT.MouseMove, e -> { - Point pt = getDisplay().getCursorLocation(); - pt = getDisplay().map(null, this, pt.x, pt.y); - - hoverLeftArrow = arrowLeftArea.contains(pt); - hoverRightArrow = arrowRightArea.contains(pt); - - Cursor expectedCursor = hoverLeftArrow || hoverRightArrow ? getDisplay().getSystemCursor(SWT.CURSOR_HAND) : getDisplay().getSystemCursor(SWT.CURSOR_ARROW); - indexHover = -1; - for (int i = 0; i < rects.size(); i++) { - final Rectangle rect = rects.get(i); - if (rect.contains(pt)) { - expectedCursor = getDisplay().getSystemCursor(SWT.CURSOR_HAND); - indexHover = i; - break; - } - } - - if (!expectedCursor.equals(getCursor())) { - setCursor(expectedCursor); - } - redraw(); - }); - - addListener(SWT.MouseUp, e -> { - final ImageContainer imageContainer = parent.imageContainer; - if (hoverLeftArrow) { - imageContainer.movePrevious(); - } else if (hoverRightArrow) { - imageContainer.moveNext(); - } else if (indexHover != -1) { - imageContainer.moveTo(indexHover); - } - }); - } - - private void drawContent(final GC gc) { - final int x = drawCircles(gc); - drawArrows(x, gc); - } - - private int drawCircles(final GC gc) { - int x = 0; - final Rectangle clientArea = getClientArea(); - rects.clear(); - for (int i = 0; i < carousel.getImages().size(); i++) { - final Rectangle rect = new Rectangle(x, (clientArea.height - CIRCLE_DIAMETER) / 2, CIRCLE_DIAMETER, CIRCLE_DIAMETER); - rects.add(rect); - if (i == carousel.getSelection()) { - gc.setBackground(circleBackground); - gc.fillOval(rect.x, rect.y, CIRCLE_DIAMETER, CIRCLE_DIAMETER); - } else if (i == indexHover) { - // - gc.setForeground(circleHoverColor); - gc.drawOval(rect.x, rect.y, CIRCLE_DIAMETER, CIRCLE_DIAMETER); - } else { - gc.setForeground(circleForeground); - gc.drawOval(rect.x, rect.y, CIRCLE_DIAMETER, CIRCLE_DIAMETER); - } - x += CIRCLE_DIAMETER + 5; - } - return x + CIRCLE_DIAMETER; - - } - - private void drawArrows(int x, final GC gc) { - gc.setForeground(arrowColor); - - final Rectangle clientArea = getClientArea(); - final int topY = (clientArea.height - ARROW_SIZE) / 2; - final int width = (int) (ARROW_SIZE * .5f); - - gc.setLineWidth(hoverLeftArrow ? 3 : 1); - - gc.drawPolyline(new int[] { x + width, topY, // - x, topY + ARROW_SIZE / 2, // - x + width, topY + ARROW_SIZE }); - - arrowLeftArea = new Rectangle(x, topY, ARROW_SIZE, ARROW_SIZE); - - x += ARROW_SIZE * 3; - - gc.setLineWidth(hoverRightArrow ? 3 : 1); - gc.drawPolyline(new int[] { x, topY, // - x + width, topY + ARROW_SIZE / 2, // - x, topY + ARROW_SIZE }); - arrowRightArea = new Rectangle(x, topY, ARROW_SIZE, ARROW_SIZE); - } - - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - final Point superSize = super.computeSize(wHint, hHint, changed); - final int width = 70 + carousel.getImages().size() * (CIRCLE_DIAMETER + 5); - final int height = 40; - return new Point(Math.max(superSize.x, width), Math.max(superSize.y, height)); - } - -} +/******************************************************************************* + * Copyright (c) 2020 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.carousel; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; + +class ImageSelector extends Canvas { + private static final int CIRCLE_DIAMETER = 20; + private static final int ARROW_SIZE = 12; + + Color arrowColor, circleBackground, circleForeground, circleHoverColor; + private final List rects = new ArrayList<>(); + private int indexHover = -1; + private Rectangle arrowLeftArea, arrowRightArea; + private boolean hoverLeftArrow, hoverRightArrow; + private final Carousel carousel; + + public ImageSelector(final Carousel parent, final int none) { + super(parent, SWT.DOUBLE_BUFFERED); + carousel = parent; + + addListener(SWT.Paint, e -> { + final GC gc = e.gc; + gc.setFont(getFont()); + gc.setAdvanced(true); + gc.setTextAntialias(SWT.ON); + gc.setAntialias(SWT.ON); + final Color previousForeground = gc.getForeground(); + final Color previousBackground = gc.getBackground(); + + drawContent(gc); + + gc.setBackground(previousBackground); + gc.setForeground(previousForeground); + }); + + addListener(SWT.MouseExit, e -> { + indexHover = -1; + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); + }); + + addListener(SWT.MouseMove, e -> { + Point pt = getDisplay().getCursorLocation(); + pt = getDisplay().map(null, this, pt.x, pt.y); + + hoverLeftArrow = arrowLeftArea.contains(pt); + hoverRightArrow = arrowRightArea.contains(pt); + + Cursor expectedCursor = hoverLeftArrow || hoverRightArrow ? getDisplay().getSystemCursor(SWT.CURSOR_HAND) : getDisplay().getSystemCursor(SWT.CURSOR_ARROW); + indexHover = -1; + for (int i = 0; i < rects.size(); i++) { + final Rectangle rect = rects.get(i); + if (rect.contains(pt)) { + expectedCursor = getDisplay().getSystemCursor(SWT.CURSOR_HAND); + indexHover = i; + break; + } + } + + if (!expectedCursor.equals(getCursor())) { + setCursor(expectedCursor); + } + redraw(); + }); + + addListener(SWT.MouseUp, e -> { + final ImageContainer imageContainer = parent.imageContainer; + if (hoverLeftArrow) { + imageContainer.movePrevious(); + } else if (hoverRightArrow) { + imageContainer.moveNext(); + } else if (indexHover != -1) { + imageContainer.moveTo(indexHover); + } + }); + } + + private void drawContent(final GC gc) { + final int x = drawCircles(gc); + drawArrows(x, gc); + } + + private int drawCircles(final GC gc) { + int x = 0; + final Rectangle clientArea = getClientArea(); + rects.clear(); + for (int i = 0; i < carousel.getImages().size(); i++) { + final Rectangle rect = new Rectangle(x, (clientArea.height - CIRCLE_DIAMETER) / 2, CIRCLE_DIAMETER, CIRCLE_DIAMETER); + rects.add(rect); + if (i == carousel.getSelection()) { + gc.setBackground(circleBackground); + gc.fillOval(rect.x, rect.y, CIRCLE_DIAMETER, CIRCLE_DIAMETER); + } else if (i == indexHover) { + // + gc.setForeground(circleHoverColor); + gc.drawOval(rect.x, rect.y, CIRCLE_DIAMETER, CIRCLE_DIAMETER); + } else { + gc.setForeground(circleForeground); + gc.drawOval(rect.x, rect.y, CIRCLE_DIAMETER, CIRCLE_DIAMETER); + } + x += CIRCLE_DIAMETER + 5; + } + return x + CIRCLE_DIAMETER; + + } + + private void drawArrows(int x, final GC gc) { + gc.setForeground(arrowColor); + + final Rectangle clientArea = getClientArea(); + final int topY = (clientArea.height - ARROW_SIZE) / 2; + final int width = (int) (ARROW_SIZE * .5f); + + gc.setLineWidth(hoverLeftArrow ? 3 : 1); + + gc.drawPolyline(new int[] { x + width, topY, // + x, topY + ARROW_SIZE / 2, // + x + width, topY + ARROW_SIZE }); + + arrowLeftArea = new Rectangle(x, topY, ARROW_SIZE, ARROW_SIZE); + + x += ARROW_SIZE * 3; + + gc.setLineWidth(hoverRightArrow ? 3 : 1); + gc.drawPolyline(new int[] { x, topY, // + x + width, topY + ARROW_SIZE / 2, // + x, topY + ARROW_SIZE }); + arrowRightArea = new Rectangle(x, topY, ARROW_SIZE, ARROW_SIZE); + } + + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + final Point superSize = super.computeSize(wHint, hHint, changed); + final int width = 70 + carousel.getImages().size() * (CIRCLE_DIAMETER + 5); + final int height = 40; + return new Point(Math.max(superSize.x, width), Math.max(superSize.y, height)); + } + +} diff --git a/widgets/carousel/pom.xml b/widgets/carousel/pom.xml index 6eb6ad727..582d637b1 100644 --- a/widgets/carousel/pom.xml +++ b/widgets/carousel/pom.xml @@ -1,23 +1,23 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - nebula-parent - ../../releng/org.eclipse.nebula.nebula-parent - - - carousel - pom - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.carousel - org.eclipse.nebula.widgets.carousel.feature - org.eclipse.nebula.widgets.carousel.snippets - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + nebula-parent + ../../releng/org.eclipse.nebula.nebula-parent + + + carousel + pom + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.carousel + org.eclipse.nebula.widgets.carousel.feature + org.eclipse.nebula.widgets.carousel.snippets + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/.classpath b/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/.classpath +++ b/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/.settings/org.eclipse.jdt.core.prefs b/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/META-INF/MANIFEST.MF b/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/META-INF/MANIFEST.MF index e67f384d4..443594dbe 100644 --- a/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/META-INF/MANIFEST.MF +++ b/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/META-INF/MANIFEST.MF @@ -1,16 +1,16 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-SymbolicName: org.eclipse.nebula.jface.cdatetime -Bundle-Version: 1.3.0.qualifier -Bundle-Name: %pluginName -Bundle-Vendor: %providerName -Bundle-Localization: plugin -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.core.runtime;bundle-version="3.4.0", - org.eclipse.nebula.widgets.cdatetime;bundle-version="0.14.0", - org.eclipse.jface;bundle-version="3.4.0", - org.eclipse.core.databinding;bundle-version="1.1.0", - org.eclipse.jface.databinding, - org.eclipse.core.databinding.property;bundle-version="1.6.100" -Export-Package: org.eclipse.nebula.jface.cdatetime -Automatic-Module-Name: org.eclipse.nebula.jface.cdatetime +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.eclipse.nebula.jface.cdatetime +Bundle-Version: 1.3.0.qualifier +Bundle-Name: %pluginName +Bundle-Vendor: %providerName +Bundle-Localization: plugin +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.4.0", + org.eclipse.nebula.widgets.cdatetime;bundle-version="0.14.0", + org.eclipse.jface;bundle-version="3.4.0", + org.eclipse.core.databinding;bundle-version="1.1.0", + org.eclipse.jface.databinding, + org.eclipse.core.databinding.property;bundle-version="1.6.100" +Export-Package: org.eclipse.nebula.jface.cdatetime +Automatic-Module-Name: org.eclipse.nebula.jface.cdatetime diff --git a/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/src/org/eclipse/nebula/jface/cdatetime/CDateTimeValueProperty.java b/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/src/org/eclipse/nebula/jface/cdatetime/CDateTimeValueProperty.java index 493a78cc3..1fc012858 100644 --- a/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/src/org/eclipse/nebula/jface/cdatetime/CDateTimeValueProperty.java +++ b/widgets/cdatetime/org.eclipse.nebula.jface.cdatetime/src/org/eclipse/nebula/jface/cdatetime/CDateTimeValueProperty.java @@ -1,82 +1,82 @@ -/******************************************************************************* - * Copyright (c) 2019 Peter Pfeifer - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Peter Pfeifer - initial API and implementation - bug #279782 - *******************************************************************************/ -package org.eclipse.nebula.jface.cdatetime; -import java.util.Date; - -import org.eclipse.jface.databinding.swt.WidgetValueProperty; -import org.eclipse.nebula.widgets.cdatetime.CDateTime; -import org.eclipse.swt.SWT; - - -public class CDateTimeValueProperty extends WidgetValueProperty { - - public static final String EDITABLE = "editable"; - - String property = "date"; - - /** - * - */ - public CDateTimeValueProperty() { - super(new int[] { SWT.Selection, SWT.Modify }); - } - - /** - * @param property - */ - public CDateTimeValueProperty(String property) { - this(); - this.property = property; - } - - /** - * @see org.eclipse.core.databinding.property.value.SimpleValueProperty#doGetValue(java.lang.Object) - */ - @Override - protected Object doGetValue(Object source) { - CDateTime dateTime = (CDateTime) source; - // just in case editable property is bound - if (CDateTimeValueProperty.EDITABLE.equals(this.property)) { - return dateTime.getEditable(); - } else { - return dateTime.getSelection(); - } - } - - - /** - * @see org.eclipse.core.databinding.property.value.SimpleValueProperty#doSetValue(java.lang.Object, java.lang.Object) - */ - @Override - protected void doSetValue(Object source, Object value) { - CDateTime dateTime = (CDateTime) source; - // just in case editable property is bound - if (CDateTimeValueProperty.EDITABLE.equals(this.property)) { - dateTime.setEditable((Boolean) value); - } else { - dateTime.setSelection((Date) value); - } - } - - /** - * @see org.eclipse.core.databinding.property.value.IValueProperty#getValueType() - */ - public Object getValueType() { - // just in case editable property is bound - if (CDateTimeValueProperty.EDITABLE.equals(this.property)) { - return Boolean.class; - } - return Date.class; - } -} +/******************************************************************************* + * Copyright (c) 2019 Peter Pfeifer + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Peter Pfeifer - initial API and implementation - bug #279782 + *******************************************************************************/ +package org.eclipse.nebula.jface.cdatetime; +import java.util.Date; + +import org.eclipse.jface.databinding.swt.WidgetValueProperty; +import org.eclipse.nebula.widgets.cdatetime.CDateTime; +import org.eclipse.swt.SWT; + + +public class CDateTimeValueProperty extends WidgetValueProperty { + + public static final String EDITABLE = "editable"; + + String property = "date"; + + /** + * + */ + public CDateTimeValueProperty() { + super(new int[] { SWT.Selection, SWT.Modify }); + } + + /** + * @param property + */ + public CDateTimeValueProperty(String property) { + this(); + this.property = property; + } + + /** + * @see org.eclipse.core.databinding.property.value.SimpleValueProperty#doGetValue(java.lang.Object) + */ + @Override + protected Object doGetValue(Object source) { + CDateTime dateTime = (CDateTime) source; + // just in case editable property is bound + if (CDateTimeValueProperty.EDITABLE.equals(this.property)) { + return dateTime.getEditable(); + } else { + return dateTime.getSelection(); + } + } + + + /** + * @see org.eclipse.core.databinding.property.value.SimpleValueProperty#doSetValue(java.lang.Object, java.lang.Object) + */ + @Override + protected void doSetValue(Object source, Object value) { + CDateTime dateTime = (CDateTime) source; + // just in case editable property is bound + if (CDateTimeValueProperty.EDITABLE.equals(this.property)) { + dateTime.setEditable((Boolean) value); + } else { + dateTime.setSelection((Date) value); + } + } + + /** + * @see org.eclipse.core.databinding.property.value.IValueProperty#getValueType() + */ + public Object getValueType() { + // just in case editable property is bound + if (CDateTimeValueProperty.EDITABLE.equals(this.property)) { + return Boolean.class; + } + return Date.class; + } +} diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/.project b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/.project index 0e911020e..16bcb0729 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/.project +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.cdatetime.css.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.cdatetime.css.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/feature.xml b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/feature.xml index 6e596f635..bbcac5a02 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/feature.xml +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/feature.xml @@ -1,34 +1,34 @@ - - - - - CDateTime CSS - - - - %license - - - - - - - - - - - + + + + + CDateTime CSS + + + + %license + + + + + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/pom.xml b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/pom.xml index 84a00dd3e..3e2ced616 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/pom.xml +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css.feature/pom.xml @@ -1,32 +1,32 @@ - - - - 4.0.0 - - - org.eclipse.nebula - cdatetime - 1.5.0-SNAPSHOT - - - org.eclipse.nebula.widgets.cdatetime.css.feature - eclipse-feature - 1.4.0-SNAPSHOT - - Nebula CDateTime CSS Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + cdatetime + 1.5.0-SNAPSHOT + + + org.eclipse.nebula.widgets.cdatetime.css.feature + eclipse-feature + 1.4.0-SNAPSHOT + + Nebula CDateTime CSS Feature + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.classpath b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.classpath +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.project b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.project index 5e031ee29..51d46324b 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.project +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.cdatetime.css - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.cdatetime.css + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.settings/org.eclipse.jdt.core.prefs b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/META-INF/MANIFEST.MF b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/META-INF/MANIFEST.MF index 8cef4dd1c..45d798244 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/META-INF/MANIFEST.MF +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula CDateTime CSS -Bundle-SymbolicName: org.eclipse.nebula.widgets.cdatetime.css;singleton:=true -Bundle-Version: 1.0.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.swt, - org.eclipse.e4.ui.services;bundle-version="0.10.0", - org.eclipse.e4.ui.css.core;bundle-version="0.10.0", - org.eclipse.e4.ui.css.swt;bundle-version="0.10.0", - org.eclipse.nebula.widgets.cdatetime -Export-Package: org.eclipse.nebula.widgets.cdatetime.css -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.widgets.cdatetime.css +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula CDateTime CSS +Bundle-SymbolicName: org.eclipse.nebula.widgets.cdatetime.css;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.swt, + org.eclipse.e4.ui.services;bundle-version="0.10.0", + org.eclipse.e4.ui.css.core;bundle-version="0.10.0", + org.eclipse.e4.ui.css.swt;bundle-version="0.10.0", + org.eclipse.nebula.widgets.cdatetime +Export-Package: org.eclipse.nebula.widgets.cdatetime.css +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.widgets.cdatetime.css diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/build.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/build.properties index 6f20375d6..e9863e281 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/build.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/build.properties @@ -1,5 +1,5 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - plugin.xml +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/plugin.xml b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/plugin.xml index cb66b3872..0ce481167 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/plugin.xml +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/plugin.xml @@ -1,54 +1,54 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/pom.xml b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/pom.xml index 4a40e24ad..9c1af910f 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/pom.xml +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/pom.xml @@ -1,30 +1,30 @@ - - - - 4.0.0 - - - org.eclipse.nebula - cdatetime - 1.5.0-SNAPSHOT - - - org.eclipse.nebula.widgets.cdatetime.css - eclipse-plugin - 1.0.0-SNAPSHOT - - + + + + 4.0.0 + + + org.eclipse.nebula + cdatetime + 1.5.0-SNAPSHOT + + + org.eclipse.nebula.widgets.cdatetime.css + eclipse-plugin + 1.0.0-SNAPSHOT + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/src/org/eclipse/nebula/widgets/cdatetime/css/CDateTimePropertyHandler.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/src/org/eclipse/nebula/widgets/cdatetime/css/CDateTimePropertyHandler.java index 5781de10a..8cc6d55fd 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/src/org/eclipse/nebula/widgets/cdatetime/css/CDateTimePropertyHandler.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.css/src/org/eclipse/nebula/widgets/cdatetime/css/CDateTimePropertyHandler.java @@ -1,296 +1,296 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent Caron. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent Caron - initial API and implementation - ******************************************************************************/ -package org.eclipse.nebula.widgets.cdatetime.css; - -import org.eclipse.e4.ui.css.core.css2.CSS2FontHelper; -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.core.impl.dom.Measure; -import org.eclipse.e4.ui.css.swt.dom.ControlElement; -import org.eclipse.nebula.widgets.cdatetime.CDateTime; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.widgets.Control; -import org.w3c.dom.css.CSSPrimitiveValue; -import org.w3c.dom.css.CSSValue; -import org.w3c.dom.css.CSSValueList; - -@SuppressWarnings("restriction") -public class CDateTimePropertyHandler implements ICSSPropertyHandler { - @Override - public boolean applyCSSProperty(final Object element, final String property, final CSSValue value, final String pseudo, final CSSEngine engine) throws Exception { - final CDateTime cdt =(CDateTime) ((ControlElement) element).getNativeWidget(); - - // General properties - if ("cdt-background-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setBackground(newColor); - } - if ("cdt-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setForeground(newColor); - } - if ("cdt-font".equals(property)) { - applyCSSPropertyFont(cdt, value, false); - } - if ("cdt-font-style".equals(property)) { - applyCSSPropertyStyle(cdt, value, false); - } - if ("cdt-font-size".equals(property)) { - applyCSSPropertySize(cdt, value, false); - } - if ("cdt-font-weight".equals(property)) { - applyCSSPropertyWeight(cdt, value, false); - } - if ("cdt-font-family".equals(property)) { - applyCSSPropertyFamily(cdt, value, false); - } - - // Picker - if ("cdt-picker-background-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setPickerBackgroundColor(newColor); - } - if ("cdt-picker-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setPickerForegroundColor(newColor); - } - if ("cdt-picker-font".equals(property)) { - applyCSSPropertyFont(cdt, value, true); - } - if ("cdt-picker-font-style".equals(property)) { - applyCSSPropertyStyle(cdt, value, true); - } - if ("cdt-picker-font-size".equals(property)) { - applyCSSPropertySize(cdt, value, true); - } - if ("cdt-picker-font-weight".equals(property)) { - applyCSSPropertyWeight(cdt, value, true); - } - if ("cdt-picker-font-family".equals(property)) { - applyCSSPropertyFamily(cdt, value, true); - } - - if ("cdt-picker-active-day-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setPickerActiveDayColor(newColor); - } - if ("cdt-picker-inactive-day-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setPickerInactiveDayColor(newColor); - } - if ("cdt-picker-today-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setPickerTodayColor(newColor); - } - - // Minutes - if ("cdt-picker-minutes-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setPickerMinutesColor(newColor); - } - if ("cdt-picker-minutes-background-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setPickerMinutesBackgroundColor(newColor); - } - - // Picker buttons - if ("cdt-button-hover-border-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setButtonHoverBorderColor(newColor); - } - if ("cdt-button-hover-background-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setButtonHoverBackgroundColor(newColor); - } - if ("cdt-button-selected-border-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setButtonSelectedBorderColor(newColor); - } - if ("cdt-button-selected-background-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setButtonSelectedBackgroundColor(newColor); - } - - // Ok, Cancel & clear buttons - if ("cdt-ok-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setOkButtonColor(newColor); - } - if ("cdt-cancel-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setCancelButtonColor(newColor); - } - if ("cdt-clear-color".equals(property)) { - final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); - cdt.setClearButtonForegroundColor(newColor); - } - - if ("cdt-clear-font".equals(property)) { - applyCSSPropertyFont(cdt, value, true); - } - if ("cdt-clear-font-style".equals(property)) { - applyCSSPropertyStyle(cdt, value, true); - } - if ("cdt-clear-font-size".equals(property)) { - applyCSSPropertySize(cdt, value, true); - } - if ("cdt-clear-font-weight".equals(property)) { - applyCSSPropertyWeight(cdt, value, true); - } - if ("cdt-clear-font-family".equals(property)) { - applyCSSPropertyFamily(cdt, value, true); - } - return true; - } - - // CSS Font - private void applyCSSPropertyFont(final Control widget, final CSSValue value, final boolean picker) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { - final CSSValueList valueList = (CSSValueList) value; - final int length = valueList.getLength(); - for (int i = 0; i < length; i++) { - final CSSValue value2 = valueList.item(i); - if (value2.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final String cssProp = CSS2FontHelper.getCSSFontPropertyName((CSSPrimitiveValue) value2); - if (cssProp.equals("font-family")) { - applyCSSPropertyFamily(widget, value2, picker); - } else if (cssProp.equals("font-size")) { - applyCSSPropertySize(widget, value2, picker); - } else if (cssProp.equals("font-weight") && ("bold".equals(value2.getCssText()) || "bolder".equals(value2.getCssText()))) { - applyCSSPropertyWeight(widget, value2, picker); - } else if (cssProp.equals("font-style") && ("italic".equals(value2.getCssText()) || "oblique".equals(value2.getCssText()))) { - applyCSSPropertyStyle(widget, value2, picker); - } - } - } - } - } - - private void applyCSSPropertyStyle(final Control widget, final CSSValue value, final boolean picker) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final FontData fd = CSSEngineHelper.getFontData(widget, picker); - boolean modified = false; - if ("italic".equals(value.getCssText()) || "oblique".equals(value.getCssText())) { - modified = (fd.getStyle() & SWT.ITALIC) != SWT.ITALIC; - if (modified) { - fd.setStyle(fd.getStyle() | SWT.ITALIC); - } - } else { - modified = (fd.getStyle() & SWT.ITALIC) == SWT.ITALIC; - if (modified) { - fd.setStyle(fd.getStyle() | ~SWT.ITALIC); - } - } - if (modified) { - if (picker) { - applyFontForPicker((CDateTime) widget, fd); - } else { - applyFont(widget, fd); - } - } - - } - } - - private void applyFont(final Control widget, final FontData fd) { - if (widget.getFont() != null && !widget.getFont().equals(widget.getDisplay().getSystemFont())) { - widget.getFont().dispose(); - } - final Font newFont = new Font(widget.getDisplay(), fd); - widget.setFont(newFont); - widget.addListener(SWT.Dispose, e -> { - if (newFont != null && !newFont.isDisposed()) { - newFont.dispose(); - } - }); - } - - private void applyFontForPicker(final CDateTime widget, final FontData fd) { - if (widget.getPickerFont() != null && !widget.getPickerFont().equals(widget.getDisplay().getSystemFont())) { - widget.getPickerFont().dispose(); - } - final Font newFont = new Font(widget.getDisplay(), fd); - widget.setPickerFont(newFont); - widget.addListener(SWT.Dispose, e -> { - if (newFont != null && !newFont.isDisposed()) { - newFont.dispose(); - } - }); - } - - private void applyCSSPropertySize(final Control widget, final CSSValue value, final boolean picker) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final FontData fd = CSSEngineHelper.getFontData(widget, picker); - final Measure m = (Measure) value; - - final int newSize = Math.round(m.getFloatValue((short) 0)); - final boolean modified = fd.getHeight() != newSize; - if (modified) { - fd.setHeight(newSize); - if (picker) { - applyFontForPicker((CDateTime) widget, fd); - } else { - applyFont(widget, fd); - } - } - } - } - - private void applyCSSPropertyWeight(final Control widget, final CSSValue value, final boolean picker) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final FontData fd = CSSEngineHelper.getFontData(widget, picker); - boolean modified = false; - if ("bold".equals(value.getCssText()) || "bolder".equals(value.getCssText())) { - modified = (fd.getStyle() & SWT.BOLD) != SWT.BOLD; - if (modified) { - fd.setStyle(fd.getStyle() | SWT.BOLD); - } - } else { - modified = (fd.getStyle() & SWT.BOLD) == SWT.BOLD; - if (modified) { - fd.setStyle(fd.getStyle() | ~SWT.BOLD); - } - } - if (modified) { - if (picker) { - applyFontForPicker((CDateTime) widget, fd); - } else { - applyFont(widget, fd); - } - } - - } - } - - private void applyCSSPropertyFamily(final Control widget, final CSSValue value, final boolean picker) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final FontData fd = CSSEngineHelper.getFontData(widget, picker); - final boolean modified = !fd.getName().equals(value.getCssText()); - if (modified) { - fd.setName(value.getCssText()); - if (picker) { - applyFontForPicker((CDateTime) widget, fd); - } else { - applyFont(widget, fd); - } - } - } - } - - @Override - public String retrieveCSSProperty(final Object element, final String property, final String pseudo, final CSSEngine engine) throws Exception { - return null; - } +/******************************************************************************* + * Copyright (c) 2020 Laurent Caron. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent Caron - initial API and implementation + ******************************************************************************/ +package org.eclipse.nebula.widgets.cdatetime.css; + +import org.eclipse.e4.ui.css.core.css2.CSS2FontHelper; +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.core.impl.dom.Measure; +import org.eclipse.e4.ui.css.swt.dom.ControlElement; +import org.eclipse.nebula.widgets.cdatetime.CDateTime; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Control; +import org.w3c.dom.css.CSSPrimitiveValue; +import org.w3c.dom.css.CSSValue; +import org.w3c.dom.css.CSSValueList; + +@SuppressWarnings("restriction") +public class CDateTimePropertyHandler implements ICSSPropertyHandler { + @Override + public boolean applyCSSProperty(final Object element, final String property, final CSSValue value, final String pseudo, final CSSEngine engine) throws Exception { + final CDateTime cdt =(CDateTime) ((ControlElement) element).getNativeWidget(); + + // General properties + if ("cdt-background-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setBackground(newColor); + } + if ("cdt-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setForeground(newColor); + } + if ("cdt-font".equals(property)) { + applyCSSPropertyFont(cdt, value, false); + } + if ("cdt-font-style".equals(property)) { + applyCSSPropertyStyle(cdt, value, false); + } + if ("cdt-font-size".equals(property)) { + applyCSSPropertySize(cdt, value, false); + } + if ("cdt-font-weight".equals(property)) { + applyCSSPropertyWeight(cdt, value, false); + } + if ("cdt-font-family".equals(property)) { + applyCSSPropertyFamily(cdt, value, false); + } + + // Picker + if ("cdt-picker-background-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setPickerBackgroundColor(newColor); + } + if ("cdt-picker-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setPickerForegroundColor(newColor); + } + if ("cdt-picker-font".equals(property)) { + applyCSSPropertyFont(cdt, value, true); + } + if ("cdt-picker-font-style".equals(property)) { + applyCSSPropertyStyle(cdt, value, true); + } + if ("cdt-picker-font-size".equals(property)) { + applyCSSPropertySize(cdt, value, true); + } + if ("cdt-picker-font-weight".equals(property)) { + applyCSSPropertyWeight(cdt, value, true); + } + if ("cdt-picker-font-family".equals(property)) { + applyCSSPropertyFamily(cdt, value, true); + } + + if ("cdt-picker-active-day-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setPickerActiveDayColor(newColor); + } + if ("cdt-picker-inactive-day-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setPickerInactiveDayColor(newColor); + } + if ("cdt-picker-today-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setPickerTodayColor(newColor); + } + + // Minutes + if ("cdt-picker-minutes-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setPickerMinutesColor(newColor); + } + if ("cdt-picker-minutes-background-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setPickerMinutesBackgroundColor(newColor); + } + + // Picker buttons + if ("cdt-button-hover-border-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setButtonHoverBorderColor(newColor); + } + if ("cdt-button-hover-background-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setButtonHoverBackgroundColor(newColor); + } + if ("cdt-button-selected-border-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setButtonSelectedBorderColor(newColor); + } + if ("cdt-button-selected-background-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setButtonSelectedBackgroundColor(newColor); + } + + // Ok, Cancel & clear buttons + if ("cdt-ok-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setOkButtonColor(newColor); + } + if ("cdt-cancel-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setCancelButtonColor(newColor); + } + if ("cdt-clear-color".equals(property)) { + final Color newColor = (Color) engine.convert(value, Color.class, cdt.getDisplay()); + cdt.setClearButtonForegroundColor(newColor); + } + + if ("cdt-clear-font".equals(property)) { + applyCSSPropertyFont(cdt, value, true); + } + if ("cdt-clear-font-style".equals(property)) { + applyCSSPropertyStyle(cdt, value, true); + } + if ("cdt-clear-font-size".equals(property)) { + applyCSSPropertySize(cdt, value, true); + } + if ("cdt-clear-font-weight".equals(property)) { + applyCSSPropertyWeight(cdt, value, true); + } + if ("cdt-clear-font-family".equals(property)) { + applyCSSPropertyFamily(cdt, value, true); + } + return true; + } + + // CSS Font + private void applyCSSPropertyFont(final Control widget, final CSSValue value, final boolean picker) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { + final CSSValueList valueList = (CSSValueList) value; + final int length = valueList.getLength(); + for (int i = 0; i < length; i++) { + final CSSValue value2 = valueList.item(i); + if (value2.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final String cssProp = CSS2FontHelper.getCSSFontPropertyName((CSSPrimitiveValue) value2); + if (cssProp.equals("font-family")) { + applyCSSPropertyFamily(widget, value2, picker); + } else if (cssProp.equals("font-size")) { + applyCSSPropertySize(widget, value2, picker); + } else if (cssProp.equals("font-weight") && ("bold".equals(value2.getCssText()) || "bolder".equals(value2.getCssText()))) { + applyCSSPropertyWeight(widget, value2, picker); + } else if (cssProp.equals("font-style") && ("italic".equals(value2.getCssText()) || "oblique".equals(value2.getCssText()))) { + applyCSSPropertyStyle(widget, value2, picker); + } + } + } + } + } + + private void applyCSSPropertyStyle(final Control widget, final CSSValue value, final boolean picker) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final FontData fd = CSSEngineHelper.getFontData(widget, picker); + boolean modified = false; + if ("italic".equals(value.getCssText()) || "oblique".equals(value.getCssText())) { + modified = (fd.getStyle() & SWT.ITALIC) != SWT.ITALIC; + if (modified) { + fd.setStyle(fd.getStyle() | SWT.ITALIC); + } + } else { + modified = (fd.getStyle() & SWT.ITALIC) == SWT.ITALIC; + if (modified) { + fd.setStyle(fd.getStyle() | ~SWT.ITALIC); + } + } + if (modified) { + if (picker) { + applyFontForPicker((CDateTime) widget, fd); + } else { + applyFont(widget, fd); + } + } + + } + } + + private void applyFont(final Control widget, final FontData fd) { + if (widget.getFont() != null && !widget.getFont().equals(widget.getDisplay().getSystemFont())) { + widget.getFont().dispose(); + } + final Font newFont = new Font(widget.getDisplay(), fd); + widget.setFont(newFont); + widget.addListener(SWT.Dispose, e -> { + if (newFont != null && !newFont.isDisposed()) { + newFont.dispose(); + } + }); + } + + private void applyFontForPicker(final CDateTime widget, final FontData fd) { + if (widget.getPickerFont() != null && !widget.getPickerFont().equals(widget.getDisplay().getSystemFont())) { + widget.getPickerFont().dispose(); + } + final Font newFont = new Font(widget.getDisplay(), fd); + widget.setPickerFont(newFont); + widget.addListener(SWT.Dispose, e -> { + if (newFont != null && !newFont.isDisposed()) { + newFont.dispose(); + } + }); + } + + private void applyCSSPropertySize(final Control widget, final CSSValue value, final boolean picker) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final FontData fd = CSSEngineHelper.getFontData(widget, picker); + final Measure m = (Measure) value; + + final int newSize = Math.round(m.getFloatValue((short) 0)); + final boolean modified = fd.getHeight() != newSize; + if (modified) { + fd.setHeight(newSize); + if (picker) { + applyFontForPicker((CDateTime) widget, fd); + } else { + applyFont(widget, fd); + } + } + } + } + + private void applyCSSPropertyWeight(final Control widget, final CSSValue value, final boolean picker) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final FontData fd = CSSEngineHelper.getFontData(widget, picker); + boolean modified = false; + if ("bold".equals(value.getCssText()) || "bolder".equals(value.getCssText())) { + modified = (fd.getStyle() & SWT.BOLD) != SWT.BOLD; + if (modified) { + fd.setStyle(fd.getStyle() | SWT.BOLD); + } + } else { + modified = (fd.getStyle() & SWT.BOLD) == SWT.BOLD; + if (modified) { + fd.setStyle(fd.getStyle() | ~SWT.BOLD); + } + } + if (modified) { + if (picker) { + applyFontForPicker((CDateTime) widget, fd); + } else { + applyFont(widget, fd); + } + } + + } + } + + private void applyCSSPropertyFamily(final Control widget, final CSSValue value, final boolean picker) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final FontData fd = CSSEngineHelper.getFontData(widget, picker); + final boolean modified = !fd.getName().equals(value.getCssText()); + if (modified) { + fd.setName(value.getCssText()); + if (picker) { + applyFontForPicker((CDateTime) widget, fd); + } else { + applyFont(widget, fd); + } + } + } + } + + @Override + public String retrieveCSSProperty(final Object element, final String property, final String pseudo, final CSSEngine engine) throws Exception { + return null; + } } \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.classpath b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.classpath +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.project b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.project index 8fa1a09a4..b51d60d0f 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.project +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.cdatetime.example.e4 - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.cdatetime.example.e4 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.settings/org.eclipse.jdt.core.prefs b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/Application.e4xmi b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/Application.e4xmi index 8747d5c8c..af84b1247 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/Application.e4xmi +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/Application.e4xmi @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/build.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/build.properties index 163f78c0c..04ab1e9b8 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/build.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/build.properties @@ -1,8 +1,8 @@ -source.. = src/ -output.. = bin/ -bin.includes = plugin.xml,\ - META-INF/,\ - .,\ - icons/,\ - css/default.css,\ - Application.e4xmi +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + icons/,\ + css/default.css,\ + Application.e4xmi diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/css/default.css b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/css/default.css index ff828ea5e..97ce0a70b 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/css/default.css +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/css/default.css @@ -1,85 +1,85 @@ -/* -CSS for CDateTime -*/ - -CDateTime#one { - cdt-font: Verdana 11px; - cdt-color: white; - cdt-background-color: darkred; -} - -CDateTime#two { - cdt-picker-font: Verdana 10px; - cdt-picker-color: magenta; - cdt-picker-background-color: #ffffcc; - - cdt-picker-active-day-color: darkgreen; - cdt-picker-inactive-day-color: cyan; - cdt-picker-today-color: darkred; -} - -CDateTime#three { - cdt-picker-font: Verdana 10px; - cdt-picker-color: magenta; - cdt-picker-background-color: #ffffcc; - - cdt-picker-active-day-color: darkgreen; - cdt-picker-inactive-day-color: cyan; - cdt-picker-today-color: darkred; - cdt-picker-minutes-color: white; - cdt-picker-minutes-background-color: darkblue; - - - cdt-button-hover-border-color: cyan; - cdt-button-hover-background-color: darkblue; - cdt-button-selected-border-color: darkred; - cdt-button-selected-background-color: red; -} - -CDateTime#four,CDateTime#five,CDateTime#six { - cdt-picker-font: Verdana 10px; - cdt-picker-color: magenta; - cdt-picker-background-color: #ffffcc; - - cdt-picker-active-day-color: darkgreen; - cdt-picker-inactive-day-color: cyan; - cdt-picker-today-color: darkred; - cdt-picker-minutes-color: white; - cdt-picker-minutes-background-color: darkblue; - - - cdt-button-hover-border-color: cyan; - cdt-button-hover-background-color: darkblue; - cdt-button-selected-border-color: darkred; - cdt-button-selected-background-color: red; -} - -CDateTime#okcancelclear { - cdt-ok-color: red; - cdt-cancel-color: green; - cdt-clear-color: cyan; - cdt-clear-font: Verdana 11px; -} - -CDateTime#big_one { - cdt-picker-font: Verdana 10px; - cdt-picker-color: magenta; - cdt-picker-background-color: #ffffcc; - - cdt-picker-active-day-color: darkgreen; - cdt-picker-inactive-day-color: cyan; - cdt-picker-today-color: darkred; - cdt-picker-minutes-color: white; - cdt-picker-minutes-background-color: darkblue; - - - cdt-button-hover-border-color: cyan; - cdt-button-hover-background-color: darkblue; - cdt-button-selected-border-color: darkred; - cdt-button-selected-background-color: red; -} - -CDateTime#big_two { - cdt-background-color: darkred; -} - +/* +CSS for CDateTime +*/ + +CDateTime#one { + cdt-font: Verdana 11px; + cdt-color: white; + cdt-background-color: darkred; +} + +CDateTime#two { + cdt-picker-font: Verdana 10px; + cdt-picker-color: magenta; + cdt-picker-background-color: #ffffcc; + + cdt-picker-active-day-color: darkgreen; + cdt-picker-inactive-day-color: cyan; + cdt-picker-today-color: darkred; +} + +CDateTime#three { + cdt-picker-font: Verdana 10px; + cdt-picker-color: magenta; + cdt-picker-background-color: #ffffcc; + + cdt-picker-active-day-color: darkgreen; + cdt-picker-inactive-day-color: cyan; + cdt-picker-today-color: darkred; + cdt-picker-minutes-color: white; + cdt-picker-minutes-background-color: darkblue; + + + cdt-button-hover-border-color: cyan; + cdt-button-hover-background-color: darkblue; + cdt-button-selected-border-color: darkred; + cdt-button-selected-background-color: red; +} + +CDateTime#four,CDateTime#five,CDateTime#six { + cdt-picker-font: Verdana 10px; + cdt-picker-color: magenta; + cdt-picker-background-color: #ffffcc; + + cdt-picker-active-day-color: darkgreen; + cdt-picker-inactive-day-color: cyan; + cdt-picker-today-color: darkred; + cdt-picker-minutes-color: white; + cdt-picker-minutes-background-color: darkblue; + + + cdt-button-hover-border-color: cyan; + cdt-button-hover-background-color: darkblue; + cdt-button-selected-border-color: darkred; + cdt-button-selected-background-color: red; +} + +CDateTime#okcancelclear { + cdt-ok-color: red; + cdt-cancel-color: green; + cdt-clear-color: cyan; + cdt-clear-font: Verdana 11px; +} + +CDateTime#big_one { + cdt-picker-font: Verdana 10px; + cdt-picker-color: magenta; + cdt-picker-background-color: #ffffcc; + + cdt-picker-active-day-color: darkgreen; + cdt-picker-inactive-day-color: cyan; + cdt-picker-today-color: darkred; + cdt-picker-minutes-color: white; + cdt-picker-minutes-background-color: darkblue; + + + cdt-button-hover-border-color: cyan; + cdt-button-hover-background-color: darkblue; + cdt-button-selected-border-color: darkred; + cdt-button-selected-background-color: red; +} + +CDateTime#big_two { + cdt-background-color: darkred; +} + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/org.eclipse.nebula.widgets.cdatetime.example.e4.product b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/org.eclipse.nebula.widgets.cdatetime.example.e4.product index 2b0163c42..0e2c4d57c 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/org.eclipse.nebula.widgets.cdatetime.example.e4.product +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/org.eclipse.nebula.widgets.cdatetime.example.e4.product @@ -1,95 +1,95 @@ - - - - - - - - - - -clearPersistedState - - -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + -clearPersistedState + + -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/plugin.xml b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/plugin.xml index 80be9c9ff..7861c7d13 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/plugin.xml +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/plugin.xml @@ -1,22 +1,22 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/pom.xml b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/pom.xml index 1189816bb..04de7e4e3 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/pom.xml +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/pom.xml @@ -1,32 +1,32 @@ - - - - 4.0.0 - - - org.eclipse.nebula - cdatetime - 1.5.0-SNAPSHOT - - - org.eclipse.nebula.widgets.cdatetime.example.e4 - 1.4.0-SNAPSHOT - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + cdatetime + 1.5.0-SNAPSHOT + + + org.eclipse.nebula.widgets.cdatetime.example.e4 + 1.4.0-SNAPSHOT + eclipse-plugin + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/src/org/eclipse/nebula/widgets/cdatetime/example/e4/Activator.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/src/org/eclipse/nebula/widgets/cdatetime/example/e4/Activator.java index bb8de2141..5da150a06 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/src/org/eclipse/nebula/widgets/cdatetime/example/e4/Activator.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example.e4/src/org/eclipse/nebula/widgets/cdatetime/example/e4/Activator.java @@ -1,43 +1,43 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent Caron - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent Caron - Initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.cdatetime.example.e4; - -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -public class Activator implements BundleActivator { - - private static BundleContext context; - - static BundleContext getContext() { - return context; - } - - /** - * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) - */ - @Override - public void start(final BundleContext bundleContext) throws Exception { - Activator.context = bundleContext; - } - - /** - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(final BundleContext bundleContext) throws Exception { - Activator.context = null; - } - -} +/******************************************************************************* + * Copyright (c) 2020 Laurent Caron + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent Caron - Initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.cdatetime.example.e4; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /** + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(final BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /** + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(final BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/.classpath b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/.classpath +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/.settings/org.eclipse.jdt.core.prefs b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/META-INF/MANIFEST.MF b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/META-INF/MANIFEST.MF index 64b3e3f55..0ad1c7287 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/META-INF/MANIFEST.MF +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.example/META-INF/MANIFEST.MF @@ -1,13 +1,13 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula CDateTime Example -Bundle-SymbolicName: org.eclipse.nebula.widgets.cdatetime.example;singleton:=true -Bundle-Version: 1.0.0.qualifier -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.nebula.examples;bundle-version="1.0.4", - org.eclipse.nebula.widgets.cdatetime;bundle-version="0.14.0" -Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.widgets.cdatetime.example +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula CDateTime Example +Bundle-SymbolicName: org.eclipse.nebula.widgets.cdatetime.example;singleton:=true +Bundle-Version: 1.0.0.qualifier +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.nebula.examples;bundle-version="1.0.4", + org.eclipse.nebula.widgets.cdatetime;bundle-version="0.14.0" +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.widgets.cdatetime.example diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/.classpath b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/.classpath +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/META-INF/MANIFEST.MF b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/META-INF/MANIFEST.MF index 2a35cdd09..d22809c7a 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/META-INF/MANIFEST.MF +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-SymbolicName: org.eclipse.nebula.widgets.cdatetime.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Name: %pluginName -Bundle-Vendor: %providerName -Bundle-Localization: plugin -Export-Package: org.eclipse.nebula.widgets.cdatetime.snippets -Require-Bundle: org.eclipse.jface, - org.eclipse.ui.forms, - org.eclipse.nebula.widgets.cdatetime, - org.eclipse.nebula.jface.cdatetime -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Automatic-Module-Name: org.eclipse.nebula.widgets.cdatetime.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.eclipse.nebula.widgets.cdatetime.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Name: %pluginName +Bundle-Vendor: %providerName +Bundle-Localization: plugin +Export-Package: org.eclipse.nebula.widgets.cdatetime.snippets +Require-Bundle: org.eclipse.jface, + org.eclipse.ui.forms, + org.eclipse.nebula.widgets.cdatetime, + org.eclipse.nebula.jface.cdatetime +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Automatic-Module-Name: org.eclipse.nebula.widgets.cdatetime.snippets diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTEditorSample.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTEditorSample.java index bba2725bf..f93e886a2 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTEditorSample.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTEditorSample.java @@ -1,220 +1,220 @@ -package org.eclipse.nebula.widgets.cdatetime.snippets; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; -import org.eclipse.jface.viewers.ICellModifier; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.TableViewerColumn; -import org.eclipse.jface.viewers.TableViewerEditor; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.nebula.jface.cdatetime.CDateTimeCellEditor; -import org.eclipse.nebula.widgets.cdatetime.CDT; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.TableItem; - -/** - * Edit cell values in a table - * - * @author Tom Schindl - * - */ -public class CDTEditorSample { - private class MyContentProvider implements IStructuredContentProvider { - - /** - * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) - */ - public Object[] getElements(Object inputElement) { - return (MyModel[]) inputElement; - } - - /** - * @see org.eclipse.jface.viewers.IContentProvider#dispose() - */ - public void dispose() { - - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface. - * viewers.Viewer, java.lang.Object, java.lang.Object) - */ - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - - } - - } - - public class MyModel { - public String firstName, lastName; - public Date birthDate; - - public MyModel(String firstName, String lastName, Date birthDate) { - super(); - this.firstName = firstName; - this.lastName = lastName; - this.birthDate = birthDate; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public Date getBirthDate() { - return birthDate; - } - - public void setBirthDate(Date birthDate) { - this.birthDate = birthDate; - } - - } - - public CDTEditorSample(Shell shell) { - final TableViewer v = new TableViewer(shell, SWT.BORDER | SWT.FULL_SELECTION); - TableViewerColumn tc = new TableViewerColumn(v, SWT.NONE); - tc.getColumn().setWidth(100); - tc.getColumn().setText("First Name"); - tc.setLabelProvider(new ColumnLabelProvider() { - - @Override - public String getText(Object element) { - MyModel e = (MyModel) element; - return e.getFirstName(); - } - }); - - tc = new TableViewerColumn(v, SWT.NONE); - tc.getColumn().setWidth(200); - tc.getColumn().setText("Last Name"); - tc.setLabelProvider(new ColumnLabelProvider() { - - @Override - public String getText(Object element) { - MyModel e = (MyModel) element; - return e.getLastName(); - } - }); - - tc = new TableViewerColumn(v, SWT.NONE); - tc.getColumn().setWidth(200); - tc.getColumn().setText("Date of birth"); - tc.setLabelProvider(new ColumnLabelProvider() { - - @Override - public String getText(Object element) { - MyModel e = (MyModel) element; - return new SimpleDateFormat("MM/dd/yyyy").format(e.getBirthDate()); - } - }); - - v.setContentProvider(new MyContentProvider()); - v.setCellModifier(new ICellModifier() { - - /** - * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, - * java.lang.String) - */ - public boolean canModify(Object element, String property) { - return true; - } - - /** - * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, - * java.lang.String) - */ - public Object getValue(Object element, String property) { - MyModel e = (MyModel) element; - if (property.equals("firstName")) { - return e.getFirstName(); - } else if (property.equals("lastName")) { - return e.getLastName(); - } - return e.getBirthDate(); - } - - /** - * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, - * java.lang.String, java.lang.Object) - */ - public void modify(Object element, String property, Object value) { - TableItem item = (TableItem) element; - MyModel e = (MyModel) item.getData(); - if (property.equals("firstName")) { - e.firstName = (String) value; - } else if (property.equals("lastName")) { - e.lastName = (String) value; - } else { - e.birthDate = (Date) value; - } - v.update(item.getData(), null); - } - - }); - - v.setColumnProperties(new String[] { "firstName", "lastName", "birthDate" }); - v.setCellEditors(new CellEditor[] { new TextCellEditor(v.getTable()), new TextCellEditor(v.getTable()), - new CDateTimeCellEditor(v.getTable(), CDT.BORDER | CDT.SPINNER) }); - TableViewerEditor.create(v, new ColumnViewerEditorActivationStrategy(v), ColumnViewerEditor.TABBING_HORIZONTAL - | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL); - - MyModel[] model = createModel(); - v.setInput(model); - v.getTable().setLinesVisible(true); - } - - private MyModel[] createModel() { - MyModel[] elements = new MyModel[10]; - - for (int i = 0; i < 10; i++) { - elements[i] = new MyModel("First name #" + i, "Last Name #" + i, new Date()); - } - - return elements; - } - - /** - * @param args - */ - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - new CDTEditorSample(shell); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - display.dispose(); - - } - -} +package org.eclipse.nebula.widgets.cdatetime.snippets; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TableViewerEditor; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.nebula.jface.cdatetime.CDateTimeCellEditor; +import org.eclipse.nebula.widgets.cdatetime.CDT; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TableItem; + +/** + * Edit cell values in a table + * + * @author Tom Schindl + * + */ +public class CDTEditorSample { + private class MyContentProvider implements IStructuredContentProvider { + + /** + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return (MyModel[]) inputElement; + } + + /** + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface. + * viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + + } + + } + + public class MyModel { + public String firstName, lastName; + public Date birthDate; + + public MyModel(String firstName, String lastName, Date birthDate) { + super(); + this.firstName = firstName; + this.lastName = lastName; + this.birthDate = birthDate; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Date getBirthDate() { + return birthDate; + } + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + } + + public CDTEditorSample(Shell shell) { + final TableViewer v = new TableViewer(shell, SWT.BORDER | SWT.FULL_SELECTION); + TableViewerColumn tc = new TableViewerColumn(v, SWT.NONE); + tc.getColumn().setWidth(100); + tc.getColumn().setText("First Name"); + tc.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + MyModel e = (MyModel) element; + return e.getFirstName(); + } + }); + + tc = new TableViewerColumn(v, SWT.NONE); + tc.getColumn().setWidth(200); + tc.getColumn().setText("Last Name"); + tc.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + MyModel e = (MyModel) element; + return e.getLastName(); + } + }); + + tc = new TableViewerColumn(v, SWT.NONE); + tc.getColumn().setWidth(200); + tc.getColumn().setText("Date of birth"); + tc.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + MyModel e = (MyModel) element; + return new SimpleDateFormat("MM/dd/yyyy").format(e.getBirthDate()); + } + }); + + v.setContentProvider(new MyContentProvider()); + v.setCellModifier(new ICellModifier() { + + /** + * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, + * java.lang.String) + */ + public boolean canModify(Object element, String property) { + return true; + } + + /** + * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, + * java.lang.String) + */ + public Object getValue(Object element, String property) { + MyModel e = (MyModel) element; + if (property.equals("firstName")) { + return e.getFirstName(); + } else if (property.equals("lastName")) { + return e.getLastName(); + } + return e.getBirthDate(); + } + + /** + * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, + * java.lang.String, java.lang.Object) + */ + public void modify(Object element, String property, Object value) { + TableItem item = (TableItem) element; + MyModel e = (MyModel) item.getData(); + if (property.equals("firstName")) { + e.firstName = (String) value; + } else if (property.equals("lastName")) { + e.lastName = (String) value; + } else { + e.birthDate = (Date) value; + } + v.update(item.getData(), null); + } + + }); + + v.setColumnProperties(new String[] { "firstName", "lastName", "birthDate" }); + v.setCellEditors(new CellEditor[] { new TextCellEditor(v.getTable()), new TextCellEditor(v.getTable()), + new CDateTimeCellEditor(v.getTable(), CDT.BORDER | CDT.SPINNER) }); + TableViewerEditor.create(v, new ColumnViewerEditorActivationStrategy(v), ColumnViewerEditor.TABBING_HORIZONTAL + | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL); + + MyModel[] model = createModel(); + v.setInput(model); + v.getTable().setLinesVisible(true); + } + + private MyModel[] createModel() { + MyModel[] elements = new MyModel[10]; + + for (int i = 0; i < 10; i++) { + elements[i] = new MyModel("First name #" + i, "Last Name #" + i, new Date()); + } + + return elements; + } + + /** + * @param args + */ + public static void main(String[] args) { + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + new CDTEditorSample(shell); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + + display.dispose(); + + } + +} diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTSnippet09.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTSnippet09.java index 6b2c3d493..28e36639a 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTSnippet09.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTSnippet09.java @@ -1,83 +1,83 @@ -/**************************************************************************** - * Copyright (c) 2012 Scott Klein - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Scott Klein - initial API and implementation - *****************************************************************************/ - -package org.eclipse.nebula.widgets.cdatetime.snippets; - -import java.util.TimeZone; - -import org.eclipse.nebula.widgets.cdatetime.CDateTime; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * This snippet shows how to use the timezone features of the CDateTime widget. - * Please notice that you are able to tab to the timezone field were you can - * roll through them. - * - */ -public class CDTSnippet09 { - - /** - * @param args - */ - public static void main(String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setText("CDateTime"); - shell.setLayout(new FillLayout()); - - // build list of allowed time zones -- since there are over 600 of them - // we will add US time zones as an example of the developer - // selectively allowing particular ones using political boundaries - TimeZone[] timezones = new TimeZone[] { - TimeZone.getTimeZone("US/Alaska"), - TimeZone.getTimeZone("US/Hawaii"), - TimeZone.getTimeZone("US/Pacific"), - TimeZone.getTimeZone("US/Arizona"), - TimeZone.getTimeZone("US/Mountain"), - TimeZone.getTimeZone("US/Central"), - TimeZone.getTimeZone("US/Eastern") }; - - CDateTime dateTime = new CDateTime(shell, SWT.NONE); - - // This *requires* us to set a pattern that *must* include the Zone - // Offset key (z) - // otherwise the time zones functionality will be off - dateTime.setPattern("MM/dd/yyyy HH:mm.ss z", timezones); - - // It is always a good idea to manually set the controls' initial time - // zone - // using one of the time zones from your list of allowed time zones. - // When using the time zone functionality we do not alter the initial - // time zone - // in the setPattern( String, TimeZone[]) call - dateTime.setTimeZone(timezones[0]); - - shell.pack(); - Point size = shell.getSize(); - Rectangle screen = display.getMonitors()[0].getBounds(); - shell.setBounds((screen.width - size.x) / 2, - (screen.height - size.y) / 2, 180, 54); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - display.dispose(); - } +/**************************************************************************** + * Copyright (c) 2012 Scott Klein + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Scott Klein - initial API and implementation + *****************************************************************************/ + +package org.eclipse.nebula.widgets.cdatetime.snippets; + +import java.util.TimeZone; + +import org.eclipse.nebula.widgets.cdatetime.CDateTime; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * This snippet shows how to use the timezone features of the CDateTime widget. + * Please notice that you are able to tab to the timezone field were you can + * roll through them. + * + */ +public class CDTSnippet09 { + + /** + * @param args + */ + public static void main(String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setText("CDateTime"); + shell.setLayout(new FillLayout()); + + // build list of allowed time zones -- since there are over 600 of them + // we will add US time zones as an example of the developer + // selectively allowing particular ones using political boundaries + TimeZone[] timezones = new TimeZone[] { + TimeZone.getTimeZone("US/Alaska"), + TimeZone.getTimeZone("US/Hawaii"), + TimeZone.getTimeZone("US/Pacific"), + TimeZone.getTimeZone("US/Arizona"), + TimeZone.getTimeZone("US/Mountain"), + TimeZone.getTimeZone("US/Central"), + TimeZone.getTimeZone("US/Eastern") }; + + CDateTime dateTime = new CDateTime(shell, SWT.NONE); + + // This *requires* us to set a pattern that *must* include the Zone + // Offset key (z) + // otherwise the time zones functionality will be off + dateTime.setPattern("MM/dd/yyyy HH:mm.ss z", timezones); + + // It is always a good idea to manually set the controls' initial time + // zone + // using one of the time zones from your list of allowed time zones. + // When using the time zone functionality we do not alter the initial + // time zone + // in the setPattern( String, TimeZone[]) call + dateTime.setTimeZone(timezones[0]); + + shell.pack(); + Point size = shell.getSize(); + Rectangle screen = display.getMonitors()[0].getBounds(); + shell.setBounds((screen.width - size.x) / 2, + (screen.height - size.y) / 2, 180, 54); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } } \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTSnippet12.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTSnippet12.java index 608f59eb8..f6cca198c 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTSnippet12.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/CDTSnippet12.java @@ -1,65 +1,65 @@ -package org.eclipse.nebula.widgets.cdatetime.snippets; - -import org.eclipse.nebula.widgets.cdatetime.CDT; -import org.eclipse.nebula.widgets.cdatetime.CDateTime; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -public class CDTSnippet12 { - - private static Display display = new Display(); - - /** - * @param args - */ - public static void main(String[] args) { - Shell shell = new Shell(display); - - shell.setText("Nebula CDateTime"); - shell.setLayout(new GridLayout()); - - GridLayout layout = new GridLayout(1, false); - shell.setLayout(layout); - - CDateTime cDateTime1 = new CDateTime(shell, CDT.DROP_DOWN | CDT.DATE_SHORT | CDT.BORDER); - new CDateTime(shell, CDT.DROP_DOWN | CDT.DATE_SHORT | CDT.BORDER); - - cDateTime1.addTraverseListener(new TraverseListener() { - @Override - public void keyTraversed(TraverseEvent eParm){ - System.out.println("TraverseListener.keyTraversed() " + eParm); - } - }); - - cDateTime1.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent eParm) { - System.out.println("ModifyListener.modifyText() " + eParm); - } - }); - - shell.pack(); - Point size = shell.getSize(); - Rectangle screen = display.getMonitors()[0].getBounds(); - shell.setBounds( - (screen.width-size.x)/2, - (screen.height-size.y)/2, - size.x, - size.y - ); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - display.dispose(); - } - +package org.eclipse.nebula.widgets.cdatetime.snippets; + +import org.eclipse.nebula.widgets.cdatetime.CDT; +import org.eclipse.nebula.widgets.cdatetime.CDateTime; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class CDTSnippet12 { + + private static Display display = new Display(); + + /** + * @param args + */ + public static void main(String[] args) { + Shell shell = new Shell(display); + + shell.setText("Nebula CDateTime"); + shell.setLayout(new GridLayout()); + + GridLayout layout = new GridLayout(1, false); + shell.setLayout(layout); + + CDateTime cDateTime1 = new CDateTime(shell, CDT.DROP_DOWN | CDT.DATE_SHORT | CDT.BORDER); + new CDateTime(shell, CDT.DROP_DOWN | CDT.DATE_SHORT | CDT.BORDER); + + cDateTime1.addTraverseListener(new TraverseListener() { + @Override + public void keyTraversed(TraverseEvent eParm){ + System.out.println("TraverseListener.keyTraversed() " + eParm); + } + }); + + cDateTime1.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent eParm) { + System.out.println("ModifyListener.modifyText() " + eParm); + } + }); + + shell.pack(); + Point size = shell.getSize(); + Rectangle screen = display.getMonitors()[0].getBounds(); + shell.setBounds( + (screen.width-size.x)/2, + (screen.height-size.y)/2, + size.x, + size.y + ); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } + } \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/DropTestSnippet.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/DropTestSnippet.java index dd7c9be04..55a6bc142 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/DropTestSnippet.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.snippets/src/org/eclipse/nebula/widgets/cdatetime/snippets/DropTestSnippet.java @@ -1,106 +1,106 @@ -/**************************************************************************** - * Copyright (c) 2008 Jeremy Dowdall - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jeremy Dowdall - initial API and implementation - *****************************************************************************/ - -package org.eclipse.nebula.widgets.cdatetime.snippets; - -import org.eclipse.nebula.cwt.base.BaseCombo; -import org.eclipse.nebula.widgets.cdatetime.CDT; -import org.eclipse.nebula.widgets.cdatetime.CDateTime; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Dialog; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - - - -public class DropTestSnippet { - - /** - * @param args - */ - public static void main(String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setText("CDC"); - shell.setLayout(new GridLayout()); - - GridLayout layout = new GridLayout(2, true); - shell.setLayout(layout); - - final BaseCombo cdc1 = new CDateTime(shell, CDT.BORDER); - cdc1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - - final BaseCombo cdc2 = new CDateTime(shell, CDT.BORDER | CDT.DROP_DOWN); - cdc2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - - - shell.pack(); - Point size = shell.getSize(); - Rectangle screen = display.getMonitors()[0].getBounds(); - shell.setBounds( - (screen.width-size.x)/2, - (screen.height-size.y)/2, - size.x, - size.y - ); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - display.dispose(); - } -} - -class MyDialog extends Dialog { - /** - * - */ - Shell shell; - - public MyDialog (Shell parent, int style) { - super(parent, style); - } - public void close() { - shell.close(); - } - - public void open() { - Shell parent = getParent(); - final Shell shell = new Shell(parent, getStyle()); - shell.setText("Testing"); - shell.setLayout(new GridLayout()); - - final BaseCombo cdc2 = new CDateTime(shell, CDT.BORDER | CDT.DROP_DOWN); - cdc2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - - Display display = parent.getDisplay(); - shell.layout(true, true); - shell.pack(); - int x = shell.getSize().x; - int y = shell.getSize().y; - shell.setLocation( - (display.getBounds().width-x)/2, - (display.getBounds().height-y)/2 - ); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) display.sleep(); - } - } -} +/**************************************************************************** + * Copyright (c) 2008 Jeremy Dowdall + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Jeremy Dowdall - initial API and implementation + *****************************************************************************/ + +package org.eclipse.nebula.widgets.cdatetime.snippets; + +import org.eclipse.nebula.cwt.base.BaseCombo; +import org.eclipse.nebula.widgets.cdatetime.CDT; +import org.eclipse.nebula.widgets.cdatetime.CDateTime; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + + + +public class DropTestSnippet { + + /** + * @param args + */ + public static void main(String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setText("CDC"); + shell.setLayout(new GridLayout()); + + GridLayout layout = new GridLayout(2, true); + shell.setLayout(layout); + + final BaseCombo cdc1 = new CDateTime(shell, CDT.BORDER); + cdc1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + final BaseCombo cdc2 = new CDateTime(shell, CDT.BORDER | CDT.DROP_DOWN); + cdc2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + + shell.pack(); + Point size = shell.getSize(); + Rectangle screen = display.getMonitors()[0].getBounds(); + shell.setBounds( + (screen.width-size.x)/2, + (screen.height-size.y)/2, + size.x, + size.y + ); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } +} + +class MyDialog extends Dialog { + /** + * + */ + Shell shell; + + public MyDialog (Shell parent, int style) { + super(parent, style); + } + public void close() { + shell.close(); + } + + public void open() { + Shell parent = getParent(); + final Shell shell = new Shell(parent, getStyle()); + shell.setText("Testing"); + shell.setLayout(new GridLayout()); + + final BaseCombo cdc2 = new CDateTime(shell, CDT.BORDER | CDT.DROP_DOWN); + cdc2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + Display display = parent.getDisplay(); + shell.layout(true, true); + shell.pack(); + int x = shell.getSize().x; + int y = shell.getSize().y; + shell.setLocation( + (display.getBounds().width-x)/2, + (display.getBounds().height-y)/2 + ); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) display.sleep(); + } + } +} diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/.classpath b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/.classpath index 749841635..a42a828e0 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/.classpath +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/.classpath @@ -1,11 +1,11 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/.settings/org.eclipse.jdt.core.prefs b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/.settings/org.eclipse.jdt.core.prefs index e2e9c66d8..f2525a8b9 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/.settings/org.eclipse.jdt.core.prefs @@ -1,14 +1,14 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/Bug370605.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/Bug370605.java index 7e4dca1a0..f899b5dfe 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/Bug370605.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/Bug370605.java @@ -1,350 +1,350 @@ -/**************************************************************************** - * Copyright (c) 2012 Scott Klein - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Scott Klein - initial API and implementation - *****************************************************************************/ - -package org.eclipse.nebula.widgets.cdatetime; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; -import java.util.TimeZone; - -import org.eclipse.nebula.cwt.test.AbstractVTestCase; -import org.eclipse.swt.SWT; - -public class Bug370605 extends AbstractVTestCase { - - private static final String FALL_EPOCH = "11/04/2012 00:00.00 PDT"; - - private static Date now = new Date(); - - private static final String PATTERN_TIMESTAMP = "MM/dd/yyyy HH:mm.ss z"; - - private static final String SPRING_EPOCH = "03/11/2012 01:00.00 PST"; - - private static final TimeZone TIMEZONE_DST = TimeZone - .getTimeZone("US/Pacific"); - - private static final TimeZone TIMEZONE_INITIAL = TimeZone - .getTimeZone("Pacific/Kiritimati"); - - private static Collection timezones = new ArrayList(); - - private static final String[] TIMEZONES = { "UTC", "MIT", "HST", "AST", - "PST", "MST", "CST", "EST", "PRT", "AGT", "BET", "CET", "EET", - "NET", "IST", "VST", "JST", "NST" }; - - private CdtTester tester; - - /** - * Using traverse arrow keys, move through each field of the control - * - * Stop traversing if we have cycled back to the starting field, or we reach - * the time zone field - * - * @return true, if the time zone field has been found. false otherwise. - */ - private boolean moveToTimeZoneField(int calendarFieldSelection) { - CDateTime cdt = tester.getCDateTime(); - int initialField = cdt.getCalendarField(); - - int currentField = -1; - do { - keyPress(SWT.ARROW_RIGHT); - keyPress('\r'); - currentField = cdt.getCalendarField(); - } while (currentField != initialField - && currentField != calendarFieldSelection); - - return currentField != Calendar.ZONE_OFFSET; - } - - public void setUp() throws Exception { - timezones.clear(); - for (final String timezone : TIMEZONES) { - timezones.add(TimeZone.getTimeZone(timezone)); - } - tester = new CdtTester(getShell(), CDT.BORDER | CDT.TAB_FIELDS - | CDT.CLOCK_24_HOUR | CDT.DATE_LONG | CDT.TIME_MEDIUM); - - } - - /** - * This uses a single test with a known DST zone (PST). - * - *
    - * Test Plans - *
  1. roll over the epoch time and ensure we roll over both 1 AM times - * (Daylight and Standard).
  2. - *
  3. roll backwards and ensure we can do that also
  4. - *
  5. manually type in the epoch time and ensure we get the Java default - * time
  6. - *
- * - * @throws Exception - */ - public void testDaylightSavingsFallRoll() throws Exception { - TimeZone.setDefault(TIMEZONE_DST); - SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_TIMESTAMP); - Date fallEpochDate = sdf.parse(FALL_EPOCH); - Calendar fallEpochCal = Calendar.getInstance(); - fallEpochCal.setTime(fallEpochDate); - - tester.setPattern(PATTERN_TIMESTAMP); - tester.setTimeZone(TIMEZONE_DST); - tester.setSelection(fallEpochDate); - - click(tester.getTextWidget()); - - moveToTimeZoneField(Calendar.HOUR_OF_DAY); - - // VERIFY: Move from 12 AM to 1 AM - // Ignoring time zone DST during this test - keyPress(SWT.ARROW_UP); - keyPress('\r'); - - Date modifiedDate = tester.getCDateTime().getCalendarTime(); - Calendar modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 1, - modifiedCal.get(Calendar.HOUR_OF_DAY)); - - // VERFIY: Move from 1 AM to 1 AM - // Ignoring time zone DST during this test - keyPress(SWT.ARROW_UP); - keyPress('\r'); - - modifiedDate = tester.getCDateTime().getCalendarTime(); - modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 1, - modifiedCal.get(Calendar.HOUR_OF_DAY)); - - // VERIFY: Move from 1 AM to 2 AM - keyPress(SWT.ARROW_UP); - keyPress('\r'); - - modifiedDate = tester.getCDateTime().getCalendarTime(); - modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 2, - modifiedCal.get(Calendar.HOUR_OF_DAY)); - - // VERIFY: Move backwards from 2 AM to 1 AM - keyPress(SWT.ARROW_DOWN); - keyPress('\r'); - - modifiedDate = tester.getCDateTime().getCalendarTime(); - modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 1, - modifiedCal.get(Calendar.HOUR_OF_DAY)); - - // VERIFY: Move backwards from 1 AM to 1 AM - keyPress(SWT.ARROW_DOWN); - keyPress('\r'); - - modifiedDate = tester.getCDateTime().getCalendarTime(); - modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 1, - modifiedCal.get(Calendar.HOUR_OF_DAY)); - - // VERIFY: Move backwards from 1 AM to 12 AM - keyPress(SWT.ARROW_DOWN); - keyPress('\r'); - - modifiedDate = tester.getCDateTime().getCalendarTime(); - modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY), - modifiedCal.get(Calendar.HOUR_OF_DAY)); - - // VERIFY: Manually type in 1 AM - keyPress(SWT.KEYPAD_0); - keyPress(SWT.KEYPAD_1); - keyPress('\r'); - - modifiedDate = tester.getCDateTime().getCalendarTime(); - modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(1, modifiedCal.get(Calendar.HOUR_OF_DAY)); - - } - - /** - * This uses a single test with a known DST zone (PST). - * - *
    - * Test Plans - *
  1. roll over the epoch time and ensure we roll over 1 AM directly into 3 - * AM
  2. - *
  3. roll backwards and ensure we can do that also
  4. - *
  5. manually type in the epoch time and ensure we get the Java default - * time
  6. - *
- * - * @throws Exception - */ - public void testDaylightSavingsSpringRoll() throws Exception { - TimeZone.setDefault(TIMEZONE_DST); - SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_TIMESTAMP); - Date springEpochDate = sdf.parse(SPRING_EPOCH); - Calendar springEpochCal = Calendar.getInstance(); - springEpochCal.setTime(springEpochDate); - - tester.setPattern(PATTERN_TIMESTAMP); - tester.setTimeZone(TIMEZONE_DST); - tester.setSelection(springEpochDate); - - click(tester.getTextWidget()); - - moveToTimeZoneField(Calendar.HOUR_OF_DAY); - - // VERIFY: Spring from 1 AM to 3 AM using arrow keys - keyPress(SWT.ARROW_UP); - keyPress('\r'); - - Date modifiedDate = tester.getCDateTime().getCalendarTime(); - Calendar modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(springEpochCal.get(Calendar.HOUR_OF_DAY) + 2, - modifiedCal.get(Calendar.HOUR_OF_DAY)); - - // VERIFY: Spring backwards from 3 AM to 1 AM using arrow keys - keyPress(SWT.ARROW_DOWN); - keyPress('\r'); - - modifiedDate = tester.getCDateTime().getCalendarTime(); - modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(springEpochCal.get(Calendar.HOUR_OF_DAY), - modifiedCal.get(Calendar.HOUR_OF_DAY)); - - // VERIFY: Manully enter 2 AM and verify it reverts to 3 AM - keyPress(SWT.KEYPAD_0); - keyPress(SWT.KEYPAD_2); - - modifiedDate = tester.getCDateTime().getCalendarTime(); - modifiedCal = Calendar.getInstance(); - modifiedCal.setTime(modifiedDate); - - assertEquals(3, modifiedCal.get(Calendar.HOUR_OF_DAY)); - - } - - /** - * Using a CDateTime that is not configured for altering time zone, verify - * that the time zone field is simply not able to be traversed into. - * - * @throws Exception - */ - public void testNoTimeZoneSelection() throws Exception { - tester.setPattern(PATTERN_TIMESTAMP); - tester.setTimeZone(TIMEZONE_INITIAL); - tester.setSelection(now); - - click(tester.getTextWidget()); - - // VERIFY: TimeZone is set to the initial time zone - final TimeZone wtzOriginal = tester.getCDateTime().getTimeZone(); - assertEquals(TIMEZONE_INITIAL.getDisplayName(), - wtzOriginal.getDisplayName()); - - // VERIFY: Move over to time zone, but this should not be - // possible, so the utility method should return false - assertTrue(moveToTimeZoneField(Calendar.ZONE_OFFSET)); - } - - /** - * Using a CDateTime that is configured for altering the time zone, verify - * that our original time zone that we set to the control is still in the - * control on instantiation. Here we use a time zone that is *not* in the - * list to ensure we do no alter the programatic expectation. - * - * We then step over to the time zone field and verify that the controls - * time zone is altered in accordance with our list of time zones that we - * set into the control - * - * @throws Exception - */ - public void testTimeZoneSelection() throws Exception { - tester.setPattern(PATTERN_TIMESTAMP, timezones.toArray(new TimeZone[0])); - tester.setTimeZone(TIMEZONE_INITIAL); - tester.setSelection(now); - - // VERIFY: TimeZone is set to the initial time zone - final TimeZone wtzOriginal = tester.getCDateTime().getTimeZone(); - assertEquals(TIMEZONE_INITIAL.getDisplayName(), - wtzOriginal.getDisplayName()); - - // Move to the TimeZone field - click(tester.getTextWidget()); - moveToTimeZoneField(Calendar.ZONE_OFFSET); - - SimpleDateFormat sdf = new SimpleDateFormat("z"); - - // VERIFY: Flip forward through each available timezone and that it - // changes in the control - for (String timezone : TIMEZONES) { - keyPress(SWT.ARROW_UP); - keyPress('\r'); - - final TimeZone actualTimeZone = tester.getCDateTime().getTimeZone(); - final TimeZone expectedTimeZone = TimeZone.getTimeZone(timezone); - - // get the actual timezone format we expect, and the actual one - sdf.setTimeZone(actualTimeZone); - final String actualTimeZoneDisplay = sdf.format(new Date()); - sdf.setTimeZone(expectedTimeZone); - final String expectedTimeZoneDisplay = sdf.format(new Date()); - - assertEquals(actualTimeZoneDisplay, expectedTimeZoneDisplay); - } - - // Get back to the "1st" time zone in the list - keyPress(SWT.ARROW_UP); - keyPress('\r'); - - // VERIFY: Flip backward through each available timezone and that it - // changes in the control - for (int idx = TIMEZONES.length - 1; idx >= 0; idx--) { - keyPress(SWT.ARROW_DOWN); - keyPress('\r'); - - final TimeZone actualTimeZone = tester.getCDateTime().getTimeZone(); - final TimeZone expectedTimeZone = TimeZone - .getTimeZone(TIMEZONES[idx]); - - // get the actual timezone format we expect, and the actual one - sdf.setTimeZone(actualTimeZone); - final String actualTimeZoneDisplay = sdf.format(new Date()); - sdf.setTimeZone(expectedTimeZone); - final String expectedTimeZoneDisplay = sdf.format(new Date()); - - assertEquals(actualTimeZoneDisplay, expectedTimeZoneDisplay); - - } - } +/**************************************************************************** + * Copyright (c) 2012 Scott Klein + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Scott Klein - initial API and implementation + *****************************************************************************/ + +package org.eclipse.nebula.widgets.cdatetime; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.TimeZone; + +import org.eclipse.nebula.cwt.test.AbstractVTestCase; +import org.eclipse.swt.SWT; + +public class Bug370605 extends AbstractVTestCase { + + private static final String FALL_EPOCH = "11/04/2012 00:00.00 PDT"; + + private static Date now = new Date(); + + private static final String PATTERN_TIMESTAMP = "MM/dd/yyyy HH:mm.ss z"; + + private static final String SPRING_EPOCH = "03/11/2012 01:00.00 PST"; + + private static final TimeZone TIMEZONE_DST = TimeZone + .getTimeZone("US/Pacific"); + + private static final TimeZone TIMEZONE_INITIAL = TimeZone + .getTimeZone("Pacific/Kiritimati"); + + private static Collection timezones = new ArrayList(); + + private static final String[] TIMEZONES = { "UTC", "MIT", "HST", "AST", + "PST", "MST", "CST", "EST", "PRT", "AGT", "BET", "CET", "EET", + "NET", "IST", "VST", "JST", "NST" }; + + private CdtTester tester; + + /** + * Using traverse arrow keys, move through each field of the control + * + * Stop traversing if we have cycled back to the starting field, or we reach + * the time zone field + * + * @return true, if the time zone field has been found. false otherwise. + */ + private boolean moveToTimeZoneField(int calendarFieldSelection) { + CDateTime cdt = tester.getCDateTime(); + int initialField = cdt.getCalendarField(); + + int currentField = -1; + do { + keyPress(SWT.ARROW_RIGHT); + keyPress('\r'); + currentField = cdt.getCalendarField(); + } while (currentField != initialField + && currentField != calendarFieldSelection); + + return currentField != Calendar.ZONE_OFFSET; + } + + public void setUp() throws Exception { + timezones.clear(); + for (final String timezone : TIMEZONES) { + timezones.add(TimeZone.getTimeZone(timezone)); + } + tester = new CdtTester(getShell(), CDT.BORDER | CDT.TAB_FIELDS + | CDT.CLOCK_24_HOUR | CDT.DATE_LONG | CDT.TIME_MEDIUM); + + } + + /** + * This uses a single test with a known DST zone (PST). + * + *
    + * Test Plans + *
  1. roll over the epoch time and ensure we roll over both 1 AM times + * (Daylight and Standard).
  2. + *
  3. roll backwards and ensure we can do that also
  4. + *
  5. manually type in the epoch time and ensure we get the Java default + * time
  6. + *
+ * + * @throws Exception + */ + public void testDaylightSavingsFallRoll() throws Exception { + TimeZone.setDefault(TIMEZONE_DST); + SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_TIMESTAMP); + Date fallEpochDate = sdf.parse(FALL_EPOCH); + Calendar fallEpochCal = Calendar.getInstance(); + fallEpochCal.setTime(fallEpochDate); + + tester.setPattern(PATTERN_TIMESTAMP); + tester.setTimeZone(TIMEZONE_DST); + tester.setSelection(fallEpochDate); + + click(tester.getTextWidget()); + + moveToTimeZoneField(Calendar.HOUR_OF_DAY); + + // VERIFY: Move from 12 AM to 1 AM + // Ignoring time zone DST during this test + keyPress(SWT.ARROW_UP); + keyPress('\r'); + + Date modifiedDate = tester.getCDateTime().getCalendarTime(); + Calendar modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 1, + modifiedCal.get(Calendar.HOUR_OF_DAY)); + + // VERFIY: Move from 1 AM to 1 AM + // Ignoring time zone DST during this test + keyPress(SWT.ARROW_UP); + keyPress('\r'); + + modifiedDate = tester.getCDateTime().getCalendarTime(); + modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 1, + modifiedCal.get(Calendar.HOUR_OF_DAY)); + + // VERIFY: Move from 1 AM to 2 AM + keyPress(SWT.ARROW_UP); + keyPress('\r'); + + modifiedDate = tester.getCDateTime().getCalendarTime(); + modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 2, + modifiedCal.get(Calendar.HOUR_OF_DAY)); + + // VERIFY: Move backwards from 2 AM to 1 AM + keyPress(SWT.ARROW_DOWN); + keyPress('\r'); + + modifiedDate = tester.getCDateTime().getCalendarTime(); + modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 1, + modifiedCal.get(Calendar.HOUR_OF_DAY)); + + // VERIFY: Move backwards from 1 AM to 1 AM + keyPress(SWT.ARROW_DOWN); + keyPress('\r'); + + modifiedDate = tester.getCDateTime().getCalendarTime(); + modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY) + 1, + modifiedCal.get(Calendar.HOUR_OF_DAY)); + + // VERIFY: Move backwards from 1 AM to 12 AM + keyPress(SWT.ARROW_DOWN); + keyPress('\r'); + + modifiedDate = tester.getCDateTime().getCalendarTime(); + modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(fallEpochCal.get(Calendar.HOUR_OF_DAY), + modifiedCal.get(Calendar.HOUR_OF_DAY)); + + // VERIFY: Manually type in 1 AM + keyPress(SWT.KEYPAD_0); + keyPress(SWT.KEYPAD_1); + keyPress('\r'); + + modifiedDate = tester.getCDateTime().getCalendarTime(); + modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(1, modifiedCal.get(Calendar.HOUR_OF_DAY)); + + } + + /** + * This uses a single test with a known DST zone (PST). + * + *
    + * Test Plans + *
  1. roll over the epoch time and ensure we roll over 1 AM directly into 3 + * AM
  2. + *
  3. roll backwards and ensure we can do that also
  4. + *
  5. manually type in the epoch time and ensure we get the Java default + * time
  6. + *
+ * + * @throws Exception + */ + public void testDaylightSavingsSpringRoll() throws Exception { + TimeZone.setDefault(TIMEZONE_DST); + SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_TIMESTAMP); + Date springEpochDate = sdf.parse(SPRING_EPOCH); + Calendar springEpochCal = Calendar.getInstance(); + springEpochCal.setTime(springEpochDate); + + tester.setPattern(PATTERN_TIMESTAMP); + tester.setTimeZone(TIMEZONE_DST); + tester.setSelection(springEpochDate); + + click(tester.getTextWidget()); + + moveToTimeZoneField(Calendar.HOUR_OF_DAY); + + // VERIFY: Spring from 1 AM to 3 AM using arrow keys + keyPress(SWT.ARROW_UP); + keyPress('\r'); + + Date modifiedDate = tester.getCDateTime().getCalendarTime(); + Calendar modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(springEpochCal.get(Calendar.HOUR_OF_DAY) + 2, + modifiedCal.get(Calendar.HOUR_OF_DAY)); + + // VERIFY: Spring backwards from 3 AM to 1 AM using arrow keys + keyPress(SWT.ARROW_DOWN); + keyPress('\r'); + + modifiedDate = tester.getCDateTime().getCalendarTime(); + modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(springEpochCal.get(Calendar.HOUR_OF_DAY), + modifiedCal.get(Calendar.HOUR_OF_DAY)); + + // VERIFY: Manully enter 2 AM and verify it reverts to 3 AM + keyPress(SWT.KEYPAD_0); + keyPress(SWT.KEYPAD_2); + + modifiedDate = tester.getCDateTime().getCalendarTime(); + modifiedCal = Calendar.getInstance(); + modifiedCal.setTime(modifiedDate); + + assertEquals(3, modifiedCal.get(Calendar.HOUR_OF_DAY)); + + } + + /** + * Using a CDateTime that is not configured for altering time zone, verify + * that the time zone field is simply not able to be traversed into. + * + * @throws Exception + */ + public void testNoTimeZoneSelection() throws Exception { + tester.setPattern(PATTERN_TIMESTAMP); + tester.setTimeZone(TIMEZONE_INITIAL); + tester.setSelection(now); + + click(tester.getTextWidget()); + + // VERIFY: TimeZone is set to the initial time zone + final TimeZone wtzOriginal = tester.getCDateTime().getTimeZone(); + assertEquals(TIMEZONE_INITIAL.getDisplayName(), + wtzOriginal.getDisplayName()); + + // VERIFY: Move over to time zone, but this should not be + // possible, so the utility method should return false + assertTrue(moveToTimeZoneField(Calendar.ZONE_OFFSET)); + } + + /** + * Using a CDateTime that is configured for altering the time zone, verify + * that our original time zone that we set to the control is still in the + * control on instantiation. Here we use a time zone that is *not* in the + * list to ensure we do no alter the programatic expectation. + * + * We then step over to the time zone field and verify that the controls + * time zone is altered in accordance with our list of time zones that we + * set into the control + * + * @throws Exception + */ + public void testTimeZoneSelection() throws Exception { + tester.setPattern(PATTERN_TIMESTAMP, timezones.toArray(new TimeZone[0])); + tester.setTimeZone(TIMEZONE_INITIAL); + tester.setSelection(now); + + // VERIFY: TimeZone is set to the initial time zone + final TimeZone wtzOriginal = tester.getCDateTime().getTimeZone(); + assertEquals(TIMEZONE_INITIAL.getDisplayName(), + wtzOriginal.getDisplayName()); + + // Move to the TimeZone field + click(tester.getTextWidget()); + moveToTimeZoneField(Calendar.ZONE_OFFSET); + + SimpleDateFormat sdf = new SimpleDateFormat("z"); + + // VERIFY: Flip forward through each available timezone and that it + // changes in the control + for (String timezone : TIMEZONES) { + keyPress(SWT.ARROW_UP); + keyPress('\r'); + + final TimeZone actualTimeZone = tester.getCDateTime().getTimeZone(); + final TimeZone expectedTimeZone = TimeZone.getTimeZone(timezone); + + // get the actual timezone format we expect, and the actual one + sdf.setTimeZone(actualTimeZone); + final String actualTimeZoneDisplay = sdf.format(new Date()); + sdf.setTimeZone(expectedTimeZone); + final String expectedTimeZoneDisplay = sdf.format(new Date()); + + assertEquals(actualTimeZoneDisplay, expectedTimeZoneDisplay); + } + + // Get back to the "1st" time zone in the list + keyPress(SWT.ARROW_UP); + keyPress('\r'); + + // VERIFY: Flip backward through each available timezone and that it + // changes in the control + for (int idx = TIMEZONES.length - 1; idx >= 0; idx--) { + keyPress(SWT.ARROW_DOWN); + keyPress('\r'); + + final TimeZone actualTimeZone = tester.getCDateTime().getTimeZone(); + final TimeZone expectedTimeZone = TimeZone + .getTimeZone(TIMEZONES[idx]); + + // get the actual timezone format we expect, and the actual one + sdf.setTimeZone(actualTimeZone); + final String actualTimeZoneDisplay = sdf.format(new Date()); + sdf.setTimeZone(expectedTimeZone); + final String expectedTimeZoneDisplay = sdf.format(new Date()); + + assertEquals(actualTimeZoneDisplay, expectedTimeZoneDisplay); + + } + } } \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/BaseCSSThemingTest.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/BaseCSSThemingTest.java index 5d2237383..aa48d34b8 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/BaseCSSThemingTest.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/BaseCSSThemingTest.java @@ -1,203 +1,203 @@ -package org.eclipse.nebula.widgets.cdatetime.css; - -import java.io.StringReader; - -import org.eclipse.e4.ui.css.core.dom.properties.providers.CSSPropertyHandlerSimpleProviderImpl; -import org.eclipse.e4.ui.css.core.engine.CSSErrorHandler; -import org.eclipse.e4.ui.css.swt.dom.SWTElementProvider; -import org.eclipse.e4.ui.css.swt.engine.CSSSWTEngineImpl; -import org.eclipse.nebula.cwt.test.AbstractVTestCase; -import org.eclipse.nebula.widgets.cdatetime.CDateTime; -import org.eclipse.nebula.widgets.cdatetime.CdtTester; -import org.eclipse.nebula.widgets.cdatetime.css.CDateTimePropertyHandler; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; - -/** - * Base class for CSS tests - */ -@SuppressWarnings("restriction") -public class BaseCSSThemingTest extends AbstractVTestCase { - - protected CSSSWTEngineImpl engine; - protected CdtTester tester; - - @FunctionalInterface - protected interface ColorGetter { - Color getColor(CDateTime cdt); - } - - @FunctionalInterface - protected interface FontGetter { - Font getFont(CDateTime cdt); - } - - protected void setUp() throws Exception { - super.setUp(); - - engine = new CSSSWTEngineImpl(getShell().getDisplay()) { - protected void initializeCSSPropertyHandlers() { - CSSPropertyHandlerSimpleProviderImpl handlerProvider = new CSSPropertyHandlerSimpleProviderImpl(); - handlerProvider.registerCSSPropertyHandler(CDateTimePropertyHandler.class, new CDateTimePropertyHandler()); - - String[] props = new String[] { "cdt-background-color", "cdt-color", "cdt-font", "cdt-font-style", "cdt-font-size", "cdt-font-weight", "cdt-font-family", "cdt-picker-background-color", "cdt-picker-color", "cdt-picker-font", - "cdt-picker-font-style", "cdt-picker-font-size", "cdt-picker-font-weight", "cdt-picker-font-family", "cdt-picker-active-day-color", "cdt-picker-inactive-day-color", "cdt-picker-today-color", "cdt-picker-minutes-color", - "cdt-picker-minutes-background-color", "cdt-button-hover-border-color", "cdt-button-hover-background-color", "cdt-button-selected-border-color", "cdt-button-selected-background-color" }; - - for (String prop : props) { - handlerProvider.registerCSSProperty(prop, CDateTimePropertyHandler.class); - } - propertyHandlerProviders.add(handlerProvider); - } - }; - engine.setElementProvider(new SWTElementProvider()); - engine.setErrorHandler(new CSSErrorHandler() { - public void error(Exception e) { - e.printStackTrace(); - } - }); - } - - protected void checkColor(final String property, final ColorGetter getter) { - final boolean[] result = new boolean[1]; - result[0] = false; - getDisplay().syncExec(new Runnable() { - - public void run() { - try { - int r = (int) (Math.random() * 255); - int g = (int) (Math.random() * 255); - int b = (int) (Math.random() * 255); - applyCSS(String.format("%s: rgb(%d, %d, %d);", property, r, g, b)); - Color bgColor = getter.getColor(tester.getCDateTime()); - result[0] = (bgColor != null && bgColor.getRed() == r && bgColor.getGreen() == g && bgColor.getBlue() == b); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - assertTrue(result[0]); - } - - protected void checkFont(final String property, final FontGetter getter) { - final boolean[] result = new boolean[1]; - result[0] = false; - getDisplay().syncExec(new Runnable() { - - public void run() { - try { - applyCSS(property + ": Verdana 11px italic;"); - Font font = getter.getFont(tester.getCDateTime()); - if (font == null) { - return; - } - FontData fd = font.getFontData()[0]; - boolean assertFontName = "Verdana".equals(fd.getName()); - boolean assertFontSize = fd.getHeight() == 11; - boolean assertFontStyle = (fd.getStyle() & SWT.ITALIC) == SWT.ITALIC; - - result[0] = assertFontName && assertFontSize && assertFontStyle; - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - assertTrue(result[0]); - } - - protected void checkFontStyle(final String property, final FontGetter getter) { - final boolean[] result = new boolean[1]; - result[0] = false; - getDisplay().syncExec(new Runnable() { - - public void run() { - try { - applyCSS(property + ": italic;"); - Font font = getter.getFont(tester.getCDateTime()); - if (font == null) { - return; - } - FontData fd = font.getFontData()[0]; - result[0] = (fd.getStyle() & SWT.ITALIC) == SWT.ITALIC; - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - assertTrue(result[0]); - } - - protected void checkFontSize(final String property, final FontGetter getter) { - final boolean[] result = new boolean[1]; - result[0] = false; - getDisplay().syncExec(new Runnable() { - - public void run() { - try { - applyCSS(property + ": 13px;"); - Font font = getter.getFont(tester.getCDateTime()); - if (font == null) { - return; - } - FontData fd = font.getFontData()[0]; - result[0] = fd.getHeight() == 13; - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - assertTrue(result[0]); - } - - protected void checkFontWeight(final String property, final FontGetter getter) { - final boolean[] result = new boolean[1]; - result[0] = false; - getDisplay().syncExec(new Runnable() { - - public void run() { - try { - applyCSS(property + ": bold;"); - Font font = getter.getFont(tester.getCDateTime()); - if (font == null) { - return; - } - FontData fd = font.getFontData()[0]; - result[0] = (fd.getStyle() & SWT.BOLD) == SWT.BOLD; - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - assertTrue(result[0]); - } - - protected void checkFontFamily(final String property, final FontGetter getter) { - final boolean[] result = new boolean[1]; - result[0] = false; - getDisplay().syncExec(new Runnable() { - - public void run() { - try { - applyCSS(property + ": Helvetica;"); - Font font = getter.getFont(tester.getCDateTime()); - if (font == null) { - return; - } - FontData fd = font.getFontData()[0]; - result[0] = "Helvetica".equals(fd.getName()); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - assertTrue(result[0]); - } - - private void applyCSS(String css) throws Exception { - engine.parseStyleSheet(new StringReader("CDateTime {" + css + "}")); - engine.applyStyles(getShell(), true); - } - -} +package org.eclipse.nebula.widgets.cdatetime.css; + +import java.io.StringReader; + +import org.eclipse.e4.ui.css.core.dom.properties.providers.CSSPropertyHandlerSimpleProviderImpl; +import org.eclipse.e4.ui.css.core.engine.CSSErrorHandler; +import org.eclipse.e4.ui.css.swt.dom.SWTElementProvider; +import org.eclipse.e4.ui.css.swt.engine.CSSSWTEngineImpl; +import org.eclipse.nebula.cwt.test.AbstractVTestCase; +import org.eclipse.nebula.widgets.cdatetime.CDateTime; +import org.eclipse.nebula.widgets.cdatetime.CdtTester; +import org.eclipse.nebula.widgets.cdatetime.css.CDateTimePropertyHandler; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; + +/** + * Base class for CSS tests + */ +@SuppressWarnings("restriction") +public class BaseCSSThemingTest extends AbstractVTestCase { + + protected CSSSWTEngineImpl engine; + protected CdtTester tester; + + @FunctionalInterface + protected interface ColorGetter { + Color getColor(CDateTime cdt); + } + + @FunctionalInterface + protected interface FontGetter { + Font getFont(CDateTime cdt); + } + + protected void setUp() throws Exception { + super.setUp(); + + engine = new CSSSWTEngineImpl(getShell().getDisplay()) { + protected void initializeCSSPropertyHandlers() { + CSSPropertyHandlerSimpleProviderImpl handlerProvider = new CSSPropertyHandlerSimpleProviderImpl(); + handlerProvider.registerCSSPropertyHandler(CDateTimePropertyHandler.class, new CDateTimePropertyHandler()); + + String[] props = new String[] { "cdt-background-color", "cdt-color", "cdt-font", "cdt-font-style", "cdt-font-size", "cdt-font-weight", "cdt-font-family", "cdt-picker-background-color", "cdt-picker-color", "cdt-picker-font", + "cdt-picker-font-style", "cdt-picker-font-size", "cdt-picker-font-weight", "cdt-picker-font-family", "cdt-picker-active-day-color", "cdt-picker-inactive-day-color", "cdt-picker-today-color", "cdt-picker-minutes-color", + "cdt-picker-minutes-background-color", "cdt-button-hover-border-color", "cdt-button-hover-background-color", "cdt-button-selected-border-color", "cdt-button-selected-background-color" }; + + for (String prop : props) { + handlerProvider.registerCSSProperty(prop, CDateTimePropertyHandler.class); + } + propertyHandlerProviders.add(handlerProvider); + } + }; + engine.setElementProvider(new SWTElementProvider()); + engine.setErrorHandler(new CSSErrorHandler() { + public void error(Exception e) { + e.printStackTrace(); + } + }); + } + + protected void checkColor(final String property, final ColorGetter getter) { + final boolean[] result = new boolean[1]; + result[0] = false; + getDisplay().syncExec(new Runnable() { + + public void run() { + try { + int r = (int) (Math.random() * 255); + int g = (int) (Math.random() * 255); + int b = (int) (Math.random() * 255); + applyCSS(String.format("%s: rgb(%d, %d, %d);", property, r, g, b)); + Color bgColor = getter.getColor(tester.getCDateTime()); + result[0] = (bgColor != null && bgColor.getRed() == r && bgColor.getGreen() == g && bgColor.getBlue() == b); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + assertTrue(result[0]); + } + + protected void checkFont(final String property, final FontGetter getter) { + final boolean[] result = new boolean[1]; + result[0] = false; + getDisplay().syncExec(new Runnable() { + + public void run() { + try { + applyCSS(property + ": Verdana 11px italic;"); + Font font = getter.getFont(tester.getCDateTime()); + if (font == null) { + return; + } + FontData fd = font.getFontData()[0]; + boolean assertFontName = "Verdana".equals(fd.getName()); + boolean assertFontSize = fd.getHeight() == 11; + boolean assertFontStyle = (fd.getStyle() & SWT.ITALIC) == SWT.ITALIC; + + result[0] = assertFontName && assertFontSize && assertFontStyle; + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + assertTrue(result[0]); + } + + protected void checkFontStyle(final String property, final FontGetter getter) { + final boolean[] result = new boolean[1]; + result[0] = false; + getDisplay().syncExec(new Runnable() { + + public void run() { + try { + applyCSS(property + ": italic;"); + Font font = getter.getFont(tester.getCDateTime()); + if (font == null) { + return; + } + FontData fd = font.getFontData()[0]; + result[0] = (fd.getStyle() & SWT.ITALIC) == SWT.ITALIC; + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + assertTrue(result[0]); + } + + protected void checkFontSize(final String property, final FontGetter getter) { + final boolean[] result = new boolean[1]; + result[0] = false; + getDisplay().syncExec(new Runnable() { + + public void run() { + try { + applyCSS(property + ": 13px;"); + Font font = getter.getFont(tester.getCDateTime()); + if (font == null) { + return; + } + FontData fd = font.getFontData()[0]; + result[0] = fd.getHeight() == 13; + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + assertTrue(result[0]); + } + + protected void checkFontWeight(final String property, final FontGetter getter) { + final boolean[] result = new boolean[1]; + result[0] = false; + getDisplay().syncExec(new Runnable() { + + public void run() { + try { + applyCSS(property + ": bold;"); + Font font = getter.getFont(tester.getCDateTime()); + if (font == null) { + return; + } + FontData fd = font.getFontData()[0]; + result[0] = (fd.getStyle() & SWT.BOLD) == SWT.BOLD; + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + assertTrue(result[0]); + } + + protected void checkFontFamily(final String property, final FontGetter getter) { + final boolean[] result = new boolean[1]; + result[0] = false; + getDisplay().syncExec(new Runnable() { + + public void run() { + try { + applyCSS(property + ": Helvetica;"); + Font font = getter.getFont(tester.getCDateTime()); + if (font == null) { + return; + } + FontData fd = font.getFontData()[0]; + result[0] = "Helvetica".equals(fd.getName()); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + assertTrue(result[0]); + } + + private void applyCSS(String css) throws Exception { + engine.parseStyleSheet(new StringReader("CDateTime {" + css + "}")); + engine.applyStyles(getShell(), true); + } + +} diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingButtonPropertiesTests.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingButtonPropertiesTests.java index 80f96d163..7c42cef76 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingButtonPropertiesTests.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingButtonPropertiesTests.java @@ -1,35 +1,35 @@ -package org.eclipse.nebula.widgets.cdatetime.css; - -import java.util.Date; - -import org.eclipse.nebula.widgets.cdatetime.CDT; -import org.eclipse.nebula.widgets.cdatetime.CdtTester; - -public class ThemingButtonPropertiesTests extends BaseCSSThemingTest { - /** - * @throws java.lang.Exception - */ - @Override - protected void setUp() throws Exception { - super.setUp(); - tester = new CdtTester(getShell(), CDT.BORDER | CDT.COMPACT | CDT.DROP_DOWN | CDT.DATE_LONG | CDT.TIME_MEDIUM); - tester.setSelection(new Date()); - } - - public void testCdtButtonHoverBackgroundColor() throws Exception { - checkColor("cdt-button-hover-background-color", cdt -> cdt.getButtonHoverBackgroundColor()); - } - - public void testCdtButtonHoverBorderColor() throws Exception { - checkColor("cdt-button-hover-border-color", cdt -> cdt.getButtonHoverBorderColor()); - } - - public void testCdtButtonSelectedBackgroundColor() throws Exception { - checkColor("cdt-button-selected-background-color", cdt -> cdt.getButtonSelectedBackgroundColor()); - } - - public void testCdtButtonSelectedBorderColor() throws Exception { - checkColor("cdt-button-selected-border-color", cdt -> cdt.getButtonSelectedBorderColor()); - } - -} +package org.eclipse.nebula.widgets.cdatetime.css; + +import java.util.Date; + +import org.eclipse.nebula.widgets.cdatetime.CDT; +import org.eclipse.nebula.widgets.cdatetime.CdtTester; + +public class ThemingButtonPropertiesTests extends BaseCSSThemingTest { + /** + * @throws java.lang.Exception + */ + @Override + protected void setUp() throws Exception { + super.setUp(); + tester = new CdtTester(getShell(), CDT.BORDER | CDT.COMPACT | CDT.DROP_DOWN | CDT.DATE_LONG | CDT.TIME_MEDIUM); + tester.setSelection(new Date()); + } + + public void testCdtButtonHoverBackgroundColor() throws Exception { + checkColor("cdt-button-hover-background-color", cdt -> cdt.getButtonHoverBackgroundColor()); + } + + public void testCdtButtonHoverBorderColor() throws Exception { + checkColor("cdt-button-hover-border-color", cdt -> cdt.getButtonHoverBorderColor()); + } + + public void testCdtButtonSelectedBackgroundColor() throws Exception { + checkColor("cdt-button-selected-background-color", cdt -> cdt.getButtonSelectedBackgroundColor()); + } + + public void testCdtButtonSelectedBorderColor() throws Exception { + checkColor("cdt-button-selected-border-color", cdt -> cdt.getButtonSelectedBorderColor()); + } + +} diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingGeneralPropertiesTests.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingGeneralPropertiesTests.java index 7129d26b6..6173793e2 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingGeneralPropertiesTests.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingGeneralPropertiesTests.java @@ -1,56 +1,56 @@ -package org.eclipse.nebula.widgets.cdatetime.css; - -import java.util.Date; - -import org.eclipse.nebula.widgets.cdatetime.CDT; -import org.eclipse.nebula.widgets.cdatetime.CdtTester; - -public class ThemingGeneralPropertiesTests extends BaseCSSThemingTest { - - /** - * @throws java.lang.Exception - */ - @Override - protected void setUp() throws Exception { - super.setUp(); - tester = new CdtTester(getShell(), CDT.DATE_MEDIUM | CDT.TIME_MEDIUM); - tester.setSelection(new Date()); - } - - /** - * @throws java.lang.Exception - */ - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testCdtBackgroundColor() throws Exception { - checkColor("cdt-background-color", cdt -> cdt.getBackground()); - - } - - public void testCdtColor() throws Exception { - checkColor("cdt-color", cdt -> cdt.getForeground()); - } - - public void testCdtFont() throws Exception { - checkFont("cdt-font", cdt -> cdt.getFont()); - } - - public void testCdtFontStyle() throws Exception { - checkFontStyle("cdt-font-style", cdt -> cdt.getFont()); - } - - public void testCdtFontSize() throws Exception { - checkFontSize("cdt-font-size", cdt -> cdt.getFont()); - } - - public void testCdtFontWeight() throws Exception { - checkFontWeight("cdt-font-weight", cdt -> cdt.getFont()); - } - - public void testCdtFontFamily() throws Exception { - checkFontFamily("cdt-font-family", cdt -> cdt.getFont()); - } -} +package org.eclipse.nebula.widgets.cdatetime.css; + +import java.util.Date; + +import org.eclipse.nebula.widgets.cdatetime.CDT; +import org.eclipse.nebula.widgets.cdatetime.CdtTester; + +public class ThemingGeneralPropertiesTests extends BaseCSSThemingTest { + + /** + * @throws java.lang.Exception + */ + @Override + protected void setUp() throws Exception { + super.setUp(); + tester = new CdtTester(getShell(), CDT.DATE_MEDIUM | CDT.TIME_MEDIUM); + tester.setSelection(new Date()); + } + + /** + * @throws java.lang.Exception + */ + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testCdtBackgroundColor() throws Exception { + checkColor("cdt-background-color", cdt -> cdt.getBackground()); + + } + + public void testCdtColor() throws Exception { + checkColor("cdt-color", cdt -> cdt.getForeground()); + } + + public void testCdtFont() throws Exception { + checkFont("cdt-font", cdt -> cdt.getFont()); + } + + public void testCdtFontStyle() throws Exception { + checkFontStyle("cdt-font-style", cdt -> cdt.getFont()); + } + + public void testCdtFontSize() throws Exception { + checkFontSize("cdt-font-size", cdt -> cdt.getFont()); + } + + public void testCdtFontWeight() throws Exception { + checkFontWeight("cdt-font-weight", cdt -> cdt.getFont()); + } + + public void testCdtFontFamily() throws Exception { + checkFontFamily("cdt-font-family", cdt -> cdt.getFont()); + } +} diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingPickerPartPropertiesTests.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingPickerPartPropertiesTests.java index ed4736773..f4bb0eed7 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingPickerPartPropertiesTests.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime.tests/src/org/eclipse/nebula/widgets/cdatetime/css/ThemingPickerPartPropertiesTests.java @@ -1,71 +1,71 @@ -package org.eclipse.nebula.widgets.cdatetime.css; - -import java.util.Date; - -import org.eclipse.nebula.widgets.cdatetime.CDT; -import org.eclipse.nebula.widgets.cdatetime.CDateTime; -import org.eclipse.nebula.widgets.cdatetime.CdtTester; -import org.eclipse.swt.graphics.Color; - -public class ThemingPickerPartPropertiesTests extends BaseCSSThemingTest { - - /** - * @throws java.lang.Exception - */ - @Override - protected void setUp() throws Exception { - super.setUp(); - tester = new CdtTester(getShell(), CDT.BORDER | CDT.COMPACT | CDT.DROP_DOWN | CDT.DATE_LONG | CDT.TIME_MEDIUM); - tester.setSelection(new Date()); - } - - public void testCdtPickerBackgroundColor() throws Exception { - checkColor("cdt-picker-background-color", cdt -> cdt.getPickerBackgroundColor()); - } - - public void testCdtPickerColor() throws Exception { - checkColor("cdt-picker-color", cdt -> cdt.getPickerForegroundColor()); - } - - public void testCdtPickerFont() throws Exception { - checkFont("cdt-picker-font", cdt -> cdt.getPickerFont()); - } - - public void testCdtPickerFontStyle() throws Exception { - checkFontStyle("cdt-picker-font-style", cdt -> cdt.getPickerFont()); - } - - public void testCdtPickerFontSize() throws Exception { - checkFontSize("cdt-picker-font-size", cdt -> cdt.getPickerFont()); - } - - public void testCdtPickerFontWeight() throws Exception { - checkFontWeight("cdt-picker-font-weight", cdt -> cdt.getPickerFont()); - } - - public void testCdtPickerFontFamily() throws Exception { - checkFontFamily("cdt-picker-font-family", cdt -> cdt.getPickerFont()); - } - - public void testCdtPickerActiveDayColor() throws Exception { - checkColor("cdt-picker-active-day-color", new ColorGetter() { - public Color getColor(CDateTime cdt) { - return cdt.getPickerActiveDayColor(); - } - }); - } - public void testCdtPickerInactiveDayColor() throws Exception { - checkColor("cdt-picker-inactive-day-color", cdt -> cdt.getPickerInactiveDayColor()); - } - - public void testCdtPickerTodayColor() throws Exception { - checkColor("cdt-picker-today-color", cdt -> cdt.getPickerTodayColor()); - } - - public void testCdtPickerMinutesColor() throws Exception { - checkColor("cdt-picker-minutes-color", cdt -> cdt.getPickerMinutesColor()); - } - public void testCdtPickerMinutesBackgroundColor() throws Exception { - checkColor("cdt-picker-minutes-background-color", cdt -> cdt.getPickerMinutesBackgroundColor()); - } -} +package org.eclipse.nebula.widgets.cdatetime.css; + +import java.util.Date; + +import org.eclipse.nebula.widgets.cdatetime.CDT; +import org.eclipse.nebula.widgets.cdatetime.CDateTime; +import org.eclipse.nebula.widgets.cdatetime.CdtTester; +import org.eclipse.swt.graphics.Color; + +public class ThemingPickerPartPropertiesTests extends BaseCSSThemingTest { + + /** + * @throws java.lang.Exception + */ + @Override + protected void setUp() throws Exception { + super.setUp(); + tester = new CdtTester(getShell(), CDT.BORDER | CDT.COMPACT | CDT.DROP_DOWN | CDT.DATE_LONG | CDT.TIME_MEDIUM); + tester.setSelection(new Date()); + } + + public void testCdtPickerBackgroundColor() throws Exception { + checkColor("cdt-picker-background-color", cdt -> cdt.getPickerBackgroundColor()); + } + + public void testCdtPickerColor() throws Exception { + checkColor("cdt-picker-color", cdt -> cdt.getPickerForegroundColor()); + } + + public void testCdtPickerFont() throws Exception { + checkFont("cdt-picker-font", cdt -> cdt.getPickerFont()); + } + + public void testCdtPickerFontStyle() throws Exception { + checkFontStyle("cdt-picker-font-style", cdt -> cdt.getPickerFont()); + } + + public void testCdtPickerFontSize() throws Exception { + checkFontSize("cdt-picker-font-size", cdt -> cdt.getPickerFont()); + } + + public void testCdtPickerFontWeight() throws Exception { + checkFontWeight("cdt-picker-font-weight", cdt -> cdt.getPickerFont()); + } + + public void testCdtPickerFontFamily() throws Exception { + checkFontFamily("cdt-picker-font-family", cdt -> cdt.getPickerFont()); + } + + public void testCdtPickerActiveDayColor() throws Exception { + checkColor("cdt-picker-active-day-color", new ColorGetter() { + public Color getColor(CDateTime cdt) { + return cdt.getPickerActiveDayColor(); + } + }); + } + public void testCdtPickerInactiveDayColor() throws Exception { + checkColor("cdt-picker-inactive-day-color", cdt -> cdt.getPickerInactiveDayColor()); + } + + public void testCdtPickerTodayColor() throws Exception { + checkColor("cdt-picker-today-color", cdt -> cdt.getPickerTodayColor()); + } + + public void testCdtPickerMinutesColor() throws Exception { + checkColor("cdt-picker-minutes-color", cdt -> cdt.getPickerMinutesColor()); + } + public void testCdtPickerMinutesBackgroundColor() throws Exception { + checkColor("cdt-picker-minutes-background-color", cdt -> cdt.getPickerMinutesBackgroundColor()); + } +} diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/projectSet.psf b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/projectSet.psf index a3586557c..aec255ed4 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/projectSet.psf +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/projectSet.psf @@ -1,19 +1,19 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/CDateTime.java b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/CDateTime.java index e7a33993e..966df1b65 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/CDateTime.java +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/CDateTime.java @@ -1,2602 +1,2602 @@ -/**************************************************************************** - * Copyright (c) 2006-2019 Jeremy Dowdall - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jeremy Dowdall - initial API and implementation - * Wim Jongman - https://bugs.eclipse.org/bugs/show_bug.cgi?id=362181 - * Scott Klein - https://bugs.eclipse.org/bugs/show_bug.cgi?id=370605 - * Baruch Youssin - https://bugs.eclipse.org/bugs/show_bug.cgi?id=261414 - * Doug Showell - https://bugs.eclipse.org/bugs/show_bug.cgi?id=383589 - * Bel Razom - https://bugs.eclipse.org/bugs/show_bug.cgi?id=527399 - * Stefan Nöbauer - https://bugs.eclipse.org/bugs/show_bug.cgi?id=548149 - *****************************************************************************/ - -package org.eclipse.nebula.widgets.cdatetime; - -import java.text.AttributedCharacterIterator; -import java.text.CharacterIterator; -import java.text.DateFormat; -import java.text.DateFormat.Field; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; - -import org.eclipse.nebula.cwt.base.BaseCombo; -import org.eclipse.nebula.cwt.v.VButton; -import org.eclipse.nebula.cwt.v.VCanvas; -import org.eclipse.nebula.cwt.v.VGridLayout; -import org.eclipse.nebula.cwt.v.VLabel; -import org.eclipse.nebula.cwt.v.VLayout; -import org.eclipse.nebula.cwt.v.VNative; -import org.eclipse.nebula.cwt.v.VPanel; -import org.eclipse.nebula.cwt.v.VTracker; -import org.eclipse.nebula.widgets.cdatetime.CDT.PickerPart; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.FocusAdapter; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Spinner; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.TypedListener; - -/** - * The CDateTime provides both textual and graphical means selecting a - * date.
- * As with other combo type widgets, there are three basic styles: - *
    - *
  • Text only (default)
  • - *
  • Graphical only (CDT.SIMPLE)
  • - *
  • Combo - a text selector with a drop-down graphical selector - * (CDT.DROP_DOWN)
  • - *
- *

- * Styles are set using the constants provided in the CDT class. - *

- * - * @see CDT - * @since 1.5 - */ -public class CDateTime extends BaseCombo { - - /** - * A simple class used for editing a field numerically. - */ - private class EditField { - - private String buffer; - private int digits; - private int count = 0; - - EditField(int digits, int initialValue) { - this.digits = digits; - buffer = Integer.toString(initialValue); - } - - /** - * Adds a character if it is a digit; in case the field exceeds its - * capacity, the oldest character is dropped from the buffer. Non-digits - * are dropped. - * - * @param c - * @return true if the new character is a digit and with its addition - * the active field reaches or exceeds its capacity, false - * otherwise - */ - boolean addChar(char c) { - if (Character.isDigit(c)) { - buffer = count > 0 ? buffer : ""; //$NON-NLS-1$ - buffer += String.valueOf(c); - if (buffer.length() > digits) { - buffer = buffer.substring(buffer.length() - digits, - buffer.length()); - } - } - return ++count > digits - 1; - } - - int getValue() { - return Integer.parseInt(buffer); - } - - void removeLastCharacter() { - if (buffer.length() > 0) { - buffer = buffer.substring(0, buffer.length() - 1); - count--; - } - } - - void reset() { - count = 0; - } - - @Override - public String toString() { - if (buffer.length() < digits) { - char[] ca = new char[digits - buffer.length()]; - Arrays.fill(ca, '0'); - buffer = String.valueOf(ca).concat(buffer); - } - return buffer; - } - } - - /** - * The layout used for a "basic" CDateTime - when it is neither of style - * SIMPLE or DROP_DOWN - with style of SPINNER.
- * Note that there is a spinner, but no button for this style. - */ - class SpinnerLayout extends VLayout { - - @Override - protected Point computeSize(VPanel panel, int wHint, int hHint, - boolean flushCache) { - Point size = text.computeSize(SWT.DEFAULT, SWT.DEFAULT); - - Rectangle sRect = spinner.getControl().computeTrim(0, 0, 0, 0); - int sWidth = sRect.x + sRect.width - - 2 * spinner.getControl().getBorderWidth() + 1; - - if (gtk && sWidth == 0) { - sWidth = 67; - } - - size.x += sWidth; - size.x++; - size.y += textMarginHeight; - - if (wHint != SWT.DEFAULT) { - size.x = Math.min(size.x, wHint); - } - if (hHint != SWT.DEFAULT) { - size.y = Math.min(size.y, hHint); - } - return size; - } - - @Override - protected void layout(VPanel panel, boolean flushCache) { - Rectangle cRect = panel.getClientArea(); - if (cRect.isEmpty()) { - return; - } - - Point tSize = text.getControl().computeSize(SWT.DEFAULT, - SWT.DEFAULT); - tSize.y += textMarginHeight; - - spinner.setBounds(cRect.x, cRect.y, cRect.width, tSize.y); - - Rectangle sRect = spinner.getControl().computeTrim(0, 0, 0, 0); - int sWidth = sRect.x + sRect.width - - 2 * spinner.getControl().getBorderWidth() + 1; - - if (gtk && sWidth == 0) { - sWidth = 67; - } - - tSize.x = cRect.width - sWidth; - - text.setBounds(cRect.x, cRect.y + getBorderWidth(), tSize.x, - tSize.y); - } - } - - private static final int FIELD_NONE = -1; - - private static final int DISCARD = 0; - private static final int WRAP = 1; - private static final int BLOCK = 2; - - private static int convertStyle(int style) { - int rstyle = SWT.NONE; - if ((style & CDT.DROP_DOWN) != 0) { - rstyle |= SWT.DROP_DOWN; - } - if ((style & CDT.SIMPLE) != 0) { - rstyle |= SWT.SIMPLE; - } - if ((style & CDT.READ_ONLY) != 0) { - rstyle |= SWT.READ_ONLY; - } - if ((style & CDT.BUTTON_LEFT) != 0) { - rstyle |= SWT.LEFT; - } - if ((style & CDT.TEXT_LEAD) != 0) { - rstyle |= SWT.LEAD; - } - if ((style & CDT.BORDER) != 0) { - rstyle |= SWT.BORDER; - } - if (win32) { - rstyle |= SWT.DOUBLE_BUFFERED; - } - return rstyle; - } - - VPanel picker; - - VNative spinner; - boolean internalFocusShift = false; - boolean rightClick = false; - - private Date cancelDate; - private Calendar calendar; - private Calendar minDate; - private Calendar maxDate; - - private DateFormat df; - Locale locale; - - TimeZone timezone; - Field[] field; - int activeField; - - private boolean tabStops = false; - // Store these values so that the style can be reset automatically - // to update everything if/when the locale is changed - int style; - String pattern = null; - - int format = -1; - - private CDateTimePainter painter; - - /** - * Delegates events to their appropriate handler - */ - Listener textListener = event -> { - switch (event.type) { - case SWT.FocusIn: - rightClick = false; - if (internalFocusShift) { - if (activeField < 0) { - fieldFirst(); - updateText(); - } - } else { - if (VTracker.getLastTraverse() == SWT.TRAVERSE_TAB_PREVIOUS) { - fieldLast(); - } else { - fieldFirst(); - } - updateText(); - } - break; - case SWT.FocusOut: - if (!rightClick && !internalFocusShift) { - if (commitEditField()) { - updateText(); - } else { - editField = null; - } - } - break; - case SWT.KeyDown: - handleKey(event); - break; - case SWT.MouseDown: - if (event.button == 1) { - fieldFromTextSelection(); - } else if (event.button == 2) { - fieldNext(); - } else if (event.button == 3) { - rightClick = true; - } - break; - case SWT.MouseWheel: - Control focusedControl = getDisplay().getFocusControl(); - if (getTextWidget() != null - && getTextWidget().getControl() != focusedControl) { - // Do not handle mousewheel events if the widget does not have - // focus - break; - } - if (event.count > 0) { - fieldAdjust(1); - } else { - fieldAdjust(-1); - } - event.doit = false; - break; - case SWT.MouseUp: - if (event.button == 1) { - fieldFromTextSelection(); - } - break; - case SWT.Traverse: - handleTraverse(event); - break; - case SWT.Verify: - verify(event); - break; - } - }; - private Point textSelectionOffset = new Point(0, 0); // x = selOffset start, - // y = selOffset - // amount - private EditField editField; - - private String[] separator; - private int[] calendarFields; - private boolean isTime; - private boolean isDate; - // private boolean isNull = true; - private String nullText = null; - - private boolean defaultNullText = true; - private boolean singleSelection; - - // private boolean dragSelection; - private Date[] selection = new Date[0]; - - private boolean scrollable = true; - - CDateTimeBuilder builder; - - VPanel pickerPanel; - - private TimeZone[] allowedTimezones; - - Color buttonHoverBackgroundColor, buttonHoverBorderColor; - Color buttonSelectedBackgroundColor, buttonSelectedBorderColor; - - Color pickerForegroundColor, pickerBackgroundColor; - Font pickerFont; - - Color pickerActiveDayColor, pickerInactiveDayColor, pickerTodayColor; - Color pickerMinutesColor, pickerMinutesBackgroundColor; - - Color okButtonColor, cancelButtonColor, clearButtonForegroundColor; - Font clearButtonFont; - private VButton okButton, clearButton, cancelButton; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. The current date and the - * system's default locale are used. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - */ - public CDateTime(Composite parent, int style) { - super(parent, convertStyle(style)); - init(style); - } - - /** - * Adds the listener to the collection of listeners who will be notified - * when the receiver's selection changes, by sending it one of the messages - * defined in the SelectionListener interface. - *

- * widgetSelected is called when the selection (date/time) - * changes. widgetDefaultSelected is when ENTER is pressed the - * text box. - *

- * The event's data field will contain the newly selected Date object.
- * The event's detail field will contain which Calendar Field was changed - * - * @param listener - * the listener which should be notified - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(SelectionListener listener) { - if (listener != null) { - TypedListener typedListener = new TypedListener(listener); - addListener(SWT.Selection, typedListener); - addListener(SWT.DefaultSelection, typedListener); - } - } - - /** - * Adds the textListener for the appropriate SWT events to handle - * incrementing fields. - */ - protected void addTextListener() { - removeTextListener(); - - Text control = text.getControl(); - control.addListener(SWT.FocusIn, textListener); - control.addListener(SWT.FocusOut, textListener); - control.addListener(SWT.KeyDown, textListener); - control.addListener(SWT.MouseDown, textListener); - control.addListener(SWT.MouseWheel, textListener); - control.addListener(SWT.MouseUp, textListener); - control.addListener(SWT.Verify, textListener); - - text.addListener(SWT.Traverse, textListener); - } - - /** - * If a field is being edited (via keyboard), set the edit value to the - * active field of the calendar. Reset the count of the EditField so that a - * subsequent key press will overwrite its contents; - * - * @return true if the commit was successfull (the value was valid for the - * field) or there was no commit to be made (editField is null), - * false otherwise - */ - private boolean commitEditField() { - if (editField != null) { - int cf = getCalendarField(); - int val = editField.getValue(); - editField.reset(); - if (cf == Calendar.MONTH) { - val--; - } - return fieldSet(cf, val, DISCARD); - } - return true; - } - - /** - * If style is neither SIMPLE or DROP_DOWN, then this method simply returns, - * otherwise it creates the picker. - */ - private void createPicker() { - if (isSimple()) { - pickerPanel = panel; - setContent(panel.getComposite()); - } else if (isDropDown()) { - disposePicker(); - - Shell shell = getContentShell(); - int style = (isSimple() ? SWT.NONE : SWT.BORDER) - | SWT.DOUBLE_BUFFERED; - VCanvas canvas = new VCanvas(shell, style); - pickerPanel = canvas.getPanel(); - pickerPanel.setWidget(canvas); - VGridLayout layout = new VGridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.verticalSpacing = 1; - pickerPanel.setLayout(layout); - setContent(pickerPanel.getComposite()); - - canvas.addListener(SWT.KeyDown, event -> { - if (SWT.ESC == event.keyCode) { - event.doit = false; - if (selection.length > 0 && selection[0] != cancelDate) { - setSelection(cancelDate); - fireSelectionChanged(); - } - setOpen(false); - } - }); - - if (field.length > 1 || isTime) { - createPickerToolbar(pickerPanel); - } - } - - if (pickerBackgroundColor != null) { - pickerPanel.setBackground(pickerBackgroundColor); - } - if (pickerForegroundColor != null) { - pickerPanel.setForeground(pickerForegroundColor); - } - if (pickerFont != null) { - pickerPanel.setFont(pickerFont); - } - - if (isDate) { - DatePicker dp = new DatePicker(this); - dp.setScrollable(scrollable); - dp.setFields(calendarFields); - dp.updateView(); - picker = dp; - } else if (isTime) { - if ((style & CDT.CLOCK_DISCRETE) != 0) { - DiscreteTimePicker dtp = new DiscreteTimePicker(this); - dtp.setFields(calendarFields); - dtp.updateView(); - picker = dtp; - } else { - AnalogTimePicker atp = new AnalogTimePicker(this); - atp.setFields(calendarFields); - atp.updateView(); - picker = atp; - } - } - - if (isDropDown()) { - picker.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, false, false)); - } - } - - private void createPickerToolbar(VPanel parent) { - VPanel tb = new VPanel(parent, SWT.NONE); - VGridLayout layout = new VGridLayout(3, false); - layout.marginHeight = 0; - layout.marginWidth = 0; - layout.horizontalSpacing = 2; - tb.setLayout(layout); - tb.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false)); - tb.setData(CDT.PickerPart, PickerPart.Toolbar); - - okButton = new VButton(tb, SWT.OK | SWT.NO_FOCUS); - okButton.setData(CDT.PickerPart, PickerPart.OkButton); - okButton.setToolTipText(Resources.getString("accept.text", locale)); //$NON-NLS-1$ - okButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); - okButton.addListener(SWT.Selection, event -> setOpen(false)); - okButton.setHoverBackgroundColor(buttonHoverBackgroundColor); - okButton.setHoverBorderColor(buttonHoverBorderColor); - okButton.setSelectedBackgroundColor(buttonSelectedBackgroundColor); - okButton.setSelectedBorderColor(buttonSelectedBorderColor); - okButton.setForeground(okButtonColor); - - cancelButton = new VButton(tb, SWT.CANCEL | SWT.NO_FOCUS); - cancelButton.setData(CDT.PickerPart, PickerPart.CancelButton); - cancelButton.setToolTipText(Resources.getString("cancel.text", locale)); //$NON-NLS-1$ - cancelButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); - cancelButton.addListener(SWT.Selection, event -> { - setSelection(cancelDate); - fireSelectionChanged(); - setOpen(false); - }); - cancelButton.setHoverBackgroundColor(buttonHoverBackgroundColor); - cancelButton.setHoverBorderColor(buttonHoverBorderColor); - cancelButton.setSelectedBackgroundColor(buttonSelectedBackgroundColor); - cancelButton.setSelectedBorderColor(buttonSelectedBorderColor); - cancelButton.setForeground(cancelButtonColor); - - clearButton = new VButton(tb, SWT.NO_FOCUS); - clearButton.setData(CDT.PickerPart, PickerPart.ClearButton); - clearButton.setText(Resources.getString("clear.text", locale)); //$NON-NLS-1$ - clearButton.setToolTipText(Resources.getString("clear.text", locale)); //$NON-NLS-1$ - clearButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); - clearButton.addListener(SWT.Selection, event -> { - setOpen(false); - setSelection(null); - fireSelectionChanged(); - }); - clearButton.setForeground(clearButtonForegroundColor!=null?clearButtonForegroundColor:parent.getForeground()); - clearButton.setFont(clearButtonFont!=null?clearButtonFont:parent.getFont()); - clearButton.setHoverBackgroundColor(buttonHoverBackgroundColor); - clearButton.setHoverBorderColor(buttonHoverBorderColor); - clearButton.setSelectedBackgroundColor(buttonSelectedBackgroundColor); - clearButton.setSelectedBorderColor(buttonSelectedBorderColor); - - - VLabel sep = new VLabel(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - sep.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); - } - - private void disposePicker() { - if (content != null) { - if (picker != null) { - picker.dispose(); - picker = null; - } - if (isDropDown()) { - Control c = content; - setContent(null); - c.dispose(); - if (contentShell != null) { - Display.getDefault().asyncExec(() -> { - if (contentShell != null - && !contentShell.isDisposed()) { - contentShell.dispose(); - contentShell = null; - } - }); - } - } - } - } - - /** - * Adds the given amount to the x² field, if there is one - */ - void fieldAdjust(int amount) { - if (!hasSelection()) { - if (DatePicker.isValidDate(calendar, minDate, maxDate)) { - setSelection(calendar.getTime()); - fireSelectionChanged(); - } else { - setOpen(true); - } - } else { - int cf = getCalendarField(); - if (cf >= 0) { - fieldRoll(cf, amount, WRAP); - } - } - } - - void fieldFirst() { - // If the user has opted to have the user be able to - // change time zones then allow the next field to be the - // time zone field - if (this.allowedTimezones == null) { - if (Calendar.ZONE_OFFSET == getCalendarField(field[0])) { - setActiveField(1); - } else { - setActiveField(0); - } - } else { - // allowed time zones have been set, so let the user edit it - setActiveField(0); - } - } - - /** - * Sets the active field from the select of the text box - */ - void fieldFromTextSelection() { - if (!hasSelection()) { - // setActiveField(FIELD_ALL); - fieldNext(); - } else { - Point sel = text.getControl().getSelection(); - AttributedCharacterIterator aci = df - .formatToCharacterIterator(calendar.getTime()); - if (sel.x > textSelectionOffset.x) { - sel.x += textSelectionOffset.y; - } - aci.setIndex(sel.x); - Object[] oa = aci.getAttributes().keySet().toArray(); - if (oa.length == 0 && sel.x > 0) { - sel.x -= 1; - aci.setIndex(sel.x); - oa = aci.getAttributes().keySet().toArray(); - } - if (oa.length > 0) { - for (int i = 0; i < field.length; i++) { - if (oa[0].equals(field[i])) { - // If the user has opted to have the user be able to - // change time zones then allow the next field to be the - // time zone field - if (this.allowedTimezones == null) { - if (Calendar.ZONE_OFFSET != getCalendarField( - field[i])) { - setActiveField(i); - } - } else { - // allowed time zones have been set, so let the user - // edit it - setActiveField(i); - } - break; - } - } - updateText(); - } - } - } - - void fieldLast() { - // If the user has opted to have the user be able to change - // time zones then allow the next field to be the time zone field - if (this.allowedTimezones == null) { - if (Calendar.ZONE_OFFSET == getCalendarField( - field[field.length - 1])) { - setActiveField(field.length - 2); - } else { - setActiveField(field.length - 1); - } - } else { - // allowed time zones have been set, so let the user edit it - setActiveField(field.length - 1); - } - } - - /** - * Sets the active field to the next field; wraps if necessary and sets to - * last field if there is no current active field - */ - void fieldNext() { - fieldNext(false); - } - - /** - * Sets the active field to the next field; wraps if necessary and sets to - * last field if there is no current active field - * - * @param If - * true, the text update will be asynchronous (for changes to - * text selection) - */ - void fieldNext(boolean async) { - if (activeField >= 0 && activeField < field.length - 1) { - // If the user has opted to have the user be able to change - // time zones then allow the next field to be the time zone field - if (this.allowedTimezones == null) { - if (Calendar.ZONE_OFFSET == getCalendarField( - field[activeField + 1])) { - if (activeField < field.length - 2) { - setActiveField(activeField + 2); - } else { - setActiveField(0); - } - } else { - setActiveField(activeField + 1); - } - } else { - // allowed time zones have been set, so let the user edit it - setActiveField(activeField + 1); - } - } else { - // If the user has opted to have the user be able to change - // time zones then allow the next field to be the time zone field - if (this.allowedTimezones == null) { - if (Calendar.ZONE_OFFSET == getCalendarField(field[0])) { - setActiveField(1); - } else { - setActiveField(0); - } - } else { - // allowed time zones have been set, so let the user edit it - setActiveField(0); - } - } - updateText(async); - } - - /** - * Sets the active field to the previous field; wraps if necessary and sets - * to first field if there is no current active field - */ - private void fieldPrev() { - fieldPrev(false); - } - - /** - * Sets the active field to the previous field; wraps if necessary and sets - * to first field if there is no current active field - * - * @param If - * true, the text update will be asynchronous (for changes to - * text selection) - */ - void fieldPrev(boolean async) { - if (activeField > 0 && activeField < field.length) { - // If the user has opted to have the user be able to change - // time zones then allow the next field to be the time zone field - if (this.allowedTimezones == null) { - if (Calendar.ZONE_OFFSET == getCalendarField( - field[activeField - 1])) { - if (activeField > 1) { - setActiveField(activeField - 2); - } else { - setActiveField(field.length - 1); - } - } else { - setActiveField(activeField - 1); - } - } else { - // allowed time zones have been set, so let the user edit it - setActiveField(activeField - 1); - } - } else { - // If the user has opted to have the user be able to change - // time zones then allow the next field to be the time zone field - if (this.allowedTimezones == null) { - - if (Calendar.ZONE_OFFSET == getCalendarField( - field[field.length - 1])) { - setActiveField(field.length - 2); - } else { - setActiveField(field.length - 1); - } - } else { - // allowed time zones have been set, so let the user edit it - setActiveField(field.length - 1); - } - } - updateText(async); - } - - private boolean fieldRoll(final int calendarField, final int rollAmount, - final int style) { - if (!getEditable()) { - return false; - } - - long backup = calendar.getTimeInMillis(); - - if (calendarField == Calendar.ZONE_OFFSET - && this.allowedTimezones != null) { - boolean timeZoneSet = false; - for (int idx = 0; idx < this.allowedTimezones.length; idx++) { - TimeZone activeTimeZone = this.getTimeZone(); - if (activeTimeZone.getID() == this.allowedTimezones[idx] - .getID()) { - if (rollAmount < 0) { - if (idx == 0) { - this.setTimeZone( - this.allowedTimezones[this.allowedTimezones.length - - 1]); - } else { - this.setTimeZone(this.allowedTimezones[idx - 1]); - } - } else if (rollAmount > 0) { - if (idx == this.allowedTimezones.length - 1) { - this.setTimeZone(this.allowedTimezones[0]); - } else { - this.setTimeZone(this.allowedTimezones[idx + 1]); - } - } - timeZoneSet = true; - break; - } - } - if (!timeZoneSet) { - this.setTimeZone(this.allowedTimezones[0]); - } - } else { - if ((this.style & CDT.ADD_ON_ROLL) != 0) { - calendar.add(calendarField, rollAmount); - } else { - if (calendarField == Calendar.YEAR - && calendar.get(Calendar.YEAR) == 1 && rollAmount < 0) { - return false; - } - calendar.roll(calendarField, rollAmount); - } - } - - if (!DatePicker.isValidDate(calendar, minDate, maxDate)) { - calendar.setTimeInMillis(backup); - return false; - } - if (selection.length > 0) { - selection[0] = calendar.getTime(); - } - updateText(); - updatePicker(); - fireSelectionChanged(calendarField); - - return true; - } - - /** - * Sets the given calendar field to the given value.
- * NOTE: This is NOT the active field but a field in the "calendar" - * variable. - * - * @param calendarField - * the field of calendar to set - * @param value - * the value to set it to - * @param style - * the of set to perform; if the value is valid for the given - * calendarField then this has no affect, otherwise it will take - * an action according to this style int: - *
    - *
  • DISCARD: the value will be discarded and the method - * returns without performing and action
  • - *
  • WRAP: if value is higher than its maximum it will be set - * to its minimum, and visa versa
  • - *
  • BLOCK: if value is higher than its maximum it will be set - * to its maximum, and visa versa
  • - *
- * @return true if the field was set, false otherwise (as is possible with a - * DISCARD style) - */ - private boolean fieldSet(int calendarField, int value, int style) { - if (!getEditable()) { - return false; - } - if (calendarField >= 0) { - if (value > calendar.getActualMaximum(calendarField)) { - if (style == DISCARD) { - return false; - } else if (style == WRAP) { - value = calendar.getActualMinimum(calendarField); - } else if (style == BLOCK) { - value = calendar.getActualMaximum(calendarField); - } - } else if (value < calendar.getActualMinimum(calendarField)) { - if (style == DISCARD) { - return false; - } else if (style == WRAP) { - value = calendar.getActualMaximum(calendarField); - } else if (style == BLOCK) { - value = calendar.getActualMinimum(calendarField); - } - } - - Calendar tmp = (Calendar) calendar.clone(); - tmp.set(calendarField, value); - tmp.getTime(); // call to set the Fields in the Calendar - - if (!DatePicker.isValidDate(tmp, getMinDate(), getMaxDate())) { - return false; - } - - calendar.set(calendarField, value); - if (selection.length > 0) { - selection[0] = calendar.getTime(); - } - updateText(); - updatePicker(); - fireSelectionChanged(calendarField); - } - return true; - } - - /** - *

- * Notifies listeners that the selection for this CDateTime has changed - *

- *

- * This will fire both a regular selection event, and a default selection - * event. - *

- *

- * The data field is populated by {@link #getSelectedDates()}. - *

- */ - void fireSelectionChanged() { - fireSelectionChanged(false); - } - - void fireSelectionChanged(boolean defaultSelection) { - if (defaultSelection && isOpen()) { - setOpen(false); - } - Event event = new Event(); - event.data = getSelection(); - notifyListeners(SWT.Selection, event); - if (defaultSelection) { - notifyListeners(SWT.DefaultSelection, event); - } - } - - /** - *

- * Notifies listeners that a field of the selected date for this CDateTime - * has changed - *

- *

- * Note that this is only valid when {@link #singleSelection} is true, and - * will only fire a regular selection event (not a default selection event) - *

- *

- * The data field is populated by {@link #getSelection()} and the detail - * field holds the field which was changed. - *

- * - * @param field - * the Calendar Field which caused the change, or -1 if - * setTime was called (thus setting all Calendar - * Fields) - */ - void fireSelectionChanged(int field) { - Event event = new Event(); - event.data = getSelection(); - event.detail = field; - if (this.field.length == 1) { - if (isOpen()) { - setOpen(false); - } - notifyListeners(SWT.Selection, event); - notifyListeners(SWT.DefaultSelection, event); - } else { - notifyListeners(SWT.Selection, event); - } - } - - VButton getButtonWidget() { - return button; - } - - /** - * Gets the calendar field corresponding to the active field, if there is - * one. - * - * @return an int representing the calendar field, -1 if there isn't one. - */ - int getCalendarField() { - return hasField(activeField) ? getCalendarField(field[activeField]) - : -1; - } - - int getCalendarField(Field field) { - int cf = field.getCalendarField(); - if (cf < 0) { - if (field.toString().indexOf("hour 1") > -1) { //$NON-NLS-1$ - cf = Calendar.HOUR; - } else if (field.toString().contains("zone")) { //$NON-NLS-1$ - cf = Calendar.ZONE_OFFSET; - } else if (field.toString().contains("hour of day 1")) { //$NON-NLS-1$ - cf = Calendar.HOUR_OF_DAY; - } - } - return cf; - } - - Calendar getCalendarInstance() { - return getCalendarInstance(calendar.getTimeInMillis()); - } - - /** - *

- * WARNING: Experimental API - this method may be removed in future - * versions - *

- * Get a new instance of Calendar that is initialized with the timezone and - * locale of this CDateTime, and set to the given date. - * - * @param date - * the date that the Calendar will be set to, or null for the - * current system time - * @return a new instance of Calendar - */ - public Calendar getCalendarInstance(Date date) { - if (date == null) { - return getCalendarInstance(System.currentTimeMillis()); - } else { - return getCalendarInstance(date.getTime()); - } - } - - /** - *

- * WARNING: Experimental API - this method may be removed in future - * versions - *

- * Get a new instance of Calendar that is initialized with the timezone and - * locale of this CDateTime, and set to the given date. - * - * @param date - * the date, in millis, that the Calendar will be set to - * @return a new instance of Calendar - */ - public Calendar getCalendarInstance(long date) { - Calendar cal = Calendar.getInstance(timezone, locale); - cal.setTimeInMillis(date); - return cal; - } - - Date getCalendarTime() { - return calendar.getTime(); - } - - long getCalendarTimeInMillis() { - return calendar.getTimeInMillis(); - } - - @Override - public boolean getEditable() { - return !panel.hasStyle(SWT.READ_ONLY); - } - - /** - * The locale currently in use by this CDateTime. - * - * @return the locale - * @see #setLocale(Locale) - */ - public Locale getLocale() { - return locale; - } - - /** - * Get the text which will be shown when the selection is set to null. Note - * that this will be equal to the default null text for the given locale - * unless the null text has been explicitly set using - * {@link #setNullText(String)} - * - * @return the text shown when the selection is null - * @see #setNullText(String) - */ - public String getNullText() { - if (nullText == null) { - if (isDate) { - return Resources.getString("null_text.date", locale); //$NON-NLS-1$ - } else { - return Resources.getString("null_text.time", locale); //$NON-NLS-1$ - } - } - return nullText; - } - - CDateTimePainter getPainter() { - if (painter == null) { - setPainter(new CDateTimePainter()); - } - return painter; - } - - /** - * Get the pattern of this CDateTime as used to set its format. If the - * format was NOT set using setFormat(String) this will return - * null. - * - * @return the pattern, null if there isn't one - * @see SimpleDateFormat - * @see #setFormat(int) - * @see #setPattern(String) - */ - public String getPattern() { - return pattern; - } - - /** - * Get the current selection of this CDateTime widget, or null if there is - * no selection. - * - * @return the current selection - */ - public Date getSelection() { - return hasSelection() ? selection[0] : null; - } - - @Override - public int getStyle() { - return style; - } - - @Override - public String getText() { - return checkText() ? text.getText() : null; - } - - VNative getTextWidget() { - return text; - } - - /** - * The timezone currently in use by this CDateTime. - * - * @return the timezone - * @see #setTimeZone(String) - * @see #setTimeZone(TimeZone) - */ - public TimeZone getTimeZone() { - return timezone; - } - - /** - * The Key event handler - * - * @param event - * the event - */ - void handleKey(Event event) { - if (event.stateMask != 0 && event.stateMask != SWT.SHIFT) { - return; - } - if ('\r' == event.keyCode || SWT.KEYPAD_CR == event.keyCode) { - fieldNext(); - fireSelectionChanged(true); - } else if (SWT.BS == event.keyCode || SWT.DEL == event.keyCode) { - event.doit = false; - setSelection((Date) null); - fireSelectionChanged(); - } else if (!hasField(activeField) && !hasSelection()) { - event.doit = false; - } else { - switch (event.keyCode) { - case '-': - case SWT.KEYPAD_SUBTRACT: - fieldAdjust(-1); - break; - case '=': - case '+': - case SWT.KEYPAD_ADD: - fieldAdjust(1); - break; - case SWT.BS: - if (editField != null) { - editField.removeLastCharacter(); - } - break; - case SWT.CR: - fieldNext(); - fireSelectionChanged(); - break; - case SWT.ARROW_DOWN: - fieldAdjust(-1); - updateText(true); - break; - case SWT.ARROW_UP: - fieldAdjust(1); - updateText(true); - break; - case SWT.ARROW_LEFT: - fieldPrev(true); - break; - case SWT.ARROW_RIGHT: - fieldNext(true); - break; - case SWT.ESC: - if (contentShell != null) { - event.doit = false; - if (selection.length > 0 && selection[0] != cancelDate) { - setSelection(cancelDate); - fireSelectionChanged(); - } - setOpen(false); - } - break; - default: - if (hasField(activeField) && activeField + 1 < separator.length - && String.valueOf(event.character) - .equals(separator[activeField + 1])) { - fieldNext(); - } else if (!hasSelection() - && String.valueOf(event.character).matches("[0-9]")) { //$NON-NLS-1$ - fieldAdjust(0); - fieldFirst(); - } - } - } - } - - /** - * The Travers event handler. Note that ARROW_UP and ARROW_DOWN are handled - * in the handleKey method. - * - * @param event - * the event - */ - void handleTraverse(Event event) { - boolean allowTimeZoneEdit = this.allowedTimezones != null; - - switch (event.detail) { - case SWT.TRAVERSE_ARROW_NEXT: - if (event.keyCode == SWT.ARROW_RIGHT) { - fieldNext(); - } else if (event.keyCode == SWT.ARROW_DOWN) { - fieldAdjust(-1); - } - break; - case SWT.TRAVERSE_ARROW_PREVIOUS: - if (event.keyCode == SWT.ARROW_LEFT) { - fieldPrev(); - } else if (event.keyCode == SWT.ARROW_UP) { - fieldAdjust(1); - } - break; - case SWT.CR: - fieldNext(); - fireSelectionChanged(); - break; - case SWT.TRAVERSE_TAB_NEXT: - if (tabStops && hasSelection()) { - // if we are at the last field, allow the tab out of the control - // the last field is also considered to be the 2nd to last if - // the last is a time zone - // we now check if the control allows time zone editing - if (activeField == field.length - 1 - || activeField == field.length - 2 - && Calendar.ZONE_OFFSET == getCalendarField( - field[field.length - 1]) - && !allowTimeZoneEdit) { - event.doit = true; - } else { - event.doit = false; - if (activeField < 0) { - fieldPrev(); - } else { - fieldNext(); - } - } - } - break; - case SWT.TRAVERSE_TAB_PREVIOUS: - if (tabStops && hasSelection()) { - // if we are at the 1st field, allow the tab out of the control - // the 1st field is also considered to the the 2nd if the 1st - // is a time zone - if (activeField == 0 || activeField == 1 - && Calendar.ZONE_OFFSET == getCalendarField(field[0]) - && !allowTimeZoneEdit) { - event.doit = true; - } else { - event.doit = false; - if (activeField < 0) { - fieldNext(); - } else { - fieldPrev(); - } - } - } - break; - default: - } - } - - /** - * Determines if the given field number is backed by a real field. - * - * @param field - * the field number to check - * @return true if the given field number corresponds to a field in the - * field array - */ - private boolean hasField(int field) { - return field >= 0 && field <= this.field.length; - } - - /** - * Return true if this CDateTime has one or more dates selected; - * - * @return true if a date is selected, false otherwise - */ - public boolean hasSelection() { - return selection.length > 0; - } - - private void init(int style) { - this.style = style; - locale = Locale.getDefault(); - try { - timezone = TimeZone.getDefault(); - } catch (Exception e) { - timezone = TimeZone.getTimeZone("GMT"); //$NON-NLS-1$ - } - calendar = Calendar.getInstance(this.timezone, this.locale); - calendar.setTime(new Date()); - tabStops = (style & CDT.TAB_FIELDS) != 0; - singleSelection = (style & CDT.SIMPLE) == 0 || (style & CDT.MULTI) == 0; - - setFormat(style); - - if (isSimple()) { - return; - } - if (isDropDown()) { - if ((style & CDT.BUTTON_AUTO) != 0) { - setButtonVisibility(BaseCombo.BUTTON_AUTO); - } else { - setButtonVisibility(BaseCombo.BUTTON_ALWAYS); - } - } else { - setButtonVisibility(BaseCombo.BUTTON_NEVER); - if ((style & CDT.SPINNER) != 0) { - int sStyle = SWT.VERTICAL; - if (gtk && (style & CDT.BORDER) != 0) { - sStyle |= SWT.BORDER; - } - spinner = VNative.create(Spinner.class, panel, sStyle); - if (win32) { - spinner.setBackground(text.getControl().getBackground()); - } - spinner.getControl().setMinimum(0); - spinner.getControl().setMaximum(50); - spinner.getControl().setDigits(1); - spinner.getControl().setIncrement(1); - spinner.getControl().setPageIncrement(1); - spinner.getControl().setSelection(25); - spinner.getControl().addFocusListener(new FocusAdapter() { - @Override - public void focusGained(FocusEvent e) { - internalFocusShift = true; - setFocus(); - internalFocusShift = false; - } - }); - spinner.getControl().addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - if (e.button == 2) { - fieldNext(); - } - } - }); - spinner.getControl() - .addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (VTracker.getMouseDownButton() != 2) { - if (spinner.getControl() - .getSelection() > 25) { - fieldAdjust(1); - } else { - fieldAdjust(-1); - } - spinner.getControl().setSelection(25); - } - } - }); - panel.setLayout(new SpinnerLayout()); - } - } - - updateText(); - activeField = -5; - setActiveField(FIELD_NONE); - - if (checkText()) { - addTextListener(); - } - } - - boolean isSelected(Date date) { - for (Date d : selection) { - if (d.equals(date)) { - return true; - } - } - return false; - } - - boolean isSingleSelection() { - return singleSelection; - } - - /** - * Determine whether the provided field is the most precise field. - * According to the used pattern, e.g. - *
    - *
  • dd.mm.yyyy - *
  • MMMM yyyy - *
  • yyyy - *
- * the date picker provides the panels for selecting a day, month or year - * respectively. The panel should close itself and set the selection in the - * CDateTime field when the user selects the most precise field. The - * constants from the {@link Calendar} class may be used to determine the - * most precise field: - *
    - *
  • {@link Calendar#YEAR} -> 1 - *
  • {@link Calendar#MONTH} -> 2 - *
  • {@link Calendar#DATE} -> 5 - *
- * e.g. the highest constant is the closing field. - * - * @param calendarField - * The calendar field identifying a pattern field - * @return true if the highest pattern field - */ - boolean isClosingField(int calendarField) { - // find the "highest" constant in the pattern fields - int i = Integer.MIN_VALUE; - for (Field f : field) { - i = Math.max(i, f.getCalendarField()); - } - // compare the highest constant with the field - if (i == calendarField) { - return true; - } - return false; - } - - @Override - protected void postClose(Shell popup) { - disposePicker(); - } - - /** - * Removes the listener from the collection of listeners who will be - * notified when the receiver's selection changes. - * - * @param listener - * the listener which should no longer be notified - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(SelectionListener listener) { - if (listener != null) { - TypedListener l = new TypedListener(listener); - removeListener(SWT.Selection, l); - removeListener(SWT.DefaultSelection, l); - } - } - - /** - * Removes the textListener for the appropriate SWT events to handle - * incrementing fields. - */ - protected void removeTextListener() { - Text control = text.getControl(); - control.removeListener(SWT.KeyDown, textListener); - control.removeListener(SWT.MouseDown, textListener); - control.removeListener(SWT.MouseWheel, textListener); - control.removeListener(SWT.MouseUp, textListener); - control.removeListener(SWT.Verify, textListener); - text.removeListener(SWT.Traverse, textListener); - } - - /** - * Sets the active field, which may or may not be a real field (it may also - * be FIELD_NONE) - * - * @param field - * the field to be set active - * @see CDateTime#hasField(int) - */ - private void setActiveField(int field) { - if (activeField != field) { - commitEditField(); - editField = null; - activeField = field; - } - } - - /** - *

- * WARNING: Experimental API - this method may be removed in future - * versions - *

- * Sets the builder that this CDateTime widget will use to build its - * graphical selector to the given builder, or to a default builder if the - * given builder is null. - * - * @param builder - * the builder to use, or null to use a default builder - */ - public void setBuilder(CDateTimeBuilder builder) { - this.builder = builder; - this.minDate = builder.getMinDate(); - this.maxDate = builder.getMaxDate(); - - if (picker != null) { - disposePicker(); - createPicker(); - } - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.nebula.cwt.base.BaseCombo#setButtonImage(org.eclipse.swt. - * graphics.Image) - */ - @Override - public void setButtonImage(Image image) { - super.setButtonImage(image); - } - - @Override - protected boolean setContentFocus() { - if (checkPicker()) { - internalFocusShift = true; - boolean result = picker.setFocus(); - internalFocusShift = false; - return result; - } - return false; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.nebula.cwt.base.BaseCombo#setEditable(boolean) - */ - @Override - public void setEditable(boolean editable) { - super.setEditable(editable); - if (checkPicker()) { - if (picker instanceof DatePicker) { - ((DatePicker) picker).setEditable(editable); - } else { - picker.setActivatable(editable); - } - } - } - - private boolean checkPicker() { - return picker != null && !picker.isDisposed(); - } - - /** - * Set the date and time format of this CDateTime uses style constants which - * correspond to the various forms of DateFormat.getXxxInstance(int). - *
Valid Styles:
- *
DATE_SHORT, DATE_MEDIUM, DATE_LONG, TIME_SHORT, TIME_MEDIUM
- *

- * Styles are bitwise OR'ed together, but only one "DATE" and one "TIME" may - * be set at a time. - *

- * Examples:
- * setFormat(CDT.DATE_LONG);
- * setFormat(CDT.DATE_SHORT | CDT.TIME_MEDIUM);
- * - * @param format - * the bitwise OR'ed Date and Time format to be set - * @throws IllegalArgumentException - * @see #getPattern() - * @see #setPattern(String) - */ - public void setFormat(int format) throws IllegalArgumentException { - int dateStyle = (format & CDT.DATE_SHORT) != 0 ? DateFormat.SHORT - : (format & CDT.DATE_MEDIUM) != 0 ? DateFormat.MEDIUM - : (format & CDT.DATE_LONG) != 0 ? DateFormat.LONG : -1; - int timeStyle = (format & CDT.TIME_SHORT) != 0 ? DateFormat.SHORT - : (format & CDT.TIME_MEDIUM) != 0 ? DateFormat.MEDIUM : -1; - String str = null; - if (dateStyle != -1 && timeStyle != -1) { - str = ((SimpleDateFormat) DateFormat.getDateTimeInstance(dateStyle, - timeStyle, locale)).toPattern(); - } else if (dateStyle != -1) { - str = ((SimpleDateFormat) DateFormat.getDateInstance(dateStyle, - locale)).toPattern(); - } else if (timeStyle != -1) { - str = ((SimpleDateFormat) DateFormat.getTimeInstance(timeStyle, - locale)).toPattern(); - } else if (pattern == null) { // first call, so set to default - format = CDT.DATE_SHORT; - str = ((SimpleDateFormat) DateFormat - .getDateInstance(DateFormat.SHORT, locale)).toPattern(); - } - if (str != null) { - this.format = format; - setPattern(str); - } - } - - /** - * Sets the Locale to be used by this CDateTime and causes all affected - * attributes to be updated
- * If the provided locale is the same as the current locale then this method - * simply returns. If the provided Locale is null then this CDateTime will - * use the system's default locale.
- * If this CDateTime is of style DROP_DOWN then - * the associated CDateTime will be set to the same locale. - * - * @param locale - * the Locale, or null to use the system's default - * @see #getLocale() - */ - public void setLocale(Locale locale) { - if (locale == null) { - locale = Locale.getDefault(); - } - if (!this.locale.equals(locale)) { - this.locale = locale; - if (format > 0) { - setFormat(format); - } else { - setPattern(pattern); - } - updateNullText(); - } - } - - @Override - protected void setModifyEventProperties(Event e) { - e.data = calendar.getTime(); - } - - /** - * Set the text to be shown when the selection is null. Passing null into - * this method will cause the CDateTime widget to use a default null text - * for the given locale. - * - * @param text - */ - public void setNullText(String text) { - defaultNullText = false; - nullText = text; - updateText(); - } - - @Override - public void setOpen(boolean open) { - setOpen(open, null); - } - - @Override - public void setOpen(boolean open, Runnable callback) { - if (open) { - cancelDate = getSelection(); - createPicker(); - } else { - cancelDate = null; - } - super.setOpen(open, callback); - if (hasSelection()) { - show(getSelection()); - } - } - - /** - *

- * WARNING: Experimental API - this method may be removed in future - * versions - *

- * Sets the painter that this CDateTime widget will use to paint its - * graphical selector to the given painter, or to a default painter if the - * given painter is null. - * - * @param painter - * the painter to use, or null to use a default painter - */ - public void setPainter(CDateTimePainter painter) { - if (painter != null) { - painter.setCDateTime(this); - } - this.painter = painter; - } - - /** - * Set the style of this CDateTime to work with dates and / or times as - * determined by the given pattern. This will set the fields shown in the - * text box and, if DROP_DOWN style is set, the fields of the - * drop down component.
- * This method is backed by an implementation of SimpleDateFormat, and as - * such, any string pattern which is valid for SimpleDateFormat may be used. - * Examples (US Locale):
- * setPattern("MM/dd/yyyy h:mm a");
- * setPattern("'Meeting @' h:mm a 'on' EEEE, MMM dd, - * yyyy");
- * - * @param pattern - * the pattern to use, if it is invalid, the original is restored - * @throws IllegalArgumentException - * @see SimpleDateFormat - * @see #getPattern() - * @see #setFormat(int) - */ - public void setPattern(String pattern) throws IllegalArgumentException { - this.allowedTimezones = null; - if (isOpen()) { - setOpen(false); - } - df = new SimpleDateFormat(pattern, locale); - df.setTimeZone(timezone); - if (updateFields()) { - this.pattern = pattern; - this.format = -1; - boolean wasDate = isDate; - boolean wasTime = isTime; - isDate = isTime = false; - calendarFields = new int[field.length]; - for (int i = 0; i < calendarFields.length; i++) { - calendarFields[i] = getCalendarField(field[i]); - switch (calendarFields[i]) { - case Calendar.AM_PM: - case Calendar.HOUR: - case Calendar.HOUR_OF_DAY: - case Calendar.MILLISECOND: - case Calendar.MINUTE: - case Calendar.SECOND: - case Calendar.ZONE_OFFSET: - isTime = true; - break; - case Calendar.DAY_OF_MONTH: - case Calendar.DAY_OF_WEEK: - case Calendar.DAY_OF_WEEK_IN_MONTH: - case Calendar.DAY_OF_YEAR: - case Calendar.ERA: - case Calendar.MONTH: - case Calendar.WEEK_OF_MONTH: - case Calendar.WEEK_OF_YEAR: - case Calendar.YEAR: - isDate = true; - break; - default: - break; - } - } - if (checkButton() && (isDate != wasDate || isTime != wasTime)) { - if (defaultButtonImage) { - if (isDate && isTime) { - doSetButtonImage(Resources.getIconCalendarClock()); - } else if (isDate) { - doSetButtonImage(Resources.getIconCalendar()); - } else { - doSetButtonImage(Resources.getIconClock()); - } - } - updateNullText(); - } - if (checkText()) { - updateText(); - } - if (isSimple()) { - disposePicker(); - createPicker(); - } - } else { - throw new IllegalArgumentException( - "Problem setting pattern: \"" + pattern + "\""); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - void setScrollable(boolean scrollable) { - this.scrollable = scrollable; - if (isSimple() && !scrollable) { - if (picker != null && picker instanceof DatePicker) { - updatePicker(); - } - } - } - - /** - * Set the selection for this CDateTime to that of the provided - * Date object.
- * - * @param selection - * the new selection, or null to clear the selection - */ - public void setSelection(Date selection) { - if (getEditable()) { - if (selection == null) { - this.selection = new Date[0]; - } else if (DatePicker.isValidDate(getCalendarInstance(selection), - minDate, maxDate)) { - this.selection = new Date[] { selection }; - } - } - if (singleSelection && this.selection.length > 0) { - show(selection); - } else { - updateText(); - updatePicker(); - } - } - - /** - * Sets the timezone to the timezone specified by the given zoneID, or to - * the system default if the given zoneID is null. If the give zoneID cannot - * be understood, then the timezone will be set to GMT. - * - * @param zoneID - * the id of the timezone to use, or null to use the system - * default - * @see #setTimeZone(TimeZone) - */ - public void setTimeZone(String zoneID) { - if (zoneID == null) { - setTimeZone((TimeZone) null); - } else { - setTimeZone(TimeZone.getTimeZone(zoneID)); - } - } - - /** - * Sets the timezone to the given timezone, or to the system's default - * timezone if the given timezone is null. - * - * @param zone - * the timezone to use, or null to use the system default - * @see #setTimeZone(String) - */ - public void setTimeZone(TimeZone zone) { - if (zone == null) { - timezone = TimeZone.getDefault(); - } - if (!this.timezone.equals(zone)) { - this.timezone = zone; - calendar.setTimeZone(this.timezone); - df.setTimeZone(this.timezone); - updateText(); - } - } - - /** - * Shows the given date if it can be shown by the selector. In other words, - * for graphical selectors such as a calendar, the visible range of time is - * moved so that the given date is visible. - * - * @param date - * the date to show - */ - public void show(Date date) { - if (date == null) { - calendar.setTime(new Date()); - } else { - calendar.setTime(date); - } - updateText(); - updatePicker(); - } - - /** - * Show the selection if it can be shown by the selector. Has no affect if - * there is no selection. - * - * @see #show(Date) - */ - public void showSelection() { - if (selection.length > 0) { - show(selection[0]); - } - } - - @Override - public String toString() { - return getClass().getSimpleName() + " {" + getCalendarTime() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * inspects all of the calendar fields in the field array to - * determine what style is appropriate and then sets that style to the - * picker using the setPickerStyle method.
- */ - private boolean updateFields() { - Field[] bak = new Field[field == null ? 0 : field.length]; - if (bak.length > 0) { - System.arraycopy(field, 0, bak, 0, field.length); - } - - AttributedCharacterIterator aci = df - .formatToCharacterIterator(calendar.getTime()); - field = new Field[aci.getAllAttributeKeys().size()]; - separator = new String[field.length + 1]; // there can be a separator - // before and after - int i = 0; - Object last = null; - for (char c = aci.first(); c != CharacterIterator.DONE; c = aci - .next()) { - Object[] oa = aci.getAttributes().keySet().toArray(); - if (oa.length > 0) { - if (oa[0] != last && i < field.length) { - if (getCalendarField((Field) oa[0]) < 0) { - if (bak.length > 0) { - field = new Field[bak.length]; - System.arraycopy(bak, 0, field, 0, bak.length); - } - return false; - } else { - field[i] = (Field) oa[0]; - last = oa[0]; - } - i++; - } - } else { - if (separator[i] == null) { - separator[i] = String.valueOf(c); - } - } - } - - df.setLenient(false); - setActiveField(FIELD_NONE); - return true; - } - - private void updateNullText() { - if (defaultNullText) { - if (isDate) { - nullText = Resources.getString("null_text.date", locale); //$NON-NLS-1$ - } else { - nullText = Resources.getString("null_text.time", locale); //$NON-NLS-1$ - } - if (!hasSelection()) { - updateText(); - } - } - } - - /** - * tell the picker to update its view of the selection and reference time - */ - private void updatePicker() { - if (picker != null) { - if (picker instanceof DatePicker) { - ((DatePicker) picker).updateView(); - } else if (picker instanceof AnalogTimePicker) { - ((AnalogTimePicker) picker).updateView(); - } else if (picker instanceof DiscreteTimePicker) { - ((DiscreteTimePicker) picker).updateView(); - } - } - } - - /** - * This is the only way that text is set to the text box.
- * The selection of the text in the text box is also set here (the active - * field is selected) as well as if a field is being edited, it's "edit - * text" is inserted for display. The getSelection property of - * CDateTime remains unchanged. - */ - private void updateText() { - updateText(false); - } - - /** - * This is the only way that text is set to the text box.
- * The selection of the text in the text box is also set here (the active - * field is selected) as well as if a field is being edited, it's "edit - * text" is inserted for display. The getSelection property of - * CDateTime remains unchanged. - * - * @param async - * If true, this operation will be performed asynchronously (for - * changes to text selection) - */ - private void updateText(boolean async) { - // TODO: save previous state and only update on changes...? - - String buffer = hasSelection() ? df.format(getSelection()) - : getNullText(); - - int s0 = 0; - int s1 = 0; - - if (!hasSelection()) { - s0 = 0; - s1 = buffer.length(); - } else if (activeField >= 0 && activeField < field.length) { - AttributedCharacterIterator aci = df - .formatToCharacterIterator(getSelection()); - for (char c = aci.first(); c != CharacterIterator.DONE; c = aci - .next()) { - if (aci.getAttribute(field[activeField]) != null) { - s0 = aci.getRunStart(); - s1 = aci.getRunLimit(); - if (editField != null) { - String str = editField.toString(); - buffer = buffer.substring(0, s0) + str - + buffer.substring(s1); - int oldS1 = s1; - s1 = s0 + str.length(); - textSelectionOffset.x = Math.min(oldS1, s1); - textSelectionOffset.y = oldS1 - s0 - str.length(); - } else { - textSelectionOffset.x = buffer.length() + 1; - textSelectionOffset.y = 0; - } - break; - } - } - } else { - setActiveField(FIELD_NONE); - } - - final String string = buffer; - final int selStart = s0; - final int selEnd = s1; - - Runnable runnable = () -> { - if (text != null && !text.isDisposed()) { - if (!string.equals(text.getText())) { - text.getControl().removeListener(SWT.Verify, textListener); - text.setText(string); - text.getControl().addListener(SWT.Verify, textListener); - } - if ((text.getControl().getStyle() & SWT.READ_ONLY) == 0) { - text.getControl().setSelection(selStart, selEnd); - } - } - }; - - if (async) { - getDisplay().asyncExec(runnable); - } else { - getDisplay().syncExec(runnable); - } - } - - /** - * The Verify Event handler.
- * EVERYTHING is blocked via this handler (Event.doit is set to - * false). Depending upon the input, a course of action is determined and - * the displayed text is updated via the updateText() method. - *
- * This method implements the following logic: If the event is a paste, the - * pasted text is parsed for the entire date/time selection; if this parse - * is successful, the result is committed to the selection property and is - * displayed; otherwise, it is discarded. One-character pastes are discarded - * without parsing. When user types characters one by one, all non-digits - * are discarded (if they have effects, they have already been processed by - * other event handlers) while digits are added to - * this.editField without affecting the selection. Once - * this.editField reaches its capacity for the active field, - * its contents are attempted to be committed. If the commit is successful, - * focus switches to the next field of CDateTime. Otherwise, the contents of - * this.editField are discarded and the previous value of the - * selection (before user started typing in this field) is restored; focus - * stays in the same field. Example: if the seconds field contains - * "23", and user types 8 in the seconds field, "08" is shown on screen - * while getSelection still returns 23. If user types 9 after that, the - * field reaches its capacity, the attempt to commit 89 seconds fails, and - * 23 gets restored on screen. - * - * @param e - * the event - * @see CDateTime#updateText() - */ - void verify(Event e) { - // we don't want to reprocess the event - if (e.doit == false) { - return; - } - - e.doit = false; - if (field.length == 0 || activeField == FIELD_NONE || e.text == null) { - return; - } - - char c = e.character; - if (e.text.length() == 1 && String.valueOf(c).equals(e.text) - && Character.isDigit(c) || e.text.length() > 1) { - if (e.text.length() == 1) { - if (editField == null) { - int cf = getCalendarField(); - if (cf >= 0) { - int digits; - switch (cf) { - case Calendar.YEAR: - digits = 4; - break; - case Calendar.DAY_OF_YEAR: - digits = 3; - break; - case Calendar.AM_PM: - case Calendar.DAY_OF_WEEK: - case Calendar.ERA: - digits = 1; - break; - case Calendar.MILLISECOND: - digits = 3; - break; - default: - digits = 2; - } - editField = new EditField(digits, calendar.get(cf)); - } else { - return; - } - } - if (editField.addChar(c)) { - if (commitEditField()) { - fieldNext(); - } else { - editField = null; - if (selection.length > 0) { - selection[0] = calendar.getTime(); - } - updateText(); - } - } - if (selection.length > 0) { - selection[0] = calendar.getTime(); - } - updatePicker(); - } else { - try { - setSelection(df.parse(e.text)); - fireSelectionChanged(); - } catch (ParseException pe) { - // do nothing - } - } - } - updateText(); - } - - /** - * @param pattern - * @param allowedTimeZones - * @throws IllegalArgumentException - */ - public void setPattern(final String pattern, - final TimeZone[] allowedTimeZones) throws IllegalArgumentException { - this.setPattern(pattern); - if (pattern.indexOf('z') != -1) { - this.allowedTimezones = allowedTimeZones; - } - } - - /** - * Returns the minimum date or null. - * - * @return Returns a clone of the minDate or null if not set. - * @since 1.4 - */ - public Calendar getMinDate() { - if (minDate == null) { - return null; - } - return (Calendar) minDate.clone(); - } - - /** - * Returns the maximum date or null. - * - * @return Returns a clone of the maxDate or null if not set. - * @since 1.4 - */ - public Calendar getMaxDate() { - if (maxDate == null) { - return null; - } - return (Calendar) maxDate.clone(); - } - - /** - * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) - */ - public void setBackground(Color color) { - super.setBackground(color); - if (spinner != null) { - spinner.setBackground(color); - } - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - public void setForeground(Color color) { - super.setForeground(color); - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @param color - * @since 1.5 - */ - public void setButtonHoverBackgroundColor(Color color) { - checkWidget(); - this.buttonHoverBackgroundColor = color; - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @param color - * @since 1.5 - */ - public void setButtonHoverBorderColor(Color color) { - checkWidget(); - this.buttonHoverBorderColor = color; - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @param color - * @since 1.5 - */ - public void setButtonSelectedBackgroundColor(Color color) { - checkWidget(); - this.buttonSelectedBackgroundColor = color; - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @param color - * @since 1.5 - */ - public void setButtonSelectedBorderColor(Color color) { - checkWidget(); - this.buttonSelectedBorderColor = color; - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @return the picker foreground color - * @since 1.5 - */ - public Color getPickerForegroundColor() { - checkWidget(); - return pickerForegroundColor; - } - - /** - * @param pickerForegroundColor - * @since 1.5 - */ - public void setPickerForegroundColor(Color pickerForegroundColor) { - checkWidget(); - this.pickerForegroundColor = pickerForegroundColor; - if (pickerForegroundColor != null && pickerPanel != null) { - pickerPanel.setForeground(pickerForegroundColor); - } - if (picker != null && pickerPanel != null && pickerPanel != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @return the picker background color - * @since 1.5 - */ - public Color getPickerBackgroundColor() { - checkWidget(); - return pickerBackgroundColor; - } - - /** - * @param pickerBackgroundColor - * @since 1.5 - */ - public void setPickerBackgroundColor(Color pickerBackgroundColor) { - checkWidget(); - this.pickerBackgroundColor = pickerBackgroundColor; - if (pickerBackgroundColor != null && pickerPanel != null) { - pickerPanel.setBackground(pickerBackgroundColor); - } - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @return the picker font - * @since 1.5 - */ - public Font getPickerFont() { - checkWidget(); - return pickerFont; - } - - /** - * @param pickerFont - * @since 1.5 - */ - public void setPickerFont(Font pickerFont) { - checkWidget(); - this.pickerFont = pickerFont; - if (pickerFont != null && pickerPanel != null) { - pickerPanel.setFont(pickerFont); - } - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @return the bg color of the button hover - * @since 1.5 - */ - public Color getButtonHoverBackgroundColor() { - checkWidget(); - return buttonHoverBackgroundColor; - } - - /** - * @return the border color of the button hover - * @since 1.5 - */ - public Color getButtonHoverBorderColor() { - checkWidget(); - return buttonHoverBorderColor; - } - - /** - * @return the selected background of the button - * @since 1.5 - */ - public Color getButtonSelectedBackgroundColor() { - checkWidget(); - return buttonSelectedBackgroundColor; - } - - /** - * @return the border color of the selected button - * @since 1.5 - */ - public Color getButtonSelectedBorderColor() { - checkWidget(); - return buttonSelectedBorderColor; - } - - /** - * @return the color of the active day - * @since 1.5 - */ - public Color getPickerActiveDayColor() { - checkWidget(); - return pickerActiveDayColor; - } - - /** - * @param pickerActiveDayColor - * @since 1.5 - */ - public void setPickerActiveDayColor(Color pickerActiveDayColor) { - checkWidget(); - this.pickerActiveDayColor = pickerActiveDayColor; - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @return the color of the inactive day - * @since 1.5 - */ - public Color getPickerInactiveDayColor() { - checkWidget(); - return pickerInactiveDayColor; - } - - /** - * @param pickerInactiveDayColor - * @since 1.5 - */ - public void setPickerInactiveDayColor(Color pickerInactiveDayColor) { - checkWidget(); - this.pickerInactiveDayColor = pickerInactiveDayColor; - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @return the color of the "today" section - * @since 1.5 - */ - public Color getPickerTodayColor() { - checkWidget(); - return pickerTodayColor; - } - - /** - * @param pickerTodayColor - * @since 1.5 - */ - public void setPickerTodayColor(Color pickerTodayColor) { - checkWidget(); - this.pickerTodayColor = pickerTodayColor; - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @return the color of the minutes - * @since 1.5 - */ - public Color getPickerMinutesColor() { - checkWidget(); - return pickerMinutesColor; - } - - /** - * @param pickerMinutesColor - * @since 1.5 - */ - public void setPickerMinutesColor(Color pickerMinutesColor) { - checkWidget(); - this.pickerMinutesColor = pickerMinutesColor; - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @return the minutes background - * @since 1.5 - */ - public Color getPickerMinutesBackgroundColor() { - checkWidget(); - return pickerMinutesBackgroundColor; - } - - /** - * @param pickerMinutesBackgroundColor - * @since 1.5 - */ - public void setPickerMinutesBackgroundColor( - Color pickerMinutesBackgroundColor) { - checkWidget(); - this.pickerMinutesBackgroundColor = pickerMinutesBackgroundColor; - if (picker != null) { - picker.updateColorsAndFont(); - } - } - - /** - * @return the foreground color of the "Ok" button - */ - public Color getOkButtonColor() { - checkWidget(); - return okButtonColor; - } - - /** - * @param okButtonColor the new foreground color of the "ok" button - */ - public void setOkButtonColor(Color okButtonColor) { - checkWidget(); - this.okButtonColor = okButtonColor; - if (okButton != null) okButton.setForeground(okButtonColor); - } - - /** - * @return the foreground color of the "Cancel" button - */ - public Color getCancelButtonColor() { - checkWidget(); - return cancelButtonColor; - } - - /** - * @param cancelButtonColor the new foreground color of the "cancel" button - */ - public void setCancelButtonColor(Color cancelButtonColor) { - checkWidget(); - this.cancelButtonColor = cancelButtonColor; - if (cancelButton != null) cancelButton.setForeground(cancelButtonColor); - } - - /** - * @return the foreground color of the "clear" button - */ - public Color getClearButtonForegroundColor() { - checkWidget(); - return clearButtonForegroundColor; - } - - /** - * @param clearButtonForegroundColor the new foreground color of the "clear" button - */ - public void setClearButtonForegroundColor( - Color clearButtonForegroundColor) { - checkWidget(); - this.clearButtonForegroundColor = clearButtonForegroundColor; - if (clearButton != null) clearButton.setForeground(clearButtonForegroundColor); - } - - /** - * @return the font of the "clear" button - */ - public Font getClearButtonFont() { - checkWidget(); - return clearButtonFont; - } - - /** - * @param clearButtonFont the new font of the "clear" button - */ - public void setClearButtonFont(Font clearButtonFont) { - checkWidget(); - this.clearButtonFont = clearButtonFont; - if (clearButton != null) clearButton.setFont(clearButtonFont); - } - -} +/**************************************************************************** + * Copyright (c) 2006-2019 Jeremy Dowdall + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Jeremy Dowdall - initial API and implementation + * Wim Jongman - https://bugs.eclipse.org/bugs/show_bug.cgi?id=362181 + * Scott Klein - https://bugs.eclipse.org/bugs/show_bug.cgi?id=370605 + * Baruch Youssin - https://bugs.eclipse.org/bugs/show_bug.cgi?id=261414 + * Doug Showell - https://bugs.eclipse.org/bugs/show_bug.cgi?id=383589 + * Bel Razom - https://bugs.eclipse.org/bugs/show_bug.cgi?id=527399 + * Stefan Nöbauer - https://bugs.eclipse.org/bugs/show_bug.cgi?id=548149 + *****************************************************************************/ + +package org.eclipse.nebula.widgets.cdatetime; + +import java.text.AttributedCharacterIterator; +import java.text.CharacterIterator; +import java.text.DateFormat; +import java.text.DateFormat.Field; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import org.eclipse.nebula.cwt.base.BaseCombo; +import org.eclipse.nebula.cwt.v.VButton; +import org.eclipse.nebula.cwt.v.VCanvas; +import org.eclipse.nebula.cwt.v.VGridLayout; +import org.eclipse.nebula.cwt.v.VLabel; +import org.eclipse.nebula.cwt.v.VLayout; +import org.eclipse.nebula.cwt.v.VNative; +import org.eclipse.nebula.cwt.v.VPanel; +import org.eclipse.nebula.cwt.v.VTracker; +import org.eclipse.nebula.widgets.cdatetime.CDT.PickerPart; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Spinner; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.TypedListener; + +/** + * The CDateTime provides both textual and graphical means selecting a + * date.
+ * As with other combo type widgets, there are three basic styles: + *
    + *
  • Text only (default)
  • + *
  • Graphical only (CDT.SIMPLE)
  • + *
  • Combo - a text selector with a drop-down graphical selector + * (CDT.DROP_DOWN)
  • + *
+ *

+ * Styles are set using the constants provided in the CDT class. + *

+ * + * @see CDT + * @since 1.5 + */ +public class CDateTime extends BaseCombo { + + /** + * A simple class used for editing a field numerically. + */ + private class EditField { + + private String buffer; + private int digits; + private int count = 0; + + EditField(int digits, int initialValue) { + this.digits = digits; + buffer = Integer.toString(initialValue); + } + + /** + * Adds a character if it is a digit; in case the field exceeds its + * capacity, the oldest character is dropped from the buffer. Non-digits + * are dropped. + * + * @param c + * @return true if the new character is a digit and with its addition + * the active field reaches or exceeds its capacity, false + * otherwise + */ + boolean addChar(char c) { + if (Character.isDigit(c)) { + buffer = count > 0 ? buffer : ""; //$NON-NLS-1$ + buffer += String.valueOf(c); + if (buffer.length() > digits) { + buffer = buffer.substring(buffer.length() - digits, + buffer.length()); + } + } + return ++count > digits - 1; + } + + int getValue() { + return Integer.parseInt(buffer); + } + + void removeLastCharacter() { + if (buffer.length() > 0) { + buffer = buffer.substring(0, buffer.length() - 1); + count--; + } + } + + void reset() { + count = 0; + } + + @Override + public String toString() { + if (buffer.length() < digits) { + char[] ca = new char[digits - buffer.length()]; + Arrays.fill(ca, '0'); + buffer = String.valueOf(ca).concat(buffer); + } + return buffer; + } + } + + /** + * The layout used for a "basic" CDateTime - when it is neither of style + * SIMPLE or DROP_DOWN - with style of SPINNER.
+ * Note that there is a spinner, but no button for this style. + */ + class SpinnerLayout extends VLayout { + + @Override + protected Point computeSize(VPanel panel, int wHint, int hHint, + boolean flushCache) { + Point size = text.computeSize(SWT.DEFAULT, SWT.DEFAULT); + + Rectangle sRect = spinner.getControl().computeTrim(0, 0, 0, 0); + int sWidth = sRect.x + sRect.width + - 2 * spinner.getControl().getBorderWidth() + 1; + + if (gtk && sWidth == 0) { + sWidth = 67; + } + + size.x += sWidth; + size.x++; + size.y += textMarginHeight; + + if (wHint != SWT.DEFAULT) { + size.x = Math.min(size.x, wHint); + } + if (hHint != SWT.DEFAULT) { + size.y = Math.min(size.y, hHint); + } + return size; + } + + @Override + protected void layout(VPanel panel, boolean flushCache) { + Rectangle cRect = panel.getClientArea(); + if (cRect.isEmpty()) { + return; + } + + Point tSize = text.getControl().computeSize(SWT.DEFAULT, + SWT.DEFAULT); + tSize.y += textMarginHeight; + + spinner.setBounds(cRect.x, cRect.y, cRect.width, tSize.y); + + Rectangle sRect = spinner.getControl().computeTrim(0, 0, 0, 0); + int sWidth = sRect.x + sRect.width + - 2 * spinner.getControl().getBorderWidth() + 1; + + if (gtk && sWidth == 0) { + sWidth = 67; + } + + tSize.x = cRect.width - sWidth; + + text.setBounds(cRect.x, cRect.y + getBorderWidth(), tSize.x, + tSize.y); + } + } + + private static final int FIELD_NONE = -1; + + private static final int DISCARD = 0; + private static final int WRAP = 1; + private static final int BLOCK = 2; + + private static int convertStyle(int style) { + int rstyle = SWT.NONE; + if ((style & CDT.DROP_DOWN) != 0) { + rstyle |= SWT.DROP_DOWN; + } + if ((style & CDT.SIMPLE) != 0) { + rstyle |= SWT.SIMPLE; + } + if ((style & CDT.READ_ONLY) != 0) { + rstyle |= SWT.READ_ONLY; + } + if ((style & CDT.BUTTON_LEFT) != 0) { + rstyle |= SWT.LEFT; + } + if ((style & CDT.TEXT_LEAD) != 0) { + rstyle |= SWT.LEAD; + } + if ((style & CDT.BORDER) != 0) { + rstyle |= SWT.BORDER; + } + if (win32) { + rstyle |= SWT.DOUBLE_BUFFERED; + } + return rstyle; + } + + VPanel picker; + + VNative spinner; + boolean internalFocusShift = false; + boolean rightClick = false; + + private Date cancelDate; + private Calendar calendar; + private Calendar minDate; + private Calendar maxDate; + + private DateFormat df; + Locale locale; + + TimeZone timezone; + Field[] field; + int activeField; + + private boolean tabStops = false; + // Store these values so that the style can be reset automatically + // to update everything if/when the locale is changed + int style; + String pattern = null; + + int format = -1; + + private CDateTimePainter painter; + + /** + * Delegates events to their appropriate handler + */ + Listener textListener = event -> { + switch (event.type) { + case SWT.FocusIn: + rightClick = false; + if (internalFocusShift) { + if (activeField < 0) { + fieldFirst(); + updateText(); + } + } else { + if (VTracker.getLastTraverse() == SWT.TRAVERSE_TAB_PREVIOUS) { + fieldLast(); + } else { + fieldFirst(); + } + updateText(); + } + break; + case SWT.FocusOut: + if (!rightClick && !internalFocusShift) { + if (commitEditField()) { + updateText(); + } else { + editField = null; + } + } + break; + case SWT.KeyDown: + handleKey(event); + break; + case SWT.MouseDown: + if (event.button == 1) { + fieldFromTextSelection(); + } else if (event.button == 2) { + fieldNext(); + } else if (event.button == 3) { + rightClick = true; + } + break; + case SWT.MouseWheel: + Control focusedControl = getDisplay().getFocusControl(); + if (getTextWidget() != null + && getTextWidget().getControl() != focusedControl) { + // Do not handle mousewheel events if the widget does not have + // focus + break; + } + if (event.count > 0) { + fieldAdjust(1); + } else { + fieldAdjust(-1); + } + event.doit = false; + break; + case SWT.MouseUp: + if (event.button == 1) { + fieldFromTextSelection(); + } + break; + case SWT.Traverse: + handleTraverse(event); + break; + case SWT.Verify: + verify(event); + break; + } + }; + private Point textSelectionOffset = new Point(0, 0); // x = selOffset start, + // y = selOffset + // amount + private EditField editField; + + private String[] separator; + private int[] calendarFields; + private boolean isTime; + private boolean isDate; + // private boolean isNull = true; + private String nullText = null; + + private boolean defaultNullText = true; + private boolean singleSelection; + + // private boolean dragSelection; + private Date[] selection = new Date[0]; + + private boolean scrollable = true; + + CDateTimeBuilder builder; + + VPanel pickerPanel; + + private TimeZone[] allowedTimezones; + + Color buttonHoverBackgroundColor, buttonHoverBorderColor; + Color buttonSelectedBackgroundColor, buttonSelectedBorderColor; + + Color pickerForegroundColor, pickerBackgroundColor; + Font pickerFont; + + Color pickerActiveDayColor, pickerInactiveDayColor, pickerTodayColor; + Color pickerMinutesColor, pickerMinutesBackgroundColor; + + Color okButtonColor, cancelButtonColor, clearButtonForegroundColor; + Font clearButtonFont; + private VButton okButton, clearButton, cancelButton; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. The current date and the + * system's default locale are used. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + */ + public CDateTime(Composite parent, int style) { + super(parent, convertStyle(style)); + init(style); + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the receiver's selection changes, by sending it one of the messages + * defined in the SelectionListener interface. + *

+ * widgetSelected is called when the selection (date/time) + * changes. widgetDefaultSelected is when ENTER is pressed the + * text box. + *

+ * The event's data field will contain the newly selected Date object.
+ * The event's detail field will contain which Calendar Field was changed + * + * @param listener + * the listener which should be notified + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(SelectionListener listener) { + if (listener != null) { + TypedListener typedListener = new TypedListener(listener); + addListener(SWT.Selection, typedListener); + addListener(SWT.DefaultSelection, typedListener); + } + } + + /** + * Adds the textListener for the appropriate SWT events to handle + * incrementing fields. + */ + protected void addTextListener() { + removeTextListener(); + + Text control = text.getControl(); + control.addListener(SWT.FocusIn, textListener); + control.addListener(SWT.FocusOut, textListener); + control.addListener(SWT.KeyDown, textListener); + control.addListener(SWT.MouseDown, textListener); + control.addListener(SWT.MouseWheel, textListener); + control.addListener(SWT.MouseUp, textListener); + control.addListener(SWT.Verify, textListener); + + text.addListener(SWT.Traverse, textListener); + } + + /** + * If a field is being edited (via keyboard), set the edit value to the + * active field of the calendar. Reset the count of the EditField so that a + * subsequent key press will overwrite its contents; + * + * @return true if the commit was successfull (the value was valid for the + * field) or there was no commit to be made (editField is null), + * false otherwise + */ + private boolean commitEditField() { + if (editField != null) { + int cf = getCalendarField(); + int val = editField.getValue(); + editField.reset(); + if (cf == Calendar.MONTH) { + val--; + } + return fieldSet(cf, val, DISCARD); + } + return true; + } + + /** + * If style is neither SIMPLE or DROP_DOWN, then this method simply returns, + * otherwise it creates the picker. + */ + private void createPicker() { + if (isSimple()) { + pickerPanel = panel; + setContent(panel.getComposite()); + } else if (isDropDown()) { + disposePicker(); + + Shell shell = getContentShell(); + int style = (isSimple() ? SWT.NONE : SWT.BORDER) + | SWT.DOUBLE_BUFFERED; + VCanvas canvas = new VCanvas(shell, style); + pickerPanel = canvas.getPanel(); + pickerPanel.setWidget(canvas); + VGridLayout layout = new VGridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 1; + pickerPanel.setLayout(layout); + setContent(pickerPanel.getComposite()); + + canvas.addListener(SWT.KeyDown, event -> { + if (SWT.ESC == event.keyCode) { + event.doit = false; + if (selection.length > 0 && selection[0] != cancelDate) { + setSelection(cancelDate); + fireSelectionChanged(); + } + setOpen(false); + } + }); + + if (field.length > 1 || isTime) { + createPickerToolbar(pickerPanel); + } + } + + if (pickerBackgroundColor != null) { + pickerPanel.setBackground(pickerBackgroundColor); + } + if (pickerForegroundColor != null) { + pickerPanel.setForeground(pickerForegroundColor); + } + if (pickerFont != null) { + pickerPanel.setFont(pickerFont); + } + + if (isDate) { + DatePicker dp = new DatePicker(this); + dp.setScrollable(scrollable); + dp.setFields(calendarFields); + dp.updateView(); + picker = dp; + } else if (isTime) { + if ((style & CDT.CLOCK_DISCRETE) != 0) { + DiscreteTimePicker dtp = new DiscreteTimePicker(this); + dtp.setFields(calendarFields); + dtp.updateView(); + picker = dtp; + } else { + AnalogTimePicker atp = new AnalogTimePicker(this); + atp.setFields(calendarFields); + atp.updateView(); + picker = atp; + } + } + + if (isDropDown()) { + picker.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, false, false)); + } + } + + private void createPickerToolbar(VPanel parent) { + VPanel tb = new VPanel(parent, SWT.NONE); + VGridLayout layout = new VGridLayout(3, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.horizontalSpacing = 2; + tb.setLayout(layout); + tb.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false)); + tb.setData(CDT.PickerPart, PickerPart.Toolbar); + + okButton = new VButton(tb, SWT.OK | SWT.NO_FOCUS); + okButton.setData(CDT.PickerPart, PickerPart.OkButton); + okButton.setToolTipText(Resources.getString("accept.text", locale)); //$NON-NLS-1$ + okButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + okButton.addListener(SWT.Selection, event -> setOpen(false)); + okButton.setHoverBackgroundColor(buttonHoverBackgroundColor); + okButton.setHoverBorderColor(buttonHoverBorderColor); + okButton.setSelectedBackgroundColor(buttonSelectedBackgroundColor); + okButton.setSelectedBorderColor(buttonSelectedBorderColor); + okButton.setForeground(okButtonColor); + + cancelButton = new VButton(tb, SWT.CANCEL | SWT.NO_FOCUS); + cancelButton.setData(CDT.PickerPart, PickerPart.CancelButton); + cancelButton.setToolTipText(Resources.getString("cancel.text", locale)); //$NON-NLS-1$ + cancelButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + cancelButton.addListener(SWT.Selection, event -> { + setSelection(cancelDate); + fireSelectionChanged(); + setOpen(false); + }); + cancelButton.setHoverBackgroundColor(buttonHoverBackgroundColor); + cancelButton.setHoverBorderColor(buttonHoverBorderColor); + cancelButton.setSelectedBackgroundColor(buttonSelectedBackgroundColor); + cancelButton.setSelectedBorderColor(buttonSelectedBorderColor); + cancelButton.setForeground(cancelButtonColor); + + clearButton = new VButton(tb, SWT.NO_FOCUS); + clearButton.setData(CDT.PickerPart, PickerPart.ClearButton); + clearButton.setText(Resources.getString("clear.text", locale)); //$NON-NLS-1$ + clearButton.setToolTipText(Resources.getString("clear.text", locale)); //$NON-NLS-1$ + clearButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + clearButton.addListener(SWT.Selection, event -> { + setOpen(false); + setSelection(null); + fireSelectionChanged(); + }); + clearButton.setForeground(clearButtonForegroundColor!=null?clearButtonForegroundColor:parent.getForeground()); + clearButton.setFont(clearButtonFont!=null?clearButtonFont:parent.getFont()); + clearButton.setHoverBackgroundColor(buttonHoverBackgroundColor); + clearButton.setHoverBorderColor(buttonHoverBorderColor); + clearButton.setSelectedBackgroundColor(buttonSelectedBackgroundColor); + clearButton.setSelectedBorderColor(buttonSelectedBorderColor); + + + VLabel sep = new VLabel(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + sep.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + } + + private void disposePicker() { + if (content != null) { + if (picker != null) { + picker.dispose(); + picker = null; + } + if (isDropDown()) { + Control c = content; + setContent(null); + c.dispose(); + if (contentShell != null) { + Display.getDefault().asyncExec(() -> { + if (contentShell != null + && !contentShell.isDisposed()) { + contentShell.dispose(); + contentShell = null; + } + }); + } + } + } + } + + /** + * Adds the given amount to the x² field, if there is one + */ + void fieldAdjust(int amount) { + if (!hasSelection()) { + if (DatePicker.isValidDate(calendar, minDate, maxDate)) { + setSelection(calendar.getTime()); + fireSelectionChanged(); + } else { + setOpen(true); + } + } else { + int cf = getCalendarField(); + if (cf >= 0) { + fieldRoll(cf, amount, WRAP); + } + } + } + + void fieldFirst() { + // If the user has opted to have the user be able to + // change time zones then allow the next field to be the + // time zone field + if (this.allowedTimezones == null) { + if (Calendar.ZONE_OFFSET == getCalendarField(field[0])) { + setActiveField(1); + } else { + setActiveField(0); + } + } else { + // allowed time zones have been set, so let the user edit it + setActiveField(0); + } + } + + /** + * Sets the active field from the select of the text box + */ + void fieldFromTextSelection() { + if (!hasSelection()) { + // setActiveField(FIELD_ALL); + fieldNext(); + } else { + Point sel = text.getControl().getSelection(); + AttributedCharacterIterator aci = df + .formatToCharacterIterator(calendar.getTime()); + if (sel.x > textSelectionOffset.x) { + sel.x += textSelectionOffset.y; + } + aci.setIndex(sel.x); + Object[] oa = aci.getAttributes().keySet().toArray(); + if (oa.length == 0 && sel.x > 0) { + sel.x -= 1; + aci.setIndex(sel.x); + oa = aci.getAttributes().keySet().toArray(); + } + if (oa.length > 0) { + for (int i = 0; i < field.length; i++) { + if (oa[0].equals(field[i])) { + // If the user has opted to have the user be able to + // change time zones then allow the next field to be the + // time zone field + if (this.allowedTimezones == null) { + if (Calendar.ZONE_OFFSET != getCalendarField( + field[i])) { + setActiveField(i); + } + } else { + // allowed time zones have been set, so let the user + // edit it + setActiveField(i); + } + break; + } + } + updateText(); + } + } + } + + void fieldLast() { + // If the user has opted to have the user be able to change + // time zones then allow the next field to be the time zone field + if (this.allowedTimezones == null) { + if (Calendar.ZONE_OFFSET == getCalendarField( + field[field.length - 1])) { + setActiveField(field.length - 2); + } else { + setActiveField(field.length - 1); + } + } else { + // allowed time zones have been set, so let the user edit it + setActiveField(field.length - 1); + } + } + + /** + * Sets the active field to the next field; wraps if necessary and sets to + * last field if there is no current active field + */ + void fieldNext() { + fieldNext(false); + } + + /** + * Sets the active field to the next field; wraps if necessary and sets to + * last field if there is no current active field + * + * @param If + * true, the text update will be asynchronous (for changes to + * text selection) + */ + void fieldNext(boolean async) { + if (activeField >= 0 && activeField < field.length - 1) { + // If the user has opted to have the user be able to change + // time zones then allow the next field to be the time zone field + if (this.allowedTimezones == null) { + if (Calendar.ZONE_OFFSET == getCalendarField( + field[activeField + 1])) { + if (activeField < field.length - 2) { + setActiveField(activeField + 2); + } else { + setActiveField(0); + } + } else { + setActiveField(activeField + 1); + } + } else { + // allowed time zones have been set, so let the user edit it + setActiveField(activeField + 1); + } + } else { + // If the user has opted to have the user be able to change + // time zones then allow the next field to be the time zone field + if (this.allowedTimezones == null) { + if (Calendar.ZONE_OFFSET == getCalendarField(field[0])) { + setActiveField(1); + } else { + setActiveField(0); + } + } else { + // allowed time zones have been set, so let the user edit it + setActiveField(0); + } + } + updateText(async); + } + + /** + * Sets the active field to the previous field; wraps if necessary and sets + * to first field if there is no current active field + */ + private void fieldPrev() { + fieldPrev(false); + } + + /** + * Sets the active field to the previous field; wraps if necessary and sets + * to first field if there is no current active field + * + * @param If + * true, the text update will be asynchronous (for changes to + * text selection) + */ + void fieldPrev(boolean async) { + if (activeField > 0 && activeField < field.length) { + // If the user has opted to have the user be able to change + // time zones then allow the next field to be the time zone field + if (this.allowedTimezones == null) { + if (Calendar.ZONE_OFFSET == getCalendarField( + field[activeField - 1])) { + if (activeField > 1) { + setActiveField(activeField - 2); + } else { + setActiveField(field.length - 1); + } + } else { + setActiveField(activeField - 1); + } + } else { + // allowed time zones have been set, so let the user edit it + setActiveField(activeField - 1); + } + } else { + // If the user has opted to have the user be able to change + // time zones then allow the next field to be the time zone field + if (this.allowedTimezones == null) { + + if (Calendar.ZONE_OFFSET == getCalendarField( + field[field.length - 1])) { + setActiveField(field.length - 2); + } else { + setActiveField(field.length - 1); + } + } else { + // allowed time zones have been set, so let the user edit it + setActiveField(field.length - 1); + } + } + updateText(async); + } + + private boolean fieldRoll(final int calendarField, final int rollAmount, + final int style) { + if (!getEditable()) { + return false; + } + + long backup = calendar.getTimeInMillis(); + + if (calendarField == Calendar.ZONE_OFFSET + && this.allowedTimezones != null) { + boolean timeZoneSet = false; + for (int idx = 0; idx < this.allowedTimezones.length; idx++) { + TimeZone activeTimeZone = this.getTimeZone(); + if (activeTimeZone.getID() == this.allowedTimezones[idx] + .getID()) { + if (rollAmount < 0) { + if (idx == 0) { + this.setTimeZone( + this.allowedTimezones[this.allowedTimezones.length + - 1]); + } else { + this.setTimeZone(this.allowedTimezones[idx - 1]); + } + } else if (rollAmount > 0) { + if (idx == this.allowedTimezones.length - 1) { + this.setTimeZone(this.allowedTimezones[0]); + } else { + this.setTimeZone(this.allowedTimezones[idx + 1]); + } + } + timeZoneSet = true; + break; + } + } + if (!timeZoneSet) { + this.setTimeZone(this.allowedTimezones[0]); + } + } else { + if ((this.style & CDT.ADD_ON_ROLL) != 0) { + calendar.add(calendarField, rollAmount); + } else { + if (calendarField == Calendar.YEAR + && calendar.get(Calendar.YEAR) == 1 && rollAmount < 0) { + return false; + } + calendar.roll(calendarField, rollAmount); + } + } + + if (!DatePicker.isValidDate(calendar, minDate, maxDate)) { + calendar.setTimeInMillis(backup); + return false; + } + if (selection.length > 0) { + selection[0] = calendar.getTime(); + } + updateText(); + updatePicker(); + fireSelectionChanged(calendarField); + + return true; + } + + /** + * Sets the given calendar field to the given value.
+ * NOTE: This is NOT the active field but a field in the "calendar" + * variable. + * + * @param calendarField + * the field of calendar to set + * @param value + * the value to set it to + * @param style + * the of set to perform; if the value is valid for the given + * calendarField then this has no affect, otherwise it will take + * an action according to this style int: + *
    + *
  • DISCARD: the value will be discarded and the method + * returns without performing and action
  • + *
  • WRAP: if value is higher than its maximum it will be set + * to its minimum, and visa versa
  • + *
  • BLOCK: if value is higher than its maximum it will be set + * to its maximum, and visa versa
  • + *
+ * @return true if the field was set, false otherwise (as is possible with a + * DISCARD style) + */ + private boolean fieldSet(int calendarField, int value, int style) { + if (!getEditable()) { + return false; + } + if (calendarField >= 0) { + if (value > calendar.getActualMaximum(calendarField)) { + if (style == DISCARD) { + return false; + } else if (style == WRAP) { + value = calendar.getActualMinimum(calendarField); + } else if (style == BLOCK) { + value = calendar.getActualMaximum(calendarField); + } + } else if (value < calendar.getActualMinimum(calendarField)) { + if (style == DISCARD) { + return false; + } else if (style == WRAP) { + value = calendar.getActualMaximum(calendarField); + } else if (style == BLOCK) { + value = calendar.getActualMinimum(calendarField); + } + } + + Calendar tmp = (Calendar) calendar.clone(); + tmp.set(calendarField, value); + tmp.getTime(); // call to set the Fields in the Calendar + + if (!DatePicker.isValidDate(tmp, getMinDate(), getMaxDate())) { + return false; + } + + calendar.set(calendarField, value); + if (selection.length > 0) { + selection[0] = calendar.getTime(); + } + updateText(); + updatePicker(); + fireSelectionChanged(calendarField); + } + return true; + } + + /** + *

+ * Notifies listeners that the selection for this CDateTime has changed + *

+ *

+ * This will fire both a regular selection event, and a default selection + * event. + *

+ *

+ * The data field is populated by {@link #getSelectedDates()}. + *

+ */ + void fireSelectionChanged() { + fireSelectionChanged(false); + } + + void fireSelectionChanged(boolean defaultSelection) { + if (defaultSelection && isOpen()) { + setOpen(false); + } + Event event = new Event(); + event.data = getSelection(); + notifyListeners(SWT.Selection, event); + if (defaultSelection) { + notifyListeners(SWT.DefaultSelection, event); + } + } + + /** + *

+ * Notifies listeners that a field of the selected date for this CDateTime + * has changed + *

+ *

+ * Note that this is only valid when {@link #singleSelection} is true, and + * will only fire a regular selection event (not a default selection event) + *

+ *

+ * The data field is populated by {@link #getSelection()} and the detail + * field holds the field which was changed. + *

+ * + * @param field + * the Calendar Field which caused the change, or -1 if + * setTime was called (thus setting all Calendar + * Fields) + */ + void fireSelectionChanged(int field) { + Event event = new Event(); + event.data = getSelection(); + event.detail = field; + if (this.field.length == 1) { + if (isOpen()) { + setOpen(false); + } + notifyListeners(SWT.Selection, event); + notifyListeners(SWT.DefaultSelection, event); + } else { + notifyListeners(SWT.Selection, event); + } + } + + VButton getButtonWidget() { + return button; + } + + /** + * Gets the calendar field corresponding to the active field, if there is + * one. + * + * @return an int representing the calendar field, -1 if there isn't one. + */ + int getCalendarField() { + return hasField(activeField) ? getCalendarField(field[activeField]) + : -1; + } + + int getCalendarField(Field field) { + int cf = field.getCalendarField(); + if (cf < 0) { + if (field.toString().indexOf("hour 1") > -1) { //$NON-NLS-1$ + cf = Calendar.HOUR; + } else if (field.toString().contains("zone")) { //$NON-NLS-1$ + cf = Calendar.ZONE_OFFSET; + } else if (field.toString().contains("hour of day 1")) { //$NON-NLS-1$ + cf = Calendar.HOUR_OF_DAY; + } + } + return cf; + } + + Calendar getCalendarInstance() { + return getCalendarInstance(calendar.getTimeInMillis()); + } + + /** + *

+ * WARNING: Experimental API - this method may be removed in future + * versions + *

+ * Get a new instance of Calendar that is initialized with the timezone and + * locale of this CDateTime, and set to the given date. + * + * @param date + * the date that the Calendar will be set to, or null for the + * current system time + * @return a new instance of Calendar + */ + public Calendar getCalendarInstance(Date date) { + if (date == null) { + return getCalendarInstance(System.currentTimeMillis()); + } else { + return getCalendarInstance(date.getTime()); + } + } + + /** + *

+ * WARNING: Experimental API - this method may be removed in future + * versions + *

+ * Get a new instance of Calendar that is initialized with the timezone and + * locale of this CDateTime, and set to the given date. + * + * @param date + * the date, in millis, that the Calendar will be set to + * @return a new instance of Calendar + */ + public Calendar getCalendarInstance(long date) { + Calendar cal = Calendar.getInstance(timezone, locale); + cal.setTimeInMillis(date); + return cal; + } + + Date getCalendarTime() { + return calendar.getTime(); + } + + long getCalendarTimeInMillis() { + return calendar.getTimeInMillis(); + } + + @Override + public boolean getEditable() { + return !panel.hasStyle(SWT.READ_ONLY); + } + + /** + * The locale currently in use by this CDateTime. + * + * @return the locale + * @see #setLocale(Locale) + */ + public Locale getLocale() { + return locale; + } + + /** + * Get the text which will be shown when the selection is set to null. Note + * that this will be equal to the default null text for the given locale + * unless the null text has been explicitly set using + * {@link #setNullText(String)} + * + * @return the text shown when the selection is null + * @see #setNullText(String) + */ + public String getNullText() { + if (nullText == null) { + if (isDate) { + return Resources.getString("null_text.date", locale); //$NON-NLS-1$ + } else { + return Resources.getString("null_text.time", locale); //$NON-NLS-1$ + } + } + return nullText; + } + + CDateTimePainter getPainter() { + if (painter == null) { + setPainter(new CDateTimePainter()); + } + return painter; + } + + /** + * Get the pattern of this CDateTime as used to set its format. If the + * format was NOT set using setFormat(String) this will return + * null. + * + * @return the pattern, null if there isn't one + * @see SimpleDateFormat + * @see #setFormat(int) + * @see #setPattern(String) + */ + public String getPattern() { + return pattern; + } + + /** + * Get the current selection of this CDateTime widget, or null if there is + * no selection. + * + * @return the current selection + */ + public Date getSelection() { + return hasSelection() ? selection[0] : null; + } + + @Override + public int getStyle() { + return style; + } + + @Override + public String getText() { + return checkText() ? text.getText() : null; + } + + VNative getTextWidget() { + return text; + } + + /** + * The timezone currently in use by this CDateTime. + * + * @return the timezone + * @see #setTimeZone(String) + * @see #setTimeZone(TimeZone) + */ + public TimeZone getTimeZone() { + return timezone; + } + + /** + * The Key event handler + * + * @param event + * the event + */ + void handleKey(Event event) { + if (event.stateMask != 0 && event.stateMask != SWT.SHIFT) { + return; + } + if ('\r' == event.keyCode || SWT.KEYPAD_CR == event.keyCode) { + fieldNext(); + fireSelectionChanged(true); + } else if (SWT.BS == event.keyCode || SWT.DEL == event.keyCode) { + event.doit = false; + setSelection((Date) null); + fireSelectionChanged(); + } else if (!hasField(activeField) && !hasSelection()) { + event.doit = false; + } else { + switch (event.keyCode) { + case '-': + case SWT.KEYPAD_SUBTRACT: + fieldAdjust(-1); + break; + case '=': + case '+': + case SWT.KEYPAD_ADD: + fieldAdjust(1); + break; + case SWT.BS: + if (editField != null) { + editField.removeLastCharacter(); + } + break; + case SWT.CR: + fieldNext(); + fireSelectionChanged(); + break; + case SWT.ARROW_DOWN: + fieldAdjust(-1); + updateText(true); + break; + case SWT.ARROW_UP: + fieldAdjust(1); + updateText(true); + break; + case SWT.ARROW_LEFT: + fieldPrev(true); + break; + case SWT.ARROW_RIGHT: + fieldNext(true); + break; + case SWT.ESC: + if (contentShell != null) { + event.doit = false; + if (selection.length > 0 && selection[0] != cancelDate) { + setSelection(cancelDate); + fireSelectionChanged(); + } + setOpen(false); + } + break; + default: + if (hasField(activeField) && activeField + 1 < separator.length + && String.valueOf(event.character) + .equals(separator[activeField + 1])) { + fieldNext(); + } else if (!hasSelection() + && String.valueOf(event.character).matches("[0-9]")) { //$NON-NLS-1$ + fieldAdjust(0); + fieldFirst(); + } + } + } + } + + /** + * The Travers event handler. Note that ARROW_UP and ARROW_DOWN are handled + * in the handleKey method. + * + * @param event + * the event + */ + void handleTraverse(Event event) { + boolean allowTimeZoneEdit = this.allowedTimezones != null; + + switch (event.detail) { + case SWT.TRAVERSE_ARROW_NEXT: + if (event.keyCode == SWT.ARROW_RIGHT) { + fieldNext(); + } else if (event.keyCode == SWT.ARROW_DOWN) { + fieldAdjust(-1); + } + break; + case SWT.TRAVERSE_ARROW_PREVIOUS: + if (event.keyCode == SWT.ARROW_LEFT) { + fieldPrev(); + } else if (event.keyCode == SWT.ARROW_UP) { + fieldAdjust(1); + } + break; + case SWT.CR: + fieldNext(); + fireSelectionChanged(); + break; + case SWT.TRAVERSE_TAB_NEXT: + if (tabStops && hasSelection()) { + // if we are at the last field, allow the tab out of the control + // the last field is also considered to be the 2nd to last if + // the last is a time zone + // we now check if the control allows time zone editing + if (activeField == field.length - 1 + || activeField == field.length - 2 + && Calendar.ZONE_OFFSET == getCalendarField( + field[field.length - 1]) + && !allowTimeZoneEdit) { + event.doit = true; + } else { + event.doit = false; + if (activeField < 0) { + fieldPrev(); + } else { + fieldNext(); + } + } + } + break; + case SWT.TRAVERSE_TAB_PREVIOUS: + if (tabStops && hasSelection()) { + // if we are at the 1st field, allow the tab out of the control + // the 1st field is also considered to the the 2nd if the 1st + // is a time zone + if (activeField == 0 || activeField == 1 + && Calendar.ZONE_OFFSET == getCalendarField(field[0]) + && !allowTimeZoneEdit) { + event.doit = true; + } else { + event.doit = false; + if (activeField < 0) { + fieldNext(); + } else { + fieldPrev(); + } + } + } + break; + default: + } + } + + /** + * Determines if the given field number is backed by a real field. + * + * @param field + * the field number to check + * @return true if the given field number corresponds to a field in the + * field array + */ + private boolean hasField(int field) { + return field >= 0 && field <= this.field.length; + } + + /** + * Return true if this CDateTime has one or more dates selected; + * + * @return true if a date is selected, false otherwise + */ + public boolean hasSelection() { + return selection.length > 0; + } + + private void init(int style) { + this.style = style; + locale = Locale.getDefault(); + try { + timezone = TimeZone.getDefault(); + } catch (Exception e) { + timezone = TimeZone.getTimeZone("GMT"); //$NON-NLS-1$ + } + calendar = Calendar.getInstance(this.timezone, this.locale); + calendar.setTime(new Date()); + tabStops = (style & CDT.TAB_FIELDS) != 0; + singleSelection = (style & CDT.SIMPLE) == 0 || (style & CDT.MULTI) == 0; + + setFormat(style); + + if (isSimple()) { + return; + } + if (isDropDown()) { + if ((style & CDT.BUTTON_AUTO) != 0) { + setButtonVisibility(BaseCombo.BUTTON_AUTO); + } else { + setButtonVisibility(BaseCombo.BUTTON_ALWAYS); + } + } else { + setButtonVisibility(BaseCombo.BUTTON_NEVER); + if ((style & CDT.SPINNER) != 0) { + int sStyle = SWT.VERTICAL; + if (gtk && (style & CDT.BORDER) != 0) { + sStyle |= SWT.BORDER; + } + spinner = VNative.create(Spinner.class, panel, sStyle); + if (win32) { + spinner.setBackground(text.getControl().getBackground()); + } + spinner.getControl().setMinimum(0); + spinner.getControl().setMaximum(50); + spinner.getControl().setDigits(1); + spinner.getControl().setIncrement(1); + spinner.getControl().setPageIncrement(1); + spinner.getControl().setSelection(25); + spinner.getControl().addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + internalFocusShift = true; + setFocus(); + internalFocusShift = false; + } + }); + spinner.getControl().addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + if (e.button == 2) { + fieldNext(); + } + } + }); + spinner.getControl() + .addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (VTracker.getMouseDownButton() != 2) { + if (spinner.getControl() + .getSelection() > 25) { + fieldAdjust(1); + } else { + fieldAdjust(-1); + } + spinner.getControl().setSelection(25); + } + } + }); + panel.setLayout(new SpinnerLayout()); + } + } + + updateText(); + activeField = -5; + setActiveField(FIELD_NONE); + + if (checkText()) { + addTextListener(); + } + } + + boolean isSelected(Date date) { + for (Date d : selection) { + if (d.equals(date)) { + return true; + } + } + return false; + } + + boolean isSingleSelection() { + return singleSelection; + } + + /** + * Determine whether the provided field is the most precise field. + * According to the used pattern, e.g. + *
    + *
  • dd.mm.yyyy + *
  • MMMM yyyy + *
  • yyyy + *
+ * the date picker provides the panels for selecting a day, month or year + * respectively. The panel should close itself and set the selection in the + * CDateTime field when the user selects the most precise field. The + * constants from the {@link Calendar} class may be used to determine the + * most precise field: + *
    + *
  • {@link Calendar#YEAR} -> 1 + *
  • {@link Calendar#MONTH} -> 2 + *
  • {@link Calendar#DATE} -> 5 + *
+ * e.g. the highest constant is the closing field. + * + * @param calendarField + * The calendar field identifying a pattern field + * @return true if the highest pattern field + */ + boolean isClosingField(int calendarField) { + // find the "highest" constant in the pattern fields + int i = Integer.MIN_VALUE; + for (Field f : field) { + i = Math.max(i, f.getCalendarField()); + } + // compare the highest constant with the field + if (i == calendarField) { + return true; + } + return false; + } + + @Override + protected void postClose(Shell popup) { + disposePicker(); + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the receiver's selection changes. + * + * @param listener + * the listener which should no longer be notified + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(SelectionListener listener) { + if (listener != null) { + TypedListener l = new TypedListener(listener); + removeListener(SWT.Selection, l); + removeListener(SWT.DefaultSelection, l); + } + } + + /** + * Removes the textListener for the appropriate SWT events to handle + * incrementing fields. + */ + protected void removeTextListener() { + Text control = text.getControl(); + control.removeListener(SWT.KeyDown, textListener); + control.removeListener(SWT.MouseDown, textListener); + control.removeListener(SWT.MouseWheel, textListener); + control.removeListener(SWT.MouseUp, textListener); + control.removeListener(SWT.Verify, textListener); + text.removeListener(SWT.Traverse, textListener); + } + + /** + * Sets the active field, which may or may not be a real field (it may also + * be FIELD_NONE) + * + * @param field + * the field to be set active + * @see CDateTime#hasField(int) + */ + private void setActiveField(int field) { + if (activeField != field) { + commitEditField(); + editField = null; + activeField = field; + } + } + + /** + *

+ * WARNING: Experimental API - this method may be removed in future + * versions + *

+ * Sets the builder that this CDateTime widget will use to build its + * graphical selector to the given builder, or to a default builder if the + * given builder is null. + * + * @param builder + * the builder to use, or null to use a default builder + */ + public void setBuilder(CDateTimeBuilder builder) { + this.builder = builder; + this.minDate = builder.getMinDate(); + this.maxDate = builder.getMaxDate(); + + if (picker != null) { + disposePicker(); + createPicker(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.nebula.cwt.base.BaseCombo#setButtonImage(org.eclipse.swt. + * graphics.Image) + */ + @Override + public void setButtonImage(Image image) { + super.setButtonImage(image); + } + + @Override + protected boolean setContentFocus() { + if (checkPicker()) { + internalFocusShift = true; + boolean result = picker.setFocus(); + internalFocusShift = false; + return result; + } + return false; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.nebula.cwt.base.BaseCombo#setEditable(boolean) + */ + @Override + public void setEditable(boolean editable) { + super.setEditable(editable); + if (checkPicker()) { + if (picker instanceof DatePicker) { + ((DatePicker) picker).setEditable(editable); + } else { + picker.setActivatable(editable); + } + } + } + + private boolean checkPicker() { + return picker != null && !picker.isDisposed(); + } + + /** + * Set the date and time format of this CDateTime uses style constants which + * correspond to the various forms of DateFormat.getXxxInstance(int). + *
Valid Styles:
+ *
DATE_SHORT, DATE_MEDIUM, DATE_LONG, TIME_SHORT, TIME_MEDIUM
+ *

+ * Styles are bitwise OR'ed together, but only one "DATE" and one "TIME" may + * be set at a time. + *

+ * Examples:
+ * setFormat(CDT.DATE_LONG);
+ * setFormat(CDT.DATE_SHORT | CDT.TIME_MEDIUM);
+ * + * @param format + * the bitwise OR'ed Date and Time format to be set + * @throws IllegalArgumentException + * @see #getPattern() + * @see #setPattern(String) + */ + public void setFormat(int format) throws IllegalArgumentException { + int dateStyle = (format & CDT.DATE_SHORT) != 0 ? DateFormat.SHORT + : (format & CDT.DATE_MEDIUM) != 0 ? DateFormat.MEDIUM + : (format & CDT.DATE_LONG) != 0 ? DateFormat.LONG : -1; + int timeStyle = (format & CDT.TIME_SHORT) != 0 ? DateFormat.SHORT + : (format & CDT.TIME_MEDIUM) != 0 ? DateFormat.MEDIUM : -1; + String str = null; + if (dateStyle != -1 && timeStyle != -1) { + str = ((SimpleDateFormat) DateFormat.getDateTimeInstance(dateStyle, + timeStyle, locale)).toPattern(); + } else if (dateStyle != -1) { + str = ((SimpleDateFormat) DateFormat.getDateInstance(dateStyle, + locale)).toPattern(); + } else if (timeStyle != -1) { + str = ((SimpleDateFormat) DateFormat.getTimeInstance(timeStyle, + locale)).toPattern(); + } else if (pattern == null) { // first call, so set to default + format = CDT.DATE_SHORT; + str = ((SimpleDateFormat) DateFormat + .getDateInstance(DateFormat.SHORT, locale)).toPattern(); + } + if (str != null) { + this.format = format; + setPattern(str); + } + } + + /** + * Sets the Locale to be used by this CDateTime and causes all affected + * attributes to be updated
+ * If the provided locale is the same as the current locale then this method + * simply returns. If the provided Locale is null then this CDateTime will + * use the system's default locale.
+ * If this CDateTime is of style DROP_DOWN then + * the associated CDateTime will be set to the same locale. + * + * @param locale + * the Locale, or null to use the system's default + * @see #getLocale() + */ + public void setLocale(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + if (!this.locale.equals(locale)) { + this.locale = locale; + if (format > 0) { + setFormat(format); + } else { + setPattern(pattern); + } + updateNullText(); + } + } + + @Override + protected void setModifyEventProperties(Event e) { + e.data = calendar.getTime(); + } + + /** + * Set the text to be shown when the selection is null. Passing null into + * this method will cause the CDateTime widget to use a default null text + * for the given locale. + * + * @param text + */ + public void setNullText(String text) { + defaultNullText = false; + nullText = text; + updateText(); + } + + @Override + public void setOpen(boolean open) { + setOpen(open, null); + } + + @Override + public void setOpen(boolean open, Runnable callback) { + if (open) { + cancelDate = getSelection(); + createPicker(); + } else { + cancelDate = null; + } + super.setOpen(open, callback); + if (hasSelection()) { + show(getSelection()); + } + } + + /** + *

+ * WARNING: Experimental API - this method may be removed in future + * versions + *

+ * Sets the painter that this CDateTime widget will use to paint its + * graphical selector to the given painter, or to a default painter if the + * given painter is null. + * + * @param painter + * the painter to use, or null to use a default painter + */ + public void setPainter(CDateTimePainter painter) { + if (painter != null) { + painter.setCDateTime(this); + } + this.painter = painter; + } + + /** + * Set the style of this CDateTime to work with dates and / or times as + * determined by the given pattern. This will set the fields shown in the + * text box and, if DROP_DOWN style is set, the fields of the + * drop down component.
+ * This method is backed by an implementation of SimpleDateFormat, and as + * such, any string pattern which is valid for SimpleDateFormat may be used. + * Examples (US Locale):
+ * setPattern("MM/dd/yyyy h:mm a");
+ * setPattern("'Meeting @' h:mm a 'on' EEEE, MMM dd, + * yyyy");
+ * + * @param pattern + * the pattern to use, if it is invalid, the original is restored + * @throws IllegalArgumentException + * @see SimpleDateFormat + * @see #getPattern() + * @see #setFormat(int) + */ + public void setPattern(String pattern) throws IllegalArgumentException { + this.allowedTimezones = null; + if (isOpen()) { + setOpen(false); + } + df = new SimpleDateFormat(pattern, locale); + df.setTimeZone(timezone); + if (updateFields()) { + this.pattern = pattern; + this.format = -1; + boolean wasDate = isDate; + boolean wasTime = isTime; + isDate = isTime = false; + calendarFields = new int[field.length]; + for (int i = 0; i < calendarFields.length; i++) { + calendarFields[i] = getCalendarField(field[i]); + switch (calendarFields[i]) { + case Calendar.AM_PM: + case Calendar.HOUR: + case Calendar.HOUR_OF_DAY: + case Calendar.MILLISECOND: + case Calendar.MINUTE: + case Calendar.SECOND: + case Calendar.ZONE_OFFSET: + isTime = true; + break; + case Calendar.DAY_OF_MONTH: + case Calendar.DAY_OF_WEEK: + case Calendar.DAY_OF_WEEK_IN_MONTH: + case Calendar.DAY_OF_YEAR: + case Calendar.ERA: + case Calendar.MONTH: + case Calendar.WEEK_OF_MONTH: + case Calendar.WEEK_OF_YEAR: + case Calendar.YEAR: + isDate = true; + break; + default: + break; + } + } + if (checkButton() && (isDate != wasDate || isTime != wasTime)) { + if (defaultButtonImage) { + if (isDate && isTime) { + doSetButtonImage(Resources.getIconCalendarClock()); + } else if (isDate) { + doSetButtonImage(Resources.getIconCalendar()); + } else { + doSetButtonImage(Resources.getIconClock()); + } + } + updateNullText(); + } + if (checkText()) { + updateText(); + } + if (isSimple()) { + disposePicker(); + createPicker(); + } + } else { + throw new IllegalArgumentException( + "Problem setting pattern: \"" + pattern + "\""); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + void setScrollable(boolean scrollable) { + this.scrollable = scrollable; + if (isSimple() && !scrollable) { + if (picker != null && picker instanceof DatePicker) { + updatePicker(); + } + } + } + + /** + * Set the selection for this CDateTime to that of the provided + * Date object.
+ * + * @param selection + * the new selection, or null to clear the selection + */ + public void setSelection(Date selection) { + if (getEditable()) { + if (selection == null) { + this.selection = new Date[0]; + } else if (DatePicker.isValidDate(getCalendarInstance(selection), + minDate, maxDate)) { + this.selection = new Date[] { selection }; + } + } + if (singleSelection && this.selection.length > 0) { + show(selection); + } else { + updateText(); + updatePicker(); + } + } + + /** + * Sets the timezone to the timezone specified by the given zoneID, or to + * the system default if the given zoneID is null. If the give zoneID cannot + * be understood, then the timezone will be set to GMT. + * + * @param zoneID + * the id of the timezone to use, or null to use the system + * default + * @see #setTimeZone(TimeZone) + */ + public void setTimeZone(String zoneID) { + if (zoneID == null) { + setTimeZone((TimeZone) null); + } else { + setTimeZone(TimeZone.getTimeZone(zoneID)); + } + } + + /** + * Sets the timezone to the given timezone, or to the system's default + * timezone if the given timezone is null. + * + * @param zone + * the timezone to use, or null to use the system default + * @see #setTimeZone(String) + */ + public void setTimeZone(TimeZone zone) { + if (zone == null) { + timezone = TimeZone.getDefault(); + } + if (!this.timezone.equals(zone)) { + this.timezone = zone; + calendar.setTimeZone(this.timezone); + df.setTimeZone(this.timezone); + updateText(); + } + } + + /** + * Shows the given date if it can be shown by the selector. In other words, + * for graphical selectors such as a calendar, the visible range of time is + * moved so that the given date is visible. + * + * @param date + * the date to show + */ + public void show(Date date) { + if (date == null) { + calendar.setTime(new Date()); + } else { + calendar.setTime(date); + } + updateText(); + updatePicker(); + } + + /** + * Show the selection if it can be shown by the selector. Has no affect if + * there is no selection. + * + * @see #show(Date) + */ + public void showSelection() { + if (selection.length > 0) { + show(selection[0]); + } + } + + @Override + public String toString() { + return getClass().getSimpleName() + " {" + getCalendarTime() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * inspects all of the calendar fields in the field array to + * determine what style is appropriate and then sets that style to the + * picker using the setPickerStyle method.
+ */ + private boolean updateFields() { + Field[] bak = new Field[field == null ? 0 : field.length]; + if (bak.length > 0) { + System.arraycopy(field, 0, bak, 0, field.length); + } + + AttributedCharacterIterator aci = df + .formatToCharacterIterator(calendar.getTime()); + field = new Field[aci.getAllAttributeKeys().size()]; + separator = new String[field.length + 1]; // there can be a separator + // before and after + int i = 0; + Object last = null; + for (char c = aci.first(); c != CharacterIterator.DONE; c = aci + .next()) { + Object[] oa = aci.getAttributes().keySet().toArray(); + if (oa.length > 0) { + if (oa[0] != last && i < field.length) { + if (getCalendarField((Field) oa[0]) < 0) { + if (bak.length > 0) { + field = new Field[bak.length]; + System.arraycopy(bak, 0, field, 0, bak.length); + } + return false; + } else { + field[i] = (Field) oa[0]; + last = oa[0]; + } + i++; + } + } else { + if (separator[i] == null) { + separator[i] = String.valueOf(c); + } + } + } + + df.setLenient(false); + setActiveField(FIELD_NONE); + return true; + } + + private void updateNullText() { + if (defaultNullText) { + if (isDate) { + nullText = Resources.getString("null_text.date", locale); //$NON-NLS-1$ + } else { + nullText = Resources.getString("null_text.time", locale); //$NON-NLS-1$ + } + if (!hasSelection()) { + updateText(); + } + } + } + + /** + * tell the picker to update its view of the selection and reference time + */ + private void updatePicker() { + if (picker != null) { + if (picker instanceof DatePicker) { + ((DatePicker) picker).updateView(); + } else if (picker instanceof AnalogTimePicker) { + ((AnalogTimePicker) picker).updateView(); + } else if (picker instanceof DiscreteTimePicker) { + ((DiscreteTimePicker) picker).updateView(); + } + } + } + + /** + * This is the only way that text is set to the text box.
+ * The selection of the text in the text box is also set here (the active + * field is selected) as well as if a field is being edited, it's "edit + * text" is inserted for display. The getSelection property of + * CDateTime remains unchanged. + */ + private void updateText() { + updateText(false); + } + + /** + * This is the only way that text is set to the text box.
+ * The selection of the text in the text box is also set here (the active + * field is selected) as well as if a field is being edited, it's "edit + * text" is inserted for display. The getSelection property of + * CDateTime remains unchanged. + * + * @param async + * If true, this operation will be performed asynchronously (for + * changes to text selection) + */ + private void updateText(boolean async) { + // TODO: save previous state and only update on changes...? + + String buffer = hasSelection() ? df.format(getSelection()) + : getNullText(); + + int s0 = 0; + int s1 = 0; + + if (!hasSelection()) { + s0 = 0; + s1 = buffer.length(); + } else if (activeField >= 0 && activeField < field.length) { + AttributedCharacterIterator aci = df + .formatToCharacterIterator(getSelection()); + for (char c = aci.first(); c != CharacterIterator.DONE; c = aci + .next()) { + if (aci.getAttribute(field[activeField]) != null) { + s0 = aci.getRunStart(); + s1 = aci.getRunLimit(); + if (editField != null) { + String str = editField.toString(); + buffer = buffer.substring(0, s0) + str + + buffer.substring(s1); + int oldS1 = s1; + s1 = s0 + str.length(); + textSelectionOffset.x = Math.min(oldS1, s1); + textSelectionOffset.y = oldS1 - s0 - str.length(); + } else { + textSelectionOffset.x = buffer.length() + 1; + textSelectionOffset.y = 0; + } + break; + } + } + } else { + setActiveField(FIELD_NONE); + } + + final String string = buffer; + final int selStart = s0; + final int selEnd = s1; + + Runnable runnable = () -> { + if (text != null && !text.isDisposed()) { + if (!string.equals(text.getText())) { + text.getControl().removeListener(SWT.Verify, textListener); + text.setText(string); + text.getControl().addListener(SWT.Verify, textListener); + } + if ((text.getControl().getStyle() & SWT.READ_ONLY) == 0) { + text.getControl().setSelection(selStart, selEnd); + } + } + }; + + if (async) { + getDisplay().asyncExec(runnable); + } else { + getDisplay().syncExec(runnable); + } + } + + /** + * The Verify Event handler.
+ * EVERYTHING is blocked via this handler (Event.doit is set to + * false). Depending upon the input, a course of action is determined and + * the displayed text is updated via the updateText() method. + *
+ * This method implements the following logic: If the event is a paste, the + * pasted text is parsed for the entire date/time selection; if this parse + * is successful, the result is committed to the selection property and is + * displayed; otherwise, it is discarded. One-character pastes are discarded + * without parsing. When user types characters one by one, all non-digits + * are discarded (if they have effects, they have already been processed by + * other event handlers) while digits are added to + * this.editField without affecting the selection. Once + * this.editField reaches its capacity for the active field, + * its contents are attempted to be committed. If the commit is successful, + * focus switches to the next field of CDateTime. Otherwise, the contents of + * this.editField are discarded and the previous value of the + * selection (before user started typing in this field) is restored; focus + * stays in the same field. Example: if the seconds field contains + * "23", and user types 8 in the seconds field, "08" is shown on screen + * while getSelection still returns 23. If user types 9 after that, the + * field reaches its capacity, the attempt to commit 89 seconds fails, and + * 23 gets restored on screen. + * + * @param e + * the event + * @see CDateTime#updateText() + */ + void verify(Event e) { + // we don't want to reprocess the event + if (e.doit == false) { + return; + } + + e.doit = false; + if (field.length == 0 || activeField == FIELD_NONE || e.text == null) { + return; + } + + char c = e.character; + if (e.text.length() == 1 && String.valueOf(c).equals(e.text) + && Character.isDigit(c) || e.text.length() > 1) { + if (e.text.length() == 1) { + if (editField == null) { + int cf = getCalendarField(); + if (cf >= 0) { + int digits; + switch (cf) { + case Calendar.YEAR: + digits = 4; + break; + case Calendar.DAY_OF_YEAR: + digits = 3; + break; + case Calendar.AM_PM: + case Calendar.DAY_OF_WEEK: + case Calendar.ERA: + digits = 1; + break; + case Calendar.MILLISECOND: + digits = 3; + break; + default: + digits = 2; + } + editField = new EditField(digits, calendar.get(cf)); + } else { + return; + } + } + if (editField.addChar(c)) { + if (commitEditField()) { + fieldNext(); + } else { + editField = null; + if (selection.length > 0) { + selection[0] = calendar.getTime(); + } + updateText(); + } + } + if (selection.length > 0) { + selection[0] = calendar.getTime(); + } + updatePicker(); + } else { + try { + setSelection(df.parse(e.text)); + fireSelectionChanged(); + } catch (ParseException pe) { + // do nothing + } + } + } + updateText(); + } + + /** + * @param pattern + * @param allowedTimeZones + * @throws IllegalArgumentException + */ + public void setPattern(final String pattern, + final TimeZone[] allowedTimeZones) throws IllegalArgumentException { + this.setPattern(pattern); + if (pattern.indexOf('z') != -1) { + this.allowedTimezones = allowedTimeZones; + } + } + + /** + * Returns the minimum date or null. + * + * @return Returns a clone of the minDate or null if not set. + * @since 1.4 + */ + public Calendar getMinDate() { + if (minDate == null) { + return null; + } + return (Calendar) minDate.clone(); + } + + /** + * Returns the maximum date or null. + * + * @return Returns a clone of the maxDate or null if not set. + * @since 1.4 + */ + public Calendar getMaxDate() { + if (maxDate == null) { + return null; + } + return (Calendar) maxDate.clone(); + } + + /** + * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) + */ + public void setBackground(Color color) { + super.setBackground(color); + if (spinner != null) { + spinner.setBackground(color); + } + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + public void setForeground(Color color) { + super.setForeground(color); + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @param color + * @since 1.5 + */ + public void setButtonHoverBackgroundColor(Color color) { + checkWidget(); + this.buttonHoverBackgroundColor = color; + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @param color + * @since 1.5 + */ + public void setButtonHoverBorderColor(Color color) { + checkWidget(); + this.buttonHoverBorderColor = color; + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @param color + * @since 1.5 + */ + public void setButtonSelectedBackgroundColor(Color color) { + checkWidget(); + this.buttonSelectedBackgroundColor = color; + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @param color + * @since 1.5 + */ + public void setButtonSelectedBorderColor(Color color) { + checkWidget(); + this.buttonSelectedBorderColor = color; + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @return the picker foreground color + * @since 1.5 + */ + public Color getPickerForegroundColor() { + checkWidget(); + return pickerForegroundColor; + } + + /** + * @param pickerForegroundColor + * @since 1.5 + */ + public void setPickerForegroundColor(Color pickerForegroundColor) { + checkWidget(); + this.pickerForegroundColor = pickerForegroundColor; + if (pickerForegroundColor != null && pickerPanel != null) { + pickerPanel.setForeground(pickerForegroundColor); + } + if (picker != null && pickerPanel != null && pickerPanel != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @return the picker background color + * @since 1.5 + */ + public Color getPickerBackgroundColor() { + checkWidget(); + return pickerBackgroundColor; + } + + /** + * @param pickerBackgroundColor + * @since 1.5 + */ + public void setPickerBackgroundColor(Color pickerBackgroundColor) { + checkWidget(); + this.pickerBackgroundColor = pickerBackgroundColor; + if (pickerBackgroundColor != null && pickerPanel != null) { + pickerPanel.setBackground(pickerBackgroundColor); + } + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @return the picker font + * @since 1.5 + */ + public Font getPickerFont() { + checkWidget(); + return pickerFont; + } + + /** + * @param pickerFont + * @since 1.5 + */ + public void setPickerFont(Font pickerFont) { + checkWidget(); + this.pickerFont = pickerFont; + if (pickerFont != null && pickerPanel != null) { + pickerPanel.setFont(pickerFont); + } + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @return the bg color of the button hover + * @since 1.5 + */ + public Color getButtonHoverBackgroundColor() { + checkWidget(); + return buttonHoverBackgroundColor; + } + + /** + * @return the border color of the button hover + * @since 1.5 + */ + public Color getButtonHoverBorderColor() { + checkWidget(); + return buttonHoverBorderColor; + } + + /** + * @return the selected background of the button + * @since 1.5 + */ + public Color getButtonSelectedBackgroundColor() { + checkWidget(); + return buttonSelectedBackgroundColor; + } + + /** + * @return the border color of the selected button + * @since 1.5 + */ + public Color getButtonSelectedBorderColor() { + checkWidget(); + return buttonSelectedBorderColor; + } + + /** + * @return the color of the active day + * @since 1.5 + */ + public Color getPickerActiveDayColor() { + checkWidget(); + return pickerActiveDayColor; + } + + /** + * @param pickerActiveDayColor + * @since 1.5 + */ + public void setPickerActiveDayColor(Color pickerActiveDayColor) { + checkWidget(); + this.pickerActiveDayColor = pickerActiveDayColor; + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @return the color of the inactive day + * @since 1.5 + */ + public Color getPickerInactiveDayColor() { + checkWidget(); + return pickerInactiveDayColor; + } + + /** + * @param pickerInactiveDayColor + * @since 1.5 + */ + public void setPickerInactiveDayColor(Color pickerInactiveDayColor) { + checkWidget(); + this.pickerInactiveDayColor = pickerInactiveDayColor; + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @return the color of the "today" section + * @since 1.5 + */ + public Color getPickerTodayColor() { + checkWidget(); + return pickerTodayColor; + } + + /** + * @param pickerTodayColor + * @since 1.5 + */ + public void setPickerTodayColor(Color pickerTodayColor) { + checkWidget(); + this.pickerTodayColor = pickerTodayColor; + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @return the color of the minutes + * @since 1.5 + */ + public Color getPickerMinutesColor() { + checkWidget(); + return pickerMinutesColor; + } + + /** + * @param pickerMinutesColor + * @since 1.5 + */ + public void setPickerMinutesColor(Color pickerMinutesColor) { + checkWidget(); + this.pickerMinutesColor = pickerMinutesColor; + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @return the minutes background + * @since 1.5 + */ + public Color getPickerMinutesBackgroundColor() { + checkWidget(); + return pickerMinutesBackgroundColor; + } + + /** + * @param pickerMinutesBackgroundColor + * @since 1.5 + */ + public void setPickerMinutesBackgroundColor( + Color pickerMinutesBackgroundColor) { + checkWidget(); + this.pickerMinutesBackgroundColor = pickerMinutesBackgroundColor; + if (picker != null) { + picker.updateColorsAndFont(); + } + } + + /** + * @return the foreground color of the "Ok" button + */ + public Color getOkButtonColor() { + checkWidget(); + return okButtonColor; + } + + /** + * @param okButtonColor the new foreground color of the "ok" button + */ + public void setOkButtonColor(Color okButtonColor) { + checkWidget(); + this.okButtonColor = okButtonColor; + if (okButton != null) okButton.setForeground(okButtonColor); + } + + /** + * @return the foreground color of the "Cancel" button + */ + public Color getCancelButtonColor() { + checkWidget(); + return cancelButtonColor; + } + + /** + * @param cancelButtonColor the new foreground color of the "cancel" button + */ + public void setCancelButtonColor(Color cancelButtonColor) { + checkWidget(); + this.cancelButtonColor = cancelButtonColor; + if (cancelButton != null) cancelButton.setForeground(cancelButtonColor); + } + + /** + * @return the foreground color of the "clear" button + */ + public Color getClearButtonForegroundColor() { + checkWidget(); + return clearButtonForegroundColor; + } + + /** + * @param clearButtonForegroundColor the new foreground color of the "clear" button + */ + public void setClearButtonForegroundColor( + Color clearButtonForegroundColor) { + checkWidget(); + this.clearButtonForegroundColor = clearButtonForegroundColor; + if (clearButton != null) clearButton.setForeground(clearButtonForegroundColor); + } + + /** + * @return the font of the "clear" button + */ + public Font getClearButtonFont() { + checkWidget(); + return clearButtonFont; + } + + /** + * @param clearButtonFont the new font of the "clear" button + */ + public void setClearButtonFont(Font clearButtonFont) { + checkWidget(); + this.clearButtonFont = clearButtonFont; + if (clearButton != null) clearButton.setFont(clearButtonFont); + } + +} diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages.properties index 1f6eec133..775b0b7b7 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages.properties @@ -1,44 +1,44 @@ -null_text.date= -null_text.time= -accept.text=Accept -cancel.text=Cancel -clear.text=Clear -nav_current_day=Go To Today -nav_current_time=Go To Current Time -nav_prev_month=Previous Month -nav_next_month=Next Month -nav_prev_year=Previous Year -nav_next_year=Next Year -today.text=Today -today_verbose.text=Today is {0,date,EEEE}, the {1} -date_ordinal_1=1st -date_ordinal_2=2nd -date_ordinal_3=3rd -date_ordinal_4=4th -date_ordinal_5=5th -date_ordinal_6=6th -date_ordinal_7=7th -date_ordinal_8=8th -date_ordinal_9=9th -date_ordinal_10=10th -date_ordinal_11=11th -date_ordinal_12=12th -date_ordinal_13=13th -date_ordinal_14=14th -date_ordinal_15=15th -date_ordinal_16=16th -date_ordinal_17=17th -date_ordinal_18=18th -date_ordinal_19=19th -date_ordinal_20=20th -date_ordinal_21=21st -date_ordinal_22=22nd -date_ordinal_23=23rd -date_ordinal_24=24th -date_ordinal_25=25th -date_ordinal_26=26th -date_ordinal_27=27th -date_ordinal_28=28th -date_ordinal_29=29th -date_ordinal_30=30th +null_text.date= +null_text.time= +accept.text=Accept +cancel.text=Cancel +clear.text=Clear +nav_current_day=Go To Today +nav_current_time=Go To Current Time +nav_prev_month=Previous Month +nav_next_month=Next Month +nav_prev_year=Previous Year +nav_next_year=Next Year +today.text=Today +today_verbose.text=Today is {0,date,EEEE}, the {1} +date_ordinal_1=1st +date_ordinal_2=2nd +date_ordinal_3=3rd +date_ordinal_4=4th +date_ordinal_5=5th +date_ordinal_6=6th +date_ordinal_7=7th +date_ordinal_8=8th +date_ordinal_9=9th +date_ordinal_10=10th +date_ordinal_11=11th +date_ordinal_12=12th +date_ordinal_13=13th +date_ordinal_14=14th +date_ordinal_15=15th +date_ordinal_16=16th +date_ordinal_17=17th +date_ordinal_18=18th +date_ordinal_19=19th +date_ordinal_20=20th +date_ordinal_21=21st +date_ordinal_22=22nd +date_ordinal_23=23rd +date_ordinal_24=24th +date_ordinal_25=25th +date_ordinal_26=26th +date_ordinal_27=27th +date_ordinal_28=28th +date_ordinal_29=29th +date_ordinal_30=30th date_ordinal_31=31st \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_de.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_de.properties index 170c01d92..b88476ce2 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_de.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_de.properties @@ -1,44 +1,44 @@ -null_text.date= -null_text.time= -accept.text=OK -cancel.text=Abbrechen -clear.text=Löschen -nav_current_day=Gehe zu Heute -nav_current_time=Gehe zu aktueller Zeit -nav_prev_month=Vorheriger Monat -nav_next_month=Nächster Monat -nav_prev_year=Vorheriges Jahr -nav_next_year=Nächstes Jahr -today.text=Heute -today_verbose.text=Heute ist {0,date,EEEE}, der {1} {0,date,M}. {0,date,yyyy} -date_ordinal_1=1. -date_ordinal_2=2. -date_ordinal_3=3. -date_ordinal_4=4. -date_ordinal_5=5. -date_ordinal_6=6. -date_ordinal_7=7. -date_ordinal_8=8. -date_ordinal_9=9. -date_ordinal_10=10. -date_ordinal_11=11. -date_ordinal_12=12. -date_ordinal_13=13. -date_ordinal_14=14. -date_ordinal_15=15. -date_ordinal_16=16. -date_ordinal_17=17. -date_ordinal_18=18. -date_ordinal_19=19. -date_ordinal_20=20. -date_ordinal_21=21. -date_ordinal_22=22. -date_ordinal_23=23. -date_ordinal_24=24. -date_ordinal_25=25. -date_ordinal_26=26. -date_ordinal_27=27. -date_ordinal_28=28. -date_ordinal_29=29. -date_ordinal_30=30. +null_text.date= +null_text.time= +accept.text=OK +cancel.text=Abbrechen +clear.text=Löschen +nav_current_day=Gehe zu Heute +nav_current_time=Gehe zu aktueller Zeit +nav_prev_month=Vorheriger Monat +nav_next_month=Nächster Monat +nav_prev_year=Vorheriges Jahr +nav_next_year=Nächstes Jahr +today.text=Heute +today_verbose.text=Heute ist {0,date,EEEE}, der {1} {0,date,M}. {0,date,yyyy} +date_ordinal_1=1. +date_ordinal_2=2. +date_ordinal_3=3. +date_ordinal_4=4. +date_ordinal_5=5. +date_ordinal_6=6. +date_ordinal_7=7. +date_ordinal_8=8. +date_ordinal_9=9. +date_ordinal_10=10. +date_ordinal_11=11. +date_ordinal_12=12. +date_ordinal_13=13. +date_ordinal_14=14. +date_ordinal_15=15. +date_ordinal_16=16. +date_ordinal_17=17. +date_ordinal_18=18. +date_ordinal_19=19. +date_ordinal_20=20. +date_ordinal_21=21. +date_ordinal_22=22. +date_ordinal_23=23. +date_ordinal_24=24. +date_ordinal_25=25. +date_ordinal_26=26. +date_ordinal_27=27. +date_ordinal_28=28. +date_ordinal_29=29. +date_ordinal_30=30. date_ordinal_31=31. \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_el_GR.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_el_GR.properties index 3b8961954..66817e1d6 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_el_GR.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_el_GR.properties @@ -1,45 +1,45 @@ -null_text.date=<\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03b7\u03bc\u03b5\u03c1/\u03bd\u03af\u03b1> -null_text.time=<\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03ce\u03c1\u03b1> -accept.text=\u0391\u03c0\u03bf\u03b4\u03bf\u03c7\u03ae -cancel.text=\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7 -clear.text=\u0395\u03ba\u03ba\u03b1\u03b8\u03ac\u03c1\u03b9\u03c3\u03b7 -nav_current_day=\u03a4\u03c1\u03ad\u03c7\u03bf\u03c5\u03c3\u03b1 \u03b7\u03bc\u03ad\u03c1\u03b1 -nav_current_time=\u03a4\u03c1\u03ac\u03c7\u03bf\u03c5\u03c3\u03b1 \u03ce\u03c1\u03b1 -nav_prev_mon\u03bf\u03c2=\u03a0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2 \u03bc\u03ae\u03bd\u03b1\u03c2 -nav_next_mon\u03bf\u03c2=\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf\u03c2 \u03bc\u03ae\u03bd\u03b1\u03c2 -nav_prev_year=\u03a0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2 \u03c7\u03c1\u03cc\u03bd\u03bf\u03c2 -nav_next_year=\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf\u03c2 \u03c7\u03c1\u03cc\u03bd\u03bf\u03c2 -today.text=\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 -today_verbose.text=\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 {0,date,EEEE} {1} {0,date,MMMMM} {0,date,yyyy} -show_selection=\u0395\u03bc\u03c6\u03ac\u03bd\u03b9\u03c3\u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae\u03c2 -date_ordinal_1=1\u03bf\u03c2 -date_ordinal_2=2\u03bf\u03c2 -date_ordinal_3=3\u03bf\u03c2 -date_ordinal_4=4\u03bf\u03c2 -date_ordinal_5=5\u03bf\u03c2 -date_ordinal_6=6\u03bf\u03c2 -date_ordinal_7=7\u03bf\u03c2 -date_ordinal_8=8\u03bf\u03c2 -date_ordinal_9=9\u03bf\u03c2 -date_ordinal_10=10\u03bf\u03c2 -date_ordinal_11=11\u03bf\u03c2 -date_ordinal_12=12\u03bf\u03c2 -date_ordinal_13=13\u03bf\u03c2 -date_ordinal_14=14\u03bf\u03c2 -date_ordinal_15=15\u03bf\u03c2 -date_ordinal_16=16\u03bf\u03c2 -date_ordinal_17=17\u03bf\u03c2 -date_ordinal_18=18\u03bf\u03c2 -date_ordinal_19=19\u03bf\u03c2 -date_ordinal_20=20\u03bf\u03c2 -date_ordinal_21=21\u03bf\u03c2 -date_ordinal_22=22\u03bf\u03c2 -date_ordinal_23=23\u03bf\u03c2 -date_ordinal_24=24\u03bf\u03c2 -date_ordinal_25=25\u03bf\u03c2 -date_ordinal_26=26\u03bf\u03c2 -date_ordinal_27=27\u03bf\u03c2 -date_ordinal_28=28\u03bf\u03c2 -date_ordinal_29=29\u03bf\u03c2 -date_ordinal_30=30\u03bf\u03c2 +null_text.date=<\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03b7\u03bc\u03b5\u03c1/\u03bd\u03af\u03b1> +null_text.time=<\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03ce\u03c1\u03b1> +accept.text=\u0391\u03c0\u03bf\u03b4\u03bf\u03c7\u03ae +cancel.text=\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7 +clear.text=\u0395\u03ba\u03ba\u03b1\u03b8\u03ac\u03c1\u03b9\u03c3\u03b7 +nav_current_day=\u03a4\u03c1\u03ad\u03c7\u03bf\u03c5\u03c3\u03b1 \u03b7\u03bc\u03ad\u03c1\u03b1 +nav_current_time=\u03a4\u03c1\u03ac\u03c7\u03bf\u03c5\u03c3\u03b1 \u03ce\u03c1\u03b1 +nav_prev_mon\u03bf\u03c2=\u03a0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2 \u03bc\u03ae\u03bd\u03b1\u03c2 +nav_next_mon\u03bf\u03c2=\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf\u03c2 \u03bc\u03ae\u03bd\u03b1\u03c2 +nav_prev_year=\u03a0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2 \u03c7\u03c1\u03cc\u03bd\u03bf\u03c2 +nav_next_year=\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf\u03c2 \u03c7\u03c1\u03cc\u03bd\u03bf\u03c2 +today.text=\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 +today_verbose.text=\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 {0,date,EEEE} {1} {0,date,MMMMM} {0,date,yyyy} +show_selection=\u0395\u03bc\u03c6\u03ac\u03bd\u03b9\u03c3\u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae\u03c2 +date_ordinal_1=1\u03bf\u03c2 +date_ordinal_2=2\u03bf\u03c2 +date_ordinal_3=3\u03bf\u03c2 +date_ordinal_4=4\u03bf\u03c2 +date_ordinal_5=5\u03bf\u03c2 +date_ordinal_6=6\u03bf\u03c2 +date_ordinal_7=7\u03bf\u03c2 +date_ordinal_8=8\u03bf\u03c2 +date_ordinal_9=9\u03bf\u03c2 +date_ordinal_10=10\u03bf\u03c2 +date_ordinal_11=11\u03bf\u03c2 +date_ordinal_12=12\u03bf\u03c2 +date_ordinal_13=13\u03bf\u03c2 +date_ordinal_14=14\u03bf\u03c2 +date_ordinal_15=15\u03bf\u03c2 +date_ordinal_16=16\u03bf\u03c2 +date_ordinal_17=17\u03bf\u03c2 +date_ordinal_18=18\u03bf\u03c2 +date_ordinal_19=19\u03bf\u03c2 +date_ordinal_20=20\u03bf\u03c2 +date_ordinal_21=21\u03bf\u03c2 +date_ordinal_22=22\u03bf\u03c2 +date_ordinal_23=23\u03bf\u03c2 +date_ordinal_24=24\u03bf\u03c2 +date_ordinal_25=25\u03bf\u03c2 +date_ordinal_26=26\u03bf\u03c2 +date_ordinal_27=27\u03bf\u03c2 +date_ordinal_28=28\u03bf\u03c2 +date_ordinal_29=29\u03bf\u03c2 +date_ordinal_30=30\u03bf\u03c2 date_ordinal_31=31\u03bf\u03c2 \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_en_US.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_en_US.properties index 28f0c2bd2..103a11fa1 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_en_US.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_en_US.properties @@ -1,45 +1,45 @@ -null_text.date= -null_text.time= -accept.text=Accept -cancel.text=Cancel -clear.text=Clear -nav_current_day=Go To Today -nav_current_time=Go To Current Time -nav_prev_month=Previous Month -nav_next_month=Next Month -nav_prev_year=Previous Year -nav_next_year=Next Year -today.text=Today -today_verbose.text=Today is {0,date,EEEE}, the {1} -show_selection=Show Selection -date_ordinal_1=1st -date_ordinal_2=2nd -date_ordinal_3=3rd -date_ordinal_4=4th -date_ordinal_5=5th -date_ordinal_6=6th -date_ordinal_7=7th -date_ordinal_8=8th -date_ordinal_9=9th -date_ordinal_10=10th -date_ordinal_11=11th -date_ordinal_12=12th -date_ordinal_13=13th -date_ordinal_14=14th -date_ordinal_15=15th -date_ordinal_16=16th -date_ordinal_17=17th -date_ordinal_18=18th -date_ordinal_19=19th -date_ordinal_20=20th -date_ordinal_21=21st -date_ordinal_22=22nd -date_ordinal_23=23rd -date_ordinal_24=24th -date_ordinal_25=25th -date_ordinal_26=26th -date_ordinal_27=27th -date_ordinal_28=28th -date_ordinal_29=29th -date_ordinal_30=30th +null_text.date= +null_text.time= +accept.text=Accept +cancel.text=Cancel +clear.text=Clear +nav_current_day=Go To Today +nav_current_time=Go To Current Time +nav_prev_month=Previous Month +nav_next_month=Next Month +nav_prev_year=Previous Year +nav_next_year=Next Year +today.text=Today +today_verbose.text=Today is {0,date,EEEE}, the {1} +show_selection=Show Selection +date_ordinal_1=1st +date_ordinal_2=2nd +date_ordinal_3=3rd +date_ordinal_4=4th +date_ordinal_5=5th +date_ordinal_6=6th +date_ordinal_7=7th +date_ordinal_8=8th +date_ordinal_9=9th +date_ordinal_10=10th +date_ordinal_11=11th +date_ordinal_12=12th +date_ordinal_13=13th +date_ordinal_14=14th +date_ordinal_15=15th +date_ordinal_16=16th +date_ordinal_17=17th +date_ordinal_18=18th +date_ordinal_19=19th +date_ordinal_20=20th +date_ordinal_21=21st +date_ordinal_22=22nd +date_ordinal_23=23rd +date_ordinal_24=24th +date_ordinal_25=25th +date_ordinal_26=26th +date_ordinal_27=27th +date_ordinal_28=28th +date_ordinal_29=29th +date_ordinal_30=30th date_ordinal_31=31st \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_es_ES.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_es_ES.properties index 954819b54..1bd7db2ad 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_es_ES.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_es_ES.properties @@ -1,44 +1,44 @@ -null_text.date= -null_text.time= -accept.text=Aceptar -cancel.text=Cancelar -clear.text=Despejar -nav_current_day=Ir a Hoy -nav_current_time=Ir a la Hora Actual -nav_prev_month=Mes Anterior -nav_next_month=Siguiente Mes -nav_prev_year=Año Anterior -nav_next_year=Siguiente Año -today.text=Hoy -today_verbose.text=Hoy es {0,date,EEEE}, {1} -date_ordinal_1=1º -date_ordinal_2=2º -date_ordinal_3=3º -date_ordinal_4=4º -date_ordinal_5=5º -date_ordinal_6=6º -date_ordinal_7=7º -date_ordinal_8=8º -date_ordinal_9=9º -date_ordinal_10=10º -date_ordinal_11=11º -date_ordinal_12=12º -date_ordinal_13=13º -date_ordinal_14=14º -date_ordinal_15=15º -date_ordinal_16=16º -date_ordinal_17=17º -date_ordinal_18=18º -date_ordinal_19=19º -date_ordinal_20=20º -date_ordinal_21=21º -date_ordinal_22=22º -date_ordinal_23=23º -date_ordinal_24=24º -date_ordinal_25=25º -date_ordinal_26=26º -date_ordinal_27=27º -date_ordinal_28=28º -date_ordinal_29=29º -date_ordinal_30=30º +null_text.date= +null_text.time= +accept.text=Aceptar +cancel.text=Cancelar +clear.text=Despejar +nav_current_day=Ir a Hoy +nav_current_time=Ir a la Hora Actual +nav_prev_month=Mes Anterior +nav_next_month=Siguiente Mes +nav_prev_year=Año Anterior +nav_next_year=Siguiente Año +today.text=Hoy +today_verbose.text=Hoy es {0,date,EEEE}, {1} +date_ordinal_1=1º +date_ordinal_2=2º +date_ordinal_3=3º +date_ordinal_4=4º +date_ordinal_5=5º +date_ordinal_6=6º +date_ordinal_7=7º +date_ordinal_8=8º +date_ordinal_9=9º +date_ordinal_10=10º +date_ordinal_11=11º +date_ordinal_12=12º +date_ordinal_13=13º +date_ordinal_14=14º +date_ordinal_15=15º +date_ordinal_16=16º +date_ordinal_17=17º +date_ordinal_18=18º +date_ordinal_19=19º +date_ordinal_20=20º +date_ordinal_21=21º +date_ordinal_22=22º +date_ordinal_23=23º +date_ordinal_24=24º +date_ordinal_25=25º +date_ordinal_26=26º +date_ordinal_27=27º +date_ordinal_28=28º +date_ordinal_29=29º +date_ordinal_30=30º date_ordinal_31=31º \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_fr.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_fr.properties index aa2f2243c..7d5c97e69 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_fr.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_fr.properties @@ -1,44 +1,44 @@ -null_text.date= -null_text.time= -accept.text=Accepter -cancel.text=Annuler -clear.text=Supprimer -nav_current_day=Aller \u00E0 aujourd'hui -nav_current_time=Aller \u00E0 l''heure actuelle -nav_prev_month=Mois pr\u00E9c\u00E9dent -nav_next_month=Mois suivant -nav_prev_year=Ann\u00E9e pr\u00E9c\u00E9dente -nav_next_year=Ann\u00E9e suivante -today.text=Aujourd'hui -today_verbose.text=Aujourd''hui nous sommes le {0,date,EEEE} {1} {0,date,MMMMM} {0,date,yyyy} -date_ordinal_1=1er -date_ordinal_2=2 -date_ordinal_3=3 -date_ordinal_4=4 -date_ordinal_5=5 -date_ordinal_6=6 -date_ordinal_7=7 -date_ordinal_8=8 -date_ordinal_9=9 -date_ordinal_10=10 -date_ordinal_11=11 -date_ordinal_12=12 -date_ordinal_13=13 -date_ordinal_14=14 -date_ordinal_15=15 -date_ordinal_16=16 -date_ordinal_17=17 -date_ordinal_18=18 -date_ordinal_19=19 -date_ordinal_20=20 -date_ordinal_21=21 -date_ordinal_22=22 -date_ordinal_23=23 -date_ordinal_24=24 -date_ordinal_25=25 -date_ordinal_26=26 -date_ordinal_27=27 -date_ordinal_28=28 -date_ordinal_29=29 -date_ordinal_30=30 -date_ordinal_31=31 +null_text.date= +null_text.time= +accept.text=Accepter +cancel.text=Annuler +clear.text=Supprimer +nav_current_day=Aller \u00E0 aujourd'hui +nav_current_time=Aller \u00E0 l''heure actuelle +nav_prev_month=Mois pr\u00E9c\u00E9dent +nav_next_month=Mois suivant +nav_prev_year=Ann\u00E9e pr\u00E9c\u00E9dente +nav_next_year=Ann\u00E9e suivante +today.text=Aujourd'hui +today_verbose.text=Aujourd''hui nous sommes le {0,date,EEEE} {1} {0,date,MMMMM} {0,date,yyyy} +date_ordinal_1=1er +date_ordinal_2=2 +date_ordinal_3=3 +date_ordinal_4=4 +date_ordinal_5=5 +date_ordinal_6=6 +date_ordinal_7=7 +date_ordinal_8=8 +date_ordinal_9=9 +date_ordinal_10=10 +date_ordinal_11=11 +date_ordinal_12=12 +date_ordinal_13=13 +date_ordinal_14=14 +date_ordinal_15=15 +date_ordinal_16=16 +date_ordinal_17=17 +date_ordinal_18=18 +date_ordinal_19=19 +date_ordinal_20=20 +date_ordinal_21=21 +date_ordinal_22=22 +date_ordinal_23=23 +date_ordinal_24=24 +date_ordinal_25=25 +date_ordinal_26=26 +date_ordinal_27=27 +date_ordinal_28=28 +date_ordinal_29=29 +date_ordinal_30=30 +date_ordinal_31=31 diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_hu_HU.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_hu_HU.properties index 0224b7c20..3d6675904 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_hu_HU.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_hu_HU.properties @@ -1,89 +1,89 @@ - -accept.text = Elfogad - -cancel.text = M\u00E9gse - -clear.text = T\u00F6r\u00F6l - -date_ordinal_1 = 1. - -date_ordinal_10 = 10. - -date_ordinal_11 = 11. - -date_ordinal_12 = 12. - -date_ordinal_13 = 13. - -date_ordinal_14 = 14. - -date_ordinal_15 = 15. - -date_ordinal_16 = 16. - -date_ordinal_17 = 17. - -date_ordinal_18 = 18. - -date_ordinal_19 = 19. - -date_ordinal_2 = 2. - -date_ordinal_20 = 20. - -date_ordinal_21 = 21. - -date_ordinal_22 = 22. - -date_ordinal_23 = 23. - -date_ordinal_24 = 24. - -date_ordinal_25 = 25. - -date_ordinal_26 = 26. - -date_ordinal_27 = 27. - -date_ordinal_28 = 28. - -date_ordinal_29 = 29. - -date_ordinal_3 = 3. - -date_ordinal_30 = 30. - -date_ordinal_31 = 31. - -date_ordinal_4 = 4. - -date_ordinal_5 = 5. - -date_ordinal_6 = 6. - -date_ordinal_7 = 7. - -date_ordinal_8 = 8. - -date_ordinal_9 = 9. - -nav_current_day = Ugr\u00E1s a mai napra - -nav_current_time = Aktu\u00E1lis id\u0151 - -nav_next_month = K\u00F6vetkez\u0151 h\u00F3nap - -nav_next_year = K\u00F6vetkez\u0151 \u00E9v - -nav_prev_month = El\u0151z\u0151 h\u00F3nap - -nav_prev_year = El\u0151z\u0151 \u00E9v - -null_text.date = -null_text.time = - -show_selection = Kiv\u00E1laszt\u00E1. mutat - -today.text = Ma - -today_verbose.text = Ma {0,date,EEEE}, {1} van + +accept.text = Elfogad + +cancel.text = M\u00E9gse + +clear.text = T\u00F6r\u00F6l + +date_ordinal_1 = 1. + +date_ordinal_10 = 10. + +date_ordinal_11 = 11. + +date_ordinal_12 = 12. + +date_ordinal_13 = 13. + +date_ordinal_14 = 14. + +date_ordinal_15 = 15. + +date_ordinal_16 = 16. + +date_ordinal_17 = 17. + +date_ordinal_18 = 18. + +date_ordinal_19 = 19. + +date_ordinal_2 = 2. + +date_ordinal_20 = 20. + +date_ordinal_21 = 21. + +date_ordinal_22 = 22. + +date_ordinal_23 = 23. + +date_ordinal_24 = 24. + +date_ordinal_25 = 25. + +date_ordinal_26 = 26. + +date_ordinal_27 = 27. + +date_ordinal_28 = 28. + +date_ordinal_29 = 29. + +date_ordinal_3 = 3. + +date_ordinal_30 = 30. + +date_ordinal_31 = 31. + +date_ordinal_4 = 4. + +date_ordinal_5 = 5. + +date_ordinal_6 = 6. + +date_ordinal_7 = 7. + +date_ordinal_8 = 8. + +date_ordinal_9 = 9. + +nav_current_day = Ugr\u00E1s a mai napra + +nav_current_time = Aktu\u00E1lis id\u0151 + +nav_next_month = K\u00F6vetkez\u0151 h\u00F3nap + +nav_next_year = K\u00F6vetkez\u0151 \u00E9v + +nav_prev_month = El\u0151z\u0151 h\u00F3nap + +nav_prev_year = El\u0151z\u0151 \u00E9v + +null_text.date = +null_text.time = + +show_selection = Kiv\u00E1laszt\u00E1. mutat + +today.text = Ma + +today_verbose.text = Ma {0,date,EEEE}, {1} van diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_it_IT.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_it_IT.properties index 79b809242..27adb7810 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_it_IT.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_it_IT.properties @@ -1,44 +1,44 @@ -null_text.date= -null_text.time= -accept.text=Accetta -cancel.text=Cancella -clear.text=Selezione Libera -nav_current_day=Vai a Oggi -nav_current_time=Vai all'ora corrente -nav_prev_month=Mese Precedente -nav_next_month=Prossimo Mese -nav_prev_year=Anno Precedente -nav_next_year=Prossimo Anno -today.text=Oggi -today_verbose.text=Oggi è {0,date,EEEE}, il {1} giorno -date_ordinal_1=1° -date_ordinal_2=2° -date_ordinal_3=3° -date_ordinal_4=4° -date_ordinal_5=5° -date_ordinal_6=6° -date_ordinal_7=7° -date_ordinal_8=8° -date_ordinal_9=9° -date_ordinal_10=10° -date_ordinal_11=11° -date_ordinal_12=12° -date_ordinal_13=13° -date_ordinal_14=14° -date_ordinal_15=15° -date_ordinal_16=16° -date_ordinal_17=17° -date_ordinal_18=18° -date_ordinal_19=19° -date_ordinal_20=20° -date_ordinal_21=21° -date_ordinal_22=22° -date_ordinal_23=23° -date_ordinal_24=24° -date_ordinal_25=25° -date_ordinal_26=26° -date_ordinal_27=27° -date_ordinal_28=28° -date_ordinal_29=29° -date_ordinal_30=30° +null_text.date= +null_text.time= +accept.text=Accetta +cancel.text=Cancella +clear.text=Selezione Libera +nav_current_day=Vai a Oggi +nav_current_time=Vai all'ora corrente +nav_prev_month=Mese Precedente +nav_next_month=Prossimo Mese +nav_prev_year=Anno Precedente +nav_next_year=Prossimo Anno +today.text=Oggi +today_verbose.text=Oggi è {0,date,EEEE}, il {1} giorno +date_ordinal_1=1° +date_ordinal_2=2° +date_ordinal_3=3° +date_ordinal_4=4° +date_ordinal_5=5° +date_ordinal_6=6° +date_ordinal_7=7° +date_ordinal_8=8° +date_ordinal_9=9° +date_ordinal_10=10° +date_ordinal_11=11° +date_ordinal_12=12° +date_ordinal_13=13° +date_ordinal_14=14° +date_ordinal_15=15° +date_ordinal_16=16° +date_ordinal_17=17° +date_ordinal_18=18° +date_ordinal_19=19° +date_ordinal_20=20° +date_ordinal_21=21° +date_ordinal_22=22° +date_ordinal_23=23° +date_ordinal_24=24° +date_ordinal_25=25° +date_ordinal_26=26° +date_ordinal_27=27° +date_ordinal_28=28° +date_ordinal_29=29° +date_ordinal_30=30° date_ordinal_31=31° \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_nl_NL.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_nl_NL.properties index 849f066d4..7397ab53a 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_nl_NL.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_nl_NL.properties @@ -1,45 +1,45 @@ -null_text.date= -null_text.time= -accept.text=Accepteren -cancel.text=Afbreken -clear.text=Wissen -nav_current_day=Vandaag -nav_current_time=Huidige Tijd -nav_prev_month=Vorige Maand -nav_next_month=Volgende Maand -nav_prev_year=Vorig Jaar -nav_next_year=Volgend Jaar -today.text=Vandaag -today_verbose.text=Vandaag is het {0,date,EEEE}, de {1} -show_selection=Toon Selectie -date_ordinal_1=1e -date_ordinal_2=2e -date_ordinal_3=3e -date_ordinal_4=4e -date_ordinal_5=5e -date_ordinal_6=6e -date_ordinal_7=7e -date_ordinal_8=8e -date_ordinal_9=9e -date_ordinal_10=10e -date_ordinal_11=11e -date_ordinal_12=12e -date_ordinal_13=13e -date_ordinal_14=14e -date_ordinal_15=15e -date_ordinal_16=16e -date_ordinal_17=17e -date_ordinal_18=18e -date_ordinal_19=19e -date_ordinal_20=20e -date_ordinal_21=21e -date_ordinal_22=22e -date_ordinal_23=23e -date_ordinal_24=24e -date_ordinal_25=25e -date_ordinal_26=26e -date_ordinal_27=27e -date_ordinal_28=28e -date_ordinal_29=29e -date_ordinal_30=30e +null_text.date= +null_text.time= +accept.text=Accepteren +cancel.text=Afbreken +clear.text=Wissen +nav_current_day=Vandaag +nav_current_time=Huidige Tijd +nav_prev_month=Vorige Maand +nav_next_month=Volgende Maand +nav_prev_year=Vorig Jaar +nav_next_year=Volgend Jaar +today.text=Vandaag +today_verbose.text=Vandaag is het {0,date,EEEE}, de {1} +show_selection=Toon Selectie +date_ordinal_1=1e +date_ordinal_2=2e +date_ordinal_3=3e +date_ordinal_4=4e +date_ordinal_5=5e +date_ordinal_6=6e +date_ordinal_7=7e +date_ordinal_8=8e +date_ordinal_9=9e +date_ordinal_10=10e +date_ordinal_11=11e +date_ordinal_12=12e +date_ordinal_13=13e +date_ordinal_14=14e +date_ordinal_15=15e +date_ordinal_16=16e +date_ordinal_17=17e +date_ordinal_18=18e +date_ordinal_19=19e +date_ordinal_20=20e +date_ordinal_21=21e +date_ordinal_22=22e +date_ordinal_23=23e +date_ordinal_24=24e +date_ordinal_25=25e +date_ordinal_26=26e +date_ordinal_27=27e +date_ordinal_28=28e +date_ordinal_29=29e +date_ordinal_30=30e date_ordinal_31=31e \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_no_NO.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_no_NO.properties index 9aa602ea5..5823bef1b 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_no_NO.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_no_NO.properties @@ -1,44 +1,44 @@ -null_text.date= -null_text.time= -accept.text=Velg -cancel.text=Avbryt -clear.text=Clear -nav_current_day=Gå Til Idag -nav_current_time=Gå Til Nå -nav_prev_month=Forrige Måned -nav_next_month=Neste Måned -nav_prev_year=Forrige År -nav_next_year=Neste År -today.text=Idag -today_verbose.text=Idag er {0,date,EEEE} den {1} -date_ordinal_1=1ste -date_ordinal_2=2dre -date_ordinal_3=3dje -date_ordinal_4=4de -date_ordinal_5=5te -date_ordinal_6=6te -date_ordinal_7=7nde -date_ordinal_8=8nde -date_ordinal_9=9nde -date_ordinal_10=10nde -date_ordinal_11=11te -date_ordinal_12=12te -date_ordinal_13=13nde -date_ordinal_14=14nde -date_ordinal_15=15nde -date_ordinal_16=16nde -date_ordinal_17=17nde -date_ordinal_18=18nde -date_ordinal_19=19nde -date_ordinal_20=20nde -date_ordinal_21=21ste -date_ordinal_22=22dre -date_ordinal_23=23dje -date_ordinal_24=24de -date_ordinal_25=25te -date_ordinal_26=26te -date_ordinal_27=27nde -date_ordinal_28=28nde -date_ordinal_29=29nde -date_ordinal_30=30te +null_text.date= +null_text.time= +accept.text=Velg +cancel.text=Avbryt +clear.text=Clear +nav_current_day=Gå Til Idag +nav_current_time=Gå Til Nå +nav_prev_month=Forrige Måned +nav_next_month=Neste Måned +nav_prev_year=Forrige År +nav_next_year=Neste År +today.text=Idag +today_verbose.text=Idag er {0,date,EEEE} den {1} +date_ordinal_1=1ste +date_ordinal_2=2dre +date_ordinal_3=3dje +date_ordinal_4=4de +date_ordinal_5=5te +date_ordinal_6=6te +date_ordinal_7=7nde +date_ordinal_8=8nde +date_ordinal_9=9nde +date_ordinal_10=10nde +date_ordinal_11=11te +date_ordinal_12=12te +date_ordinal_13=13nde +date_ordinal_14=14nde +date_ordinal_15=15nde +date_ordinal_16=16nde +date_ordinal_17=17nde +date_ordinal_18=18nde +date_ordinal_19=19nde +date_ordinal_20=20nde +date_ordinal_21=21ste +date_ordinal_22=22dre +date_ordinal_23=23dje +date_ordinal_24=24de +date_ordinal_25=25te +date_ordinal_26=26te +date_ordinal_27=27nde +date_ordinal_28=28nde +date_ordinal_29=29nde +date_ordinal_30=30te date_ordinal_31=31ste \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_pl_PL.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_pl_PL.properties index 4d2df38aa..d46252ee4 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_pl_PL.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_pl_PL.properties @@ -1,44 +1,44 @@ -null_text.date= -null_text.time= -accept.text=Akceptuj -cancel.text=Anuluj -clear.text=Clear -nav_current_day=Id\u017a do dzisiejszej daty -nav_current_time=Id\u017a do obecnego czasu -nav_prev_month=Poprzedni miesi\u0105c -nav_next_month=Nast\u0119pny miesi\u0105c -nav_prev_year=Poprzedni rok -nav_next_year=Nast\u0119pny rok -today.text=Dzi\u015b -today_verbose.text=Dzi\u015b jest {0,date,EEEE}, {1} {0,date,MMMM} -date_ordinal_1=1. -date_ordinal_2=2. -date_ordinal_3=3. -date_ordinal_4=4. -date_ordinal_5=5. -date_ordinal_6=6. -date_ordinal_7=7. -date_ordinal_8=8. -date_ordinal_9=9. -date_ordinal_10=10. -date_ordinal_11=11. -date_ordinal_12=12. -date_ordinal_13=13. -date_ordinal_14=14. -date_ordinal_15=15. -date_ordinal_16=16. -date_ordinal_17=17. -date_ordinal_18=18. -date_ordinal_19=19. -date_ordinal_20=20. -date_ordinal_21=21. -date_ordinal_22=22. -date_ordinal_23=23. -date_ordinal_24=24. -date_ordinal_25=25. -date_ordinal_26=26. -date_ordinal_27=27. -date_ordinal_28=28. -date_ordinal_29=29. -date_ordinal_30=30. +null_text.date= +null_text.time= +accept.text=Akceptuj +cancel.text=Anuluj +clear.text=Clear +nav_current_day=Id\u017a do dzisiejszej daty +nav_current_time=Id\u017a do obecnego czasu +nav_prev_month=Poprzedni miesi\u0105c +nav_next_month=Nast\u0119pny miesi\u0105c +nav_prev_year=Poprzedni rok +nav_next_year=Nast\u0119pny rok +today.text=Dzi\u015b +today_verbose.text=Dzi\u015b jest {0,date,EEEE}, {1} {0,date,MMMM} +date_ordinal_1=1. +date_ordinal_2=2. +date_ordinal_3=3. +date_ordinal_4=4. +date_ordinal_5=5. +date_ordinal_6=6. +date_ordinal_7=7. +date_ordinal_8=8. +date_ordinal_9=9. +date_ordinal_10=10. +date_ordinal_11=11. +date_ordinal_12=12. +date_ordinal_13=13. +date_ordinal_14=14. +date_ordinal_15=15. +date_ordinal_16=16. +date_ordinal_17=17. +date_ordinal_18=18. +date_ordinal_19=19. +date_ordinal_20=20. +date_ordinal_21=21. +date_ordinal_22=22. +date_ordinal_23=23. +date_ordinal_24=24. +date_ordinal_25=25. +date_ordinal_26=26. +date_ordinal_27=27. +date_ordinal_28=28. +date_ordinal_29=29. +date_ordinal_30=30. date_ordinal_31=31. \ No newline at end of file diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_pt_BR.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_pt_BR.properties index 18e20fe9f..0a251bb0a 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_pt_BR.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_pt_BR.properties @@ -1,45 +1,45 @@ -null_text.date= -null_text.time= -accept.text=OK -cancel.text=Cancelar -clear.text=Limpar -nav_current_day=Ir Para a Data Atual -nav_current_time=Ir Para a Hora Atual -nav_prev_month=Mês Anterior -nav_next_month=Próximo Mês -nav_prev_year=Ano Anterior -nav_next_year=Próximo Ano -today.text=Hoje -today_verbose.text=Hoje é {0,date,EEEE}, dia {1} -show_selection=Mostrar Seleção -date_ordinal_1=1 -date_ordinal_2=2 -date_ordinal_3=3 -date_ordinal_4=4 -date_ordinal_5=5 -date_ordinal_6=6 -date_ordinal_7=7 -date_ordinal_8=8 -date_ordinal_9=9 -date_ordinal_10=10 -date_ordinal_11=11 -date_ordinal_12=12 -date_ordinal_13=13 -date_ordinal_14=14 -date_ordinal_15=15 -date_ordinal_16=16 -date_ordinal_17=17 -date_ordinal_18=18 -date_ordinal_19=19 -date_ordinal_20=20 -date_ordinal_21=21 -date_ordinal_22=22 -date_ordinal_23=23 -date_ordinal_24=24 -date_ordinal_25=25 -date_ordinal_26=26 -date_ordinal_27=27 -date_ordinal_28=28 -date_ordinal_29=29 -date_ordinal_30=30 -date_ordinal_31=31 +null_text.date= +null_text.time= +accept.text=OK +cancel.text=Cancelar +clear.text=Limpar +nav_current_day=Ir Para a Data Atual +nav_current_time=Ir Para a Hora Atual +nav_prev_month=Mês Anterior +nav_next_month=Próximo Mês +nav_prev_year=Ano Anterior +nav_next_year=Próximo Ano +today.text=Hoje +today_verbose.text=Hoje é {0,date,EEEE}, dia {1} +show_selection=Mostrar Seleção +date_ordinal_1=1 +date_ordinal_2=2 +date_ordinal_3=3 +date_ordinal_4=4 +date_ordinal_5=5 +date_ordinal_6=6 +date_ordinal_7=7 +date_ordinal_8=8 +date_ordinal_9=9 +date_ordinal_10=10 +date_ordinal_11=11 +date_ordinal_12=12 +date_ordinal_13=13 +date_ordinal_14=14 +date_ordinal_15=15 +date_ordinal_16=16 +date_ordinal_17=17 +date_ordinal_18=18 +date_ordinal_19=19 +date_ordinal_20=20 +date_ordinal_21=21 +date_ordinal_22=22 +date_ordinal_23=23 +date_ordinal_24=24 +date_ordinal_25=25 +date_ordinal_26=26 +date_ordinal_27=27 +date_ordinal_28=28 +date_ordinal_29=29 +date_ordinal_30=30 +date_ordinal_31=31 diff --git a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_ru.properties b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_ru.properties index de82a69f7..f9da0a25d 100644 --- a/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_ru.properties +++ b/widgets/cdatetime/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/messages_ru.properties @@ -1,89 +1,89 @@ - -accept.text = \u041F\u0440\u0438\u043D\u044F\u0442\u044C - -cancel.text = \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C - -clear.text = \u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C - -date_ordinal_1 = 1 - -date_ordinal_10 = 10 - -date_ordinal_11 = 11 - -date_ordinal_12 = 12 - -date_ordinal_13 = 13 - -date_ordinal_14 = 14 - -date_ordinal_15 = 15 - -date_ordinal_16 = 16 - -date_ordinal_17 = 17 - -date_ordinal_18 = 18 - -date_ordinal_19 = 19 - -date_ordinal_2 = 2 - -date_ordinal_20 = 20 - -date_ordinal_21 = 21 - -date_ordinal_22 = 22 - -date_ordinal_23 = 23 - -date_ordinal_24 = 24 - -date_ordinal_25 = 25 - -date_ordinal_26 = 26 - -date_ordinal_27 = 27 - -date_ordinal_28 = 28 - -date_ordinal_29 = 29 - -date_ordinal_3 = 3 - -date_ordinal_30 = 30 - -date_ordinal_31 = 31 - -date_ordinal_4 = 4 - -date_ordinal_5 = 5 - -date_ordinal_6 = 6 - -date_ordinal_7 = 7 - -date_ordinal_8 = 8 - -date_ordinal_9 = 9 - -nav_current_day = \u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u043A \u0441\u0435\u0433\u043E\u0434\u043D\u044F\u0448\u043D\u0435\u0439 \u0434\u0430\u0442\u0435 - -nav_current_time = \u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0442\u0435\u043A\u0443\u0449\u0435\u0435 \u0432\u0440\u0435\u043C\u044F - -nav_next_month = \u0421\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439 \u043C\u0435\u0441\u044F\u0446 - -nav_next_year = \u0421\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439 \u0433\u043E\u0434 - -nav_prev_month = \u041F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0438\u0439 \u043C\u0435\u0441\u044F\u0446 - -nav_prev_year = \u041F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0438\u0439 \u0433\u043E\u0434 - -null_text.date = <\u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0430\u0442\u0443> -null_text.time = <\u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0440\u0435\u043C\u044F> - -show_selection = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u0434\u0430\u0442\u0443 \u0438 \u0432\u0440\u0435\u043C\u044F - -today.text = \u0421\u0435\u0433\u043E\u0434\u043D\u044F - -today_verbose.text = \u0421\u0435\u0433\u043E\u0434\u043D\u044F {0,date,EEEE, d MMM.} + +accept.text = \u041F\u0440\u0438\u043D\u044F\u0442\u044C + +cancel.text = \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C + +clear.text = \u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C + +date_ordinal_1 = 1 + +date_ordinal_10 = 10 + +date_ordinal_11 = 11 + +date_ordinal_12 = 12 + +date_ordinal_13 = 13 + +date_ordinal_14 = 14 + +date_ordinal_15 = 15 + +date_ordinal_16 = 16 + +date_ordinal_17 = 17 + +date_ordinal_18 = 18 + +date_ordinal_19 = 19 + +date_ordinal_2 = 2 + +date_ordinal_20 = 20 + +date_ordinal_21 = 21 + +date_ordinal_22 = 22 + +date_ordinal_23 = 23 + +date_ordinal_24 = 24 + +date_ordinal_25 = 25 + +date_ordinal_26 = 26 + +date_ordinal_27 = 27 + +date_ordinal_28 = 28 + +date_ordinal_29 = 29 + +date_ordinal_3 = 3 + +date_ordinal_30 = 30 + +date_ordinal_31 = 31 + +date_ordinal_4 = 4 + +date_ordinal_5 = 5 + +date_ordinal_6 = 6 + +date_ordinal_7 = 7 + +date_ordinal_8 = 8 + +date_ordinal_9 = 9 + +nav_current_day = \u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u043A \u0441\u0435\u0433\u043E\u0434\u043D\u044F\u0448\u043D\u0435\u0439 \u0434\u0430\u0442\u0435 + +nav_current_time = \u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0442\u0435\u043A\u0443\u0449\u0435\u0435 \u0432\u0440\u0435\u043C\u044F + +nav_next_month = \u0421\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439 \u043C\u0435\u0441\u044F\u0446 + +nav_next_year = \u0421\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439 \u0433\u043E\u0434 + +nav_prev_month = \u041F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0438\u0439 \u043C\u0435\u0441\u044F\u0446 + +nav_prev_year = \u041F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0438\u0439 \u0433\u043E\u0434 + +null_text.date = <\u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0430\u0442\u0443> +null_text.time = <\u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0440\u0435\u043C\u044F> + +show_selection = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u0434\u0430\u0442\u0443 \u0438 \u0432\u0440\u0435\u043C\u044F + +today.text = \u0421\u0435\u0433\u043E\u0434\u043D\u044F + +today_verbose.text = \u0421\u0435\u0433\u043E\u0434\u043D\u044F {0,date,EEEE, d MMM.} diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/.project b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/.project index 7e8bc136f..3614e50d6 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/.project +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.chips.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.chips.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/build.properties b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/build.properties +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/feature.properties b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/feature.properties +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/feature.xml b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/feature.xml index 8f7e36b7c..cf9a97b9a 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/feature.xml +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/feature.xml @@ -1,34 +1,34 @@ - - - - - Chips Widget - - - - %license - - - - - - - - - - - + + + + + Chips Widget + + + + %license + + + + + + + + + + + diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/pom.xml b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/pom.xml index 9a5744395..95325b749 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.feature/pom.xml +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - chips - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.chips.feature - eclipse-feature - 1.0.0-SNAPSHOT - - Nebula Chips Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + chips + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.chips.feature + eclipse-feature + 1.0.0-SNAPSHOT + + Nebula Chips Feature + + diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.classpath b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.classpath +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.project b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.project index 97576d320..e21a1652b 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.project +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.chips.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.chips.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/META-INF/MANIFEST.MF b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/META-INF/MANIFEST.MF index 74acb8648..e97980c74 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/META-INF/MANIFEST.MF +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Chips Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.chips.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.chips;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.chips.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Chips Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.chips.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.chips;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.chips.snippets diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/build.properties b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/build.properties +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/pom.xml b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/pom.xml index e78b35fa8..0c31cb9aa 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/pom.xml +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - chips - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.chips.snippets - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + chips + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.chips.snippets + eclipse-plugin + + diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/src/org/eclipse/nebula/widgets/chips/ChipsSnippet.java b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/src/org/eclipse/nebula/widgets/chips/ChipsSnippet.java index d421fdb13..1e007ea7c 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/src/org/eclipse/nebula/widgets/chips/ChipsSnippet.java +++ b/widgets/chips/org.eclipse.nebula.widgets.chips.snippets/src/org/eclipse/nebula/widgets/chips/ChipsSnippet.java @@ -1,341 +1,341 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.chips; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; - -/** - * Snippet for the Chips widget - */ -public class ChipsSnippet { - - private static Shell shell; - - /** - * @param args - */ - public static void main(final String[] args) { - final Display display = new Display(); - shell = new Shell(display); - shell.setText("Chips Snippet"); - shell.setLayout(new GridLayout(1, false)); - shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); - - createColoredChipsArea(); - createCloseChipsArea(); - createCloseImageChipsArea(); - createCheckedChipsArea(); - createPushChipsArea(); - - shell.pack(); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - display.dispose(); - - } - - private static void createColoredChipsArea() { - final Label lbl = new Label(shell, SWT.CENTER); - lbl.setText("Colored chips (Eclipse Projects) - Read Only"); - lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - final Composite cmp = new Composite(shell, SWT.NONE); - cmp.setLayoutData(new GridData(GridData.CENTER, GridData.FILL, false, false)); - cmp.setLayout(new GridLayout(5, false)); - cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Chips chip1 = new Chips(cmp, SWT.NONE); - chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip1.setChipsBackground(SWTGraphicUtil.getColorSafely(227, 22, 91)); - chip1.setText("Equinox"); - chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Chips chip2 = new Chips(cmp, SWT.NONE); - chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip2.setChipsBackground(SWTGraphicUtil.getColorSafely(3, 120, 213)); - chip2.setText("Nebula"); - chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Chips chip3 = new Chips(cmp, SWT.NONE); - chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip3.setChipsBackground(SWTGraphicUtil.getColorSafely(77, 132, 29)); - chip3.setText("XText"); - chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Chips chip4 = new Chips(cmp, SWT.NONE); - chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip4.setChipsBackground(SWTGraphicUtil.getColorSafely(214, 65, 19)); - chip4.setText("Wild Web Developer"); - chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Chips chip5 = new Chips(cmp, SWT.NONE); - chip5.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip5.setChipsBackground(SWTGraphicUtil.getColorSafely(193, 87, 0)); - chip5.setText("JDT"); - chip5.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - } - - private static void createCloseChipsArea() { - final Label lbl = new Label(shell, SWT.CENTER); - lbl.setText("Close chips (Eclipse Fundation Members)"); - lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - final Composite cmp = new Composite(shell, SWT.NONE); - cmp.setLayoutData(new GridData(GridData.CENTER, GridData.FILL, false, false)); - cmp.setLayout(new GridLayout(4, false)); - cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Color bgColor = SWTGraphicUtil.getColorSafely(224, 224, 244); - - final Chips chip1 = new Chips(cmp, SWT.CLOSE); - chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip1.setChipsBackground(bgColor); - chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip1.setText("IBM"); - - final Chips chip2 = new Chips(cmp, SWT.CLOSE); - chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip2.setChipsBackground(bgColor); - chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip2.setText("Red Hat"); - - final Chips chip3 = new Chips(cmp, SWT.CLOSE); - chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip3.setChipsBackground(bgColor); - chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip3.setText("Remain Software"); - - final Chips chip4 = new Chips(cmp, SWT.CLOSE); - chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip4.setChipsBackground(bgColor); - chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip4.setText("Vogella"); - - final CloseListener closeListener = event -> { - final Chips chip = (Chips) event.widget; - System.out.println("Closed on " + chip.getText()); - chip.dispose(); - cmp.layout(true); - }; - - chip1.addCloseListener(closeListener); - chip2.addCloseListener(closeListener); - chip3.addCloseListener(closeListener); - chip4.addCloseListener(closeListener); - } - - private static void createCloseImageChipsArea() { - final Label lbl = new Label(shell, SWT.CENTER); - lbl.setText("Close & Images (Nebula Devs)"); - lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - final Composite cmp = new Composite(shell, SWT.NONE); - cmp.setLayoutData(new GridData(GridData.CENTER, GridData.FILL, false, false)); - cmp.setLayout(new GridLayout(5, false)); - cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Color bgColor = SWTGraphicUtil.getColorSafely(224, 224, 244); - - final Chips chip1 = new Chips(cmp, SWT.CLOSE); - chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip1.setChipsBackground(bgColor); - chip1.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip1.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip1.setImage(loadImage("dirk.png")); - chip1.setText("Dirk"); - chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Chips chip2 = new Chips(cmp, SWT.CLOSE); - chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip2.setChipsBackground(bgColor); - chip2.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip2.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip2.setImage(loadImage("donald.png")); - chip2.setText("Donald"); - chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Chips chip3 = new Chips(cmp, SWT.CLOSE); - chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip3.setChipsBackground(bgColor); - chip3.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip3.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip3.setImage(loadImage("johannes.png")); - chip3.setText("Johannes"); - chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Chips chip4 = new Chips(cmp, SWT.CLOSE); - chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip4.setChipsBackground(bgColor); - chip4.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip4.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip4.setImage(loadImage("laurent.png")); - chip4.setText("Laurent"); - chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Chips chip5 = new Chips(cmp, SWT.CLOSE); - chip5.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip5.setChipsBackground(bgColor); - chip5.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip5.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip5.setImage(loadImage("wim.png")); - chip5.setText("Wim"); - chip5.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final CloseListener closeListener = event -> { - final Chips chip = (Chips) event.widget; - System.out.println("Closed on " + chip.getText()); - chip.dispose(); - cmp.layout(true); - }; - - chip1.addCloseListener(closeListener); - chip2.addCloseListener(closeListener); - chip3.addCloseListener(closeListener); - chip4.addCloseListener(closeListener); - - } - - private static Image loadImage(final String img) { - return new Image(shell.getDisplay(), ChipsSnippet.class.getResourceAsStream(img)); - } - - private static void createCheckedChipsArea() { - final Label lbl = new Label(shell, SWT.CENTER); - lbl.setText("Checked chips : Skills"); - lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - final Composite cmp = new Composite(shell, SWT.NONE); - cmp.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - cmp.setLayout(new GridLayout(5, false)); - cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Color bgColor = SWTGraphicUtil.getColorSafely(224, 224, 244); - final Color checkColor = SWTGraphicUtil.getColorSafely(188, 188, 188); - - final Chips chip1 = new Chips(cmp, SWT.CHECK); - chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip1.setChipsBackground(bgColor); - chip1.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip1.setPushedStateBackground(checkColor); - chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip1.setText("Java"); - chip1.setSelection(true); - chip1.setLayoutData(new GridData(GridData.END, GridData.FILL, true, false)); - - final Chips chip2 = new Chips(cmp, SWT.CHECK); - chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip2.setChipsBackground(bgColor); - chip2.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip2.setPushedStateBackground(checkColor); - chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip2.setText("SWT"); - - final Chips chip3 = new Chips(cmp, SWT.CHECK); - chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip3.setChipsBackground(bgColor); - chip3.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip3.setPushedStateBackground(checkColor); - chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip3.setText("JFace"); - - final Chips chip4 = new Chips(cmp, SWT.CHECK); - chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip4.setChipsBackground(bgColor); - chip4.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip4.setPushedStateBackground(checkColor); - chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip4.setText("EMF"); - chip4.setLayoutData(new GridData(GridData.BEGINNING, GridData.FILL, true, false)); - - final Listener listener = event -> { - final Chips chip = (Chips) event.widget; - System.out.println("Click on " + chip.getText()); - }; - - chip1.addListener(SWT.Selection, listener); - chip2.addListener(SWT.Selection, listener); - chip3.addListener(SWT.Selection, listener); - chip4.addListener(SWT.Selection, listener); - - } - - private static void createPushChipsArea() { - final Label lbl = new Label(shell, SWT.CENTER); - lbl.setText("Push chips"); - lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - final Composite cmp = new Composite(shell, SWT.NONE); - cmp.setLayoutData(new GridData(GridData.CENTER, GridData.FILL, false, false)); - cmp.setLayout(new GridLayout(4, false)); - cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - final Color checkColor = SWTGraphicUtil.getColorSafely(227, 22, 91); - - final Chips chip1 = new Chips(cmp, SWT.PUSH); - chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip1.setChipsBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip1.setBorderColor(checkColor); - chip1.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip1.setPushedStateBackground(checkColor); - chip1.setImage(loadImage("icons/bubble1_b.png")); - chip1.setPushImage(loadImage("icons/bubble1_w.png")); - chip1.setText("One"); - - final Chips chip2 = new Chips(cmp, SWT.PUSH); - chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip2.setChipsBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip2.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip2.setPushedStateBackground(checkColor); - chip2.setImage(loadImage("icons/bubble2_b.png")); - chip2.setPushImage(loadImage("icons/bubble2_w.png")); - chip2.setBorderColor(checkColor); - - chip2.setText("Two"); - - final Chips chip3 = new Chips(cmp, SWT.PUSH); - chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip3.setChipsBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip3.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip3.setPushedStateBackground(checkColor); - chip3.setImage(loadImage("icons/bubble3_b.png")); - chip3.setPushImage(loadImage("icons/bubble3_w.png")); - chip3.setBorderColor(checkColor); - chip3.setText("Three"); - - final Chips chip4 = new Chips(cmp, SWT.PUSH); - chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip4.setChipsBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip4.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - chip4.setPushedStateBackground(checkColor); - chip4.setImage(loadImage("icons/email_b.png")); - chip4.setPushImage(loadImage("icons/email_w.png")); - chip4.setBorderColor(checkColor); - chip4.setText("Mail"); - - } - +/******************************************************************************* + * Copyright (c) 2020 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.chips; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; + +/** + * Snippet for the Chips widget + */ +public class ChipsSnippet { + + private static Shell shell; + + /** + * @param args + */ + public static void main(final String[] args) { + final Display display = new Display(); + shell = new Shell(display); + shell.setText("Chips Snippet"); + shell.setLayout(new GridLayout(1, false)); + shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); + + createColoredChipsArea(); + createCloseChipsArea(); + createCloseImageChipsArea(); + createCheckedChipsArea(); + createPushChipsArea(); + + shell.pack(); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + display.dispose(); + + } + + private static void createColoredChipsArea() { + final Label lbl = new Label(shell, SWT.CENTER); + lbl.setText("Colored chips (Eclipse Projects) - Read Only"); + lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + final Composite cmp = new Composite(shell, SWT.NONE); + cmp.setLayoutData(new GridData(GridData.CENTER, GridData.FILL, false, false)); + cmp.setLayout(new GridLayout(5, false)); + cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Chips chip1 = new Chips(cmp, SWT.NONE); + chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip1.setChipsBackground(SWTGraphicUtil.getColorSafely(227, 22, 91)); + chip1.setText("Equinox"); + chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Chips chip2 = new Chips(cmp, SWT.NONE); + chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip2.setChipsBackground(SWTGraphicUtil.getColorSafely(3, 120, 213)); + chip2.setText("Nebula"); + chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Chips chip3 = new Chips(cmp, SWT.NONE); + chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip3.setChipsBackground(SWTGraphicUtil.getColorSafely(77, 132, 29)); + chip3.setText("XText"); + chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Chips chip4 = new Chips(cmp, SWT.NONE); + chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip4.setChipsBackground(SWTGraphicUtil.getColorSafely(214, 65, 19)); + chip4.setText("Wild Web Developer"); + chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Chips chip5 = new Chips(cmp, SWT.NONE); + chip5.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip5.setChipsBackground(SWTGraphicUtil.getColorSafely(193, 87, 0)); + chip5.setText("JDT"); + chip5.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + } + + private static void createCloseChipsArea() { + final Label lbl = new Label(shell, SWT.CENTER); + lbl.setText("Close chips (Eclipse Fundation Members)"); + lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + final Composite cmp = new Composite(shell, SWT.NONE); + cmp.setLayoutData(new GridData(GridData.CENTER, GridData.FILL, false, false)); + cmp.setLayout(new GridLayout(4, false)); + cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Color bgColor = SWTGraphicUtil.getColorSafely(224, 224, 244); + + final Chips chip1 = new Chips(cmp, SWT.CLOSE); + chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip1.setChipsBackground(bgColor); + chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip1.setText("IBM"); + + final Chips chip2 = new Chips(cmp, SWT.CLOSE); + chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip2.setChipsBackground(bgColor); + chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip2.setText("Red Hat"); + + final Chips chip3 = new Chips(cmp, SWT.CLOSE); + chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip3.setChipsBackground(bgColor); + chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip3.setText("Remain Software"); + + final Chips chip4 = new Chips(cmp, SWT.CLOSE); + chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip4.setChipsBackground(bgColor); + chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip4.setText("Vogella"); + + final CloseListener closeListener = event -> { + final Chips chip = (Chips) event.widget; + System.out.println("Closed on " + chip.getText()); + chip.dispose(); + cmp.layout(true); + }; + + chip1.addCloseListener(closeListener); + chip2.addCloseListener(closeListener); + chip3.addCloseListener(closeListener); + chip4.addCloseListener(closeListener); + } + + private static void createCloseImageChipsArea() { + final Label lbl = new Label(shell, SWT.CENTER); + lbl.setText("Close & Images (Nebula Devs)"); + lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + final Composite cmp = new Composite(shell, SWT.NONE); + cmp.setLayoutData(new GridData(GridData.CENTER, GridData.FILL, false, false)); + cmp.setLayout(new GridLayout(5, false)); + cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Color bgColor = SWTGraphicUtil.getColorSafely(224, 224, 244); + + final Chips chip1 = new Chips(cmp, SWT.CLOSE); + chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip1.setChipsBackground(bgColor); + chip1.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip1.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip1.setImage(loadImage("dirk.png")); + chip1.setText("Dirk"); + chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Chips chip2 = new Chips(cmp, SWT.CLOSE); + chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip2.setChipsBackground(bgColor); + chip2.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip2.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip2.setImage(loadImage("donald.png")); + chip2.setText("Donald"); + chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Chips chip3 = new Chips(cmp, SWT.CLOSE); + chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip3.setChipsBackground(bgColor); + chip3.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip3.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip3.setImage(loadImage("johannes.png")); + chip3.setText("Johannes"); + chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Chips chip4 = new Chips(cmp, SWT.CLOSE); + chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip4.setChipsBackground(bgColor); + chip4.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip4.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip4.setImage(loadImage("laurent.png")); + chip4.setText("Laurent"); + chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Chips chip5 = new Chips(cmp, SWT.CLOSE); + chip5.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip5.setChipsBackground(bgColor); + chip5.setHoverForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip5.setHoverBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip5.setImage(loadImage("wim.png")); + chip5.setText("Wim"); + chip5.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final CloseListener closeListener = event -> { + final Chips chip = (Chips) event.widget; + System.out.println("Closed on " + chip.getText()); + chip.dispose(); + cmp.layout(true); + }; + + chip1.addCloseListener(closeListener); + chip2.addCloseListener(closeListener); + chip3.addCloseListener(closeListener); + chip4.addCloseListener(closeListener); + + } + + private static Image loadImage(final String img) { + return new Image(shell.getDisplay(), ChipsSnippet.class.getResourceAsStream(img)); + } + + private static void createCheckedChipsArea() { + final Label lbl = new Label(shell, SWT.CENTER); + lbl.setText("Checked chips : Skills"); + lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + final Composite cmp = new Composite(shell, SWT.NONE); + cmp.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + cmp.setLayout(new GridLayout(5, false)); + cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Color bgColor = SWTGraphicUtil.getColorSafely(224, 224, 244); + final Color checkColor = SWTGraphicUtil.getColorSafely(188, 188, 188); + + final Chips chip1 = new Chips(cmp, SWT.CHECK); + chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip1.setChipsBackground(bgColor); + chip1.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip1.setPushedStateBackground(checkColor); + chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip1.setText("Java"); + chip1.setSelection(true); + chip1.setLayoutData(new GridData(GridData.END, GridData.FILL, true, false)); + + final Chips chip2 = new Chips(cmp, SWT.CHECK); + chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip2.setChipsBackground(bgColor); + chip2.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip2.setPushedStateBackground(checkColor); + chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip2.setText("SWT"); + + final Chips chip3 = new Chips(cmp, SWT.CHECK); + chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip3.setChipsBackground(bgColor); + chip3.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip3.setPushedStateBackground(checkColor); + chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip3.setText("JFace"); + + final Chips chip4 = new Chips(cmp, SWT.CHECK); + chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip4.setChipsBackground(bgColor); + chip4.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip4.setPushedStateBackground(checkColor); + chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip4.setText("EMF"); + chip4.setLayoutData(new GridData(GridData.BEGINNING, GridData.FILL, true, false)); + + final Listener listener = event -> { + final Chips chip = (Chips) event.widget; + System.out.println("Click on " + chip.getText()); + }; + + chip1.addListener(SWT.Selection, listener); + chip2.addListener(SWT.Selection, listener); + chip3.addListener(SWT.Selection, listener); + chip4.addListener(SWT.Selection, listener); + + } + + private static void createPushChipsArea() { + final Label lbl = new Label(shell, SWT.CENTER); + lbl.setText("Push chips"); + lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + final Composite cmp = new Composite(shell, SWT.NONE); + cmp.setLayoutData(new GridData(GridData.CENTER, GridData.FILL, false, false)); + cmp.setLayout(new GridLayout(4, false)); + cmp.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Color checkColor = SWTGraphicUtil.getColorSafely(227, 22, 91); + + final Chips chip1 = new Chips(cmp, SWT.PUSH); + chip1.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip1.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip1.setChipsBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip1.setBorderColor(checkColor); + chip1.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip1.setPushedStateBackground(checkColor); + chip1.setImage(loadImage("icons/bubble1_b.png")); + chip1.setPushImage(loadImage("icons/bubble1_w.png")); + chip1.setText("One"); + + final Chips chip2 = new Chips(cmp, SWT.PUSH); + chip2.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip2.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip2.setChipsBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip2.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip2.setPushedStateBackground(checkColor); + chip2.setImage(loadImage("icons/bubble2_b.png")); + chip2.setPushImage(loadImage("icons/bubble2_w.png")); + chip2.setBorderColor(checkColor); + + chip2.setText("Two"); + + final Chips chip3 = new Chips(cmp, SWT.PUSH); + chip3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip3.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip3.setChipsBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip3.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip3.setPushedStateBackground(checkColor); + chip3.setImage(loadImage("icons/bubble3_b.png")); + chip3.setPushImage(loadImage("icons/bubble3_w.png")); + chip3.setBorderColor(checkColor); + chip3.setText("Three"); + + final Chips chip4 = new Chips(cmp, SWT.PUSH); + chip4.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chip4.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip4.setChipsBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip4.setPushedStateForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + chip4.setPushedStateBackground(checkColor); + chip4.setImage(loadImage("icons/email_b.png")); + chip4.setPushImage(loadImage("icons/email_w.png")); + chip4.setBorderColor(checkColor); + chip4.setText("Mail"); + + } + } \ No newline at end of file diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips/.classpath b/widgets/chips/org.eclipse.nebula.widgets.chips/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips/.classpath +++ b/widgets/chips/org.eclipse.nebula.widgets.chips/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips/.project b/widgets/chips/org.eclipse.nebula.widgets.chips/.project index 4a76145bb..94ee36f57 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips/.project +++ b/widgets/chips/org.eclipse.nebula.widgets.chips/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.chips - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.chips + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips/.settings/org.eclipse.jdt.core.prefs b/widgets/chips/org.eclipse.nebula.widgets.chips/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/chips/org.eclipse.nebula.widgets.chips/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips/META-INF/MANIFEST.MF b/widgets/chips/org.eclipse.nebula.widgets.chips/META-INF/MANIFEST.MF index f9e79d513..30cd11839 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips/META-INF/MANIFEST.MF +++ b/widgets/chips/org.eclipse.nebula.widgets.chips/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Chips widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.chips -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Export-Package: org.eclipse.nebula.widgets.chips -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;visibility:=reexport, - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.chips +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Chips widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.chips +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Export-Package: org.eclipse.nebula.widgets.chips +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;visibility:=reexport, + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.chips diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips/build.properties b/widgets/chips/org.eclipse.nebula.widgets.chips/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips/build.properties +++ b/widgets/chips/org.eclipse.nebula.widgets.chips/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips/pom.xml b/widgets/chips/org.eclipse.nebula.widgets.chips/pom.xml index 419968fd7..3cc63cf8b 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips/pom.xml +++ b/widgets/chips/org.eclipse.nebula.widgets.chips/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - chips - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.chips - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + chips + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.chips + eclipse-plugin + + diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/Chips.java b/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/Chips.java index fe032f6c1..8a7ce73c3 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/Chips.java +++ b/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/Chips.java @@ -1,1204 +1,1204 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.chips; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -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.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; - -/** - * Instances of this class represent a "chips". This is a kind of rounded-shapped button. It can display information, - * or be used like a check or a push button. You can also add a close button. - * - *
- *
Styles:
- *
SWT.CLOSE
- *
SWT.CHECK
- *
SWT.PUSH
- *
Events:
- *
SWT.Close, SWT.Selection
- *
- */ -public class Chips extends Canvas { - - private static final int CLOSE_CIRCLE_RAY = 7; - - private Color hoverForeground, hoverBackground; - private Color closeButtonForeground, closeButtonBackground; - private Color closeButtonHoverForeground, closeButtonHoverBackground; - private Color pushedStateForeground, pushedStateBackground; - private Color borderColor, hoverBorderColor, pushedStateBorderColor; - private Color chipsBackground; - private String text; - private Image image, pushImage, hoverImage; - private boolean selection; - private final boolean isCheck; - private final boolean isPush; - private final boolean isClose; - private final List closeListeners = new ArrayList<>(); - private boolean cursorInside; - private Point closeCenter; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - */ - public Chips(final Composite parent, final int style) { - super(parent, checkStyle(style)); - initDefaultColors(); - text = ""; - isCheck = (getStyle() & SWT.CHECK) != 0; - isPush = (getStyle() & SWT.PUSH) != 0; - isClose = (getStyle() & SWT.CLOSE) != 0; - - addListener(SWT.Paint, e -> { - final GC gc = e.gc; - gc.setFont(getFont()); - gc.setAdvanced(true); - gc.setTextAntialias(SWT.ON); - gc.setAntialias(SWT.ON); - final Color previousForeground = gc.getForeground(); - final Color previousBackground = gc.getBackground(); - - int x = drawBackground(gc); - drawWidgetBorder(gc); - if (isCheck && selection) { - x = drawCheck(gc, x); - } - - if (image != null) { - x = drawImage(gc, x); - } - - if (text != null) { - x = drawText(gc, x); - } - - if (isClose) { - drawClose(gc, x); - } - gc.setBackground(previousBackground); - gc.setForeground(previousForeground); - - }); - - addListener(SWT.MouseEnter, e -> { - cursorInside = isPush || isCheck || isClose; - if (cursorInside) { - setCursor(getDisplay().getSystemCursor(SWT.CURSOR_HAND)); - } - redraw(); - }); - addListener(SWT.MouseExit, e -> { - cursorInside = false; - if (isPush || isCheck || isClose) { - setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); - } - redraw(); - }); - addListener(SWT.MouseUp, e -> { - if (!isClose && !isCheck && !isPush) { - return; - } - if (isClose) { - final float dist = (float) Math.sqrt((e.x - closeCenter.x) * (e.x - closeCenter.x) + (e.y - closeCenter.y) * (e.y - closeCenter.y)); - if (dist < CLOSE_CIRCLE_RAY) { - final CloseEvent event = new CloseEvent(e); - for (final CloseListener listener : closeListeners) { - listener.onClose(event); - if (!event.doit) { - break; - } - } - } - } - if (isDisposed()) { - return; - } - setSelection(!selection); - SelectionListenerUtil.fireSelectionListeners(this, e); - }); - } - - private static int checkStyle(final int style) { - final int mask = SWT.CLOSE | SWT.CHECK | SWT.PUSH; - int newStyle = style & mask; - newStyle |= SWT.DOUBLE_BUFFERED; - return newStyle; - } - - private int drawBackground(final GC gc) { - final Rectangle rect = getClientArea(); - - final Color color = determineBackgroundColor(); - gc.setBackground(color); - gc.fillRoundRectangle(0, 0, rect.width, rect.height, rect.height, rect.height); - - return rect.height / 2 + 2; - } - - private void drawWidgetBorder(final GC gc) { - final Rectangle rect = getClientArea(); - Color color = borderColor; - if (cursorInside) { - color = hoverBorderColor; - } else if (isPush && selection) { - color = pushedStateBorderColor; - } - - if (color == null) { - // No border - return; - } - - gc.setForeground(color); - gc.drawRoundRectangle(0, 0, rect.width - 2, rect.height - 2, rect.height, rect.height); - - } - - private Color determineBackgroundColor() { - if (cursorInside) { - return hoverBackground == null ? getBackground() : hoverBackground; - } - if (isPush && selection) { - return pushedStateBackground == null ? getBackground() : pushedStateBackground; - } - return getChipsBackground() == null ? getBackground() : getChipsBackground(); - } - - private int drawCheck(final GC gc, final int x) { - Color foreground = null; - if (cursorInside) { - foreground = hoverForeground; - } else if (isPush && selection) { - foreground = pushedStateForeground; - } - foreground = foreground == null ? getForeground() : foreground; - gc.setForeground(foreground); - gc.setLineWidth(2); - - final Rectangle rect = getClientArea(); - - final int centerX = x + 4 + CLOSE_CIRCLE_RAY; - final int centerY = (rect.height - 2 * CLOSE_CIRCLE_RAY) / 2 + CLOSE_CIRCLE_RAY; - gc.drawLine(x + 6, centerY, x + 9, centerY + 4); - gc.drawLine(x + 9, centerY + 4, centerX + 4, centerY - 3); - return x + 16; - } - - private int drawImage(final GC gc, final int x) { - Image img = image; - if (cursorInside) { - img = hoverImage == null ? img : hoverImage; - } - if (isPush && selection) { - img = pushImage == null ? img : pushImage; - } - - final Rectangle rect = getClientArea(); - gc.drawImage(img, x + 2, (rect.height - img.getBounds().height) / 2); - - return x + 4 + img.getBounds().width; - } - - private int drawText(final GC gc, final int x) { - final Point textSize = gc.stringExtent(text); - Color color = null; - if (cursorInside) { - color = hoverForeground; - } else if (isPush && selection) { - color = pushedStateForeground; - } - color = color == null ? getForeground() : color; - gc.setForeground(color); - - gc.drawText(text, x + 2, (getClientArea().height - textSize.y) / 2, true); - - return x + 2 + textSize.x; - } - - private void drawClose(final GC gc, final int x) { - final Color foreground = cursorInside ? closeButtonHoverForeground : closeButtonForeground; - final Color background = cursorInside ? closeButtonHoverBackground : closeButtonBackground; - final Rectangle rect = getClientArea(); - - gc.setBackground(background); - gc.setForeground(foreground); - closeCenter = new Point(x + 4 + CLOSE_CIRCLE_RAY, (rect.height - 2 * CLOSE_CIRCLE_RAY) / 2 + CLOSE_CIRCLE_RAY); - gc.fillOval(x + 4, (rect.height - 2 * CLOSE_CIRCLE_RAY) / 2, 2 * CLOSE_CIRCLE_RAY, 2 * CLOSE_CIRCLE_RAY); - - // Cross - gc.setLineWidth(2); - gc.drawLine(closeCenter.x - 3, closeCenter.y - 3, closeCenter.x + 3, closeCenter.y + 3); - gc.drawLine(closeCenter.x + 3, closeCenter.y - 3, closeCenter.x - 3, closeCenter.y + 3); - } - - private void initDefaultColors() { - setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); - chipsBackground = SWTGraphicUtil.getColorSafely(224, 224, 224); - - hoverForeground = SWTGraphicUtil.getColorSafely(62, 28, 96); - hoverBackground = SWTGraphicUtil.getColorSafely(214, 214, 214); - - closeButtonForeground = SWTGraphicUtil.getColorSafely(229, 229, 229); - closeButtonBackground = SWTGraphicUtil.getColorSafely(100, 100, 100); - closeButtonHoverForeground = SWTGraphicUtil.getColorSafely(214, 214, 214); - closeButtonHoverBackground = SWTGraphicUtil.getColorSafely(64, 64, 64); - - pushedStateForeground = SWTGraphicUtil.getColorSafely(224, 224, 224); - pushedStateBackground = getDisplay().getSystemColor(SWT.COLOR_BLACK); - } - - /** - * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - checkWidget(); - int width = 0; // Border - int height = 20; - if (image != null) { - final Rectangle imageSize = image.getBounds(); - width += 4 + imageSize.width; - height = Math.max(height, imageSize.height + 4); - - } - - if (text != null) { - final GC gc = new GC(this); - final Point textSize = gc.stringExtent(text); - width += 4 + textSize.x; - height = Math.max(height, textSize.y); - gc.dispose(); - } - - if (isCheck && selection || isClose) { - width += 20; - } - - width += Math.max(height, hHint); // Size for left & right half-circle - return new Point(Math.max(width, wHint), Math.max(height, hHint)); - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the control is closed by the user, by sending it one of the messages - * defined in the CodeListener interface. - *

- * widgetDefaultSelected is not called. - *

- * - * @param listener the listener which should be notified when the control is - * closed by the user, - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see CloseListener - * @see #removeCloseListener - * @see SelectionEvent - */ - public void addCloseListener(final CloseListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - closeListeners.add(listener); - } - - /** - * @see org.eclipse.swt.widgets.Widget#addListener(int, org.eclipse.swt.widgets.Listener) - */ - @Override - public void addListener(final int eventType, final Listener listener) { - if (eventType == SWT.Close) { - closeListeners.add(e -> { - final Event event = new Event(); - event.widget = Chips.this; - event.display = getDisplay(); - event.type = SWT.Close; - listener.handleEvent(event); - }); - return; - } - super.addListener(eventType, listener); - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the control is selected by the user, by sending it one of the messages - * defined in the SelectionListener interface. - *

- * widgetDefaultSelected is not called. - *

- * - * @param listener the listener which should be notified when the control is - * selected by the user, - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.addSelectionListener(this, listener); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the control is closed by the user. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see CloseListener - * @see #addCloseListener - */ - public void removeCloseListener(final CloseListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - closeListeners.remove(listener); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the control is selected by the user. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.removeSelectionListener(this, listener); - } - - // ---- Getters & Setters - - /** - * Returns the receiver's background color. - * - * @return the background color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getChipsBackground() { - checkWidget(); - return chipsBackground; - } - - /** - * Returns the receiver's foreground color when mouse is hover the widget. - *

- * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. - *

- * - * @return the foreground color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getHoverForeground() { - checkWidget(); - return hoverForeground; - } - - /** - * Returns the receiver's background color when mouse is hover the widget. - *

- * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. - *

- * - * @return the background color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getHoverBackground() { - checkWidget(); - return hoverBackground; - } - - /** - * Returns the receiver's close item foreground color. - *

- * Note: This operation is only available if the SWT.CLOSE flag is set. - *

- * - * @return the foreground color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getCloseButtonForeground() { - checkWidget(); - return closeButtonForeground; - } - - /** - * Returns the receiver's close item background color. - *

- * Note: This operation is only available if the SWT.CLOSE flag is set. - *

- * - * @return the background color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getCloseButtonBackground() { - checkWidget(); - return closeButtonBackground; - } - - /** - * Returns the receiver's close item foreground color when the mouse is hover the widget. - *

- * Note: This operation is only available if the SWT.CLOSE flag is set. - *

- * - * @return the foreground color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getCloseButtonHoverForeground() { - checkWidget(); - return closeButtonHoverForeground; - } - - /** - * Returns the receiver's close item background color when the mouse is hover the widget. - *

- * Note: This operation is only available if the SWT.CLOSE flag is set. - *

- * - * @return the background color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getCloseButtonHoverBackground() { - checkWidget(); - return closeButtonHoverBackground; - } - - /** - * Returns the receiver's foreground color when the widget is "pushed" (selected). - *

- * Note: This operation is only available if the SWT.PUSH flag is set. - *

- * - * @return the foreground color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getPushedStateForeground() { - checkWidget(); - return pushedStateForeground; - } - - /** - * Returns the receiver's background color when the widget is "pushed" (selected). - *

- * Note: This operation is only available if the SWT.PUSH flag is set. - *

- * - * @return the background color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getPushedStateBackground() { - checkWidget(); - return pushedStateBackground; - } - - /** - * Returns the receiver's color for the border of the widget. - * - * @return the border color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getBorderColor() { - checkWidget(); - return borderColor; - } - - /** - * Returns the receiver's color for the border when the mouse is hover the widget - *

- * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. - *

- * - * @return the border color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getHoverBorderColor() { - checkWidget(); - return hoverBorderColor; - } - - /** - * Returns the receiver's color for the border when the widget is "pushed" (selected) - *

- * Note: This operation is only available if the SWT.PUSH flag is set. - *

- * - * @return the border color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getPushedStateBorderColor() { - checkWidget(); - return pushedStateBorderColor; - } - - /** - * Returns the receiver's text, which will be an empty - * string if it has never been set. - * - * @return the receiver's text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public String getText() { - checkWidget(); - return text; - } - - /** - * Returns the receiver's image if it has one, or null - * if it does not. - * - * @return the receiver's image - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Image getImage() { - checkWidget(); - return image; - } - - /** - * Returns the receiver's image when the widget is pushed (selected) if it has one, or null - * if it does not. - *

- * Note: This operation is only available if the SWT.PUSH flag is set. - *

- * - * @return the receiver's image - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Image getPushImage() { - checkWidget(); - return pushImage; - } - - /** - * Returns the receiver's image when the mouse is hover the widget if it has one, or null - * if it does not. - *

- * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. - *

- * - * @return the receiver's image - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Image getHoverImage() { - checkWidget(); - return hoverImage; - } - - /** - * Returns true if the receiver is selected, - * and false otherwise. - *

- * Note: This operation is only available if the SWT.CHECK or the SWT.PUSH flag is set. - *

- * - * @return the selection state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public boolean getSelection() { - checkWidget(); - return selection; - } - - /** - * Sets the receiver's background color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setChipsBackground(final Color chipsBackground) { - checkWidget(); - this.chipsBackground = chipsBackground; - } - - /** - * Sets the receiver's foreground color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setHoverForeground(final Color hoverForeground) { - checkWidget(); - this.hoverForeground = hoverForeground; - } - - /** - * Sets the receiver's background color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setHoverBackground(final Color hoverBackground) { - checkWidget(); - this.hoverBackground = hoverBackground; - } - - /** - * Sets the receiver's close button foreground color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is only available if the SWT.CLOSE flag is set. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setCloseButtonForeground(final Color closeButtonForeground) { - checkWidget(); - this.closeButtonForeground = closeButtonForeground; - } - - /** - * Sets the receiver's close button background color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is only available if the SWT.CLOSE flag is set. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setCloseButtonBackground(final Color closeButtonBackground) { - checkWidget(); - this.closeButtonBackground = closeButtonBackground; - } - - /** - * Sets the receiver's close button foreground color (when the mouse is hover the widget) to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is only available if the SWT.CLOSE flag is set. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setCloseButtonHoverForeground(final Color closeButtonHoverForeground) { - checkWidget(); - this.closeButtonHoverForeground = closeButtonHoverForeground; - } - - /** - * Sets the receiver's close button background color (when the mouse is hover the widget) to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is only available if the SWT.CLOSE flag is set. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setCloseButtonHoverBackground(final Color closeButtonHoverBackground) { - checkWidget(); - this.closeButtonHoverBackground = closeButtonHoverBackground; - } - - /** - * Sets the receiver's foreground color when the button is "pushed" (=selected) to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is only available if the SWT.PUSH flag is set. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setPushedStateForeground(final Color pushedStateForeground) { - checkWidget(); - this.pushedStateForeground = pushedStateForeground; - } - - /** - * Sets the receiver's background color when the button is "pushed" (=selected) to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is only available if the SWT.PUSH flag is set. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setPushedStateBackground(final Color pushedStateBackground) { - checkWidget(); - this.pushedStateBackground = pushedStateBackground; - } - - /** - * Sets the receiver's border color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setBorderColor(final Color borderColor) { - checkWidget(); - this.borderColor = borderColor; - } - - /** - * Sets the receiver's border color (when the mouse is hover the widget) to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setHoverBorderColor(final Color hoverBorderColor) { - checkWidget(); - this.hoverBorderColor = hoverBorderColor; - } - - /** - * Sets the receiver's border color when the button is "pushed" (selected) to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is a hint and may be overridden by the platform. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setPushedStateBorderColor(final Color pushedStateBorderColor) { - checkWidget(); - this.pushedStateBorderColor = pushedStateBorderColor; - } - - /** - * Sets the receiver's text. - *

- * This method sets the widget label. The label may include - * the mnemonic character and line delimiters. - *

- * - * @param string the new text - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the text is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setText(final String text) { - checkWidget(); - this.text = text; - } - - /** - * Sets the receiver's image to the argument, which may be - * null indicating that no image should be displayed. - * - * @param image the image to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setImage(final Image image) { - checkWidget(); - this.image = image; - } - - /** - * Sets the receiver's image to the argument when the widget is "pushed" (=selected), which may be - * null indicating that no image should be displayed. - *

- * Note: This operation is only available if the SWT.PUSH flag is set. - *

- * - * @param image the image to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setPushImage(final Image pushImage) { - checkWidget(); - this.pushImage = pushImage; - } - - /** - * Sets the receiver's image to the argument when the mouse is hover the widget, which may be - * null indicating that no image should be displayed. - *

- * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. - *

- * - * @param image the image to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setHoverImage(final Image hoverImage) { - checkWidget(); - this.hoverImage = hoverImage; - } - - /** - * Sets the selection state of the receiver, if it is of type CHECK or - * PUSH. - * - *

- * When the receiver is of type CHECK or RADIO, - * it is selected when it is checked. When it is of type TOGGLE, - * it is selected when it is pushed in. - * - * @param selected the new selection state - * - * @exception SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setSelection(final boolean selected) { - checkWidget(); - selection = selected; - if (isCheck) { - getParent().layout(new Control[] { this }); - } - redraw(); - } - -} +/******************************************************************************* + * Copyright (c) 2020 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.chips; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +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.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; + +/** + * Instances of this class represent a "chips". This is a kind of rounded-shapped button. It can display information, + * or be used like a check or a push button. You can also add a close button. + * + *
+ *
Styles:
+ *
SWT.CLOSE
+ *
SWT.CHECK
+ *
SWT.PUSH
+ *
Events:
+ *
SWT.Close, SWT.Selection
+ *
+ */ +public class Chips extends Canvas { + + private static final int CLOSE_CIRCLE_RAY = 7; + + private Color hoverForeground, hoverBackground; + private Color closeButtonForeground, closeButtonBackground; + private Color closeButtonHoverForeground, closeButtonHoverBackground; + private Color pushedStateForeground, pushedStateBackground; + private Color borderColor, hoverBorderColor, pushedStateBorderColor; + private Color chipsBackground; + private String text; + private Image image, pushImage, hoverImage; + private boolean selection; + private final boolean isCheck; + private final boolean isPush; + private final boolean isClose; + private final List closeListeners = new ArrayList<>(); + private boolean cursorInside; + private Point closeCenter; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + */ + public Chips(final Composite parent, final int style) { + super(parent, checkStyle(style)); + initDefaultColors(); + text = ""; + isCheck = (getStyle() & SWT.CHECK) != 0; + isPush = (getStyle() & SWT.PUSH) != 0; + isClose = (getStyle() & SWT.CLOSE) != 0; + + addListener(SWT.Paint, e -> { + final GC gc = e.gc; + gc.setFont(getFont()); + gc.setAdvanced(true); + gc.setTextAntialias(SWT.ON); + gc.setAntialias(SWT.ON); + final Color previousForeground = gc.getForeground(); + final Color previousBackground = gc.getBackground(); + + int x = drawBackground(gc); + drawWidgetBorder(gc); + if (isCheck && selection) { + x = drawCheck(gc, x); + } + + if (image != null) { + x = drawImage(gc, x); + } + + if (text != null) { + x = drawText(gc, x); + } + + if (isClose) { + drawClose(gc, x); + } + gc.setBackground(previousBackground); + gc.setForeground(previousForeground); + + }); + + addListener(SWT.MouseEnter, e -> { + cursorInside = isPush || isCheck || isClose; + if (cursorInside) { + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_HAND)); + } + redraw(); + }); + addListener(SWT.MouseExit, e -> { + cursorInside = false; + if (isPush || isCheck || isClose) { + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); + } + redraw(); + }); + addListener(SWT.MouseUp, e -> { + if (!isClose && !isCheck && !isPush) { + return; + } + if (isClose) { + final float dist = (float) Math.sqrt((e.x - closeCenter.x) * (e.x - closeCenter.x) + (e.y - closeCenter.y) * (e.y - closeCenter.y)); + if (dist < CLOSE_CIRCLE_RAY) { + final CloseEvent event = new CloseEvent(e); + for (final CloseListener listener : closeListeners) { + listener.onClose(event); + if (!event.doit) { + break; + } + } + } + } + if (isDisposed()) { + return; + } + setSelection(!selection); + SelectionListenerUtil.fireSelectionListeners(this, e); + }); + } + + private static int checkStyle(final int style) { + final int mask = SWT.CLOSE | SWT.CHECK | SWT.PUSH; + int newStyle = style & mask; + newStyle |= SWT.DOUBLE_BUFFERED; + return newStyle; + } + + private int drawBackground(final GC gc) { + final Rectangle rect = getClientArea(); + + final Color color = determineBackgroundColor(); + gc.setBackground(color); + gc.fillRoundRectangle(0, 0, rect.width, rect.height, rect.height, rect.height); + + return rect.height / 2 + 2; + } + + private void drawWidgetBorder(final GC gc) { + final Rectangle rect = getClientArea(); + Color color = borderColor; + if (cursorInside) { + color = hoverBorderColor; + } else if (isPush && selection) { + color = pushedStateBorderColor; + } + + if (color == null) { + // No border + return; + } + + gc.setForeground(color); + gc.drawRoundRectangle(0, 0, rect.width - 2, rect.height - 2, rect.height, rect.height); + + } + + private Color determineBackgroundColor() { + if (cursorInside) { + return hoverBackground == null ? getBackground() : hoverBackground; + } + if (isPush && selection) { + return pushedStateBackground == null ? getBackground() : pushedStateBackground; + } + return getChipsBackground() == null ? getBackground() : getChipsBackground(); + } + + private int drawCheck(final GC gc, final int x) { + Color foreground = null; + if (cursorInside) { + foreground = hoverForeground; + } else if (isPush && selection) { + foreground = pushedStateForeground; + } + foreground = foreground == null ? getForeground() : foreground; + gc.setForeground(foreground); + gc.setLineWidth(2); + + final Rectangle rect = getClientArea(); + + final int centerX = x + 4 + CLOSE_CIRCLE_RAY; + final int centerY = (rect.height - 2 * CLOSE_CIRCLE_RAY) / 2 + CLOSE_CIRCLE_RAY; + gc.drawLine(x + 6, centerY, x + 9, centerY + 4); + gc.drawLine(x + 9, centerY + 4, centerX + 4, centerY - 3); + return x + 16; + } + + private int drawImage(final GC gc, final int x) { + Image img = image; + if (cursorInside) { + img = hoverImage == null ? img : hoverImage; + } + if (isPush && selection) { + img = pushImage == null ? img : pushImage; + } + + final Rectangle rect = getClientArea(); + gc.drawImage(img, x + 2, (rect.height - img.getBounds().height) / 2); + + return x + 4 + img.getBounds().width; + } + + private int drawText(final GC gc, final int x) { + final Point textSize = gc.stringExtent(text); + Color color = null; + if (cursorInside) { + color = hoverForeground; + } else if (isPush && selection) { + color = pushedStateForeground; + } + color = color == null ? getForeground() : color; + gc.setForeground(color); + + gc.drawText(text, x + 2, (getClientArea().height - textSize.y) / 2, true); + + return x + 2 + textSize.x; + } + + private void drawClose(final GC gc, final int x) { + final Color foreground = cursorInside ? closeButtonHoverForeground : closeButtonForeground; + final Color background = cursorInside ? closeButtonHoverBackground : closeButtonBackground; + final Rectangle rect = getClientArea(); + + gc.setBackground(background); + gc.setForeground(foreground); + closeCenter = new Point(x + 4 + CLOSE_CIRCLE_RAY, (rect.height - 2 * CLOSE_CIRCLE_RAY) / 2 + CLOSE_CIRCLE_RAY); + gc.fillOval(x + 4, (rect.height - 2 * CLOSE_CIRCLE_RAY) / 2, 2 * CLOSE_CIRCLE_RAY, 2 * CLOSE_CIRCLE_RAY); + + // Cross + gc.setLineWidth(2); + gc.drawLine(closeCenter.x - 3, closeCenter.y - 3, closeCenter.x + 3, closeCenter.y + 3); + gc.drawLine(closeCenter.x + 3, closeCenter.y - 3, closeCenter.x - 3, closeCenter.y + 3); + } + + private void initDefaultColors() { + setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); + chipsBackground = SWTGraphicUtil.getColorSafely(224, 224, 224); + + hoverForeground = SWTGraphicUtil.getColorSafely(62, 28, 96); + hoverBackground = SWTGraphicUtil.getColorSafely(214, 214, 214); + + closeButtonForeground = SWTGraphicUtil.getColorSafely(229, 229, 229); + closeButtonBackground = SWTGraphicUtil.getColorSafely(100, 100, 100); + closeButtonHoverForeground = SWTGraphicUtil.getColorSafely(214, 214, 214); + closeButtonHoverBackground = SWTGraphicUtil.getColorSafely(64, 64, 64); + + pushedStateForeground = SWTGraphicUtil.getColorSafely(224, 224, 224); + pushedStateBackground = getDisplay().getSystemColor(SWT.COLOR_BLACK); + } + + /** + * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + checkWidget(); + int width = 0; // Border + int height = 20; + if (image != null) { + final Rectangle imageSize = image.getBounds(); + width += 4 + imageSize.width; + height = Math.max(height, imageSize.height + 4); + + } + + if (text != null) { + final GC gc = new GC(this); + final Point textSize = gc.stringExtent(text); + width += 4 + textSize.x; + height = Math.max(height, textSize.y); + gc.dispose(); + } + + if (isCheck && selection || isClose) { + width += 20; + } + + width += Math.max(height, hHint); // Size for left & right half-circle + return new Point(Math.max(width, wHint), Math.max(height, hHint)); + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the control is closed by the user, by sending it one of the messages + * defined in the CodeListener interface. + *

+ * widgetDefaultSelected is not called. + *

+ * + * @param listener the listener which should be notified when the control is + * closed by the user, + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see CloseListener + * @see #removeCloseListener + * @see SelectionEvent + */ + public void addCloseListener(final CloseListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + closeListeners.add(listener); + } + + /** + * @see org.eclipse.swt.widgets.Widget#addListener(int, org.eclipse.swt.widgets.Listener) + */ + @Override + public void addListener(final int eventType, final Listener listener) { + if (eventType == SWT.Close) { + closeListeners.add(e -> { + final Event event = new Event(); + event.widget = Chips.this; + event.display = getDisplay(); + event.type = SWT.Close; + listener.handleEvent(event); + }); + return; + } + super.addListener(eventType, listener); + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the control is selected by the user, by sending it one of the messages + * defined in the SelectionListener interface. + *

+ * widgetDefaultSelected is not called. + *

+ * + * @param listener the listener which should be notified when the control is + * selected by the user, + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.addSelectionListener(this, listener); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the control is closed by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see CloseListener + * @see #addCloseListener + */ + public void removeCloseListener(final CloseListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + closeListeners.remove(listener); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.removeSelectionListener(this, listener); + } + + // ---- Getters & Setters + + /** + * Returns the receiver's background color. + * + * @return the background color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getChipsBackground() { + checkWidget(); + return chipsBackground; + } + + /** + * Returns the receiver's foreground color when mouse is hover the widget. + *

+ * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. + *

+ * + * @return the foreground color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getHoverForeground() { + checkWidget(); + return hoverForeground; + } + + /** + * Returns the receiver's background color when mouse is hover the widget. + *

+ * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. + *

+ * + * @return the background color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getHoverBackground() { + checkWidget(); + return hoverBackground; + } + + /** + * Returns the receiver's close item foreground color. + *

+ * Note: This operation is only available if the SWT.CLOSE flag is set. + *

+ * + * @return the foreground color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getCloseButtonForeground() { + checkWidget(); + return closeButtonForeground; + } + + /** + * Returns the receiver's close item background color. + *

+ * Note: This operation is only available if the SWT.CLOSE flag is set. + *

+ * + * @return the background color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getCloseButtonBackground() { + checkWidget(); + return closeButtonBackground; + } + + /** + * Returns the receiver's close item foreground color when the mouse is hover the widget. + *

+ * Note: This operation is only available if the SWT.CLOSE flag is set. + *

+ * + * @return the foreground color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getCloseButtonHoverForeground() { + checkWidget(); + return closeButtonHoverForeground; + } + + /** + * Returns the receiver's close item background color when the mouse is hover the widget. + *

+ * Note: This operation is only available if the SWT.CLOSE flag is set. + *

+ * + * @return the background color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getCloseButtonHoverBackground() { + checkWidget(); + return closeButtonHoverBackground; + } + + /** + * Returns the receiver's foreground color when the widget is "pushed" (selected). + *

+ * Note: This operation is only available if the SWT.PUSH flag is set. + *

+ * + * @return the foreground color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getPushedStateForeground() { + checkWidget(); + return pushedStateForeground; + } + + /** + * Returns the receiver's background color when the widget is "pushed" (selected). + *

+ * Note: This operation is only available if the SWT.PUSH flag is set. + *

+ * + * @return the background color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getPushedStateBackground() { + checkWidget(); + return pushedStateBackground; + } + + /** + * Returns the receiver's color for the border of the widget. + * + * @return the border color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getBorderColor() { + checkWidget(); + return borderColor; + } + + /** + * Returns the receiver's color for the border when the mouse is hover the widget + *

+ * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. + *

+ * + * @return the border color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getHoverBorderColor() { + checkWidget(); + return hoverBorderColor; + } + + /** + * Returns the receiver's color for the border when the widget is "pushed" (selected) + *

+ * Note: This operation is only available if the SWT.PUSH flag is set. + *

+ * + * @return the border color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getPushedStateBorderColor() { + checkWidget(); + return pushedStateBorderColor; + } + + /** + * Returns the receiver's text, which will be an empty + * string if it has never been set. + * + * @return the receiver's text + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public String getText() { + checkWidget(); + return text; + } + + /** + * Returns the receiver's image if it has one, or null + * if it does not. + * + * @return the receiver's image + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Image getImage() { + checkWidget(); + return image; + } + + /** + * Returns the receiver's image when the widget is pushed (selected) if it has one, or null + * if it does not. + *

+ * Note: This operation is only available if the SWT.PUSH flag is set. + *

+ * + * @return the receiver's image + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Image getPushImage() { + checkWidget(); + return pushImage; + } + + /** + * Returns the receiver's image when the mouse is hover the widget if it has one, or null + * if it does not. + *

+ * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. + *

+ * + * @return the receiver's image + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Image getHoverImage() { + checkWidget(); + return hoverImage; + } + + /** + * Returns true if the receiver is selected, + * and false otherwise. + *

+ * Note: This operation is only available if the SWT.CHECK or the SWT.PUSH flag is set. + *

+ * + * @return the selection state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public boolean getSelection() { + checkWidget(); + return selection; + } + + /** + * Sets the receiver's background color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setChipsBackground(final Color chipsBackground) { + checkWidget(); + this.chipsBackground = chipsBackground; + } + + /** + * Sets the receiver's foreground color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setHoverForeground(final Color hoverForeground) { + checkWidget(); + this.hoverForeground = hoverForeground; + } + + /** + * Sets the receiver's background color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setHoverBackground(final Color hoverBackground) { + checkWidget(); + this.hoverBackground = hoverBackground; + } + + /** + * Sets the receiver's close button foreground color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is only available if the SWT.CLOSE flag is set. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setCloseButtonForeground(final Color closeButtonForeground) { + checkWidget(); + this.closeButtonForeground = closeButtonForeground; + } + + /** + * Sets the receiver's close button background color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is only available if the SWT.CLOSE flag is set. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setCloseButtonBackground(final Color closeButtonBackground) { + checkWidget(); + this.closeButtonBackground = closeButtonBackground; + } + + /** + * Sets the receiver's close button foreground color (when the mouse is hover the widget) to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is only available if the SWT.CLOSE flag is set. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setCloseButtonHoverForeground(final Color closeButtonHoverForeground) { + checkWidget(); + this.closeButtonHoverForeground = closeButtonHoverForeground; + } + + /** + * Sets the receiver's close button background color (when the mouse is hover the widget) to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is only available if the SWT.CLOSE flag is set. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setCloseButtonHoverBackground(final Color closeButtonHoverBackground) { + checkWidget(); + this.closeButtonHoverBackground = closeButtonHoverBackground; + } + + /** + * Sets the receiver's foreground color when the button is "pushed" (=selected) to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is only available if the SWT.PUSH flag is set. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setPushedStateForeground(final Color pushedStateForeground) { + checkWidget(); + this.pushedStateForeground = pushedStateForeground; + } + + /** + * Sets the receiver's background color when the button is "pushed" (=selected) to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is only available if the SWT.PUSH flag is set. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setPushedStateBackground(final Color pushedStateBackground) { + checkWidget(); + this.pushedStateBackground = pushedStateBackground; + } + + /** + * Sets the receiver's border color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setBorderColor(final Color borderColor) { + checkWidget(); + this.borderColor = borderColor; + } + + /** + * Sets the receiver's border color (when the mouse is hover the widget) to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setHoverBorderColor(final Color hoverBorderColor) { + checkWidget(); + this.hoverBorderColor = hoverBorderColor; + } + + /** + * Sets the receiver's border color when the button is "pushed" (selected) to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setPushedStateBorderColor(final Color pushedStateBorderColor) { + checkWidget(); + this.pushedStateBorderColor = pushedStateBorderColor; + } + + /** + * Sets the receiver's text. + *

+ * This method sets the widget label. The label may include + * the mnemonic character and line delimiters. + *

+ * + * @param string the new text + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the text is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setText(final String text) { + checkWidget(); + this.text = text; + } + + /** + * Sets the receiver's image to the argument, which may be + * null indicating that no image should be displayed. + * + * @param image the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setImage(final Image image) { + checkWidget(); + this.image = image; + } + + /** + * Sets the receiver's image to the argument when the widget is "pushed" (=selected), which may be + * null indicating that no image should be displayed. + *

+ * Note: This operation is only available if the SWT.PUSH flag is set. + *

+ * + * @param image the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setPushImage(final Image pushImage) { + checkWidget(); + this.pushImage = pushImage; + } + + /** + * Sets the receiver's image to the argument when the mouse is hover the widget, which may be + * null indicating that no image should be displayed. + *

+ * Note: This operation is only available if at least one the SWT.CHECK, SWT.PUSH and SWT.CLOSE flag is set. + *

+ * + * @param image the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setHoverImage(final Image hoverImage) { + checkWidget(); + this.hoverImage = hoverImage; + } + + /** + * Sets the selection state of the receiver, if it is of type CHECK or + * PUSH. + * + *

+ * When the receiver is of type CHECK or RADIO, + * it is selected when it is checked. When it is of type TOGGLE, + * it is selected when it is pushed in. + * + * @param selected the new selection state + * + * @exception SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setSelection(final boolean selected) { + checkWidget(); + selection = selected; + if (isCheck) { + getParent().layout(new Control[] { this }); + } + redraw(); + } + +} diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/CloseEvent.java b/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/CloseEvent.java index cc6b5e04c..ccac601bb 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/CloseEvent.java +++ b/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/CloseEvent.java @@ -1,47 +1,47 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.chips; - -import org.eclipse.swt.events.TypedEvent; -import org.eclipse.swt.widgets.Event; - -/** - * Instances of this class are sent as a result of - * widgets being closed. - *

- * Note: The fields that are filled in depend on the widget. - *

- * - * @see CloseListener - */ -public class CloseEvent extends TypedEvent { - - private static final long serialVersionUID = 5028668219476966408L; - - /** - * A flag indicating whether the operation should be allowed. - * Setting this field to false will cancel the - * operation, depending on the widget. - */ - public boolean doit; - - /** - * Constructs a new instance of this class based on the - * information in the given untyped event. - * - * @param e the untyped event containing the information - */ - public CloseEvent(final Event e) { - super(e); - } -} +/******************************************************************************* + * Copyright (c) 2020 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.chips; + +import org.eclipse.swt.events.TypedEvent; +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * widgets being closed. + *

+ * Note: The fields that are filled in depend on the widget. + *

+ * + * @see CloseListener + */ +public class CloseEvent extends TypedEvent { + + private static final long serialVersionUID = 5028668219476966408L; + + /** + * A flag indicating whether the operation should be allowed. + * Setting this field to false will cancel the + * operation, depending on the widget. + */ + public boolean doit; + + /** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ + public CloseEvent(final Event e) { + super(e); + } +} diff --git a/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/CloseListener.java b/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/CloseListener.java index 5379e2d7e..d1d595e0b 100644 --- a/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/CloseListener.java +++ b/widgets/chips/org.eclipse.nebula.widgets.chips/src/org/eclipse/nebula/widgets/chips/CloseListener.java @@ -1,40 +1,40 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.chips; - -import org.eclipse.swt.internal.SWTEventListener; - -/** - * Classes which implement this interface provide methods - * that deal with the events that are generated when a Chips widget is closed. - *

- * After creating an instance of a class that implements - * this interface it can be added to a control using the - * addCloseListener method and removed using - * the removeCloseListener method. When - * selection occurs in a control the appropriate method - * will be invoked. - *

- * - * @see CloseEvent - */ -@SuppressWarnings("restriction") -@FunctionalInterface -public interface CloseListener extends SWTEventListener { - /** - * Sent when a Chips widget is closed. - * - * @param e an event containing information about the chips that is closed - */ - void onClose(CloseEvent event); -} +/******************************************************************************* + * Copyright (c) 2020 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.chips; + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the events that are generated when a Chips widget is closed. + *

+ * After creating an instance of a class that implements + * this interface it can be added to a control using the + * addCloseListener method and removed using + * the removeCloseListener method. When + * selection occurs in a control the appropriate method + * will be invoked. + *

+ * + * @see CloseEvent + */ +@SuppressWarnings("restriction") +@FunctionalInterface +public interface CloseListener extends SWTEventListener { + /** + * Sent when a Chips widget is closed. + * + * @param e an event containing information about the chips that is closed + */ + void onClose(CloseEvent event); +} diff --git a/widgets/chips/pom.xml b/widgets/chips/pom.xml index 261fd6dcc..0a5e2d2c1 100644 --- a/widgets/chips/pom.xml +++ b/widgets/chips/pom.xml @@ -1,23 +1,23 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - nebula-parent - ../../releng/org.eclipse.nebula.nebula-parent - - - chips - pom - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.chips - org.eclipse.nebula.widgets.chips.feature - org.eclipse.nebula.widgets.chips.snippets - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + nebula-parent + ../../releng/org.eclipse.nebula.nebula-parent + + + chips + pom + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.chips + org.eclipse.nebula.widgets.chips.feature + org.eclipse.nebula.widgets.chips.snippets + + + diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/.classpath b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/.classpath +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/.settings/org.eclipse.jdt.core.prefs b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/META-INF/MANIFEST.MF b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/META-INF/MANIFEST.MF index 63a90675d..3701e8c35 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/META-INF/MANIFEST.MF +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Collapsible Buttons Example -Incubating -Bundle-SymbolicName: org.eclipse.nebula.widgets.collapsiblebuttons.example;singleton:=true -Bundle-Version: 1.0.0.qualifier -Bundle-Activator: org.eclipse.nebula.widgets.collapsiblebuttons.example.Activator -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.nebula.widgets.collapsiblebuttons;bundle-version="1.0.0", - org.eclipse.nebula.examples;bundle-version="1.0.4" -Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.widgets.collapsiblebuttons.example +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Collapsible Buttons Example -Incubating +Bundle-SymbolicName: org.eclipse.nebula.widgets.collapsiblebuttons.example;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.nebula.widgets.collapsiblebuttons.example.Activator +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.nebula.widgets.collapsiblebuttons;bundle-version="1.0.0", + org.eclipse.nebula.examples;bundle-version="1.0.4" +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.widgets.collapsiblebuttons.example diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/src/org/eclipse/nebula/widgets/collapsiblebuttons/example/CollapsibleButtonsExampleTab.java b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/src/org/eclipse/nebula/widgets/collapsiblebuttons/example/CollapsibleButtonsExampleTab.java index e2f3057df..f78cabf21 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/src/org/eclipse/nebula/widgets/collapsiblebuttons/example/CollapsibleButtonsExampleTab.java +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons.example/src/org/eclipse/nebula/widgets/collapsiblebuttons/example/CollapsibleButtonsExampleTab.java @@ -1,96 +1,96 @@ -/******************************************************************************* - * Copyright (c) 2006-2007 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.collapsiblebuttons.example; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.nebula.examples.AbstractExampleTab; -import org.eclipse.nebula.widgets.collapsiblebuttons.CollapsibleButtons; -import org.eclipse.nebula.widgets.collapsiblebuttons.IColorManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.ImageLoader; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.ui.PlatformUI; - -/** - * Demonstrates the CollapsibleButtons widget. - * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - */ -public class CollapsibleButtonsExampleTab extends AbstractExampleTab { - - Image womanImage = null; - Image bgImage = null; - Image eclipseImage = null; - - CollapsibleButtons collapsibleButtons = null; - - Image itemImage24 = null; - Image itemImage16 = null; - - @Override - public Control createControl(Composite parent) { - - itemImage24 = new Image(PlatformUI.getWorkbench().getDisplay(), PlatformUI.getWorkbench().getDisplay().getSystemImage(SWT.ICON_WORKING).getImageData().scaledTo(24, 24)); - itemImage16 = new Image(PlatformUI.getWorkbench().getDisplay(), PlatformUI.getWorkbench().getDisplay().getSystemImage(SWT.ICON_WORKING).getImageData().scaledTo(16, 16)); - - parent.setLayout(new FillLayout()); - - Composite inner = new Composite(parent, SWT.NONE); - GridLayout gl = new GridLayout(1, true); - gl.marginBottom = 0; - gl.marginHeight = 0; - gl.marginWidth = 0; - gl.marginHeight = 0; - inner.setLayout(gl); - - collapsibleButtons = new CollapsibleButtons(inner, SWT.NONE, IColorManager.SKIN_OFFICE_2007); - collapsibleButtons.setLayoutData( - new GridData(GridData.GRAB_VERTICAL | GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_END)); - - for (int i = 0; i < 5; i++) { - collapsibleButtons.addButton("Button " + i, "Tooltip " + i, itemImage24, itemImage16); - } - - return collapsibleButtons; - } - - @Override - public String[] createLinks() { - String[] links = new String[4]; - - links[0] = "CollapsibleButtons Home Page"; - - links[1] = "Snippets"; - - links[2] = "Bugs"; - - links[3] = "Projet plan"; - - return links; - } - - @Override - public void createParameters(Composite parent) { - GridLayoutFactory.swtDefaults().margins(0, 0).numColumns(3).applyTo(parent); - } - -} +/******************************************************************************* + * Copyright (c) 2006-2007 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.collapsiblebuttons.example; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.nebula.examples.AbstractExampleTab; +import org.eclipse.nebula.widgets.collapsiblebuttons.CollapsibleButtons; +import org.eclipse.nebula.widgets.collapsiblebuttons.IColorManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.PlatformUI; + +/** + * Demonstrates the CollapsibleButtons widget. + * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + */ +public class CollapsibleButtonsExampleTab extends AbstractExampleTab { + + Image womanImage = null; + Image bgImage = null; + Image eclipseImage = null; + + CollapsibleButtons collapsibleButtons = null; + + Image itemImage24 = null; + Image itemImage16 = null; + + @Override + public Control createControl(Composite parent) { + + itemImage24 = new Image(PlatformUI.getWorkbench().getDisplay(), PlatformUI.getWorkbench().getDisplay().getSystemImage(SWT.ICON_WORKING).getImageData().scaledTo(24, 24)); + itemImage16 = new Image(PlatformUI.getWorkbench().getDisplay(), PlatformUI.getWorkbench().getDisplay().getSystemImage(SWT.ICON_WORKING).getImageData().scaledTo(16, 16)); + + parent.setLayout(new FillLayout()); + + Composite inner = new Composite(parent, SWT.NONE); + GridLayout gl = new GridLayout(1, true); + gl.marginBottom = 0; + gl.marginHeight = 0; + gl.marginWidth = 0; + gl.marginHeight = 0; + inner.setLayout(gl); + + collapsibleButtons = new CollapsibleButtons(inner, SWT.NONE, IColorManager.SKIN_OFFICE_2007); + collapsibleButtons.setLayoutData( + new GridData(GridData.GRAB_VERTICAL | GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_END)); + + for (int i = 0; i < 5; i++) { + collapsibleButtons.addButton("Button " + i, "Tooltip " + i, itemImage24, itemImage16); + } + + return collapsibleButtons; + } + + @Override + public String[] createLinks() { + String[] links = new String[4]; + + links[0] = "CollapsibleButtons Home Page"; + + links[1] = "Snippets"; + + links[2] = "Bugs"; + + links[3] = "Projet plan"; + + return links; + } + + @Override + public void createParameters(Composite parent) { + GridLayoutFactory.swtDefaults().margins(0, 0).numColumns(3).applyTo(parent); + } + +} diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/.classpath b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/.classpath index 92e333a4b..c3ba59e4c 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/.classpath +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/.settings/org.eclipse.jdt.core.prefs b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/.settings/org.eclipse.jdt.core.prefs index e2e9c66d8..f2525a8b9 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/.settings/org.eclipse.jdt.core.prefs @@ -1,14 +1,14 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/META-INF/MANIFEST.MF b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/META-INF/MANIFEST.MF index 74b112f63..08adf1039 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/META-INF/MANIFEST.MF +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Collapsible Buttons - Incubating -Bundle-SymbolicName: org.eclipse.nebula.widgets.collapsiblebuttons -Bundle-Version: 1.0.0.qualifier -Require-Bundle: org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.collapsiblebuttons -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.widgets.collapsiblebuttons +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Collapsible Buttons - Incubating +Bundle-SymbolicName: org.eclipse.nebula.widgets.collapsiblebuttons +Bundle-Version: 1.0.0.qualifier +Require-Bundle: org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.collapsiblebuttons +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.widgets.collapsiblebuttons diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CollapsibleButtons.java b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CollapsibleButtons.java index 1c0a6cdea..75dbd47f3 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CollapsibleButtons.java +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CollapsibleButtons.java @@ -1,1171 +1,1171 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.collapsiblebuttons; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.graphics.Cursor; -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.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Layout; - -/** - * CollapsibleButtonsWidget - SWT/JFace Widget - 2005-2007. Version 1.0. - * © Emil Crumhorn - emil.crumhorn@gmail.com. - *

- * Website
- * If you want more info or more documentation, please visit: http://www.hexapixel.com - *

- * Description
- * ButtonComposite is a Widget that displays a vertical row of buttons similar - * to the way that Microsoft® shows buttons in the bottom left of the - * Microsoft Outlook 2005, and 2007 editions. The button bar is a collapsible - * bar that contains an image, text, and an associated toolbar at the very - * bottom where buttons that are currently "collapsed" are shown. There is also - * a menu which is activated by clicking a small arrow icon on the toolbar that - * will allow you to do actions that are similar to the actions you can do with - * the mouse. - *

- * The bar is resized by dragging the handle-bar which is at the very top. When - * the mouse is clicked on the handlebar and dragged either up or down, buttons - * will be shown and hidden accordingly. The button bar also has a feature where - * - if there's no space to show the actively shown buttons due to progam window - * size, buttons will automatically collapse to conserve space, and then - * automatically expand back to the original number of visible buttons when the - * program window is returned to a size where they can be shown. - *

- * Where to put it
- * It is important to point out that due to the nature of the ButtonComposite, - * it is important to put it inside a layout that will allow it to - * expand/collapse with the widgets that are around it - as whenever a button is - * shown/hidden, the actual physical size of the widget changes, which should - * cause surrounding widgets to take up either more or less space. I personally - * recommend putting the ButtonBar inside either a ViewForm, SashForm. - *

- * If you still wish to put it on a plain composite, I suggest doing it the - * following way: - *

- * - * // outer layer wrapper
- * Composite bcWrapper = new Composite(parentComposite, SWT.None);
- * GridLayout gl = new GridLayout(1, true);
- * gl.marginBottom = 0;
- * gl.marginHeight = 0;
- * gl.marginWidth = 0;
- * gl.marginHeight = 0;
- * inner.setLayout(gl);
- *
- * CollapsibleButtons cButtons = new CollapsibleButtons(bcWrapper, SWT.NONE);
- * // will ensure the composite takes up the appropriate amount of space and gets aligned correctly, we align it at the end as that is where it should live
- * cButtons.setLayoutData(new GridData(GridData.GRAB_VERTICAL | GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_END));
- * cButtons.addButton(...);
- *
- *

- * Customizing
- * As many people wish to customize the widget beyond the capabilities it - * already has, there are a few ways you may basically take control over as much - * or little as you please. First, there are three interfaces that are of - * importance (apart from the IButtonListener), one is the IButtonPainter, the - * IColorManager and the ISettings. Let's start with the IColorManager. - *

- * IColorManager
- * If you don't specify a color manager, the DefaultColorManager will be used. - * The color manager's job is to return colors to the method that is painting - * the button when the button is drawn, when you move over a button, when you - * select a button, and when you hover over a selected button. The colors that - * are returned from the ColorManager will determine everything as far as looks - * go. - *

- * IButtonPainter
- * Then there's the IButtonPainter. The IButtonPainter lets you take over 3 - * methods, which are how A. The background colors of the button are painted. B. - * How the text is drawn, and C. How the image is painted. As this is basically - * 100% of how a button is drawn, you can control every aspect of the button - * look and feel. By default, if no IButtonPainter is assigned, the - * DefaultButtonPainter will be used. The IButtonPainter's paintBackground(...) - * method is also used to draw all aspects of the tool bar. That way, the - * toolbar automatically gets the same colors etc like the normal buttons. - *

- * ISettings
- * To control a lot of the features, such as, whether to show the toolbar or - * not, whether you want certain size buttons, painted borders, and so on, you - * can create a class that implements ISettings and set it as the Settings - * manager when you create a ButtonComposite. If you don't specify one, - * DefaultSettings will be used. - *

- * Each button is esentially a composite inside a custom layout, and the toolbar - * is a composite by itself. - *

- * If a toolbar is not wanted, you may control its visibility by implementing - * ISettings - *

- * Double Buffering
- * It is also important to note that the widget uses custom double buffering as - * neither Windows XP's or SWT's DOUBLE_BUFFER flag do the job well enough. To - * do a proper double buffer, the widget is first drawn into a cached Graphics - * object that is then copied onto the actual graphics object. This reduces - * flickering and other odd widget behavior. If you intend to run the widget on - * either Linux or Macintosh (which both know how to double buffer in the OS), - * you may turn it off. - * - * @author Emil Crumhorn - * @version 1.0 - * - */ -public class CollapsibleButtons extends Composite implements MouseListener, MouseMoveListener, MouseTrackListener { - - // cursors we'll use, hand is for mouse-button-overs, size-tool for resize - // bar - private static final Cursor CURSOR_SIZENS = CursorCache.getCursor(SWT.CURSOR_SIZENS); - private static final Cursor CURSOR_HAND = CursorCache.getCursor(SWT.CURSOR_HAND); - - private int mResizeBarSize; - - private Rectangle mBounds; - private Rectangle mMoveBar; - - private List mButtons; - - private int mButtonHeight; - - private CustomButton mSelectedButton; - - private boolean mMouseIsDown; - private int mStartY = 0; - - private int mHiddenButtons = 0; - - private ToolbarComposite mToolBarComposite; - - // beats the built-in double buffering via SWT.DOUBLE_BUFFER - private boolean mEnableDoubleBuffering = true; - private boolean mCreated; - - private int mInvoluntaryButtonLevel = -1; - - private List mHidden; - private Composite mParent; - - private int mColorTheme = IColorManager.SKIN_AUTO_DETECT; - - private IColorManager mColorManager; - private List mButtonListeners; - - private ISettings mSettings; - private ILanguageSettings mLanguage; - - private List mMenuListeners; - - /** - * Creates a new ButtonComposite. Add buttons using the addButton(...) - * method call. - * - * @param parent Parent composite - * @param style Composite style, SWT.NO_BACKGROUND will be appended to the - * style. - */ - public CollapsibleButtons(Composite parent, int style) { - super(parent, checkStyle(style)); - this.mParent = parent; - init(); - } - - /** - * Creates a new ButtonComposite with a given language manager. - * - * @param parent Parent composite - * @param style style - * @param language Language manager - */ - public CollapsibleButtons(Composite parent, int style, ILanguageSettings language) { - this(parent, style, IColorManager.SKIN_AUTO_DETECT, null, null, language); - } - - /** - * Creates a new ButtonComposite with a given settings and language manager. - * - * @param parent Parent composite - * @param style style - * @param settings Settings manager - * @param language Language manager - */ - public CollapsibleButtons(Composite parent, int style, ISettings settings, ILanguageSettings language) { - this(parent, style, IColorManager.SKIN_AUTO_DETECT, null, settings, language); - } - - /** - * Creates a new ButtonComposite. Add buttons using the addButton(...) - * method call. - * - * By default, unless you set a theme, the theme will be read from whatever - * the active color scheme is in Windows XP. If you are using a custom theme - * and the color scheme cannot be determined, the fall-back will be the - * Windows XP Blue theme. - * - * NOTE: If you want the Office 2007 theme, you have to set it manually as - * there is no way to guess if you have office 2007 installed or 2005. - * - * @param parent Parent composite - * @param style Composite style, SWT.NO_BACKGROUND will be appended to the - * style - * @param theme IColorManager.STYLE_ - */ - public CollapsibleButtons(Composite parent, int style, int theme) { - super(parent, checkStyle(style)); - this.mColorTheme = theme; - this.mParent = parent; - init(); - } - - /** - * Creates a new ButtonComposite. Add buttons using the addButton(...) - * method call. - * - * @param parent Parent composite - * @param style Composite style, SWT.NO_BACKGROUND will be appended to the - * style - * @param colorManager IColorManager implementation. Set to null to use the - * default - */ - public CollapsibleButtons(Composite parent, int style, IColorManager colorManager) { - super(parent, checkStyle(style)); - this.mParent = parent; - init(); - } - - /** - * Creates a new ButtonComposite. Add buttons using the addButton(...) - * method call. - * - * By default, unless you set a theme, the theme will be read from whatever - * the active color scheme is in Windows XP. If you are using a custom theme - * and the color scheme cannot be determined, the fall-back will be the - * Windows XP Blue theme. - * - * NOTE: If you want the Office 2007 theme, you have to set it manually as - * there is no way to guess if you have office 2007 installed or 2005. - * - * @param parent Parent composite - * @param style Composite style, SWT.NO_BACKGROUND will be appended to the - * style - * @param theme IColorManager.STYLE_ - * @param colorManager IColorManager implementation. Set to null to use the - * default - */ - public CollapsibleButtons(Composite parent, int style, int theme, IColorManager colorManager) { - super(parent, checkStyle(style)); - this.mColorTheme = theme; - this.mParent = parent; - init(); - } - - /** - * Creates a new ButtonComposite. Add buttons using the addButton(...) - * method call. - * - * By default, unless you set a theme, the theme will be read from whatever - * the active color scheme is in Windows XP. If you are using a custom theme - * and the color scheme cannot be determined, the fall-back will be the - * Windows XP Blue theme. - * - * NOTE: If you want the Office 2007 theme, you have to set it manually as - * there is no way to guess if you have office 2007 installed or 2005. - * - * @param parent Parent composite - * @param style Composite style, SWT.NO_BACKGROUND will be appended to the - * style - * @param theme IColorManager.STYLE_ - * @param colorManager IColorManager implementation. Set to null to use the - * default - * @param settings ISettings implementation. Set to null to use the default - * @param language ILanguage implementations. Set to null to use the - * default. - */ - public CollapsibleButtons(Composite parent, int style, int theme, IColorManager colorManager, ISettings settings, ILanguageSettings language) { - super(parent, checkStyle(style)); - this.mColorTheme = theme; - this.mColorManager = colorManager; - this.mParent = parent; - this.mSettings = settings; - this.mLanguage = language; - init(); - } - - private static int checkStyle(int style) { - int mask = SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.MULTI | SWT.NO_FOCUS | SWT.CHECK | SWT.VIRTUAL; - int newStyle = style & mask; - newStyle |= SWT.NO_BACKGROUND; - return newStyle; - } - - /** - * Adds a new IButtonListener listener that will report clicks and other - * events. - * - * @param listener IButtonListener - */ - public void addButtonListener(IButtonListener listener) { - checkWidget(); - if (!mButtonListeners.contains(listener)) - mButtonListeners.add(listener); - } - - /** - * Removes an IButtonListener - * - * @param listener IButtonListener - */ - public void removeButtonListener(IButtonListener listener) { - checkWidget(); - mButtonListeners.remove(listener); - } - - private void init() { - // we need one, or *crash* - if (mColorManager == null) - mColorManager = new DefaultColorManager(mColorTheme); - - // same here - if (mSettings == null) - mSettings = new DefaultSettings(); - - if (mLanguage == null) - mLanguage = new DefaultLanguageManager(); - - // outlook 2007 specific - if (mColorTheme == IColorManager.SKIN_OFFICE_2007) - mResizeBarSize = mSettings.getOutlook2007ResizeBarSize(); - else - mResizeBarSize = mSettings.getOutlook2005ResizeBarSize(); - - mButtonHeight = mSettings.getButtonHeight(); - - mMenuListeners = new ArrayList<>(); - mButtons = new ArrayList<>(); - mHidden = new ArrayList<>(); - mButtonListeners = new ArrayList<>(); - - // this lets us auto-fit the buttons to the aviaiable space when the - // parent composite is resized. - // Outlook does the same thing when the buttons don't have enough space. - // We hide 1 button per call, - // which should be enough as the next call will to 99.9% certainty in - // less than 31 pixels (or whatever the button size is). - // when the control is manually resized we reset the invuluntary size as - // a "new size" has been picked, and that's - // the starting point for the next invuluntary size if any. Confusing? - // Just try it then look at the code. - mParent.addListener(SWT.Resize, e-> { - int availableHeight = mParent.getClientArea().height; - int neededHeight = getBounds().height; - - if (availableHeight < neededHeight) { - if (mInvoluntaryButtonLevel == -1) { - mInvoluntaryButtonLevel = getNumVisibleButtons(); - } - - hideNextButton(); - } - - if (mInvoluntaryButtonLevel != -1) { - if (availableHeight - mButtonHeight > neededHeight) { - if (getNumVisibleButtons() < mInvoluntaryButtonLevel) { - showNextButton(); - } - } - } - }); - - addListener(SWT.Paint, event -> repaint(event)); - addListener(SWT.FocusOut, event -> redraw()); - addListener(SWT.MouseExit, event -> setCursor(null)); - - addMouseListener(this); - - addListener(SWT.MouseMove, event -> { - Point p = toDisplay(new Point(event.x, event.y)); - - if (!mMouseIsDown) { - if (isInside(event.x, event.y, mMoveBar)) { - if (mSettings.allowButtonResizing()) { - setCursor(CURSOR_SIZENS); - } - } else { - setCursor(null); - } - } - - if (mMouseIsDown) { - // reset the "forced size" value, as we resized it to pick - // what size we wanted - mInvoluntaryButtonLevel = -1; - int diff = p.y - mStartY; - - if (diff > mButtonHeight) { - // ensures bar doesn't get smaller unless mouse pointer - // is south of the move-bar - if (event.y < mMoveBar.y) { - return; - } - - hideNextButton(); - mStartY = p.y; - } else { - if (Math.abs(diff) > mButtonHeight) { - showNextButton(); - mStartY = p.y; - } - } - } - }); - - setLayout(new VerticalLayout()); - } - - private void repaint(Event event) { - GC gc = event.gc; - if (mCreated && mEnableDoubleBuffering) { - try { - Image buffer = new Image(Display.getDefault(), super.getBounds()); - GC gc2 = new GC(buffer); - drawOntoGC(gc2); - - // transfer the image buffer onto this canvas - // just drawImage(buffer, w, h) didn't work, so we do the whole - // source transfer call - Rectangle b = getBounds(); - gc.drawImage(buffer, 0, 0, b.width, b.height, 0, 0, b.width, b.height); - - // dispose the buffer, very important or we'll run out of - // address space for buffered images - buffer.dispose(); - gc2.dispose(); - } catch (IllegalArgumentException iea) { - // seems to come here for some reason when we switch phases - // while the gantt chart is being viewed, I'm not sure why - // but no time to figure it out for the demo.. so instead of - // buffering, just draw it onto the GC - drawOntoGC(gc); - } - } else { - drawOntoGC(gc); - mCreated = true; - - } - } - - private void drawOntoGC(GC gc) { - gc.setBackground(mColorManager.getBorderColor()); - gc.fillRectangle(getClientArea()); - - mBounds = super.getBounds(); - - gc.setBackground(mColorManager.getDarkResizeColor()); - gc.setForeground(mColorManager.getLightResizeColor()); - - gc.fillGradientRectangle(0, 0, mBounds.width, mResizeBarSize, true); - mMoveBar = new Rectangle(0, 0, mBounds.width, mResizeBarSize); - - // office 2007 draws a 1 pixel around the resize bar, let's do that too - if (mColorManager.getTheme() == IColorManager.SKIN_OFFICE_2007) { - // top line inside is white, rest is gradient down to the next dark - // color that is the border - gc.setForeground(IColorManager.white); - gc.drawLine(0, 0, mBounds.width, 0); - - // do the gradient - gc.setBackground(mColorManager.getDarkResizeColor()); - gc.setForeground(mColorManager.getLightResizeColor()); - - gc.fillGradientRectangle(0, 2, mBounds.width, mResizeBarSize - 2, true); - - gc.setForeground(mColorManager.getBorderColor()); - gc.drawLine(0, 0, mBounds.width, 0); - gc.drawLine(0, mResizeBarSize - 1, mBounds.width, mResizeBarSize - 1); - - if (mSettings.drawBorder()) { - gc.drawLine(0, 0, 0, mResizeBarSize); - gc.drawLine(mBounds.width - 1, 0, mBounds.width - 1, mResizeBarSize); - } - } - - drawMarkers(gc); - } - - private void drawMarkers(GC gc) { - int numMarkers; - if (mColorManager.getTheme() == IColorManager.SKIN_OFFICE_2007) - numMarkers = mSettings.getOutlook2007ResizeDotNumber(); - else - numMarkers = mSettings.getOutlook2005ResizeDotNumber(); - - int start = (mBounds.width / 2) - numMarkers * 2; - int extra = 0; - - // -1 is to align - int y = (mResizeBarSize / 2) - 1; - if (y < 0) - y = 0; - - for (int i = 0; i < numMarkers; i++) { - drawMarker(gc, start + extra, y); - extra += 4; - } - } - - // draws a squared "shaded" marker on the resize bar - private void drawMarker(GC gc, int x, int y) { - gc.setBackground(mColorManager.getDotDarkColor()); - gc.fillRectangle(x, y, 2, 2); - gc.setBackground(mColorManager.getDotMiddleColor()); - gc.fillRectangle(x + 1, y + 1, 2, 2); - gc.setBackground(mColorManager.getDotLightColor()); - gc.fillRectangle(x + 1, y + 1, 1, 1); - } - - public void mouseMove(MouseEvent event) { - } - - /** - * Returns the number of currently visible buttons. - * - * @return Number of visible buttons - */ - public int getNumVisibleButtons() { - checkWidget(); - int num = 0; - for (int i = 0; i < mButtons.size(); i++) { - CustomButton b = mButtons.get(i); - if (b.isVisible()) - num++; - } - return num; - } - - /** - * Hides the button from the list and the toolbar. - * - * @param button Button to hide - */ - public void permanentlyHideButton(CustomButton button) { - checkWidget(); - if (mHidden.contains(button)) - return; - - mHidden.add(button); - - for (int i = 0; i < mButtons.size(); i++) { - CustomButton b = mButtons.get(i); - if (b == button) { - if (b.isVisible()) { - b.setVisible(false); - // Don't redraw until stuff is laid out, that way, no - // toolbar ghosting! - mHiddenButtons++; - setRedraw(false); - // parent needs to re-adjust it's size, which in turn - // adjusts our size via (true) as that forces - // children (us) to resize. - getParent().layout(true); - setRedraw(true); - } - - // mToolBarComposite.removeItem(b); - mToolBarComposite.hideButton(b); - mToolBarComposite.redraw(); - break; - } - } - } - - /** - * Un-hides a button that has been hidden from toolbar and ButtonComposite - * view. - * - * @param button Button to show - */ - public void permanentlyShowButton(CustomButton button) { - checkWidget(); - mHidden.remove(button); - - for (int i = 0; i < mButtons.size(); i++) { - CustomButton b = mButtons.get(i); - - if (b == button) { - if (!b.isVisible()) { - b.setVisible(true); - mHiddenButtons--; - // Don't redraw until stuff is laid out, that way, no - // toolbar ghosting! - setRedraw(false); - // parent needs to re-adjust it's size, which in turn - // adjusts our size via (true) as that forces - // children (us) to resize. - getParent().layout(true); - setRedraw(true); - } - - mToolBarComposite.removeItem(b); - break; - } - } - } - - /** - * Hides the given button (and adds it to the toolbar). - * - * @param button Button to hide - */ - public void hideButton(CustomButton button) { - checkWidget(); - for (int i = 0; i < mButtons.size(); i++) { - CustomButton b = mButtons.get(i); - if (b == button) { - // if (label.isVisible() == true) { - b.setVisible(false); - // Don't redraw until stuff is laid out, that way, no toolbar - // ghosting! - mHiddenButtons++; - setRedraw(false); - // parent needs to re-adjust it's size, which in turn adjusts - // our size via (true) as that forces - // children (us) to resize. - getParent().layout(true); - setRedraw(true); - // } - - mToolBarComposite.addItem(b); - break; - } - } - } - - /** - * Shows the given button (and removes it from the toolbar). - * - * @param button Button to show - */ - public void showButton(CustomButton button) { - checkWidget(); - for (int i = 0; i < mButtons.size(); i++) { - CustomButton b = mButtons.get(i); - - if (b == button) { - if (!b.isVisible()) { - b.setVisible(true); - mHiddenButtons--; - // Don't redraw until stuff is laid out, that way, no - // toolbar ghosting! - setRedraw(false); - // parent needs to re-adjust it's size, which in turn - // adjusts our size via (true) as that forces - // children (us) to resize. - getParent().layout(true); - setRedraw(true); - } - - mToolBarComposite.addItem(b); - mToolBarComposite.redraw(); - break; - } - } - } - - /** - * If a button is permanently hidden or permanently shown. - * - * @param button CustomButton to check - * @return true or false - */ - public boolean isVisible(CustomButton button) { - checkWidget(); - return !mHidden.contains(button); - } - - /** - * Hides the next button furthest down in the list. If there are no more - * buttons left to hide, nothing will happen. - * - */ - public void hideNextButton() { - checkWidget(); - if (!mSettings.allowButtonResizing()) { - return; - } - - for (int i = (mButtons.size() - 1); i >= 0; i--) { - CustomButton b = mButtons.get(i); - - if (mHidden.contains(b)) - continue; - - if (b.isVisible()) { - mHiddenButtons++; - b.setVisible(false); - // laying out the parent with true forces us to layout too, so - // don't overdo it by calling layout(true) locally - setRedraw(false); - getParent().layout(true); - setRedraw(true); - - mToolBarComposite.addItem(b); - break; - } - } - } - - /** - * Should you ever need to force a re-layout of the composite, this is the - * method to call. It is not recommended to be used. - * - */ - public void forceLayoutUpdate() { - checkWidget(); - getParent().layout(true); - } - - /** - * Shows the next button from the list of buttons that are currently hidden. - * If there are no more buttons hiding, nothing will happen. - * - */ - public void showNextButton() { - checkWidget(); - if (!mSettings.allowButtonResizing()) { - return; - } - - for (int i = 0; i < mButtons.size(); i++) { - CustomButton b = mButtons.get(i); - - if (mHidden.contains(b)) - continue; - - if (!b.isVisible()) { - mHiddenButtons--; - b.setVisible(true); - // Don't redraw until stuff is laid out, that way, no toolbar - // ghosting! - setRedraw(false); - // parent needs to re-adjust it's size, which in turn adjusts - // our size via (true) as that forces - // children (us) to resize. - getParent().layout(true); - setRedraw(true); - - mToolBarComposite.removeItem(b); - break; - } - } - } - - // rectangle intersection, the easier way - private boolean isInside(int x, int y, Rectangle rect) { - if (rect == null) - return false; - - return x >= rect.x && y >= rect.y && x <= (rect.x + rect.width) && y <= (rect.y + rect.height); - } - - /** - * Adds a button to the composite. Button will be added at the bottom of any - * previously existing buttons. - * - * @param name Text that should be displayed on button. May be null. - * @param toolTip Tooltip that is displayed when mouse moves over both - * button and tool bar icon. Recommended null. - * @param bigImage Image displayed on the button. Ideally 24x24 pixels - * transparent PNG image. - * @param toolbarImage Image displayed on the toolbar and on any menu items. - * Ideally 16x16 pixels transparent GIF image. - * @return CustomButton for further pre-launch modification. - */ - public CustomButton addButton(String name, String toolTip, Image bigImage, Image toolbarImage) { - checkWidget(); - return addButton(name, toolTip, bigImage, toolbarImage, false); - } - - // _addButton - private CustomButton addButton(String name, String toolTip, Image bigImage, Image toolbarImage, boolean selected) { - checkWidget(); - CustomButton cb = new CustomButton(this, SWT.FLAT, name, bigImage, toolbarImage, toolTip, mSettings); - - cb.addMouseListener(this); - cb.addMouseTrackListener(this); - - mButtons.add(cb); - - if (mToolBarComposite == null) - mToolBarComposite = new ToolbarComposite(this, SWT.NONE); - - mParent.redraw(); - mParent.layout(); - - reindexButtons(); - return cb; - - } - - private void reindexButtons() { - for (int i = 0; i < mButtons.size(); i++) { - mButtons.get(i).setNumber(i); - } - } - - public void mouseDoubleClick(MouseEvent event) { - checkWidget(); - } - - public void mouseDown(MouseEvent event) { - checkWidget(); - Point p = toDisplay(new Point(event.x, event.y)); - mStartY = p.y; - mMouseIsDown = true; - - if (event.widget instanceof CustomButton) { - CustomButton cb = (CustomButton) event.widget; - if (event.button == 1) { - if (mSelectedButton != null && cb.equals(mSelectedButton)) - return; - - for (int i = 0; i < mButtonListeners.size(); i++) { - IButtonListener inav = mButtonListeners.get(i); - inav.buttonClicked(cb, event); - } - - selectButton(cb); - } - } - } - - public void mouseUp(MouseEvent event) { - checkWidget(); - setCursor(null); - mMouseIsDown = false; - } - - public Point getSize() { - checkWidget(); - int bs = mButtons.size() - mHiddenButtons; - int y = bs * (mButtonHeight + 1); - if (mSettings.showToolBar()) { - y += mButtonHeight; - } - - y += mResizeBarSize; - - return new Point(super.getSize().x, y); - } - - public void mouseEnter(MouseEvent event) { - checkWidget(); - if (event.widget instanceof CustomButton) { - CustomButton cb = (CustomButton) event.widget; - - setCursor(CURSOR_HAND); - - cb.updateHover(true); - - for (int i = 0; i < mButtonListeners.size(); i++) { - IButtonListener inav = mButtonListeners.get(i); - inav.buttonEnter(cb, event); - } - } - } - - public void mouseExit(MouseEvent event) { - checkWidget(); - if (event.widget instanceof CustomButton) { - CustomButton cb = (CustomButton) event.widget; - cb.updateHover(false); - - setCursor(null); - - for (int i = 0; i < mButtonListeners.size(); i++) { - IButtonListener inav = mButtonListeners.get(i); - inav.buttonExit(cb, event); - } - } - } - - public void mouseHover(MouseEvent event) { - checkWidget(); - if (event.widget instanceof CustomButton) { - CustomButton cb = (CustomButton) event.widget; - - for (int i = 0; i < mButtonListeners.size(); i++) { - IButtonListener inav = mButtonListeners.get(i); - inav.buttonHover(cb, event); - } - } - } - - /** - * Flags a button as selected and pretends it got clicked. - * - * @param button Button to select and click - */ - public void selectItemAndLoad(CustomButton button) { - checkWidget(); - selectItem(button); - for (int i = 0; i < mButtonListeners.size(); i++) { - IButtonListener inav = mButtonListeners.get(i); - inav.buttonClicked(getSelection(), null); - } - } - - /** - * Selects a specific CustomButton. - * - * @param button CustomButton to select - */ - public void selectItem(CustomButton button) { - checkWidget(); - for (int i = 0; i < mButtons.size(); i++) { - CustomButton b = mButtons.get(i); - if (b == button) { - selectButton(button); - break; - } - } - } - - /** - * Deselects all buttons - */ - public void deselectAll() { - if (mSelectedButton != null) { - mSelectedButton.updateSelection(false); - } - mSelectedButton = null; - mToolBarComposite.setSelectedItem(null); - redraw(); - } - - // selects a button - private void selectButton(CustomButton button) { - if (mSelectedButton != null) { - if (mSelectedButton.equals(button)) - return; - - // clear old selection - mSelectedButton.updateSelection(false); - } - - // set new selection - button.updateSelection(true); - mSelectedButton = button; - mToolBarComposite.setSelectedItem(mSelectedButton); - } - - /** - * Returns the list of all buttons. - * - * @return List of buttons - */ - public List getItems() { - checkWidget(); - return mButtons; - } - - /** - * Returns the current selection, or null if none. - * - * @return Selected button. - */ - public CustomButton getSelection() { - checkWidget(); - return mSelectedButton; - } - - /** - * Returns the number of buttons in the list. - * - * @return Button count - */ - public int itemCount() { - checkWidget(); - return mButtons.size(); - } - - /** - * Returns the active color manager. - * - * @return IColorManager - */ - public IColorManager getColorManager() { - checkWidget(); - return mColorManager; - } - - /** - * Returns the current Settings manager. - * - * @return ISettings - */ - public ISettings getSettings() { - checkWidget(); - return mSettings; - } - - /** - * Returns the current Language settings manager. - * - * @return ILanguageSettings - */ - public ILanguageSettings getLanguageSettings() { - checkWidget(); - return mLanguage; - } - - /** - * Returns the toolbar composite. - * - * @return ToolbarComposite - */ - public ToolbarComposite getToolbarComposite() { - checkWidget(); - return mToolBarComposite; - } - - /** - * Adds a menu listener that is notified before and after the menu popup is shown. - * - * @param listener Listener to add - */ - public void addMenuListener(IMenuListener listener) { - if (!mMenuListeners.contains(listener)) - mMenuListeners.add(listener); - } - - /** - * Removes a menu listener. - * - * @param listener Listener to remove - */ - public void removeMenuListener(IMenuListener listener) { - mMenuListeners.remove(listener); - } - - /** - * Removes all buttons. - */ - public void removeAllButtons() { - checkWidget(); - - // remove them in reverse or we'll have some interesting issues - for (int i = mButtons.size()-1; i >= 0; i--) { - mButtons.get(i).dispose(); - } - - if (mToolBarComposite != null) - mToolBarComposite.removeAll(); - - mButtonListeners.clear(); - mButtons.clear(); - mParent.redraw(); - mParent.layout(); - } - - /** - * Same method that is called when {@link CustomButton#dispose()} is called. - * - * @param cb CustomButton to remove - */ - public void removeButton(CustomButton cb) { - checkWidget(); - remove(cb, true); - } - - // internal remove of button - void remove(CustomButton cb, boolean callDispose) { - cb.removeMouseListener(this); - cb.removeMouseTrackListener(this); - - mButtons.remove(cb); - - if (mToolBarComposite != null) - mToolBarComposite.removeItem(cb); - - mParent.redraw(); - mParent.layout(); - - if (callDispose) - cb.dispose(); - - reindexButtons(); - } - - List getMenuListeners() { - return mMenuListeners; - } - - // layout class that deals with the actual layout of the buttons, toolbar - // and other drawn items - class VerticalLayout extends Layout { - - public VerticalLayout() { - } - - protected Point computeSize(Composite aComposite, int wHint, int hHint, boolean flushCache) { - return getSize(); - } - - protected void layout(final Composite aComposite, boolean flushCache) { - int top = mResizeBarSize; - int left = (mSettings.drawBorder() ? 1 : 0); - - if (mSettings.showToolBar()) { - int toolTop = top; - - // calculate where toolbar goes first, causes less ghosting - for (int i = 0; i < mButtons.size(); i++) { - CustomButton button = mButtons.get(i); - if (!button.isVisible()) { - continue; - } - - toolTop += mButtonHeight + 1; - } - - if (mToolBarComposite != null) - mToolBarComposite.setBounds(left, toolTop, aComposite.getBounds().width - (mSettings.drawBorder() ? 2 : 0), mButtonHeight); - } - - // now set the toolbars - for (int i = 0; i < mButtons.size(); i++) { - CustomButton button = mButtons.get(i); - if (!button.isVisible()) { - continue; - } - - button.setBounds(left, top, aComposite.getBounds().width - (mSettings.drawBorder() ? 2 : 0), mButtonHeight); - top += mButtonHeight + 1; - } - } - } -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.collapsiblebuttons; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.graphics.Cursor; +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.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Layout; + +/** + * CollapsibleButtonsWidget - SWT/JFace Widget - 2005-2007. Version 1.0. + * © Emil Crumhorn - emil.crumhorn@gmail.com. + *

+ * Website
+ * If you want more info or more documentation, please visit: http://www.hexapixel.com + *

+ * Description
+ * ButtonComposite is a Widget that displays a vertical row of buttons similar + * to the way that Microsoft® shows buttons in the bottom left of the + * Microsoft Outlook 2005, and 2007 editions. The button bar is a collapsible + * bar that contains an image, text, and an associated toolbar at the very + * bottom where buttons that are currently "collapsed" are shown. There is also + * a menu which is activated by clicking a small arrow icon on the toolbar that + * will allow you to do actions that are similar to the actions you can do with + * the mouse. + *

+ * The bar is resized by dragging the handle-bar which is at the very top. When + * the mouse is clicked on the handlebar and dragged either up or down, buttons + * will be shown and hidden accordingly. The button bar also has a feature where + * - if there's no space to show the actively shown buttons due to progam window + * size, buttons will automatically collapse to conserve space, and then + * automatically expand back to the original number of visible buttons when the + * program window is returned to a size where they can be shown. + *

+ * Where to put it
+ * It is important to point out that due to the nature of the ButtonComposite, + * it is important to put it inside a layout that will allow it to + * expand/collapse with the widgets that are around it - as whenever a button is + * shown/hidden, the actual physical size of the widget changes, which should + * cause surrounding widgets to take up either more or less space. I personally + * recommend putting the ButtonBar inside either a ViewForm, SashForm. + *

+ * If you still wish to put it on a plain composite, I suggest doing it the + * following way: + *

+ * + * // outer layer wrapper
+ * Composite bcWrapper = new Composite(parentComposite, SWT.None);
+ * GridLayout gl = new GridLayout(1, true);
+ * gl.marginBottom = 0;
+ * gl.marginHeight = 0;
+ * gl.marginWidth = 0;
+ * gl.marginHeight = 0;
+ * inner.setLayout(gl);
+ *
+ * CollapsibleButtons cButtons = new CollapsibleButtons(bcWrapper, SWT.NONE);
+ * // will ensure the composite takes up the appropriate amount of space and gets aligned correctly, we align it at the end as that is where it should live
+ * cButtons.setLayoutData(new GridData(GridData.GRAB_VERTICAL | GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_END));
+ * cButtons.addButton(...);
+ *
+ *

+ * Customizing
+ * As many people wish to customize the widget beyond the capabilities it + * already has, there are a few ways you may basically take control over as much + * or little as you please. First, there are three interfaces that are of + * importance (apart from the IButtonListener), one is the IButtonPainter, the + * IColorManager and the ISettings. Let's start with the IColorManager. + *

+ * IColorManager
+ * If you don't specify a color manager, the DefaultColorManager will be used. + * The color manager's job is to return colors to the method that is painting + * the button when the button is drawn, when you move over a button, when you + * select a button, and when you hover over a selected button. The colors that + * are returned from the ColorManager will determine everything as far as looks + * go. + *

+ * IButtonPainter
+ * Then there's the IButtonPainter. The IButtonPainter lets you take over 3 + * methods, which are how A. The background colors of the button are painted. B. + * How the text is drawn, and C. How the image is painted. As this is basically + * 100% of how a button is drawn, you can control every aspect of the button + * look and feel. By default, if no IButtonPainter is assigned, the + * DefaultButtonPainter will be used. The IButtonPainter's paintBackground(...) + * method is also used to draw all aspects of the tool bar. That way, the + * toolbar automatically gets the same colors etc like the normal buttons. + *

+ * ISettings
+ * To control a lot of the features, such as, whether to show the toolbar or + * not, whether you want certain size buttons, painted borders, and so on, you + * can create a class that implements ISettings and set it as the Settings + * manager when you create a ButtonComposite. If you don't specify one, + * DefaultSettings will be used. + *

+ * Each button is esentially a composite inside a custom layout, and the toolbar + * is a composite by itself. + *

+ * If a toolbar is not wanted, you may control its visibility by implementing + * ISettings + *

+ * Double Buffering
+ * It is also important to note that the widget uses custom double buffering as + * neither Windows XP's or SWT's DOUBLE_BUFFER flag do the job well enough. To + * do a proper double buffer, the widget is first drawn into a cached Graphics + * object that is then copied onto the actual graphics object. This reduces + * flickering and other odd widget behavior. If you intend to run the widget on + * either Linux or Macintosh (which both know how to double buffer in the OS), + * you may turn it off. + * + * @author Emil Crumhorn + * @version 1.0 + * + */ +public class CollapsibleButtons extends Composite implements MouseListener, MouseMoveListener, MouseTrackListener { + + // cursors we'll use, hand is for mouse-button-overs, size-tool for resize + // bar + private static final Cursor CURSOR_SIZENS = CursorCache.getCursor(SWT.CURSOR_SIZENS); + private static final Cursor CURSOR_HAND = CursorCache.getCursor(SWT.CURSOR_HAND); + + private int mResizeBarSize; + + private Rectangle mBounds; + private Rectangle mMoveBar; + + private List mButtons; + + private int mButtonHeight; + + private CustomButton mSelectedButton; + + private boolean mMouseIsDown; + private int mStartY = 0; + + private int mHiddenButtons = 0; + + private ToolbarComposite mToolBarComposite; + + // beats the built-in double buffering via SWT.DOUBLE_BUFFER + private boolean mEnableDoubleBuffering = true; + private boolean mCreated; + + private int mInvoluntaryButtonLevel = -1; + + private List mHidden; + private Composite mParent; + + private int mColorTheme = IColorManager.SKIN_AUTO_DETECT; + + private IColorManager mColorManager; + private List mButtonListeners; + + private ISettings mSettings; + private ILanguageSettings mLanguage; + + private List mMenuListeners; + + /** + * Creates a new ButtonComposite. Add buttons using the addButton(...) + * method call. + * + * @param parent Parent composite + * @param style Composite style, SWT.NO_BACKGROUND will be appended to the + * style. + */ + public CollapsibleButtons(Composite parent, int style) { + super(parent, checkStyle(style)); + this.mParent = parent; + init(); + } + + /** + * Creates a new ButtonComposite with a given language manager. + * + * @param parent Parent composite + * @param style style + * @param language Language manager + */ + public CollapsibleButtons(Composite parent, int style, ILanguageSettings language) { + this(parent, style, IColorManager.SKIN_AUTO_DETECT, null, null, language); + } + + /** + * Creates a new ButtonComposite with a given settings and language manager. + * + * @param parent Parent composite + * @param style style + * @param settings Settings manager + * @param language Language manager + */ + public CollapsibleButtons(Composite parent, int style, ISettings settings, ILanguageSettings language) { + this(parent, style, IColorManager.SKIN_AUTO_DETECT, null, settings, language); + } + + /** + * Creates a new ButtonComposite. Add buttons using the addButton(...) + * method call. + * + * By default, unless you set a theme, the theme will be read from whatever + * the active color scheme is in Windows XP. If you are using a custom theme + * and the color scheme cannot be determined, the fall-back will be the + * Windows XP Blue theme. + * + * NOTE: If you want the Office 2007 theme, you have to set it manually as + * there is no way to guess if you have office 2007 installed or 2005. + * + * @param parent Parent composite + * @param style Composite style, SWT.NO_BACKGROUND will be appended to the + * style + * @param theme IColorManager.STYLE_ + */ + public CollapsibleButtons(Composite parent, int style, int theme) { + super(parent, checkStyle(style)); + this.mColorTheme = theme; + this.mParent = parent; + init(); + } + + /** + * Creates a new ButtonComposite. Add buttons using the addButton(...) + * method call. + * + * @param parent Parent composite + * @param style Composite style, SWT.NO_BACKGROUND will be appended to the + * style + * @param colorManager IColorManager implementation. Set to null to use the + * default + */ + public CollapsibleButtons(Composite parent, int style, IColorManager colorManager) { + super(parent, checkStyle(style)); + this.mParent = parent; + init(); + } + + /** + * Creates a new ButtonComposite. Add buttons using the addButton(...) + * method call. + * + * By default, unless you set a theme, the theme will be read from whatever + * the active color scheme is in Windows XP. If you are using a custom theme + * and the color scheme cannot be determined, the fall-back will be the + * Windows XP Blue theme. + * + * NOTE: If you want the Office 2007 theme, you have to set it manually as + * there is no way to guess if you have office 2007 installed or 2005. + * + * @param parent Parent composite + * @param style Composite style, SWT.NO_BACKGROUND will be appended to the + * style + * @param theme IColorManager.STYLE_ + * @param colorManager IColorManager implementation. Set to null to use the + * default + */ + public CollapsibleButtons(Composite parent, int style, int theme, IColorManager colorManager) { + super(parent, checkStyle(style)); + this.mColorTheme = theme; + this.mParent = parent; + init(); + } + + /** + * Creates a new ButtonComposite. Add buttons using the addButton(...) + * method call. + * + * By default, unless you set a theme, the theme will be read from whatever + * the active color scheme is in Windows XP. If you are using a custom theme + * and the color scheme cannot be determined, the fall-back will be the + * Windows XP Blue theme. + * + * NOTE: If you want the Office 2007 theme, you have to set it manually as + * there is no way to guess if you have office 2007 installed or 2005. + * + * @param parent Parent composite + * @param style Composite style, SWT.NO_BACKGROUND will be appended to the + * style + * @param theme IColorManager.STYLE_ + * @param colorManager IColorManager implementation. Set to null to use the + * default + * @param settings ISettings implementation. Set to null to use the default + * @param language ILanguage implementations. Set to null to use the + * default. + */ + public CollapsibleButtons(Composite parent, int style, int theme, IColorManager colorManager, ISettings settings, ILanguageSettings language) { + super(parent, checkStyle(style)); + this.mColorTheme = theme; + this.mColorManager = colorManager; + this.mParent = parent; + this.mSettings = settings; + this.mLanguage = language; + init(); + } + + private static int checkStyle(int style) { + int mask = SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.MULTI | SWT.NO_FOCUS | SWT.CHECK | SWT.VIRTUAL; + int newStyle = style & mask; + newStyle |= SWT.NO_BACKGROUND; + return newStyle; + } + + /** + * Adds a new IButtonListener listener that will report clicks and other + * events. + * + * @param listener IButtonListener + */ + public void addButtonListener(IButtonListener listener) { + checkWidget(); + if (!mButtonListeners.contains(listener)) + mButtonListeners.add(listener); + } + + /** + * Removes an IButtonListener + * + * @param listener IButtonListener + */ + public void removeButtonListener(IButtonListener listener) { + checkWidget(); + mButtonListeners.remove(listener); + } + + private void init() { + // we need one, or *crash* + if (mColorManager == null) + mColorManager = new DefaultColorManager(mColorTheme); + + // same here + if (mSettings == null) + mSettings = new DefaultSettings(); + + if (mLanguage == null) + mLanguage = new DefaultLanguageManager(); + + // outlook 2007 specific + if (mColorTheme == IColorManager.SKIN_OFFICE_2007) + mResizeBarSize = mSettings.getOutlook2007ResizeBarSize(); + else + mResizeBarSize = mSettings.getOutlook2005ResizeBarSize(); + + mButtonHeight = mSettings.getButtonHeight(); + + mMenuListeners = new ArrayList<>(); + mButtons = new ArrayList<>(); + mHidden = new ArrayList<>(); + mButtonListeners = new ArrayList<>(); + + // this lets us auto-fit the buttons to the aviaiable space when the + // parent composite is resized. + // Outlook does the same thing when the buttons don't have enough space. + // We hide 1 button per call, + // which should be enough as the next call will to 99.9% certainty in + // less than 31 pixels (or whatever the button size is). + // when the control is manually resized we reset the invuluntary size as + // a "new size" has been picked, and that's + // the starting point for the next invuluntary size if any. Confusing? + // Just try it then look at the code. + mParent.addListener(SWT.Resize, e-> { + int availableHeight = mParent.getClientArea().height; + int neededHeight = getBounds().height; + + if (availableHeight < neededHeight) { + if (mInvoluntaryButtonLevel == -1) { + mInvoluntaryButtonLevel = getNumVisibleButtons(); + } + + hideNextButton(); + } + + if (mInvoluntaryButtonLevel != -1) { + if (availableHeight - mButtonHeight > neededHeight) { + if (getNumVisibleButtons() < mInvoluntaryButtonLevel) { + showNextButton(); + } + } + } + }); + + addListener(SWT.Paint, event -> repaint(event)); + addListener(SWT.FocusOut, event -> redraw()); + addListener(SWT.MouseExit, event -> setCursor(null)); + + addMouseListener(this); + + addListener(SWT.MouseMove, event -> { + Point p = toDisplay(new Point(event.x, event.y)); + + if (!mMouseIsDown) { + if (isInside(event.x, event.y, mMoveBar)) { + if (mSettings.allowButtonResizing()) { + setCursor(CURSOR_SIZENS); + } + } else { + setCursor(null); + } + } + + if (mMouseIsDown) { + // reset the "forced size" value, as we resized it to pick + // what size we wanted + mInvoluntaryButtonLevel = -1; + int diff = p.y - mStartY; + + if (diff > mButtonHeight) { + // ensures bar doesn't get smaller unless mouse pointer + // is south of the move-bar + if (event.y < mMoveBar.y) { + return; + } + + hideNextButton(); + mStartY = p.y; + } else { + if (Math.abs(diff) > mButtonHeight) { + showNextButton(); + mStartY = p.y; + } + } + } + }); + + setLayout(new VerticalLayout()); + } + + private void repaint(Event event) { + GC gc = event.gc; + if (mCreated && mEnableDoubleBuffering) { + try { + Image buffer = new Image(Display.getDefault(), super.getBounds()); + GC gc2 = new GC(buffer); + drawOntoGC(gc2); + + // transfer the image buffer onto this canvas + // just drawImage(buffer, w, h) didn't work, so we do the whole + // source transfer call + Rectangle b = getBounds(); + gc.drawImage(buffer, 0, 0, b.width, b.height, 0, 0, b.width, b.height); + + // dispose the buffer, very important or we'll run out of + // address space for buffered images + buffer.dispose(); + gc2.dispose(); + } catch (IllegalArgumentException iea) { + // seems to come here for some reason when we switch phases + // while the gantt chart is being viewed, I'm not sure why + // but no time to figure it out for the demo.. so instead of + // buffering, just draw it onto the GC + drawOntoGC(gc); + } + } else { + drawOntoGC(gc); + mCreated = true; + + } + } + + private void drawOntoGC(GC gc) { + gc.setBackground(mColorManager.getBorderColor()); + gc.fillRectangle(getClientArea()); + + mBounds = super.getBounds(); + + gc.setBackground(mColorManager.getDarkResizeColor()); + gc.setForeground(mColorManager.getLightResizeColor()); + + gc.fillGradientRectangle(0, 0, mBounds.width, mResizeBarSize, true); + mMoveBar = new Rectangle(0, 0, mBounds.width, mResizeBarSize); + + // office 2007 draws a 1 pixel around the resize bar, let's do that too + if (mColorManager.getTheme() == IColorManager.SKIN_OFFICE_2007) { + // top line inside is white, rest is gradient down to the next dark + // color that is the border + gc.setForeground(IColorManager.white); + gc.drawLine(0, 0, mBounds.width, 0); + + // do the gradient + gc.setBackground(mColorManager.getDarkResizeColor()); + gc.setForeground(mColorManager.getLightResizeColor()); + + gc.fillGradientRectangle(0, 2, mBounds.width, mResizeBarSize - 2, true); + + gc.setForeground(mColorManager.getBorderColor()); + gc.drawLine(0, 0, mBounds.width, 0); + gc.drawLine(0, mResizeBarSize - 1, mBounds.width, mResizeBarSize - 1); + + if (mSettings.drawBorder()) { + gc.drawLine(0, 0, 0, mResizeBarSize); + gc.drawLine(mBounds.width - 1, 0, mBounds.width - 1, mResizeBarSize); + } + } + + drawMarkers(gc); + } + + private void drawMarkers(GC gc) { + int numMarkers; + if (mColorManager.getTheme() == IColorManager.SKIN_OFFICE_2007) + numMarkers = mSettings.getOutlook2007ResizeDotNumber(); + else + numMarkers = mSettings.getOutlook2005ResizeDotNumber(); + + int start = (mBounds.width / 2) - numMarkers * 2; + int extra = 0; + + // -1 is to align + int y = (mResizeBarSize / 2) - 1; + if (y < 0) + y = 0; + + for (int i = 0; i < numMarkers; i++) { + drawMarker(gc, start + extra, y); + extra += 4; + } + } + + // draws a squared "shaded" marker on the resize bar + private void drawMarker(GC gc, int x, int y) { + gc.setBackground(mColorManager.getDotDarkColor()); + gc.fillRectangle(x, y, 2, 2); + gc.setBackground(mColorManager.getDotMiddleColor()); + gc.fillRectangle(x + 1, y + 1, 2, 2); + gc.setBackground(mColorManager.getDotLightColor()); + gc.fillRectangle(x + 1, y + 1, 1, 1); + } + + public void mouseMove(MouseEvent event) { + } + + /** + * Returns the number of currently visible buttons. + * + * @return Number of visible buttons + */ + public int getNumVisibleButtons() { + checkWidget(); + int num = 0; + for (int i = 0; i < mButtons.size(); i++) { + CustomButton b = mButtons.get(i); + if (b.isVisible()) + num++; + } + return num; + } + + /** + * Hides the button from the list and the toolbar. + * + * @param button Button to hide + */ + public void permanentlyHideButton(CustomButton button) { + checkWidget(); + if (mHidden.contains(button)) + return; + + mHidden.add(button); + + for (int i = 0; i < mButtons.size(); i++) { + CustomButton b = mButtons.get(i); + if (b == button) { + if (b.isVisible()) { + b.setVisible(false); + // Don't redraw until stuff is laid out, that way, no + // toolbar ghosting! + mHiddenButtons++; + setRedraw(false); + // parent needs to re-adjust it's size, which in turn + // adjusts our size via (true) as that forces + // children (us) to resize. + getParent().layout(true); + setRedraw(true); + } + + // mToolBarComposite.removeItem(b); + mToolBarComposite.hideButton(b); + mToolBarComposite.redraw(); + break; + } + } + } + + /** + * Un-hides a button that has been hidden from toolbar and ButtonComposite + * view. + * + * @param button Button to show + */ + public void permanentlyShowButton(CustomButton button) { + checkWidget(); + mHidden.remove(button); + + for (int i = 0; i < mButtons.size(); i++) { + CustomButton b = mButtons.get(i); + + if (b == button) { + if (!b.isVisible()) { + b.setVisible(true); + mHiddenButtons--; + // Don't redraw until stuff is laid out, that way, no + // toolbar ghosting! + setRedraw(false); + // parent needs to re-adjust it's size, which in turn + // adjusts our size via (true) as that forces + // children (us) to resize. + getParent().layout(true); + setRedraw(true); + } + + mToolBarComposite.removeItem(b); + break; + } + } + } + + /** + * Hides the given button (and adds it to the toolbar). + * + * @param button Button to hide + */ + public void hideButton(CustomButton button) { + checkWidget(); + for (int i = 0; i < mButtons.size(); i++) { + CustomButton b = mButtons.get(i); + if (b == button) { + // if (label.isVisible() == true) { + b.setVisible(false); + // Don't redraw until stuff is laid out, that way, no toolbar + // ghosting! + mHiddenButtons++; + setRedraw(false); + // parent needs to re-adjust it's size, which in turn adjusts + // our size via (true) as that forces + // children (us) to resize. + getParent().layout(true); + setRedraw(true); + // } + + mToolBarComposite.addItem(b); + break; + } + } + } + + /** + * Shows the given button (and removes it from the toolbar). + * + * @param button Button to show + */ + public void showButton(CustomButton button) { + checkWidget(); + for (int i = 0; i < mButtons.size(); i++) { + CustomButton b = mButtons.get(i); + + if (b == button) { + if (!b.isVisible()) { + b.setVisible(true); + mHiddenButtons--; + // Don't redraw until stuff is laid out, that way, no + // toolbar ghosting! + setRedraw(false); + // parent needs to re-adjust it's size, which in turn + // adjusts our size via (true) as that forces + // children (us) to resize. + getParent().layout(true); + setRedraw(true); + } + + mToolBarComposite.addItem(b); + mToolBarComposite.redraw(); + break; + } + } + } + + /** + * If a button is permanently hidden or permanently shown. + * + * @param button CustomButton to check + * @return true or false + */ + public boolean isVisible(CustomButton button) { + checkWidget(); + return !mHidden.contains(button); + } + + /** + * Hides the next button furthest down in the list. If there are no more + * buttons left to hide, nothing will happen. + * + */ + public void hideNextButton() { + checkWidget(); + if (!mSettings.allowButtonResizing()) { + return; + } + + for (int i = (mButtons.size() - 1); i >= 0; i--) { + CustomButton b = mButtons.get(i); + + if (mHidden.contains(b)) + continue; + + if (b.isVisible()) { + mHiddenButtons++; + b.setVisible(false); + // laying out the parent with true forces us to layout too, so + // don't overdo it by calling layout(true) locally + setRedraw(false); + getParent().layout(true); + setRedraw(true); + + mToolBarComposite.addItem(b); + break; + } + } + } + + /** + * Should you ever need to force a re-layout of the composite, this is the + * method to call. It is not recommended to be used. + * + */ + public void forceLayoutUpdate() { + checkWidget(); + getParent().layout(true); + } + + /** + * Shows the next button from the list of buttons that are currently hidden. + * If there are no more buttons hiding, nothing will happen. + * + */ + public void showNextButton() { + checkWidget(); + if (!mSettings.allowButtonResizing()) { + return; + } + + for (int i = 0; i < mButtons.size(); i++) { + CustomButton b = mButtons.get(i); + + if (mHidden.contains(b)) + continue; + + if (!b.isVisible()) { + mHiddenButtons--; + b.setVisible(true); + // Don't redraw until stuff is laid out, that way, no toolbar + // ghosting! + setRedraw(false); + // parent needs to re-adjust it's size, which in turn adjusts + // our size via (true) as that forces + // children (us) to resize. + getParent().layout(true); + setRedraw(true); + + mToolBarComposite.removeItem(b); + break; + } + } + } + + // rectangle intersection, the easier way + private boolean isInside(int x, int y, Rectangle rect) { + if (rect == null) + return false; + + return x >= rect.x && y >= rect.y && x <= (rect.x + rect.width) && y <= (rect.y + rect.height); + } + + /** + * Adds a button to the composite. Button will be added at the bottom of any + * previously existing buttons. + * + * @param name Text that should be displayed on button. May be null. + * @param toolTip Tooltip that is displayed when mouse moves over both + * button and tool bar icon. Recommended null. + * @param bigImage Image displayed on the button. Ideally 24x24 pixels + * transparent PNG image. + * @param toolbarImage Image displayed on the toolbar and on any menu items. + * Ideally 16x16 pixels transparent GIF image. + * @return CustomButton for further pre-launch modification. + */ + public CustomButton addButton(String name, String toolTip, Image bigImage, Image toolbarImage) { + checkWidget(); + return addButton(name, toolTip, bigImage, toolbarImage, false); + } + + // _addButton + private CustomButton addButton(String name, String toolTip, Image bigImage, Image toolbarImage, boolean selected) { + checkWidget(); + CustomButton cb = new CustomButton(this, SWT.FLAT, name, bigImage, toolbarImage, toolTip, mSettings); + + cb.addMouseListener(this); + cb.addMouseTrackListener(this); + + mButtons.add(cb); + + if (mToolBarComposite == null) + mToolBarComposite = new ToolbarComposite(this, SWT.NONE); + + mParent.redraw(); + mParent.layout(); + + reindexButtons(); + return cb; + + } + + private void reindexButtons() { + for (int i = 0; i < mButtons.size(); i++) { + mButtons.get(i).setNumber(i); + } + } + + public void mouseDoubleClick(MouseEvent event) { + checkWidget(); + } + + public void mouseDown(MouseEvent event) { + checkWidget(); + Point p = toDisplay(new Point(event.x, event.y)); + mStartY = p.y; + mMouseIsDown = true; + + if (event.widget instanceof CustomButton) { + CustomButton cb = (CustomButton) event.widget; + if (event.button == 1) { + if (mSelectedButton != null && cb.equals(mSelectedButton)) + return; + + for (int i = 0; i < mButtonListeners.size(); i++) { + IButtonListener inav = mButtonListeners.get(i); + inav.buttonClicked(cb, event); + } + + selectButton(cb); + } + } + } + + public void mouseUp(MouseEvent event) { + checkWidget(); + setCursor(null); + mMouseIsDown = false; + } + + public Point getSize() { + checkWidget(); + int bs = mButtons.size() - mHiddenButtons; + int y = bs * (mButtonHeight + 1); + if (mSettings.showToolBar()) { + y += mButtonHeight; + } + + y += mResizeBarSize; + + return new Point(super.getSize().x, y); + } + + public void mouseEnter(MouseEvent event) { + checkWidget(); + if (event.widget instanceof CustomButton) { + CustomButton cb = (CustomButton) event.widget; + + setCursor(CURSOR_HAND); + + cb.updateHover(true); + + for (int i = 0; i < mButtonListeners.size(); i++) { + IButtonListener inav = mButtonListeners.get(i); + inav.buttonEnter(cb, event); + } + } + } + + public void mouseExit(MouseEvent event) { + checkWidget(); + if (event.widget instanceof CustomButton) { + CustomButton cb = (CustomButton) event.widget; + cb.updateHover(false); + + setCursor(null); + + for (int i = 0; i < mButtonListeners.size(); i++) { + IButtonListener inav = mButtonListeners.get(i); + inav.buttonExit(cb, event); + } + } + } + + public void mouseHover(MouseEvent event) { + checkWidget(); + if (event.widget instanceof CustomButton) { + CustomButton cb = (CustomButton) event.widget; + + for (int i = 0; i < mButtonListeners.size(); i++) { + IButtonListener inav = mButtonListeners.get(i); + inav.buttonHover(cb, event); + } + } + } + + /** + * Flags a button as selected and pretends it got clicked. + * + * @param button Button to select and click + */ + public void selectItemAndLoad(CustomButton button) { + checkWidget(); + selectItem(button); + for (int i = 0; i < mButtonListeners.size(); i++) { + IButtonListener inav = mButtonListeners.get(i); + inav.buttonClicked(getSelection(), null); + } + } + + /** + * Selects a specific CustomButton. + * + * @param button CustomButton to select + */ + public void selectItem(CustomButton button) { + checkWidget(); + for (int i = 0; i < mButtons.size(); i++) { + CustomButton b = mButtons.get(i); + if (b == button) { + selectButton(button); + break; + } + } + } + + /** + * Deselects all buttons + */ + public void deselectAll() { + if (mSelectedButton != null) { + mSelectedButton.updateSelection(false); + } + mSelectedButton = null; + mToolBarComposite.setSelectedItem(null); + redraw(); + } + + // selects a button + private void selectButton(CustomButton button) { + if (mSelectedButton != null) { + if (mSelectedButton.equals(button)) + return; + + // clear old selection + mSelectedButton.updateSelection(false); + } + + // set new selection + button.updateSelection(true); + mSelectedButton = button; + mToolBarComposite.setSelectedItem(mSelectedButton); + } + + /** + * Returns the list of all buttons. + * + * @return List of buttons + */ + public List getItems() { + checkWidget(); + return mButtons; + } + + /** + * Returns the current selection, or null if none. + * + * @return Selected button. + */ + public CustomButton getSelection() { + checkWidget(); + return mSelectedButton; + } + + /** + * Returns the number of buttons in the list. + * + * @return Button count + */ + public int itemCount() { + checkWidget(); + return mButtons.size(); + } + + /** + * Returns the active color manager. + * + * @return IColorManager + */ + public IColorManager getColorManager() { + checkWidget(); + return mColorManager; + } + + /** + * Returns the current Settings manager. + * + * @return ISettings + */ + public ISettings getSettings() { + checkWidget(); + return mSettings; + } + + /** + * Returns the current Language settings manager. + * + * @return ILanguageSettings + */ + public ILanguageSettings getLanguageSettings() { + checkWidget(); + return mLanguage; + } + + /** + * Returns the toolbar composite. + * + * @return ToolbarComposite + */ + public ToolbarComposite getToolbarComposite() { + checkWidget(); + return mToolBarComposite; + } + + /** + * Adds a menu listener that is notified before and after the menu popup is shown. + * + * @param listener Listener to add + */ + public void addMenuListener(IMenuListener listener) { + if (!mMenuListeners.contains(listener)) + mMenuListeners.add(listener); + } + + /** + * Removes a menu listener. + * + * @param listener Listener to remove + */ + public void removeMenuListener(IMenuListener listener) { + mMenuListeners.remove(listener); + } + + /** + * Removes all buttons. + */ + public void removeAllButtons() { + checkWidget(); + + // remove them in reverse or we'll have some interesting issues + for (int i = mButtons.size()-1; i >= 0; i--) { + mButtons.get(i).dispose(); + } + + if (mToolBarComposite != null) + mToolBarComposite.removeAll(); + + mButtonListeners.clear(); + mButtons.clear(); + mParent.redraw(); + mParent.layout(); + } + + /** + * Same method that is called when {@link CustomButton#dispose()} is called. + * + * @param cb CustomButton to remove + */ + public void removeButton(CustomButton cb) { + checkWidget(); + remove(cb, true); + } + + // internal remove of button + void remove(CustomButton cb, boolean callDispose) { + cb.removeMouseListener(this); + cb.removeMouseTrackListener(this); + + mButtons.remove(cb); + + if (mToolBarComposite != null) + mToolBarComposite.removeItem(cb); + + mParent.redraw(); + mParent.layout(); + + if (callDispose) + cb.dispose(); + + reindexButtons(); + } + + List getMenuListeners() { + return mMenuListeners; + } + + // layout class that deals with the actual layout of the buttons, toolbar + // and other drawn items + class VerticalLayout extends Layout { + + public VerticalLayout() { + } + + protected Point computeSize(Composite aComposite, int wHint, int hHint, boolean flushCache) { + return getSize(); + } + + protected void layout(final Composite aComposite, boolean flushCache) { + int top = mResizeBarSize; + int left = (mSettings.drawBorder() ? 1 : 0); + + if (mSettings.showToolBar()) { + int toolTop = top; + + // calculate where toolbar goes first, causes less ghosting + for (int i = 0; i < mButtons.size(); i++) { + CustomButton button = mButtons.get(i); + if (!button.isVisible()) { + continue; + } + + toolTop += mButtonHeight + 1; + } + + if (mToolBarComposite != null) + mToolBarComposite.setBounds(left, toolTop, aComposite.getBounds().width - (mSettings.drawBorder() ? 2 : 0), mButtonHeight); + } + + // now set the toolbars + for (int i = 0; i < mButtons.size(); i++) { + CustomButton button = mButtons.get(i); + if (!button.isVisible()) { + continue; + } + + button.setBounds(left, top, aComposite.getBounds().width - (mSettings.drawBorder() ? 2 : 0), mButtonHeight); + top += mButtonHeight + 1; + } + } + } +} diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ColorCache.java b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ColorCache.java index e3c256abc..c4ef137ca 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ColorCache.java +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ColorCache.java @@ -1,327 +1,327 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.collapsiblebuttons; - -import java.util.HashMap; -import java.util.Iterator; - -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Display; - -public class ColorCache { - - public static final RGB BLACK = new RGB(0, 0, 0); - public static final RGB WHITE = new RGB(255, 255, 255); - - private static HashMap mColorTable; - private static ColorCache mInstance; - - public static final int SKIN_NONE = -1; - public static final int SKIN_AUTO = 0; // auto detect - public static final int SKIN_BLUE = 1; - public static final int SKIN_OLIVE = 2; - public static final int SKIN_SILVER = 3; - public static final int SKIN_OFFICE_2007 = 4; - - public static final int SKIN_FALLBACK = SKIN_BLUE; // if auto fails, what skin to use - - public static int SKIN_CURRENT = SKIN_AUTO; - - /** - * Disposes all colors held in the cache and colors created when class is created. - *

- * IMPORTANT: ONLY CALL WHEN YOU WANT TO DISPOSE THE WIDGET USING THIS CLASS! - *

- * If you only wish to dispose colors you have created through the use of the class, please use disposeCachedColors() - * - * @see #disposeCachedColor() - */ - public static void disposeAll() { - mInstance.dispose(); - - blueHeaderColor = null; - lightBlueButtonColor = null; - blueButtonBackground = null; - blueToolbarColor = null; - lightBlueToolbarcolor = null; - oliveHeaderColor = null; - lightOliveButtonColor = null; - lightOliveButtonColor = null; - oliveButtonBackground = null; - oliveToolbarColor = null; - lightOliveToolbarcolor = null; - silverHeaderColor = null; - lightSilverButtonColor = null; - silverButtonBackground = null; - silverToolbarColor = null; - lightSilverToolbarcolor = null; - lightBrownColor = null; - lightBrownColorReverse = null; - darkBrownColor = null; - calendarBlueHeader = null; - calendarBlueBorder = null; - calendarOliveHeader = null; - calendarOliveBorder = null; - calendarSilverBorder = null; - calendarSilverHeader = null; - } - - /** - * Disposes the cached colors only. - */ - public static void disposeCachedColor() { - Iterator e = mColorTable.values().iterator(); - while (e.hasNext()) e.next().dispose(); - - mColorTable.clear(); - } - - // -- blue skin - public static Color [] blueHeaderColor = new Color[]{ - ColorCache.getColor(89, 135, 214), - ColorCache.getColor(3, 56, 148), - ColorCache.getColor(89, 135, 214) - }; - - public static Color [] lightBlueButtonColor = new Color[]{ - ColorCache.getColor(203, 225, 252), - ColorCache.getColor(125, 165, 224), - ColorCache.getColor(203, 225, 252) - }; - - public static Color blueButtonBackground = ColorCache.getColor(3, 56, 148); - - public static Color blueToolbarColor = ColorCache.getColor(77, 124, 205); - public static Color lightBlueToolbarcolor = ColorCache.getColor(170, 199, 246); - // -- end blue skin - - // toolbar - public static Color [] oliveHeaderColor = new Color[]{ - ColorCache.getColor(175, 192, 130), // light - ColorCache.getColor(99, 122, 68), // dark - ColorCache.getColor(175, 192, 130) // light - }; - - // buttons - public static Color [] lightOliveButtonColor = new Color[]{ - ColorCache.getColor(232, 238, 204), - ColorCache.getColor(177, 192, 140), - ColorCache.getColor(232, 238, 204) - }; - - public static Color oliveButtonBackground = ColorCache.getColor(99, 122, 68); - - public static Color oliveToolbarColor = ColorCache.getColor(230, 230, 200); - public static Color lightOliveToolbarcolor = ColorCache.getColor(232, 232, 206); - // -- end olive skin - - // -- silver skin - public static Color [] silverHeaderColor = new Color[]{ - ColorCache.getColor(168, 167, 191), // light - ColorCache.getColor(124, 124, 148), // dark - ColorCache.getColor(168, 167, 191) // light - }; - - // buttons - public static Color [] lightSilverButtonColor = new Color[]{ - ColorCache.getColor(225, 226, 236), - ColorCache.getColor(149, 147, 177), - ColorCache.getColor(225, 226, 236) - }; - - public static Color silverButtonBackground = ColorCache.getColor(124, 124, 148); - - public static Color silverToolbarColor = ColorCache.getColor(164, 163, 187); - public static Color lightSilverToolbarcolor = ColorCache.getColor(231, 231, 239); - // -- end silver skin - - public static Color [] lightBrownColor = new Color[]{ - ColorCache.getColor(254, 252, 215), - ColorCache.getColor(247, 192, 91), - ColorCache.getColor(254, 252, 215) - }; - - public static Color [] lightBrownColorReverse = new Color[]{ - ColorCache.getColor(247, 192, 91), - ColorCache.getColor(254, 252, 215), - ColorCache.getColor(247, 192, 91) - }; - - public static Color [] darkBrownColor = new Color[]{ - ColorCache.getColor(232, 127, 8), - ColorCache.getColor(247, 218, 124), - ColorCache.getColor(232, 127, 8) - }; - - public static Color calendarBlueHeader = ColorCache.getColor(158, 190, 245); - public static Color calendarBlueBorder = ColorCache.getColor(127, 157, 185); - - public static Color calendarOliveHeader = ColorCache.getColor(217, 217, 167); - public static Color calendarOliveBorder = ColorCache.getColor(164, 185, 127); - - public static Color calendarSilverHeader = ColorCache.getColor(215, 215, 229); - public static Color calendarSilverBorder = ColorCache.getColor(157, 157, 161); - - // office 2007 does chrome gradients, top color goes 12 pixels down - public static Color o2007blueTop = ColorCache.getColor(227, 239, 255); - public static Color o2007blueMid = ColorCache.getColor(173, 209, 255); - public static Color o2007blueBot = ColorCache.getColor(192, 219, 255); - - public static Color o2007orangeSelectedTop = ColorCache.getColor(255, 217, 170); - public static Color o2007orangeSelectedMid = ColorCache.getColor(255, 187, 110); - public static Color o2007orangeSelectedBot = ColorCache.getColor(254, 225, 122); - - public static Color o2007orangeHoveredTop = ColorCache.getColor(255, 254, 228); - public static Color o2007orangeHoveredMid = ColorCache.getColor(255, 232, 167); - public static Color o2007orangeHoveredBot = ColorCache.getColor(255, 230, 158); - - public static Color o2007buttonBackgroundColor = ColorCache.getColor(101, 147, 207); - - private ColorCache() { - if (mColorTable == null) { - mColorTable = new HashMap<>(); - } - } - - private static void checkInstance() { - if (mInstance == null) - mInstance = new ColorCache(); - } - - // see disposeAll(); - private void dispose() { - checkInstance(); - - Iterator e = mColorTable.values().iterator(); - while (e.hasNext()) e.next().dispose(); - - mColorTable.clear(); - - for (int i = 0; i < blueHeaderColor.length; i++) { - Color color = blueHeaderColor[i]; - color.dispose(); - } - - for (int i = 0; i < darkBrownColor.length; i++) { - Color color = darkBrownColor[i]; - color.dispose(); - } - - for (int i = 0; i < lightBlueButtonColor.length; i++) { - Color color = lightBlueButtonColor[i]; - color.dispose(); - } - - for (int i = 0; i < lightBrownColor.length; i++) { - Color color = lightBrownColor[i]; - color.dispose(); - } - - for (int i = 0; i < lightBrownColorReverse.length; i++) { - Color color = lightBrownColorReverse[i]; - color.dispose(); - } - - for (int i = 0; i < lightOliveButtonColor.length; i++) { - Color color = lightOliveButtonColor[i]; - color.dispose(); - } - - for (int i = 0; i < lightSilverButtonColor.length; i++) { - Color color = lightSilverButtonColor[i]; - color.dispose(); - } - - for (int i = 0; i < oliveHeaderColor.length; i++) { - Color color = oliveHeaderColor[i]; - color.dispose(); - } - - for (int i = 0; i < silverHeaderColor.length; i++) { - Color color = silverHeaderColor[i]; - color.dispose(); - } - - blueButtonBackground.dispose(); - blueToolbarColor.dispose(); - silverButtonBackground.dispose(); - silverToolbarColor.dispose(); - oliveButtonBackground.dispose(); - oliveToolbarColor.dispose(); - lightBlueToolbarcolor.dispose(); - lightOliveToolbarcolor.dispose(); - lightSilverToolbarcolor.dispose(); - - calendarBlueBorder.dispose(); - calendarBlueHeader.dispose(); - calendarOliveBorder.dispose(); - calendarOliveHeader.dispose(); - calendarSilverBorder.dispose(); - calendarSilverHeader.dispose(); - } - - /** - * Returns the color white R255, G255, B255 - * - * @return White color - */ - public static Color getWhite() { - checkInstance(); - return getColor(WHITE); - } - - /** - * Returns the color black R0, G0, B0 - * - * @return Black color - */ - public static Color getBlack() { - checkInstance(); - return getColor(BLACK); - } - - /** - * Returns a color that is also cached if it has not been created before. - * - * @param rgb RGB colors - * @return Color - */ - public static Color getColor(RGB rgb) { - checkInstance(); - Color color = mColorTable.get(rgb); - - if (color == null) { - color = new Color(Display.getCurrent(), rgb); - mColorTable.put(rgb, color); - } - - return color; - } - - /** - * Returns a color that is also cached if it has not been created before. - * - * @param r Red - * @param g Green - * @param b Blue - * @return Color - */ - public static Color getColor(int r, int g, int b) { - checkInstance(); - RGB rgb = new RGB(r, g, b); - return getColor(rgb); - } -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.collapsiblebuttons; + +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +public class ColorCache { + + public static final RGB BLACK = new RGB(0, 0, 0); + public static final RGB WHITE = new RGB(255, 255, 255); + + private static HashMap mColorTable; + private static ColorCache mInstance; + + public static final int SKIN_NONE = -1; + public static final int SKIN_AUTO = 0; // auto detect + public static final int SKIN_BLUE = 1; + public static final int SKIN_OLIVE = 2; + public static final int SKIN_SILVER = 3; + public static final int SKIN_OFFICE_2007 = 4; + + public static final int SKIN_FALLBACK = SKIN_BLUE; // if auto fails, what skin to use + + public static int SKIN_CURRENT = SKIN_AUTO; + + /** + * Disposes all colors held in the cache and colors created when class is created. + *

+ * IMPORTANT: ONLY CALL WHEN YOU WANT TO DISPOSE THE WIDGET USING THIS CLASS! + *

+ * If you only wish to dispose colors you have created through the use of the class, please use disposeCachedColors() + * + * @see #disposeCachedColor() + */ + public static void disposeAll() { + mInstance.dispose(); + + blueHeaderColor = null; + lightBlueButtonColor = null; + blueButtonBackground = null; + blueToolbarColor = null; + lightBlueToolbarcolor = null; + oliveHeaderColor = null; + lightOliveButtonColor = null; + lightOliveButtonColor = null; + oliveButtonBackground = null; + oliveToolbarColor = null; + lightOliveToolbarcolor = null; + silverHeaderColor = null; + lightSilverButtonColor = null; + silverButtonBackground = null; + silverToolbarColor = null; + lightSilverToolbarcolor = null; + lightBrownColor = null; + lightBrownColorReverse = null; + darkBrownColor = null; + calendarBlueHeader = null; + calendarBlueBorder = null; + calendarOliveHeader = null; + calendarOliveBorder = null; + calendarSilverBorder = null; + calendarSilverHeader = null; + } + + /** + * Disposes the cached colors only. + */ + public static void disposeCachedColor() { + Iterator e = mColorTable.values().iterator(); + while (e.hasNext()) e.next().dispose(); + + mColorTable.clear(); + } + + // -- blue skin + public static Color [] blueHeaderColor = new Color[]{ + ColorCache.getColor(89, 135, 214), + ColorCache.getColor(3, 56, 148), + ColorCache.getColor(89, 135, 214) + }; + + public static Color [] lightBlueButtonColor = new Color[]{ + ColorCache.getColor(203, 225, 252), + ColorCache.getColor(125, 165, 224), + ColorCache.getColor(203, 225, 252) + }; + + public static Color blueButtonBackground = ColorCache.getColor(3, 56, 148); + + public static Color blueToolbarColor = ColorCache.getColor(77, 124, 205); + public static Color lightBlueToolbarcolor = ColorCache.getColor(170, 199, 246); + // -- end blue skin + + // toolbar + public static Color [] oliveHeaderColor = new Color[]{ + ColorCache.getColor(175, 192, 130), // light + ColorCache.getColor(99, 122, 68), // dark + ColorCache.getColor(175, 192, 130) // light + }; + + // buttons + public static Color [] lightOliveButtonColor = new Color[]{ + ColorCache.getColor(232, 238, 204), + ColorCache.getColor(177, 192, 140), + ColorCache.getColor(232, 238, 204) + }; + + public static Color oliveButtonBackground = ColorCache.getColor(99, 122, 68); + + public static Color oliveToolbarColor = ColorCache.getColor(230, 230, 200); + public static Color lightOliveToolbarcolor = ColorCache.getColor(232, 232, 206); + // -- end olive skin + + // -- silver skin + public static Color [] silverHeaderColor = new Color[]{ + ColorCache.getColor(168, 167, 191), // light + ColorCache.getColor(124, 124, 148), // dark + ColorCache.getColor(168, 167, 191) // light + }; + + // buttons + public static Color [] lightSilverButtonColor = new Color[]{ + ColorCache.getColor(225, 226, 236), + ColorCache.getColor(149, 147, 177), + ColorCache.getColor(225, 226, 236) + }; + + public static Color silverButtonBackground = ColorCache.getColor(124, 124, 148); + + public static Color silverToolbarColor = ColorCache.getColor(164, 163, 187); + public static Color lightSilverToolbarcolor = ColorCache.getColor(231, 231, 239); + // -- end silver skin + + public static Color [] lightBrownColor = new Color[]{ + ColorCache.getColor(254, 252, 215), + ColorCache.getColor(247, 192, 91), + ColorCache.getColor(254, 252, 215) + }; + + public static Color [] lightBrownColorReverse = new Color[]{ + ColorCache.getColor(247, 192, 91), + ColorCache.getColor(254, 252, 215), + ColorCache.getColor(247, 192, 91) + }; + + public static Color [] darkBrownColor = new Color[]{ + ColorCache.getColor(232, 127, 8), + ColorCache.getColor(247, 218, 124), + ColorCache.getColor(232, 127, 8) + }; + + public static Color calendarBlueHeader = ColorCache.getColor(158, 190, 245); + public static Color calendarBlueBorder = ColorCache.getColor(127, 157, 185); + + public static Color calendarOliveHeader = ColorCache.getColor(217, 217, 167); + public static Color calendarOliveBorder = ColorCache.getColor(164, 185, 127); + + public static Color calendarSilverHeader = ColorCache.getColor(215, 215, 229); + public static Color calendarSilverBorder = ColorCache.getColor(157, 157, 161); + + // office 2007 does chrome gradients, top color goes 12 pixels down + public static Color o2007blueTop = ColorCache.getColor(227, 239, 255); + public static Color o2007blueMid = ColorCache.getColor(173, 209, 255); + public static Color o2007blueBot = ColorCache.getColor(192, 219, 255); + + public static Color o2007orangeSelectedTop = ColorCache.getColor(255, 217, 170); + public static Color o2007orangeSelectedMid = ColorCache.getColor(255, 187, 110); + public static Color o2007orangeSelectedBot = ColorCache.getColor(254, 225, 122); + + public static Color o2007orangeHoveredTop = ColorCache.getColor(255, 254, 228); + public static Color o2007orangeHoveredMid = ColorCache.getColor(255, 232, 167); + public static Color o2007orangeHoveredBot = ColorCache.getColor(255, 230, 158); + + public static Color o2007buttonBackgroundColor = ColorCache.getColor(101, 147, 207); + + private ColorCache() { + if (mColorTable == null) { + mColorTable = new HashMap<>(); + } + } + + private static void checkInstance() { + if (mInstance == null) + mInstance = new ColorCache(); + } + + // see disposeAll(); + private void dispose() { + checkInstance(); + + Iterator e = mColorTable.values().iterator(); + while (e.hasNext()) e.next().dispose(); + + mColorTable.clear(); + + for (int i = 0; i < blueHeaderColor.length; i++) { + Color color = blueHeaderColor[i]; + color.dispose(); + } + + for (int i = 0; i < darkBrownColor.length; i++) { + Color color = darkBrownColor[i]; + color.dispose(); + } + + for (int i = 0; i < lightBlueButtonColor.length; i++) { + Color color = lightBlueButtonColor[i]; + color.dispose(); + } + + for (int i = 0; i < lightBrownColor.length; i++) { + Color color = lightBrownColor[i]; + color.dispose(); + } + + for (int i = 0; i < lightBrownColorReverse.length; i++) { + Color color = lightBrownColorReverse[i]; + color.dispose(); + } + + for (int i = 0; i < lightOliveButtonColor.length; i++) { + Color color = lightOliveButtonColor[i]; + color.dispose(); + } + + for (int i = 0; i < lightSilverButtonColor.length; i++) { + Color color = lightSilverButtonColor[i]; + color.dispose(); + } + + for (int i = 0; i < oliveHeaderColor.length; i++) { + Color color = oliveHeaderColor[i]; + color.dispose(); + } + + for (int i = 0; i < silverHeaderColor.length; i++) { + Color color = silverHeaderColor[i]; + color.dispose(); + } + + blueButtonBackground.dispose(); + blueToolbarColor.dispose(); + silverButtonBackground.dispose(); + silverToolbarColor.dispose(); + oliveButtonBackground.dispose(); + oliveToolbarColor.dispose(); + lightBlueToolbarcolor.dispose(); + lightOliveToolbarcolor.dispose(); + lightSilverToolbarcolor.dispose(); + + calendarBlueBorder.dispose(); + calendarBlueHeader.dispose(); + calendarOliveBorder.dispose(); + calendarOliveHeader.dispose(); + calendarSilverBorder.dispose(); + calendarSilverHeader.dispose(); + } + + /** + * Returns the color white R255, G255, B255 + * + * @return White color + */ + public static Color getWhite() { + checkInstance(); + return getColor(WHITE); + } + + /** + * Returns the color black R0, G0, B0 + * + * @return Black color + */ + public static Color getBlack() { + checkInstance(); + return getColor(BLACK); + } + + /** + * Returns a color that is also cached if it has not been created before. + * + * @param rgb RGB colors + * @return Color + */ + public static Color getColor(RGB rgb) { + checkInstance(); + Color color = mColorTable.get(rgb); + + if (color == null) { + color = new Color(Display.getCurrent(), rgb); + mColorTable.put(rgb, color); + } + + return color; + } + + /** + * Returns a color that is also cached if it has not been created before. + * + * @param r Red + * @param g Green + * @param b Blue + * @return Color + */ + public static Color getColor(int r, int g, int b) { + checkInstance(); + RGB rgb = new RGB(r, g, b); + return getColor(rgb); + } +} diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CursorCache.java b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CursorCache.java index 35639aa3a..68e737e0f 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CursorCache.java +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CursorCache.java @@ -1,59 +1,59 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.collapsiblebuttons; - -import java.util.HashMap; -import java.util.Iterator; - -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.widgets.Display; - -public class CursorCache { - - private static HashMap map = new HashMap<>(); - - /** - * Returns a cursor that is also cached as to not create more handles for each time the cursor type is fetched. - * - * @param type Cursor Type to fetch - * @return Cursor - */ - public static Cursor getCursor(int type) { - if (map.get(new Integer(type)) != null) { - return map.get(new Integer(type)); - } else { - Cursor c = new Cursor(Display.getDefault(), type); - map.put(new Integer(type), c); - return c; - } - } - - /** - * Disposes all cursors held in the cache. - *

- * IMPORTANT: ONLY CALL WHEN YOU WANT TO DISPOSE ALL CACHED CURSORS! - * - */ - public static void dispose() { - if (map != null && map.keySet() != null) { - Iterator keys = map.keySet().iterator(); - while (keys.hasNext()) { - Object key = keys.next(); - map.get(key).dispose(); - } - } - map = null; - } -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.collapsiblebuttons; + +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Display; + +public class CursorCache { + + private static HashMap map = new HashMap<>(); + + /** + * Returns a cursor that is also cached as to not create more handles for each time the cursor type is fetched. + * + * @param type Cursor Type to fetch + * @return Cursor + */ + public static Cursor getCursor(int type) { + if (map.get(new Integer(type)) != null) { + return map.get(new Integer(type)); + } else { + Cursor c = new Cursor(Display.getDefault(), type); + map.put(new Integer(type), c); + return c; + } + } + + /** + * Disposes all cursors held in the cache. + *

+ * IMPORTANT: ONLY CALL WHEN YOU WANT TO DISPOSE ALL CACHED CURSORS! + * + */ + public static void dispose() { + if (map != null && map.keySet() != null) { + Iterator keys = map.keySet().iterator(); + while (keys.hasNext()) { + Object key = keys.next(); + map.get(key).dispose(); + } + } + map = null; + } +} diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CustomButton.java b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CustomButton.java index ad4fff25a..096d5440d 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CustomButton.java +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/CustomButton.java @@ -1,228 +1,228 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.collapsiblebuttons; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; - -public class CustomButton extends Composite { - - public static final int BUTTON_HEIGHT = 31; - - private Image mImage; - private String mText; - private Rectangle mBounds; - private Image mToolBarImage; - private String mToolTip; - - private boolean mHover; - private boolean mSelected; - private ISettings mSettings; - private CollapsibleButtons mParent; - private IColorManager mColorManager; - - private int mOrderNumber; - - /** - * Creates a new CustomButton. - * - * @param parent ButtonComposite parent - * @param style Widget style - * @param text Label text - * @param image Image to show, null if none - * @param toolBarImage Tooolbar image, null if none - * @param toolTip Tooltip text - * @param settings Button painter class that decides look and feel of button - */ - public CustomButton(CollapsibleButtons parent, int style, String text, Image image, Image toolBarImage, String toolTip, ISettings settings) { - super(parent, style); - mImage = image; - mText = text; - mToolTip = toolTip; - mToolBarImage = toolBarImage; - mSettings = settings; - mParent = parent; - mColorManager = mParent.getColorManager(); - - setToolTipText(toolTip); - - init(); - } - - private void init() { - addListener(SWT.Paint, event-> repaint(event.gc)); - addListener(SWT.Resize, event ->redraw()); - } - - /** - * Updates the hover state. - * - * @param hover true for hover, false for off - */ - public void updateHover(boolean hover) { - if (isDisposed()) - return; - - if (hover && mHover) - return; - - if (!hover && !mHover) - return; - - mHover = hover; - redraw(); - } - - /** - * Updates the selection state. - * - * @param selected true for selected, false for not - */ - public void updateSelection(boolean selected) { - if (isDisposed()) - return; - - if (selected && mSelected) - return; - - if (!selected && !mSelected) - return; - - mSelected = selected; - redraw(); - } - - /** - * Returns the button label text - * - * @return Button text - */ - public String getText() { - return mText; - } - - /** - * Returns the tooltip text - * - * @return Tooltip text - */ - public String getToolTip() { - return mToolTip; - } - - /** - * Returns the toolbar image - * - * @return Toolbar image - */ - public Image getToolBarImage() { - return mToolBarImage; - } - - /** - * Sets the visible text - * - * @param text - */ - public void setText(String text) { - mText = text; - } - - /** - * Sets the toolbar image. - * - * @param toolBarImage - */ - public void setToolBarImage(Image toolBarImage) { - mToolBarImage = toolBarImage; - } - - /** - * Sets the tooltip text. - * - * @param toolTip - */ - public void setToolTip(String toolTip) { - mToolTip = toolTip; - } - - /** - * Returns the big image. - * - * @return Image - */ - public Image getImage() { - return mImage; - } - - /** - * Sets the big image. - * - * @param image to set - */ - public void setImage(Image image) { - mImage = image; - } - - private void repaint(GC gc) { - mBounds = new Rectangle(0, 0, super.getBounds().width, BUTTON_HEIGHT); - - IButtonPainter bp = mSettings.getButtonPainter(); - - bp.paintBackground(gc, mColorManager, mSettings, mBounds, mHover, mSelected); - bp.paintImage(gc, mColorManager, mSettings, mBounds, mHover, mSelected, mImage); - bp.paintText(gc, mColorManager, mSettings, mBounds, (mImage == null ? null : mImage.getBounds()), mHover, mSelected, mText); - } - - /** - * Internal function. - * This is used to keep a list of numbered buttons in memory via an ever-increasing integer value for setting the - * order of buttons back to their original position when buttons are permanently hidden/shown. - * - * Should you wish to use this, for some reason, then make sure that there is no gap in numbers in the buttons and that they - * start at 0. - * - * @param number - */ - public void setNumber(int number) { - mOrderNumber = number; - } - - /** - * Internal function. - * Returns the current number for this button. The number reflects what position in the list the button has - visually. - * - * @return Number - */ - public int getNumber() { - return mOrderNumber; - } - - public String toString() { - return "[CustomButton '"+mText+"']"; - } - - /** - * Disposes this button and removes it from the control. - */ - public void dispose() { - mParent.remove(this, false); - super.dispose(); - } - -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.collapsiblebuttons; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + +public class CustomButton extends Composite { + + public static final int BUTTON_HEIGHT = 31; + + private Image mImage; + private String mText; + private Rectangle mBounds; + private Image mToolBarImage; + private String mToolTip; + + private boolean mHover; + private boolean mSelected; + private ISettings mSettings; + private CollapsibleButtons mParent; + private IColorManager mColorManager; + + private int mOrderNumber; + + /** + * Creates a new CustomButton. + * + * @param parent ButtonComposite parent + * @param style Widget style + * @param text Label text + * @param image Image to show, null if none + * @param toolBarImage Tooolbar image, null if none + * @param toolTip Tooltip text + * @param settings Button painter class that decides look and feel of button + */ + public CustomButton(CollapsibleButtons parent, int style, String text, Image image, Image toolBarImage, String toolTip, ISettings settings) { + super(parent, style); + mImage = image; + mText = text; + mToolTip = toolTip; + mToolBarImage = toolBarImage; + mSettings = settings; + mParent = parent; + mColorManager = mParent.getColorManager(); + + setToolTipText(toolTip); + + init(); + } + + private void init() { + addListener(SWT.Paint, event-> repaint(event.gc)); + addListener(SWT.Resize, event ->redraw()); + } + + /** + * Updates the hover state. + * + * @param hover true for hover, false for off + */ + public void updateHover(boolean hover) { + if (isDisposed()) + return; + + if (hover && mHover) + return; + + if (!hover && !mHover) + return; + + mHover = hover; + redraw(); + } + + /** + * Updates the selection state. + * + * @param selected true for selected, false for not + */ + public void updateSelection(boolean selected) { + if (isDisposed()) + return; + + if (selected && mSelected) + return; + + if (!selected && !mSelected) + return; + + mSelected = selected; + redraw(); + } + + /** + * Returns the button label text + * + * @return Button text + */ + public String getText() { + return mText; + } + + /** + * Returns the tooltip text + * + * @return Tooltip text + */ + public String getToolTip() { + return mToolTip; + } + + /** + * Returns the toolbar image + * + * @return Toolbar image + */ + public Image getToolBarImage() { + return mToolBarImage; + } + + /** + * Sets the visible text + * + * @param text + */ + public void setText(String text) { + mText = text; + } + + /** + * Sets the toolbar image. + * + * @param toolBarImage + */ + public void setToolBarImage(Image toolBarImage) { + mToolBarImage = toolBarImage; + } + + /** + * Sets the tooltip text. + * + * @param toolTip + */ + public void setToolTip(String toolTip) { + mToolTip = toolTip; + } + + /** + * Returns the big image. + * + * @return Image + */ + public Image getImage() { + return mImage; + } + + /** + * Sets the big image. + * + * @param image to set + */ + public void setImage(Image image) { + mImage = image; + } + + private void repaint(GC gc) { + mBounds = new Rectangle(0, 0, super.getBounds().width, BUTTON_HEIGHT); + + IButtonPainter bp = mSettings.getButtonPainter(); + + bp.paintBackground(gc, mColorManager, mSettings, mBounds, mHover, mSelected); + bp.paintImage(gc, mColorManager, mSettings, mBounds, mHover, mSelected, mImage); + bp.paintText(gc, mColorManager, mSettings, mBounds, (mImage == null ? null : mImage.getBounds()), mHover, mSelected, mText); + } + + /** + * Internal function. + * This is used to keep a list of numbered buttons in memory via an ever-increasing integer value for setting the + * order of buttons back to their original position when buttons are permanently hidden/shown. + * + * Should you wish to use this, for some reason, then make sure that there is no gap in numbers in the buttons and that they + * start at 0. + * + * @param number + */ + public void setNumber(int number) { + mOrderNumber = number; + } + + /** + * Internal function. + * Returns the current number for this button. The number reflects what position in the list the button has - visually. + * + * @return Number + */ + public int getNumber() { + return mOrderNumber; + } + + public String toString() { + return "[CustomButton '"+mText+"']"; + } + + /** + * Disposes this button and removes it from the control. + */ + public void dispose() { + mParent.remove(this, false); + super.dispose(); + } + +} diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ImageCache.java b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ImageCache.java index fe5ae0722..b564b6275 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ImageCache.java +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ImageCache.java @@ -1,88 +1,88 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.collapsiblebuttons; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Iterator; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; - -public class ImageCache { - - private static HashMap mImageMap; - - static { - mImageMap = new HashMap<>(); - } - - /** - * Returns an image that is also cached if it has to be created and does not already exist in the cache. - * - * @param fileName Filename of image to fetch - * @return Image file or null if it could not be found - */ - public static Image getImage(String fileName) { - Image image = mImageMap.get(fileName); - if (image == null) { - image = createImage(fileName); - mImageMap.put(fileName, image); - } - return image; - } - - // creates the image, and tries really hard to do so - private static Image createImage(String fileName) { - ClassLoader classLoader = ImageCache.class.getClassLoader(); - InputStream is = classLoader.getResourceAsStream(fileName); - if (is == null) { - // the old way didn't have leading slash, so if we can't find the image stream, - // let's see if the old way works. - is = classLoader.getResourceAsStream(fileName.substring(1)); - - if (is == null) { - is = classLoader.getResourceAsStream(fileName); - if (is == null) { - is = classLoader.getResourceAsStream(fileName.substring(1)); - if (is == null) { - //logger.debug("null input stream for both " + path + " and " + path); - return null; - } - } - } - } - - Image img = new Image(Display.getDefault(), is); - try { - is.close(); - } catch (IOException e) { - e.printStackTrace(); - } - - return img; - } - - /** - * Disposes ALL images that have been cached. - * - */ - public static void dispose() { - Iterator e = mImageMap.values().iterator(); - while (e.hasNext()) - e.next().dispose(); - } -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.collapsiblebuttons; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +public class ImageCache { + + private static HashMap mImageMap; + + static { + mImageMap = new HashMap<>(); + } + + /** + * Returns an image that is also cached if it has to be created and does not already exist in the cache. + * + * @param fileName Filename of image to fetch + * @return Image file or null if it could not be found + */ + public static Image getImage(String fileName) { + Image image = mImageMap.get(fileName); + if (image == null) { + image = createImage(fileName); + mImageMap.put(fileName, image); + } + return image; + } + + // creates the image, and tries really hard to do so + private static Image createImage(String fileName) { + ClassLoader classLoader = ImageCache.class.getClassLoader(); + InputStream is = classLoader.getResourceAsStream(fileName); + if (is == null) { + // the old way didn't have leading slash, so if we can't find the image stream, + // let's see if the old way works. + is = classLoader.getResourceAsStream(fileName.substring(1)); + + if (is == null) { + is = classLoader.getResourceAsStream(fileName); + if (is == null) { + is = classLoader.getResourceAsStream(fileName.substring(1)); + if (is == null) { + //logger.debug("null input stream for both " + path + " and " + path); + return null; + } + } + } + } + + Image img = new Image(Display.getDefault(), is); + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + return img; + } + + /** + * Disposes ALL images that have been cached. + * + */ + public static void dispose() { + Iterator e = mImageMap.values().iterator(); + while (e.hasNext()) + e.next().dispose(); + } +} diff --git a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ToolbarComposite.java b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ToolbarComposite.java index 2aba2c93f..b36d04f32 100644 --- a/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ToolbarComposite.java +++ b/widgets/collapsiblebuttons/org.eclipse.nebula.widgets.collapsiblebuttons/src/org/eclipse/nebula/widgets/collapsiblebuttons/ToolbarComposite.java @@ -1,493 +1,493 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.collapsiblebuttons; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -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.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; - -public class ToolbarComposite extends Composite implements MouseListener, MouseMoveListener, MouseTrackListener { - - private List mToolBarItems; - private TBItem mLastHover; - private CustomButton mSelectedItem; - private CollapsibleButtons mButtonComposite; - - private boolean mEnableDoubleBuffering = true; - private boolean mCreated = false; - - private static Image mOutlook2005ArrowsImage = ImageCache.getImage("icons/arrows.gif"); - private static Image mOutlook2007ArrowImage = ImageCache.getImage("icons/o2007arrow.gif"); - private Rectangle mArrowsBounds; - private boolean mArrowHover = false; - - private IColorManager mColorManager; - private AbstractButtonPainter mButtonPainter; - - private Image mArrowImage; - private ISettings mSettings; - private ILanguageSettings mLanguage; - - /** - * Creates a new toolbar composite. - * - * @param bc ButtonComposite parent - * @param style Composite style - */ - public ToolbarComposite(CollapsibleButtons bc, int style) { - super(bc, style | SWT.NO_BACKGROUND); - - this.mLanguage = bc.getLanguageSettings(); - this.mButtonPainter = new AbstractButtonPainter(); - this.mButtonComposite = bc; - this.mColorManager = bc.getColorManager(); - this.mSettings = bc.getSettings(); - - if (mColorManager.getTheme() == IColorManager.SKIN_OFFICE_2007) - mArrowImage = mOutlook2007ArrowImage; - else - mArrowImage = mOutlook2005ArrowsImage; - - mToolBarItems = new ArrayList<>(); - - addListener(SWT.Paint, event -> repaint(event)); - addMouseListener(this); - addMouseTrackListener(this); - addMouseMoveListener(this); - } - - private void repaint(Event event) { - GC gc = event.gc; - if (mCreated && mEnableDoubleBuffering) { - try { - Image buffer = new Image(Display.getDefault(), super.getBounds()); - GC gc2 = new GC(buffer); - drawOntoGC(gc2); - - // transfer the image buffer onto this canvas - // just drawImage(buffer, w, h) didn't work, so we do the whole - // source transfer call - Rectangle b = getBounds(); - gc.drawImage(buffer, 0, 0, b.width, b.height, 0, 0, b.width, b.height); - - // dispose the buffer, very important or we'll run out of - // address space for buffered images - buffer.dispose(); - gc2.dispose(); - } catch (IllegalArgumentException iea) { - // seems to come here for some reason when we switch phases - // while the gantt chart is being viewed, I'm not sure why - // but no time to figure it out for the demo.. so instead of - // buffering, just draw it onto the GC - drawOntoGC(gc); - } - } else { - drawOntoGC(gc); - mCreated = true; - } - - gc.dispose(); - } - - private void drawOntoGC(GC gc) { - Rectangle rect = getClientArea(); - Rectangle imageBounds = (mArrowImage != null ? mArrowImage.getBounds() : new Rectangle(0, 0, 0, 0)); - int verticalLoc = (getBounds().height / 2) - (mArrowImage == null ? 0 : mArrowImage.getBounds().height / 2); - // move it down just a smidge, the human eye percieves things - // mis-aligned when exactly centered - verticalLoc += 1; - mButtonPainter.paintBackground(gc, mColorManager, mSettings, rect, false, false); - - int right = rect.width; - - if (mArrowImage != null) - gc.drawImage(mArrowImage, rect.width - imageBounds.width, verticalLoc); - mArrowsBounds = new Rectangle(rect.width - imageBounds.width, verticalLoc, imageBounds.width, imageBounds.height); - right -= imageBounds.width + mSettings.getToolBarSpacing(); - - // reorganize items if stuff have been hidden/shown (permanently) - orderItems(); - - for (int i = 0; i < mToolBarItems.size(); i++) { - TBItem tb = mToolBarItems.get(i); - if (tb.getHidden()) - continue; - - if (tb.getButton() == mSelectedItem) { - Rectangle cur = tb.getBounds(); - // TODO: Clean up code-repeat - if (cur == null) { - if (tb.getButton().getToolBarImage() != null) { - Rectangle imBounds = tb.getButton().getToolBarImage().getBounds(); - cur = new Rectangle(right - imBounds.width, verticalLoc, imBounds.width, imBounds.width); - tb.setBounds(cur); - } else { - // basically a non-existent button, but no image = no - // button, so that's fine - tb.setBounds(new Rectangle(right, verticalLoc, 0, 0)); - continue; - } - } - - Rectangle bounds = new Rectangle(cur.x - mSettings.getToolBarLeftSpacer(), cur.y, cur.width + mSettings.getToolBarRightSpacer(), cur.height); - mButtonPainter.paintBackground(gc, mColorManager, mSettings, bounds, false, true); - } - - Rectangle imBounds = null; - if (tb.getButton().getToolBarImage() != null) { - imBounds = tb.getButton().getToolBarImage().getBounds(); - gc.drawImage(tb.getButton().getToolBarImage(), right - imBounds.width, verticalLoc); - tb.setBounds(new Rectangle(right - imBounds.width, verticalLoc, imBounds.width, imBounds.width)); - } - - right -= (imBounds == null ? 0 : imBounds.width) + mSettings.getToolBarSpacing(); - } - } - - private void orderItems() { - if (mToolBarItems.size() == 0) - return; - - Collections.sort(mToolBarItems); - } - - public Point getSize() { - checkWidget(); - return new Point(super.getSize().x, CustomButton.BUTTON_HEIGHT); - } - - public void addItem(CustomButton button) { - checkWidget(); - mToolBarItems.add(new TBItem(button)); - } - - public void removeAll() { - checkWidget(); - mToolBarItems.clear(); - } - - public void removeItem(CustomButton button) { - checkWidget(); - for (int i = 0; i < mToolBarItems.size(); i++) { - TBItem item = mToolBarItems.get(i); - if (item.getButton() == button) { - mToolBarItems.remove(item); - break; - } - } - } - - public void hideButton(CustomButton button) { - checkWidget(); - for (int i = 0; i < mToolBarItems.size(); i++) { - TBItem item = mToolBarItems.get(i); - if (item.getButton() == button) { - item.setHidden(true); - break; - } - } - } - - public void setSelectedItem(CustomButton button) { - checkWidget(); - clearHover(); - clearArrowsHover(); - clearSelection(); - mSelectedItem = button; - - for (int i = 0; i < mToolBarItems.size(); i++) { - TBItem item = mToolBarItems.get(i); - - if (item.getButton() == mSelectedItem) { - Rectangle lb = item.getBounds(); - GC gc = new GC(this); - Rectangle rect = new Rectangle(lb.x - mSettings.getToolBarLeftSpacer(), 0, lb.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT); - mButtonPainter.paintBackground(gc, mColorManager, mSettings, rect, false, true); - gc.drawImage(item.getButton().getToolBarImage(), lb.x, lb.y); - gc.dispose(); - } - } - - } - - public void mouseDoubleClick(MouseEvent event) { - checkWidget(); - } - - public void mouseDown(MouseEvent event) { - checkWidget(); - Rectangle bigArrowsBounds = new Rectangle(mArrowsBounds.x, 0, mArrowsBounds.width, CustomButton.BUTTON_HEIGHT); - if (isInside(event.x, event.y, bigArrowsBounds)) { - GC gc = new GC(this); - Rectangle rect = new Rectangle(mArrowsBounds.x - mSettings.getToolBarLeftSpacer(), 0, mArrowsBounds.width + mSettings.getToolBarRightSpacer(), - CustomButton.BUTTON_HEIGHT); - mButtonPainter.paintBackground(gc, mColorManager, mSettings, rect, false, true); - - gc.drawImage(mArrowImage, mArrowsBounds.x, mArrowsBounds.y); - - gc.dispose(); - - Menu mainMenu = new Menu(Display.getDefault().getActiveShell(), SWT.POP_UP); - - List menuListeners = mButtonComposite.getMenuListeners(); - for (int i = 0; i < menuListeners.size(); i++) { - menuListeners.get(i).preMenuItemsCreated(mainMenu); - } - - MenuItem menuShowMoreButtons = new MenuItem(mainMenu, SWT.PUSH); - MenuItem menuShowFewerButtons = new MenuItem(mainMenu, SWT.PUSH); - menuShowFewerButtons.addListener(SWT.Selection, e -> mButtonComposite.hideNextButton()); - menuShowMoreButtons.addListener(SWT.Selection, e-> mButtonComposite.showNextButton()); - - menuShowMoreButtons.setText(mLanguage.getShowMoreButtonsText()); - menuShowFewerButtons.setText(mLanguage.getShowFewerButtonsText()); - - new MenuItem(mainMenu, SWT.SEPARATOR); - MenuItem more = new MenuItem(mainMenu, SWT.CASCADE); - more.setText(mLanguage.getAddOrRemoveButtonsText()); - Menu moreMenu = new Menu(more); - more.setMenu(moreMenu); - - List cbs = mButtonComposite.getItems(); - for (int i = 0; i < cbs.size(); i++) { - final CustomButton cb = cbs.get(i); - final MenuItem temp = new MenuItem(moreMenu, SWT.CHECK); - temp.setText(cb.getText()); - temp.setImage(cb.getToolBarImage()); - temp.setSelection(mButtonComposite.isVisible(cb)); - temp.addListener(SWT.Selection, e -> { - if (mButtonComposite.isVisible(cb)) { - mButtonComposite.permanentlyHideButton(cb); - temp.setSelection(false); - } else { - mButtonComposite.permanentlyShowButton(cb); - temp.setSelection(true); - } - }); - } - - for (int i = 0; i < menuListeners.size(); i++) { - menuListeners.get(i).postMenuItemsCreated(mainMenu); - } - - mainMenu.setVisible(true); - return; - } - - for (int i = 0; i < mToolBarItems.size(); i++) { - TBItem item = mToolBarItems.get(i); - if (item.getBounds() != null) { - if (isInside(event.x, event.y, item.getBounds())) { - mButtonComposite.selectItemAndLoad(item.getButton()); - break; - } - } - } - } - - public void mouseUp(MouseEvent event) { - checkWidget(); - } - - public void mouseMove(MouseEvent event) { - checkWidget(); - TBItem found = null; - - Rectangle bigArrowsBounds = new Rectangle(mArrowsBounds.x, 0, mArrowsBounds.width, CustomButton.BUTTON_HEIGHT); - if (isInside(event.x, event.y, bigArrowsBounds)) { - setToolTipText(null); - GC gc = new GC(this); - Rectangle rect = new Rectangle(mArrowsBounds.x - mSettings.getToolBarLeftSpacer(), 0, mArrowsBounds.width + mSettings.getToolBarRightSpacer(), - CustomButton.BUTTON_HEIGHT); - mButtonPainter.paintBackground(gc, mColorManager, mSettings, rect, true, false); - - gc.drawImage(mArrowImage, mArrowsBounds.x, mArrowsBounds.y); - gc.dispose(); - mArrowHover = true; - return; - } - - clearArrowsHover(); - - for (int i = 0; i < mToolBarItems.size(); i++) { - TBItem item = mToolBarItems.get(i); - if (item.getBounds() != null) { - if (isInside(event.x, event.y, item.getBounds())) { - found = item; - break; - } - } - } - - if (found == null) { - clearHover(); - return; - } - - setToolTipText(found.getButton().getToolTip()); - - if (found.isHovered()) { - return; - } - - if (found.getButton() == mSelectedItem) { - return; - } - - clearHover(); - - GC gc = new GC(this); - Rectangle tbBounds = found.getBounds(); - Rectangle toUse = new Rectangle(tbBounds.x - mSettings.getToolBarLeftSpacer(), 0, tbBounds.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT); - mButtonPainter.paintBackground(gc, mColorManager, mSettings, toUse, true, false); - gc.drawImage(found.getButton().getToolBarImage(), tbBounds.x, tbBounds.y); - gc.dispose(); - found.setHovered(true); - mLastHover = found; - } - - public void mouseEnter(MouseEvent event) { - - } - - public void mouseExit(MouseEvent event) { - checkWidget(); - clearHover(); - clearArrowsHover(); - } - - public void mouseHover(MouseEvent event) { - - } - - private void clearSelection() { - for (int i = 0; i < mToolBarItems.size(); i++) { - TBItem item = mToolBarItems.get(i); - if (item.getButton() == mSelectedItem) { - GC gc = new GC(this); - Rectangle lb = item.getBounds(); - redraw(lb.x - mSettings.getToolBarLeftSpacer(), 0, lb.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT, false); - if (item.getButton().getToolBarImage() != null) - gc.drawImage(item.getButton().getToolBarImage(), lb.x, lb.y); - gc.dispose(); - } - } - } - - private void clearHover() { - if (mLastHover != null) { - GC gc = new GC(this); - Rectangle lb = mLastHover.getBounds(); - redraw(lb.x - mSettings.getToolBarLeftSpacer(), 0, lb.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT, false); - gc.drawImage(mLastHover.getButton().getToolBarImage(), lb.x, lb.y); - gc.dispose(); - mLastHover.setHovered(false); - mLastHover = null; - setToolTipText(null); - } - } - - private void clearArrowsHover() { - if (mArrowHover) { - GC gc = new GC(this); - redraw(mArrowsBounds.x - mSettings.getToolBarLeftSpacer(), 0, mArrowsBounds.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT, false); - gc.drawImage(mArrowImage, mArrowsBounds.x, mArrowsBounds.y); - gc.dispose(); - mArrowHover = false; - } - } - - private boolean isInside(int x, int y, Rectangle rect) { - if (rect == null) { - return false; - } - - if (x >= rect.x && y >= rect.y && x <= (rect.x + rect.width) && y <= (rect.y + rect.height)) { - return true; - } - - return false; - } - - class TBItem implements Comparable { - private Rectangle bounds; - private CustomButton button; - private boolean hovered; - private boolean hidden; - - public TBItem(CustomButton button) { - this.button = button; - } - - public Rectangle getBounds() { - return bounds; - } - - public void setBounds(Rectangle bounds) { - this.bounds = bounds; - } - - public CustomButton getButton() { - return button; - } - - public boolean isHovered() { - return hovered; - } - - public void setHovered(boolean hovered) { - this.hovered = hovered; - } - - public void setHidden(boolean hidden) { - this.hidden = hidden; - } - - public boolean getHidden() { - return this.hidden; - } - - public String toString() { - return "[TBItem " + button.getNumber() + "]"; - } - - public int compareTo(Object item) { - if (!(item instanceof TBItem)) - return 0; - - TBItem tbitem = (TBItem) item; - - Integer one = new Integer(tbitem.getButton().getNumber()); - Integer two = new Integer(getButton().getNumber()); - return one.compareTo(two); - } - } - -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.collapsiblebuttons; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +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.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; + +public class ToolbarComposite extends Composite implements MouseListener, MouseMoveListener, MouseTrackListener { + + private List mToolBarItems; + private TBItem mLastHover; + private CustomButton mSelectedItem; + private CollapsibleButtons mButtonComposite; + + private boolean mEnableDoubleBuffering = true; + private boolean mCreated = false; + + private static Image mOutlook2005ArrowsImage = ImageCache.getImage("icons/arrows.gif"); + private static Image mOutlook2007ArrowImage = ImageCache.getImage("icons/o2007arrow.gif"); + private Rectangle mArrowsBounds; + private boolean mArrowHover = false; + + private IColorManager mColorManager; + private AbstractButtonPainter mButtonPainter; + + private Image mArrowImage; + private ISettings mSettings; + private ILanguageSettings mLanguage; + + /** + * Creates a new toolbar composite. + * + * @param bc ButtonComposite parent + * @param style Composite style + */ + public ToolbarComposite(CollapsibleButtons bc, int style) { + super(bc, style | SWT.NO_BACKGROUND); + + this.mLanguage = bc.getLanguageSettings(); + this.mButtonPainter = new AbstractButtonPainter(); + this.mButtonComposite = bc; + this.mColorManager = bc.getColorManager(); + this.mSettings = bc.getSettings(); + + if (mColorManager.getTheme() == IColorManager.SKIN_OFFICE_2007) + mArrowImage = mOutlook2007ArrowImage; + else + mArrowImage = mOutlook2005ArrowsImage; + + mToolBarItems = new ArrayList<>(); + + addListener(SWT.Paint, event -> repaint(event)); + addMouseListener(this); + addMouseTrackListener(this); + addMouseMoveListener(this); + } + + private void repaint(Event event) { + GC gc = event.gc; + if (mCreated && mEnableDoubleBuffering) { + try { + Image buffer = new Image(Display.getDefault(), super.getBounds()); + GC gc2 = new GC(buffer); + drawOntoGC(gc2); + + // transfer the image buffer onto this canvas + // just drawImage(buffer, w, h) didn't work, so we do the whole + // source transfer call + Rectangle b = getBounds(); + gc.drawImage(buffer, 0, 0, b.width, b.height, 0, 0, b.width, b.height); + + // dispose the buffer, very important or we'll run out of + // address space for buffered images + buffer.dispose(); + gc2.dispose(); + } catch (IllegalArgumentException iea) { + // seems to come here for some reason when we switch phases + // while the gantt chart is being viewed, I'm not sure why + // but no time to figure it out for the demo.. so instead of + // buffering, just draw it onto the GC + drawOntoGC(gc); + } + } else { + drawOntoGC(gc); + mCreated = true; + } + + gc.dispose(); + } + + private void drawOntoGC(GC gc) { + Rectangle rect = getClientArea(); + Rectangle imageBounds = (mArrowImage != null ? mArrowImage.getBounds() : new Rectangle(0, 0, 0, 0)); + int verticalLoc = (getBounds().height / 2) - (mArrowImage == null ? 0 : mArrowImage.getBounds().height / 2); + // move it down just a smidge, the human eye percieves things + // mis-aligned when exactly centered + verticalLoc += 1; + mButtonPainter.paintBackground(gc, mColorManager, mSettings, rect, false, false); + + int right = rect.width; + + if (mArrowImage != null) + gc.drawImage(mArrowImage, rect.width - imageBounds.width, verticalLoc); + mArrowsBounds = new Rectangle(rect.width - imageBounds.width, verticalLoc, imageBounds.width, imageBounds.height); + right -= imageBounds.width + mSettings.getToolBarSpacing(); + + // reorganize items if stuff have been hidden/shown (permanently) + orderItems(); + + for (int i = 0; i < mToolBarItems.size(); i++) { + TBItem tb = mToolBarItems.get(i); + if (tb.getHidden()) + continue; + + if (tb.getButton() == mSelectedItem) { + Rectangle cur = tb.getBounds(); + // TODO: Clean up code-repeat + if (cur == null) { + if (tb.getButton().getToolBarImage() != null) { + Rectangle imBounds = tb.getButton().getToolBarImage().getBounds(); + cur = new Rectangle(right - imBounds.width, verticalLoc, imBounds.width, imBounds.width); + tb.setBounds(cur); + } else { + // basically a non-existent button, but no image = no + // button, so that's fine + tb.setBounds(new Rectangle(right, verticalLoc, 0, 0)); + continue; + } + } + + Rectangle bounds = new Rectangle(cur.x - mSettings.getToolBarLeftSpacer(), cur.y, cur.width + mSettings.getToolBarRightSpacer(), cur.height); + mButtonPainter.paintBackground(gc, mColorManager, mSettings, bounds, false, true); + } + + Rectangle imBounds = null; + if (tb.getButton().getToolBarImage() != null) { + imBounds = tb.getButton().getToolBarImage().getBounds(); + gc.drawImage(tb.getButton().getToolBarImage(), right - imBounds.width, verticalLoc); + tb.setBounds(new Rectangle(right - imBounds.width, verticalLoc, imBounds.width, imBounds.width)); + } + + right -= (imBounds == null ? 0 : imBounds.width) + mSettings.getToolBarSpacing(); + } + } + + private void orderItems() { + if (mToolBarItems.size() == 0) + return; + + Collections.sort(mToolBarItems); + } + + public Point getSize() { + checkWidget(); + return new Point(super.getSize().x, CustomButton.BUTTON_HEIGHT); + } + + public void addItem(CustomButton button) { + checkWidget(); + mToolBarItems.add(new TBItem(button)); + } + + public void removeAll() { + checkWidget(); + mToolBarItems.clear(); + } + + public void removeItem(CustomButton button) { + checkWidget(); + for (int i = 0; i < mToolBarItems.size(); i++) { + TBItem item = mToolBarItems.get(i); + if (item.getButton() == button) { + mToolBarItems.remove(item); + break; + } + } + } + + public void hideButton(CustomButton button) { + checkWidget(); + for (int i = 0; i < mToolBarItems.size(); i++) { + TBItem item = mToolBarItems.get(i); + if (item.getButton() == button) { + item.setHidden(true); + break; + } + } + } + + public void setSelectedItem(CustomButton button) { + checkWidget(); + clearHover(); + clearArrowsHover(); + clearSelection(); + mSelectedItem = button; + + for (int i = 0; i < mToolBarItems.size(); i++) { + TBItem item = mToolBarItems.get(i); + + if (item.getButton() == mSelectedItem) { + Rectangle lb = item.getBounds(); + GC gc = new GC(this); + Rectangle rect = new Rectangle(lb.x - mSettings.getToolBarLeftSpacer(), 0, lb.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT); + mButtonPainter.paintBackground(gc, mColorManager, mSettings, rect, false, true); + gc.drawImage(item.getButton().getToolBarImage(), lb.x, lb.y); + gc.dispose(); + } + } + + } + + public void mouseDoubleClick(MouseEvent event) { + checkWidget(); + } + + public void mouseDown(MouseEvent event) { + checkWidget(); + Rectangle bigArrowsBounds = new Rectangle(mArrowsBounds.x, 0, mArrowsBounds.width, CustomButton.BUTTON_HEIGHT); + if (isInside(event.x, event.y, bigArrowsBounds)) { + GC gc = new GC(this); + Rectangle rect = new Rectangle(mArrowsBounds.x - mSettings.getToolBarLeftSpacer(), 0, mArrowsBounds.width + mSettings.getToolBarRightSpacer(), + CustomButton.BUTTON_HEIGHT); + mButtonPainter.paintBackground(gc, mColorManager, mSettings, rect, false, true); + + gc.drawImage(mArrowImage, mArrowsBounds.x, mArrowsBounds.y); + + gc.dispose(); + + Menu mainMenu = new Menu(Display.getDefault().getActiveShell(), SWT.POP_UP); + + List menuListeners = mButtonComposite.getMenuListeners(); + for (int i = 0; i < menuListeners.size(); i++) { + menuListeners.get(i).preMenuItemsCreated(mainMenu); + } + + MenuItem menuShowMoreButtons = new MenuItem(mainMenu, SWT.PUSH); + MenuItem menuShowFewerButtons = new MenuItem(mainMenu, SWT.PUSH); + menuShowFewerButtons.addListener(SWT.Selection, e -> mButtonComposite.hideNextButton()); + menuShowMoreButtons.addListener(SWT.Selection, e-> mButtonComposite.showNextButton()); + + menuShowMoreButtons.setText(mLanguage.getShowMoreButtonsText()); + menuShowFewerButtons.setText(mLanguage.getShowFewerButtonsText()); + + new MenuItem(mainMenu, SWT.SEPARATOR); + MenuItem more = new MenuItem(mainMenu, SWT.CASCADE); + more.setText(mLanguage.getAddOrRemoveButtonsText()); + Menu moreMenu = new Menu(more); + more.setMenu(moreMenu); + + List cbs = mButtonComposite.getItems(); + for (int i = 0; i < cbs.size(); i++) { + final CustomButton cb = cbs.get(i); + final MenuItem temp = new MenuItem(moreMenu, SWT.CHECK); + temp.setText(cb.getText()); + temp.setImage(cb.getToolBarImage()); + temp.setSelection(mButtonComposite.isVisible(cb)); + temp.addListener(SWT.Selection, e -> { + if (mButtonComposite.isVisible(cb)) { + mButtonComposite.permanentlyHideButton(cb); + temp.setSelection(false); + } else { + mButtonComposite.permanentlyShowButton(cb); + temp.setSelection(true); + } + }); + } + + for (int i = 0; i < menuListeners.size(); i++) { + menuListeners.get(i).postMenuItemsCreated(mainMenu); + } + + mainMenu.setVisible(true); + return; + } + + for (int i = 0; i < mToolBarItems.size(); i++) { + TBItem item = mToolBarItems.get(i); + if (item.getBounds() != null) { + if (isInside(event.x, event.y, item.getBounds())) { + mButtonComposite.selectItemAndLoad(item.getButton()); + break; + } + } + } + } + + public void mouseUp(MouseEvent event) { + checkWidget(); + } + + public void mouseMove(MouseEvent event) { + checkWidget(); + TBItem found = null; + + Rectangle bigArrowsBounds = new Rectangle(mArrowsBounds.x, 0, mArrowsBounds.width, CustomButton.BUTTON_HEIGHT); + if (isInside(event.x, event.y, bigArrowsBounds)) { + setToolTipText(null); + GC gc = new GC(this); + Rectangle rect = new Rectangle(mArrowsBounds.x - mSettings.getToolBarLeftSpacer(), 0, mArrowsBounds.width + mSettings.getToolBarRightSpacer(), + CustomButton.BUTTON_HEIGHT); + mButtonPainter.paintBackground(gc, mColorManager, mSettings, rect, true, false); + + gc.drawImage(mArrowImage, mArrowsBounds.x, mArrowsBounds.y); + gc.dispose(); + mArrowHover = true; + return; + } + + clearArrowsHover(); + + for (int i = 0; i < mToolBarItems.size(); i++) { + TBItem item = mToolBarItems.get(i); + if (item.getBounds() != null) { + if (isInside(event.x, event.y, item.getBounds())) { + found = item; + break; + } + } + } + + if (found == null) { + clearHover(); + return; + } + + setToolTipText(found.getButton().getToolTip()); + + if (found.isHovered()) { + return; + } + + if (found.getButton() == mSelectedItem) { + return; + } + + clearHover(); + + GC gc = new GC(this); + Rectangle tbBounds = found.getBounds(); + Rectangle toUse = new Rectangle(tbBounds.x - mSettings.getToolBarLeftSpacer(), 0, tbBounds.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT); + mButtonPainter.paintBackground(gc, mColorManager, mSettings, toUse, true, false); + gc.drawImage(found.getButton().getToolBarImage(), tbBounds.x, tbBounds.y); + gc.dispose(); + found.setHovered(true); + mLastHover = found; + } + + public void mouseEnter(MouseEvent event) { + + } + + public void mouseExit(MouseEvent event) { + checkWidget(); + clearHover(); + clearArrowsHover(); + } + + public void mouseHover(MouseEvent event) { + + } + + private void clearSelection() { + for (int i = 0; i < mToolBarItems.size(); i++) { + TBItem item = mToolBarItems.get(i); + if (item.getButton() == mSelectedItem) { + GC gc = new GC(this); + Rectangle lb = item.getBounds(); + redraw(lb.x - mSettings.getToolBarLeftSpacer(), 0, lb.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT, false); + if (item.getButton().getToolBarImage() != null) + gc.drawImage(item.getButton().getToolBarImage(), lb.x, lb.y); + gc.dispose(); + } + } + } + + private void clearHover() { + if (mLastHover != null) { + GC gc = new GC(this); + Rectangle lb = mLastHover.getBounds(); + redraw(lb.x - mSettings.getToolBarLeftSpacer(), 0, lb.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT, false); + gc.drawImage(mLastHover.getButton().getToolBarImage(), lb.x, lb.y); + gc.dispose(); + mLastHover.setHovered(false); + mLastHover = null; + setToolTipText(null); + } + } + + private void clearArrowsHover() { + if (mArrowHover) { + GC gc = new GC(this); + redraw(mArrowsBounds.x - mSettings.getToolBarLeftSpacer(), 0, mArrowsBounds.width + mSettings.getToolBarRightSpacer(), CustomButton.BUTTON_HEIGHT, false); + gc.drawImage(mArrowImage, mArrowsBounds.x, mArrowsBounds.y); + gc.dispose(); + mArrowHover = false; + } + } + + private boolean isInside(int x, int y, Rectangle rect) { + if (rect == null) { + return false; + } + + if (x >= rect.x && y >= rect.y && x <= (rect.x + rect.width) && y <= (rect.y + rect.height)) { + return true; + } + + return false; + } + + class TBItem implements Comparable { + private Rectangle bounds; + private CustomButton button; + private boolean hovered; + private boolean hidden; + + public TBItem(CustomButton button) { + this.button = button; + } + + public Rectangle getBounds() { + return bounds; + } + + public void setBounds(Rectangle bounds) { + this.bounds = bounds; + } + + public CustomButton getButton() { + return button; + } + + public boolean isHovered() { + return hovered; + } + + public void setHovered(boolean hovered) { + this.hovered = hovered; + } + + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + public boolean getHidden() { + return this.hidden; + } + + public String toString() { + return "[TBItem " + button.getNumber() + "]"; + } + + public int compareTo(Object item) { + if (!(item instanceof TBItem)) + return 0; + + TBItem tbitem = (TBItem) item; + + Integer one = new Integer(tbitem.getButton().getNumber()); + Integer two = new Integer(getButton().getNumber()); + return one.compareTo(two); + } + } + +} diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable.tests/META-INF/MANIFEST.MF b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable.tests/META-INF/MANIFEST.MF index 527a2b030..c3ea1869b 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable.tests/META-INF/MANIFEST.MF +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable.tests/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Compositetable Tests -Bundle-SymbolicName: org.eclipse.nebula.widgets.compositetable.tests -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Fragment-Host: org.eclipse.nebula.widgets.compositetable;bundle-version="1.0.0" -Export-Package: org.eclipse.nebula.widgets.compositetable, - org.eclipse.nebula.widgets.compositetable.day -Import-Package: junit.framework;version="4.12.0", - junit.runner;version="4.12.0", - org.junit;version="4.12.0" -Automatic-Module-Name: org.eclipse.nebula.widgets.compositetable.tests -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Compositetable Tests +Bundle-SymbolicName: org.eclipse.nebula.widgets.compositetable.tests +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Fragment-Host: org.eclipse.nebula.widgets.compositetable;bundle-version="1.0.0" +Export-Package: org.eclipse.nebula.widgets.compositetable, + org.eclipse.nebula.widgets.compositetable.day +Import-Package: junit.framework;version="4.12.0", + junit.runner;version="4.12.0", + org.junit;version="4.12.0" +Automatic-Module-Name: org.eclipse.nebula.widgets.compositetable.tests +Bundle-RequiredExecutionEnvironment: JavaSE-11 diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/META-INF/MANIFEST.MF b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/META-INF/MANIFEST.MF index e988c2243..b1fb8f07d 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/META-INF/MANIFEST.MF +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Compositetable -Bundle-SymbolicName: org.eclipse.nebula.widgets.compositetable -Bundle-Version: 1.0.0.qualifier -Export-Package: org.eclipse.nebula.widgets.compositetable, - org.eclipse.nebula.widgets.compositetable.day, - org.eclipse.nebula.widgets.compositetable.month, - org.eclipse.nebula.widgets.compositetable.timeeditor -Require-Bundle: org.eclipse.swt, - org.eclipse.jface -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.widgets.compositetable +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Compositetable +Bundle-SymbolicName: org.eclipse.nebula.widgets.compositetable +Bundle-Version: 1.0.0.qualifier +Export-Package: org.eclipse.nebula.widgets.compositetable, + org.eclipse.nebula.widgets.compositetable.day, + org.eclipse.nebula.widgets.compositetable.month, + org.eclipse.nebula.widgets.compositetable.timeeditor +Require-Bundle: org.eclipse.swt, + org.eclipse.jface +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.widgets.compositetable diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/HeaderLayout.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/HeaderLayout.java index b1e9a7062..96856df73 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/HeaderLayout.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/HeaderLayout.java @@ -1,453 +1,453 @@ -package org.eclipse.nebula.widgets.compositetable; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.Widget; - - -class HeaderLayout extends AbstractGridRowLayout { - - private static final int MINIMUM_COL_WIDTH = 5; - - private boolean layingOut = false; - private int[] lastWidths = null; - - private AbstractNativeHeader header = null; - - /** - * Constructor HeaderLayout. The default constructor. If you use this - * constructor, you must manually specify the column weights, and possibly, - * the fittingHorizontally property value. - */ - public HeaderLayout() { - super(); - } - - /** - * Constructor HeaderLayout. Construct a HeaderLayout, specifying the - * column weights. By default, fittingHorizontally is false. - * - * @param weights - * int[] The amount of weight desired for each column in the - * table. If fittingHorizontally is set to true, the sum of all - * weights must be 100 and each weight indicates the percentage - * of the whole table that each column will occupy. If - * fittingHorizontally is set to false, each weight is the - * minimum width of the column in pixels. If the table is - * narrower than can fit all widths, CompositeTable will display - * a horizontal scroll bar. If the table is wider than can fit - * all widths, the columns are scaled so that the entire table - * fills the desired space and the ratios of the column widths - * remains constant. fittingHorizontally defaults to false. - */ - public HeaderLayout(int[] weights) { - super(weights); - } - - /** - * Construct a HeaderLayout, specifying both the weights and the - * fittingHorizontally property. - * - * @param weights - * int[] The amount of weight desired for each column in the - * table. If fittingHorizontally is set to true, the sum of all - * weights must be 100 and each weight indicates the percentage - * of the whole table that each column will occupy. If - * fittingHorizontally is set to false, each weight is the - * minimum width of the column in pixels. If the table is - * narrower than can fit all widths, CompositeTable will display - * a horizontal scroll bar. If the table is wider than all - * minimum column widths, the columns will be scaled so that the - * ratios of the actual widths remains constant and all columns - * fit exactly in the available space. fittingHorizontally - * defaults to false. - * - * @param fittingHorizontally - * If true, the weights are interpreted as percentages and the - * column widths are scaled so that each column occupies the - * percentage of the total width indicated by its weight. If - * false, the weights are interpreted as minimum column widths. - * If the table is narrower than can accommodate those widths, - * CompositeTable will display a horizontal scroll bar. If the - * table is wider than all minimum column widths, the columns - * will be scaled so that the ratios of the actual widths remains - * constant and all columns fit exactly in the available space. - */ - public HeaderLayout(int[] weights, boolean fittingHorizontally) { - super(weights, fittingHorizontally); - } - - protected Point computeSize(Composite child, int wHint, int hHint, boolean flushCache) { - storeHeader(child); - return super.computeSize(child, wHint, hHint, flushCache); - } - - private void storeHeader(Composite child) { - this.header = getHeader(child); - } - - /* - * FEATURE in SWT/Win32: When resizing a Shell larger, we get two layout - * events from SWT. (1) where the Shell has gotten bigger but the child - * hasn't; (2) where both the Shell and child have gotten bigger. When - * the Shell is getting bigger, we want to only process events under (2). - * - * The problem is that if the headerTable's contents is made larger before - * the child is, the headerTable will display scroll bar(s), which will - * then be erased when event (2) arrives. The solution is to only process - * event (2). - * - * TODO: Test on Linux/GTK. - */ - private int lastChildWidth = -1; - private int lastShellWidth = -1; - - protected void layout(final Composite child, boolean flushCache) { - storeHeader(child); - - int childWidth = child.getSize().x; - int shellWidth = child.getShell().getSize().x; - - if (childWidth == lastChildWidth && shellWidth > lastShellWidth) return; - - if (childWidth > lastChildWidth) { - final Table headerTable = getHeader(child).headerTable; - headerTable.addPaintListener(new PaintListener() { - public void paintControl(PaintEvent e) { - headerTable.removePaintListener(this); - layout(child); - } - }); - } else { - layout(child); - } - lastChildWidth = childWidth; - lastShellWidth = shellWidth; - } - - private void layout(Composite child) { - layingOut = true; - try { - super.layout(child, true); - storeLastWidths(getHeader(child).headerTable); - } finally { - layingOut = false; - } - } - - protected void storeLastWidths(Table table) { - if (lastWidths == null) { - lastWidths = new int[table.getColumnCount()]; - } - TableColumn[] columns = table.getColumns(); - for (int col = 0; col < columns.length; col++) { - lastWidths[col] = columns[col].getWidth(); - } - } - - // Inherited from AbstractGridRowLayout ------------------------------------ - - public int[] getWeights() { - if (header == null) { - return super.getWeights(); - } else { - int[] weightsOrder = header.headerTable.getColumnOrder(); - int[] rawWeights = super.getWeights(); - int[] orderedWeights = new int[weightsOrder.length]; - for (int i = 0; i < orderedWeights.length; i++) { - orderedWeights[i] = rawWeights[weightsOrder[i]]; - } - return orderedWeights; - } - } - - public AbstractGridRowLayout setWeights(int[] weights) { - if (header == null) { - super.setWeights(weights); - } else { - int[] weightsOrder = header.headerTable.getColumnOrder(); - int[] orderedWeights = new int[weightsOrder.length]; - for (int i = 0; i < orderedWeights.length; i++) { - orderedWeights[weightsOrder[i]] = weights[i]; - super.setWeights(orderedWeights); - } - } - return this; - } - - protected int computeMaxHeight(Composite rowOrHeader) { - return getHeader(rowOrHeader).headerTable.getHeaderHeight(); - } - - protected Point computeColumnSize(Widget columnObject, int wHint, int hHint, boolean flush) { - TableColumn tableColumn = (TableColumn) columnObject; - int currentWidth = tableColumn.getWidth(); - int headerHeight = tableColumn.getParent().getHeaderHeight(); - return new Point(currentWidth, headerHeight); - } - - protected Widget getColumnAt(Composite rowOrHeader, int offset) { - Table headerTable = getHeader(rowOrHeader).headerTable; - int[] columnOrder = headerTable.getColumnOrder(); - return headerTable.getColumn(columnOrder[offset]); - } - - protected int getNumColumns(Composite rowOrHeader) { - return getHeader(rowOrHeader).headerTable.getColumnCount(); - } - - protected void setBounds(Widget columnObject, int left, int top, int width, int height) { - TableColumn tableColumn = (TableColumn) columnObject; - tableColumn.setWidth(width + 2*CELL_BORDER_WIDTH); - } - - // Utility methods --------------------------------------------------------- - - private AbstractNativeHeader asHeader(Widget rowOrHeader) { - if (!(rowOrHeader instanceof AbstractNativeHeader)) { - throw new IllegalArgumentException("HeaderLayout must be used on an AbstractHeader"); - } - return (AbstractNativeHeader) rowOrHeader; - } - - private AbstractNativeHeader getHeader(Widget rowOrHeader) { - AbstractNativeHeader header = asHeader(rowOrHeader); - if (headerControlListener == null) { - headerControlListener = new HeaderControlListener(); - header.addColumnControlListener(headerControlListener); - header.addDisposeListener(headerDisposeListener); - } - return header; - } - - private boolean resizedColumnIsNotTheLastColumn(int resizedColumnNumber, Table table) { - return resizedColumnNumber < table.getColumnCount()-1; - } - - private int computePercentage(int totalAvailableWidth, int columnWidth) { - return (int) (((double) columnWidth) / totalAvailableWidth * 100); - } - - // Called from event handlers ---------------------------------------------- - - private void adjustWeights(AbstractNativeHeader header, TableColumn resizedColumn) { - int totalAvailableWidth = getAvailableWidth(header); - int resizedColumnNumber = 0; - int newTotalWidth = 0; - - TableColumn[] columns = resizedColumn.getParent().getColumns(); - for (int i = 0; i < columns.length; i++) { - newTotalWidth += columns[i].getWidth(); - if (columns[i] == resizedColumn) { - resizedColumnNumber = i; - } - } - - Table table = resizedColumn.getParent(); - int[] columnOrder = table.getColumnOrder(); - int resizedColumnPosition = 0; - - for (int i = 0; i < columnOrder.length; i++) { - if (columnOrder[i] == resizedColumnNumber) { - resizedColumnPosition = i; - break; - } - } - - if (resizedColumnIsNotTheLastColumn(resizedColumnPosition, resizedColumn.getParent())) { - // Compute resized column width change and make sure the resized - // column's width is sane - int resizedColumnWidth = resizedColumn.getWidth(); - - // int columnWidthChange = lastWidths[resizedColumnPosition] - resizedColumnWidth; - int columnWidthChange = lastWidths[columnOrder[resizedColumnPosition]] - resizedColumnWidth; - - int columnWidthChangeTooFar = MINIMUM_COL_WIDTH - resizedColumnWidth; - if (columnWidthChangeTooFar > 0) { - columnWidthChange -= columnWidthChangeTooFar; - resizedColumnWidth = MINIMUM_COL_WIDTH; - resizedColumn.setWidth(resizedColumnWidth); - } - - // Fix the width of the column to the right of the resized column - int columnToTheRightOfResizedColumnWidth = - lastWidths[columnOrder[resizedColumnPosition+1]] + columnWidthChange; - - // int columnToTheRightOfResizedColumnWidth = - // lastWidths[resizedColumnPosition+1] + columnWidthChange; - - columnWidthChangeTooFar = MINIMUM_COL_WIDTH - columnToTheRightOfResizedColumnWidth; - if (columnWidthChangeTooFar > 0) { - columnWidthChange += columnWidthChangeTooFar; - resizedColumnWidth -= columnWidthChangeTooFar; - resizedColumn.setWidth(resizedColumnWidth); - columnToTheRightOfResizedColumnWidth = MINIMUM_COL_WIDTH; - } - TableColumn columnToTheRightOfResizedColumn = columns[columnOrder[resizedColumnPosition+1]]; - columnToTheRightOfResizedColumn.setWidth(columnToTheRightOfResizedColumnWidth); - - if (isFittingHorizontally()) { - adjustWeightedHeader(header, resizedColumnPosition, - resizedColumn, columnToTheRightOfResizedColumn, - totalAvailableWidth, newTotalWidth); - } else { - // Fix the weights based on if the column sizes are being scaled - if (isWidthWiderThanAllColumns(header)) { - adjustScaledAbsoluteWidthWeights(resizedColumnPosition, - resizedColumnWidth, - columnToTheRightOfResizedColumnWidth, - header.getSize().x); - } else { - adjustNonScaledAbsoluteWidthWeights(resizedColumnPosition, - resizedColumnWidth, - columnToTheRightOfResizedColumnWidth); - } - } - - fireColumnResizedEvent(resizedColumnPosition, - resizedColumnWidth, - columnToTheRightOfResizedColumnWidth); - } else { - // Re-layout; the rightmost column can't be resized - layout(header, true); - } - } - - private List columnControlListeners = new ArrayList(); - - void addColumnControlListener(ColumnControlListener l) { - columnControlListeners.add(l); - } - - void removeColumnControlListener(ColumnControlListener l) { - columnControlListeners.remove(l); - } - - private void fireColumnResizedEvent(int resizedColumnNumber, int resizedColumnWidth, int columnToTheRightOfResizedColumnWidth) { - for (Iterator i = columnControlListeners.iterator(); i.hasNext();) { - ColumnControlListener l = (ColumnControlListener) i.next(); - l.columnResized(resizedColumnNumber, - resizedColumnWidth, - columnToTheRightOfResizedColumnWidth); - } - } - - private void fireColumnMovedEvent(int[] newColumnOrder) { - for (Iterator i = columnControlListeners.iterator(); i.hasNext();) { - ColumnControlListener l = (ColumnControlListener) i.next(); - l.columnMoved(newColumnOrder); - } - } - - private void adjustWeightedHeader(AbstractNativeHeader header, - int resizedColumnPosition, TableColumn resizedColumn, - TableColumn columnToTheRightOfResizedColumn, - int totalAvailableWidth, int newTotalWidth) - { - // Adjust percentage of the resized column and the column to the right - int[] weights = getWeights(); - int resizedColumnPercentage = computePercentage(totalAvailableWidth, - resizedColumn.getWidth()); - weights[resizedColumnPosition] = resizedColumnPercentage; - giveRemainderToWeightAtColumn(resizedColumnPosition+1); - setWeights(weights); - } - - private void adjustScaledAbsoluteWidthWeights(int resizedColumnPosition, - int resizedColumnWidth, int columnToTheRightOfResizedColumnWidth, - int headerWidth) - { - int sumOfAllWeights = getSumOfAllWeights(); - double scalingFactor = (double)headerWidth / (double) sumOfAllWeights; - int unscaledResizedColumWidth = (int)(resizedColumnWidth / scalingFactor); - int unscaledColumnToTheRightOfResizedColumnWidth = - (int)(columnToTheRightOfResizedColumnWidth / scalingFactor); - - adjustNonScaledAbsoluteWidthWeights(resizedColumnPosition, - unscaledResizedColumWidth, - unscaledColumnToTheRightOfResizedColumnWidth); - } - - private void adjustNonScaledAbsoluteWidthWeights(int resizedColumnPosition, - int resizedColumnWidth, int columnToTheRightOfResizedColumnWidth) - { - int[] weights = getWeights(); - int oldWeightSum = getSumOfAllWeights(); - int currentWeightSum = oldWeightSum; - - currentWeightSum += weights[resizedColumnPosition] - resizedColumnWidth; - currentWeightSum += weights[resizedColumnPosition+1] - - columnToTheRightOfResizedColumnWidth; - int weightSumChange = oldWeightSum - currentWeightSum; - columnToTheRightOfResizedColumnWidth -= weightSumChange; - - weights[resizedColumnPosition] = resizedColumnWidth; - weights[resizedColumnPosition+1] = columnToTheRightOfResizedColumnWidth; - setWeights(weights); - } - - private void giveRemainderToWeightAtColumn(int columnNumber) { - int[] weights = getWeights(); - int totalWeightPercentage = 0; - for (int i = 0; i < weights.length; i++) { - totalWeightPercentage += weights[i]; - } - int spareWidthPercentage = 100 - totalWeightPercentage; - weights[columnNumber] += spareWidthPercentage; - } - - // Event listeners -------------------------------------------------------- - - private ControlListener headerControlListener = null; - - private boolean wasResized = true; - - private class HeaderControlListener implements ControlListener { - public void controlMoved(ControlEvent e) { - // Eat the move event that is fired after resize events - if (wasResized) { - wasResized = false; - return; - } - Table table = header.headerTable; - fireColumnMovedEvent(table.getColumnOrder()); - storeLastWidths(table); - } - - public void controlResized(ControlEvent e) { - if (lastWidths == null) return; - wasResized = true; - if (!layingOut) { - layingOut = true; - try { - TableColumn tableColumn = (TableColumn) e.widget; - AbstractNativeHeader header = asHeader(tableColumn.getParent().getParent()); - adjustWeights(header, tableColumn); - storeLastWidths(tableColumn.getParent()); - } finally { - layingOut = false; - } - } - } - } - - private DisposeListener headerDisposeListener = new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - asHeader(e.widget).removeColumnControlListener(headerControlListener); - } - }; - -} - +package org.eclipse.nebula.widgets.compositetable; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Widget; + + +class HeaderLayout extends AbstractGridRowLayout { + + private static final int MINIMUM_COL_WIDTH = 5; + + private boolean layingOut = false; + private int[] lastWidths = null; + + private AbstractNativeHeader header = null; + + /** + * Constructor HeaderLayout. The default constructor. If you use this + * constructor, you must manually specify the column weights, and possibly, + * the fittingHorizontally property value. + */ + public HeaderLayout() { + super(); + } + + /** + * Constructor HeaderLayout. Construct a HeaderLayout, specifying the + * column weights. By default, fittingHorizontally is false. + * + * @param weights + * int[] The amount of weight desired for each column in the + * table. If fittingHorizontally is set to true, the sum of all + * weights must be 100 and each weight indicates the percentage + * of the whole table that each column will occupy. If + * fittingHorizontally is set to false, each weight is the + * minimum width of the column in pixels. If the table is + * narrower than can fit all widths, CompositeTable will display + * a horizontal scroll bar. If the table is wider than can fit + * all widths, the columns are scaled so that the entire table + * fills the desired space and the ratios of the column widths + * remains constant. fittingHorizontally defaults to false. + */ + public HeaderLayout(int[] weights) { + super(weights); + } + + /** + * Construct a HeaderLayout, specifying both the weights and the + * fittingHorizontally property. + * + * @param weights + * int[] The amount of weight desired for each column in the + * table. If fittingHorizontally is set to true, the sum of all + * weights must be 100 and each weight indicates the percentage + * of the whole table that each column will occupy. If + * fittingHorizontally is set to false, each weight is the + * minimum width of the column in pixels. If the table is + * narrower than can fit all widths, CompositeTable will display + * a horizontal scroll bar. If the table is wider than all + * minimum column widths, the columns will be scaled so that the + * ratios of the actual widths remains constant and all columns + * fit exactly in the available space. fittingHorizontally + * defaults to false. + * + * @param fittingHorizontally + * If true, the weights are interpreted as percentages and the + * column widths are scaled so that each column occupies the + * percentage of the total width indicated by its weight. If + * false, the weights are interpreted as minimum column widths. + * If the table is narrower than can accommodate those widths, + * CompositeTable will display a horizontal scroll bar. If the + * table is wider than all minimum column widths, the columns + * will be scaled so that the ratios of the actual widths remains + * constant and all columns fit exactly in the available space. + */ + public HeaderLayout(int[] weights, boolean fittingHorizontally) { + super(weights, fittingHorizontally); + } + + protected Point computeSize(Composite child, int wHint, int hHint, boolean flushCache) { + storeHeader(child); + return super.computeSize(child, wHint, hHint, flushCache); + } + + private void storeHeader(Composite child) { + this.header = getHeader(child); + } + + /* + * FEATURE in SWT/Win32: When resizing a Shell larger, we get two layout + * events from SWT. (1) where the Shell has gotten bigger but the child + * hasn't; (2) where both the Shell and child have gotten bigger. When + * the Shell is getting bigger, we want to only process events under (2). + * + * The problem is that if the headerTable's contents is made larger before + * the child is, the headerTable will display scroll bar(s), which will + * then be erased when event (2) arrives. The solution is to only process + * event (2). + * + * TODO: Test on Linux/GTK. + */ + private int lastChildWidth = -1; + private int lastShellWidth = -1; + + protected void layout(final Composite child, boolean flushCache) { + storeHeader(child); + + int childWidth = child.getSize().x; + int shellWidth = child.getShell().getSize().x; + + if (childWidth == lastChildWidth && shellWidth > lastShellWidth) return; + + if (childWidth > lastChildWidth) { + final Table headerTable = getHeader(child).headerTable; + headerTable.addPaintListener(new PaintListener() { + public void paintControl(PaintEvent e) { + headerTable.removePaintListener(this); + layout(child); + } + }); + } else { + layout(child); + } + lastChildWidth = childWidth; + lastShellWidth = shellWidth; + } + + private void layout(Composite child) { + layingOut = true; + try { + super.layout(child, true); + storeLastWidths(getHeader(child).headerTable); + } finally { + layingOut = false; + } + } + + protected void storeLastWidths(Table table) { + if (lastWidths == null) { + lastWidths = new int[table.getColumnCount()]; + } + TableColumn[] columns = table.getColumns(); + for (int col = 0; col < columns.length; col++) { + lastWidths[col] = columns[col].getWidth(); + } + } + + // Inherited from AbstractGridRowLayout ------------------------------------ + + public int[] getWeights() { + if (header == null) { + return super.getWeights(); + } else { + int[] weightsOrder = header.headerTable.getColumnOrder(); + int[] rawWeights = super.getWeights(); + int[] orderedWeights = new int[weightsOrder.length]; + for (int i = 0; i < orderedWeights.length; i++) { + orderedWeights[i] = rawWeights[weightsOrder[i]]; + } + return orderedWeights; + } + } + + public AbstractGridRowLayout setWeights(int[] weights) { + if (header == null) { + super.setWeights(weights); + } else { + int[] weightsOrder = header.headerTable.getColumnOrder(); + int[] orderedWeights = new int[weightsOrder.length]; + for (int i = 0; i < orderedWeights.length; i++) { + orderedWeights[weightsOrder[i]] = weights[i]; + super.setWeights(orderedWeights); + } + } + return this; + } + + protected int computeMaxHeight(Composite rowOrHeader) { + return getHeader(rowOrHeader).headerTable.getHeaderHeight(); + } + + protected Point computeColumnSize(Widget columnObject, int wHint, int hHint, boolean flush) { + TableColumn tableColumn = (TableColumn) columnObject; + int currentWidth = tableColumn.getWidth(); + int headerHeight = tableColumn.getParent().getHeaderHeight(); + return new Point(currentWidth, headerHeight); + } + + protected Widget getColumnAt(Composite rowOrHeader, int offset) { + Table headerTable = getHeader(rowOrHeader).headerTable; + int[] columnOrder = headerTable.getColumnOrder(); + return headerTable.getColumn(columnOrder[offset]); + } + + protected int getNumColumns(Composite rowOrHeader) { + return getHeader(rowOrHeader).headerTable.getColumnCount(); + } + + protected void setBounds(Widget columnObject, int left, int top, int width, int height) { + TableColumn tableColumn = (TableColumn) columnObject; + tableColumn.setWidth(width + 2*CELL_BORDER_WIDTH); + } + + // Utility methods --------------------------------------------------------- + + private AbstractNativeHeader asHeader(Widget rowOrHeader) { + if (!(rowOrHeader instanceof AbstractNativeHeader)) { + throw new IllegalArgumentException("HeaderLayout must be used on an AbstractHeader"); + } + return (AbstractNativeHeader) rowOrHeader; + } + + private AbstractNativeHeader getHeader(Widget rowOrHeader) { + AbstractNativeHeader header = asHeader(rowOrHeader); + if (headerControlListener == null) { + headerControlListener = new HeaderControlListener(); + header.addColumnControlListener(headerControlListener); + header.addDisposeListener(headerDisposeListener); + } + return header; + } + + private boolean resizedColumnIsNotTheLastColumn(int resizedColumnNumber, Table table) { + return resizedColumnNumber < table.getColumnCount()-1; + } + + private int computePercentage(int totalAvailableWidth, int columnWidth) { + return (int) (((double) columnWidth) / totalAvailableWidth * 100); + } + + // Called from event handlers ---------------------------------------------- + + private void adjustWeights(AbstractNativeHeader header, TableColumn resizedColumn) { + int totalAvailableWidth = getAvailableWidth(header); + int resizedColumnNumber = 0; + int newTotalWidth = 0; + + TableColumn[] columns = resizedColumn.getParent().getColumns(); + for (int i = 0; i < columns.length; i++) { + newTotalWidth += columns[i].getWidth(); + if (columns[i] == resizedColumn) { + resizedColumnNumber = i; + } + } + + Table table = resizedColumn.getParent(); + int[] columnOrder = table.getColumnOrder(); + int resizedColumnPosition = 0; + + for (int i = 0; i < columnOrder.length; i++) { + if (columnOrder[i] == resizedColumnNumber) { + resizedColumnPosition = i; + break; + } + } + + if (resizedColumnIsNotTheLastColumn(resizedColumnPosition, resizedColumn.getParent())) { + // Compute resized column width change and make sure the resized + // column's width is sane + int resizedColumnWidth = resizedColumn.getWidth(); + + // int columnWidthChange = lastWidths[resizedColumnPosition] - resizedColumnWidth; + int columnWidthChange = lastWidths[columnOrder[resizedColumnPosition]] - resizedColumnWidth; + + int columnWidthChangeTooFar = MINIMUM_COL_WIDTH - resizedColumnWidth; + if (columnWidthChangeTooFar > 0) { + columnWidthChange -= columnWidthChangeTooFar; + resizedColumnWidth = MINIMUM_COL_WIDTH; + resizedColumn.setWidth(resizedColumnWidth); + } + + // Fix the width of the column to the right of the resized column + int columnToTheRightOfResizedColumnWidth = + lastWidths[columnOrder[resizedColumnPosition+1]] + columnWidthChange; + + // int columnToTheRightOfResizedColumnWidth = + // lastWidths[resizedColumnPosition+1] + columnWidthChange; + + columnWidthChangeTooFar = MINIMUM_COL_WIDTH - columnToTheRightOfResizedColumnWidth; + if (columnWidthChangeTooFar > 0) { + columnWidthChange += columnWidthChangeTooFar; + resizedColumnWidth -= columnWidthChangeTooFar; + resizedColumn.setWidth(resizedColumnWidth); + columnToTheRightOfResizedColumnWidth = MINIMUM_COL_WIDTH; + } + TableColumn columnToTheRightOfResizedColumn = columns[columnOrder[resizedColumnPosition+1]]; + columnToTheRightOfResizedColumn.setWidth(columnToTheRightOfResizedColumnWidth); + + if (isFittingHorizontally()) { + adjustWeightedHeader(header, resizedColumnPosition, + resizedColumn, columnToTheRightOfResizedColumn, + totalAvailableWidth, newTotalWidth); + } else { + // Fix the weights based on if the column sizes are being scaled + if (isWidthWiderThanAllColumns(header)) { + adjustScaledAbsoluteWidthWeights(resizedColumnPosition, + resizedColumnWidth, + columnToTheRightOfResizedColumnWidth, + header.getSize().x); + } else { + adjustNonScaledAbsoluteWidthWeights(resizedColumnPosition, + resizedColumnWidth, + columnToTheRightOfResizedColumnWidth); + } + } + + fireColumnResizedEvent(resizedColumnPosition, + resizedColumnWidth, + columnToTheRightOfResizedColumnWidth); + } else { + // Re-layout; the rightmost column can't be resized + layout(header, true); + } + } + + private List columnControlListeners = new ArrayList(); + + void addColumnControlListener(ColumnControlListener l) { + columnControlListeners.add(l); + } + + void removeColumnControlListener(ColumnControlListener l) { + columnControlListeners.remove(l); + } + + private void fireColumnResizedEvent(int resizedColumnNumber, int resizedColumnWidth, int columnToTheRightOfResizedColumnWidth) { + for (Iterator i = columnControlListeners.iterator(); i.hasNext();) { + ColumnControlListener l = (ColumnControlListener) i.next(); + l.columnResized(resizedColumnNumber, + resizedColumnWidth, + columnToTheRightOfResizedColumnWidth); + } + } + + private void fireColumnMovedEvent(int[] newColumnOrder) { + for (Iterator i = columnControlListeners.iterator(); i.hasNext();) { + ColumnControlListener l = (ColumnControlListener) i.next(); + l.columnMoved(newColumnOrder); + } + } + + private void adjustWeightedHeader(AbstractNativeHeader header, + int resizedColumnPosition, TableColumn resizedColumn, + TableColumn columnToTheRightOfResizedColumn, + int totalAvailableWidth, int newTotalWidth) + { + // Adjust percentage of the resized column and the column to the right + int[] weights = getWeights(); + int resizedColumnPercentage = computePercentage(totalAvailableWidth, + resizedColumn.getWidth()); + weights[resizedColumnPosition] = resizedColumnPercentage; + giveRemainderToWeightAtColumn(resizedColumnPosition+1); + setWeights(weights); + } + + private void adjustScaledAbsoluteWidthWeights(int resizedColumnPosition, + int resizedColumnWidth, int columnToTheRightOfResizedColumnWidth, + int headerWidth) + { + int sumOfAllWeights = getSumOfAllWeights(); + double scalingFactor = (double)headerWidth / (double) sumOfAllWeights; + int unscaledResizedColumWidth = (int)(resizedColumnWidth / scalingFactor); + int unscaledColumnToTheRightOfResizedColumnWidth = + (int)(columnToTheRightOfResizedColumnWidth / scalingFactor); + + adjustNonScaledAbsoluteWidthWeights(resizedColumnPosition, + unscaledResizedColumWidth, + unscaledColumnToTheRightOfResizedColumnWidth); + } + + private void adjustNonScaledAbsoluteWidthWeights(int resizedColumnPosition, + int resizedColumnWidth, int columnToTheRightOfResizedColumnWidth) + { + int[] weights = getWeights(); + int oldWeightSum = getSumOfAllWeights(); + int currentWeightSum = oldWeightSum; + + currentWeightSum += weights[resizedColumnPosition] - resizedColumnWidth; + currentWeightSum += weights[resizedColumnPosition+1] + - columnToTheRightOfResizedColumnWidth; + int weightSumChange = oldWeightSum - currentWeightSum; + columnToTheRightOfResizedColumnWidth -= weightSumChange; + + weights[resizedColumnPosition] = resizedColumnWidth; + weights[resizedColumnPosition+1] = columnToTheRightOfResizedColumnWidth; + setWeights(weights); + } + + private void giveRemainderToWeightAtColumn(int columnNumber) { + int[] weights = getWeights(); + int totalWeightPercentage = 0; + for (int i = 0; i < weights.length; i++) { + totalWeightPercentage += weights[i]; + } + int spareWidthPercentage = 100 - totalWeightPercentage; + weights[columnNumber] += spareWidthPercentage; + } + + // Event listeners -------------------------------------------------------- + + private ControlListener headerControlListener = null; + + private boolean wasResized = true; + + private class HeaderControlListener implements ControlListener { + public void controlMoved(ControlEvent e) { + // Eat the move event that is fired after resize events + if (wasResized) { + wasResized = false; + return; + } + Table table = header.headerTable; + fireColumnMovedEvent(table.getColumnOrder()); + storeLastWidths(table); + } + + public void controlResized(ControlEvent e) { + if (lastWidths == null) return; + wasResized = true; + if (!layingOut) { + layingOut = true; + try { + TableColumn tableColumn = (TableColumn) e.widget; + AbstractNativeHeader header = asHeader(tableColumn.getParent().getParent()); + adjustWeights(header, tableColumn); + storeLastWidths(tableColumn.getParent()); + } finally { + layingOut = false; + } + } + } + } + + private DisposeListener headerDisposeListener = new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + asHeader(e.widget).removeColumnControlListener(headerControlListener); + } + }; + +} + diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/IRowContentProvider.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/IRowContentProvider.java index ab3f1931e..cd50963b9 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/IRowContentProvider.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/IRowContentProvider.java @@ -1,39 +1,39 @@ -/* - * Copyright (C) 2005 David Orme - * - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * David Orme - Initial API and implementation - */ -package org.eclipse.nebula.widgets.compositetable; - -import org.eclipse.swt.widgets.Control; - -/** - * Interface IRowContentProvider. An interface for objects that are able to initialize an - * arbitrary row control with values on demand. - * @author djo - */ -@FunctionalInterface -public interface IRowContentProvider { - - /** - * Method refresh. Requests receiver to refresh the currentRowInTable with data - * to edit. - * - * @param sender The CompositeTable sending the message. - * @param currentObjectOffset The 0-based row number that is offset in the data structure of - * the table's top row. - * @param row The row control to fill with data. This will be a copy of your prototype - * row object. - */ - void refresh(CompositeTable sender, int currentObjectOffset, Control row); - -} +/* + * Copyright (C) 2005 David Orme + * + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * David Orme - Initial API and implementation + */ +package org.eclipse.nebula.widgets.compositetable; + +import org.eclipse.swt.widgets.Control; + +/** + * Interface IRowContentProvider. An interface for objects that are able to initialize an + * arbitrary row control with values on demand. + * @author djo + */ +@FunctionalInterface +public interface IRowContentProvider { + + /** + * Method refresh. Requests receiver to refresh the currentRowInTable with data + * to edit. + * + * @param sender The CompositeTable sending the message. + * @param currentObjectOffset The 0-based row number that is offset in the data structure of + * the table's top row. + * @param row The row control to fill with data. This will be a copy of your prototype + * row object. + */ + void refresh(CompositeTable sender, int currentObjectOffset, Control row); + +} diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/IRowFocusListener.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/IRowFocusListener.java index f930e4b83..77d084fd2 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/IRowFocusListener.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/IRowFocusListener.java @@ -1,61 +1,61 @@ -/* - * Copyright (C) 2005 David Orme - * - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * David Orme - Initial API and implementation - */ -package org.eclipse.nebula.widgets.compositetable; - -import org.eclipse.swt.widgets.Control; - -/** - * Interface IRowFocusListener. An interface for objects that want to listen to - * and have the possibility of vetoing row change events on a CompositeTable. - * This interface is not intended to be implemented except within the - * CompositeTable implementation. Extend RowFocusAdapter instead. - * - * @author djo - */ -public interface IRowFocusListener { - - /** - * Method requestRowChange. Requests permission to change rows. This method is - * called immediately before a row change occurs. Listeners must return true to - * grant permission for the row change to occur or return false to veto it. If - * any listener returns false, the entire row change operation is aborted.

- * - * @param sender The CompositeTable sending the event. - * @param currentObjectOffset The offset of the current object in the data structure. - * @param row The row control that is losing focus. - * @return true to permit the row change to occur; false otherwise. - */ - boolean requestRowChange(CompositeTable sender, int currentObjectOffset, Control row); - - /** - * Method depart. Called after requstRowChange has been called to indicate that - * the focus is departing the specified row. - * - * @param sender - * @param currentObjectOffset - * @param row - */ - void depart(CompositeTable sender, int currentObjectOffset, Control row); - - /** - * Method arrive. Notifies receiver that the current row has just been changed. - * - * @param sender The CompositeTable sending the event. - * @param currentObjectOffset The 0-based offset to the row that should be populated - * @param newRow The actual SWT row object that needs to be populated with data - */ - void arrive(CompositeTable sender, int currentObjectOffset, Control newRow); - -} +/* + * Copyright (C) 2005 David Orme + * + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * David Orme - Initial API and implementation + */ +package org.eclipse.nebula.widgets.compositetable; + +import org.eclipse.swt.widgets.Control; + +/** + * Interface IRowFocusListener. An interface for objects that want to listen to + * and have the possibility of vetoing row change events on a CompositeTable. + * This interface is not intended to be implemented except within the + * CompositeTable implementation. Extend RowFocusAdapter instead. + * + * @author djo + */ +public interface IRowFocusListener { + + /** + * Method requestRowChange. Requests permission to change rows. This method is + * called immediately before a row change occurs. Listeners must return true to + * grant permission for the row change to occur or return false to veto it. If + * any listener returns false, the entire row change operation is aborted.

+ * + * @param sender The CompositeTable sending the event. + * @param currentObjectOffset The offset of the current object in the data structure. + * @param row The row control that is losing focus. + * @return true to permit the row change to occur; false otherwise. + */ + boolean requestRowChange(CompositeTable sender, int currentObjectOffset, Control row); + + /** + * Method depart. Called after requstRowChange has been called to indicate that + * the focus is departing the specified row. + * + * @param sender + * @param currentObjectOffset + * @param row + */ + void depart(CompositeTable sender, int currentObjectOffset, Control row); + + /** + * Method arrive. Notifies receiver that the current row has just been changed. + * + * @param sender The CompositeTable sending the event. + * @param currentObjectOffset The 0-based offset to the row that should be populated + * @param newRow The actual SWT row object that needs to be populated with data + */ + void arrive(CompositeTable sender, int currentObjectOffset, Control newRow); + +} diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/InternalCompositeTable.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/InternalCompositeTable.java index 98a890333..717dbdeb0 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/InternalCompositeTable.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/InternalCompositeTable.java @@ -1,2190 +1,2190 @@ -/* - * Copyright (C) 2005 David Orme - * - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * David Orme - Initial API and implementation - * Elias Volanakis - 267316 - */ -package org.eclipse.nebula.widgets.compositetable; - -import java.lang.reflect.Constructor; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.ListIterator; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.nebula.widgets.compositetable.internal.DuckType; -import org.eclipse.nebula.widgets.compositetable.internal.ISelectableRegionControl; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Slider; -import org.eclipse.swt.widgets.Widget; - -/** - * (non-API) Class InternalCompositeTable. This is the run-time - * CompositeTableControl. It gets its prototype row and (optional) header - * objects from its SWT parent, then uses them to implement an SWT virtual table - * control. - * - * @author djo - */ -class InternalCompositeTable extends Composite implements Listener { - // The internal UI controls that make up this control. - private Composite controlHolder = null; - private Composite vSliderHolder = null; - private Slider vSlider = null; - private Composite hScroller; - private Composite hSliderHolder = null; - private Slider hSlider = null; - EmptyTablePlaceholder emptyTablePlaceholder = null; - - // My parent CompositeTable - private CompositeTable parent; - - // Property fields - private int maxRowsVisible; - private int numRowsInDisplay; - private int numRowsInCollection; - private int topRow; - private int currentRow; - private int currentColumn; - - // The visible/invisible row objects and bookeeping info about them - private int currentVisibleTopRow = 0; - private int numRowsVisible = 0; - private LinkedList rows = new LinkedList(); - private LinkedList spareRows = new LinkedList(); - int clientAreaHeight; - - // The prototype header/row objects and Constructors so we can duplicate - // them - private Constructor headerConstructor; - private Constructor rowConstructor; - private Control headerControl; - private Control myHeader = null; - private Control rowControl; - - /** - * Constructor InternalCompositeTable. The usual SWT constructor. The same - * style bits are allowed here as are allowed on Composite. - * - * @param parentControl - * The SWT parent. - * @param style - * Style bits. - */ - public InternalCompositeTable(Composite parentControl, int style) { - super(parentControl, style); - initialize(); - - this.parent = (CompositeTable) parentControl; - - setBackground(parentControl.getBackground()); - controlHolder.addListener(SWT.MouseWheel, this); - - maxRowsVisible = parent.getMaxRowsVisible(); - numRowsInCollection = parent.getNumRowsInCollection(); - topRow = parent.getTopRow(); - - headerConstructor = parent.getHeaderConstructor(); - rowConstructor = parent.getRowConstructor(); - headerControl = parent.getHeaderControl(); - rowControl = parent.getRowControl(); - - setMenu(parent.getMenu()); - - currentVisibleTopRow = topRow; - showHeader(); - updateVisibleRows(); - - if (numRowsVisible < 1) { - createEmptyTablePlaceholer(); - } - currentRow = -1; // initialize to undefined - } - - public void setBackground(Color color) { - super.setBackground(color); - controlHolder.setBackground(color); - } - - /** - * Initialize the overall table UI. - */ - private void initialize() { - GridLayout gl = new GridLayout(); - gl.numColumns = 2; - gl.verticalSpacing = 0; - gl.marginWidth = 0; - gl.marginHeight = 0; - // borderWidth times two, since border steals pixels from both sides - int borderInPixels = getParent().getBorderWidth() * 2; - gl.marginRight = borderInPixels; - gl.marginBottom = borderInPixels; - gl.horizontalSpacing = 0; - this.setLayout(gl); - createControlHolder(); - createVSliderHolder(); - createHSliderHolder(); - } - - /** - * Initialize the controlHolder, which is the holder Composite for the - * header object (if applicable) and the row objects. - */ - private void createControlHolder() { - hScroller = new Composite(this, SWT.NULL); - GridData gridData = new GridData(); - gridData.horizontalAlignment = GridData.FILL; - gridData.grabExcessHorizontalSpace = true; - gridData.grabExcessVerticalSpace = true; - gridData.verticalAlignment = GridData.FILL; - hScroller.setLayoutData(gridData); - - controlHolder = new Composite(hScroller, SWT.NONE); - - controlHolder.setLayout(new Layout() { - protected Point computeSize(Composite composite, int wHint, - int hHint, boolean flushCache) { - if (rowControl != null) { - int height = 0; - int width = 0; - if (headerControl != null) { - Point headerSize = headerControl.computeSize(wHint, hHint, flushCache); - width = headerSize.x; - height = headerSize.y; - } - Point rowSize = rowControl.computeSize(wHint, hHint, flushCache); - height += rowSize.y * 2; - if (width < rowSize.x) { - width = rowSize.x; - } - return new Point(width, height); - } - return new Point(50, 50); - } - - protected void layout(Composite composite, boolean flushCache) { - layoutControlHolder(); - } - }); - - hScroller.addControlListener(scrollerResizeHandler); - } - - ControlAdapter scrollerResizeHandler = new ControlAdapter() { - public void controlResized(ControlEvent e) { - Point size = hScroller.getSize(); - - int preferredWidth = controlHolder.computeSize(SWT.DEFAULT, - SWT.DEFAULT, true).x; - - if (preferredWidth > size.x && !isHSliderVisible()) { - setHSliderVisible(true); - } - if (preferredWidth <= size.x && isHSliderVisible()) { - setHSliderVisible(false); - } - - if (preferredWidth <= size.x) { - controlHolder.setBounds(0, 0, size.x, size.y); - return; - } - - if (isHSliderVisible()) { - hSlider.setMaximum(preferredWidth); - hSlider.setPageIncrement(size.x); - hSlider.setThumb(preferredWidth - (preferredWidth - size.x)); - int currentSelection = hSlider.getSelection(); - if (preferredWidth - currentSelection < size.x) { - hSlider.setSelection(preferredWidth - size.x); - } - } - hSlider.notifyListeners(SWT.Selection, new Event()); - } - }; - - - /** - * Initialize the sliderHolder and slider. The SliderHolder is a Composite - * that is responsible for showing and hiding the vertical slider upon - * request. - */ - private void createVSliderHolder() { - GridData gd = getVSliderGridData(); - vSliderHolder = new Composite(this, SWT.NULL); - vSlider = new Slider(vSliderHolder, SWT.VERTICAL); - vSlider.addSelectionListener(sliderSelectionListener); - vSliderHolder.setLayout(new FillLayout()); - vSliderHolder.setLayoutData(gd); - vSliderHolder.setTabList(new Control[] {}); - } - - /** - * Initialize the sliderHolder and slider. The SliderHolder is a Composite - * that is responsible for showing and hiding the vertical slider upon - * request. - */ - private void createHSliderHolder() { - GridData gd = getHSliderGridData(); - hSliderHolder = new Composite(this, SWT.NULL); - hSlider = new Slider(hSliderHolder, SWT.HORIZONTAL); - hSlider.setMinimum(0); - hSlider.setIncrement(20); - hSlider.addSelectionListener(sliderSelectionListener); - hSliderHolder.setLayout(new FillLayout()); - hSliderHolder.setLayoutData(gd); - hSliderHolder.setTabList(new Control[] {}); - hSlider.addSelectionListener(hSliderSelectionListener); - } - - // Slider utility methods - // --------------------------------------------------------------------- - - /** - * Returns a GridData for the SliderHolder appropriate for if the slider is - * visible or not. - * - * @return A GridData with a widthHint of 0 if the slider is not visible or - * with a widthHint of SWT.DEFAULT otherwise. - */ - private GridData getVSliderGridData() { - GridData gd = new GridData(); - gd.grabExcessVerticalSpace = true; - gd.verticalAlignment = GridData.FILL; - gd.verticalSpan = 1; - if (!vSliderVisible) { - gd.widthHint = 0; - } - return gd; - } - - /** - * Returns a GridData for the SliderHolder appropriate for if the slider is - * visible or not. - * - * @return A GridData with a heightHint of 0 if the slider is not visible or - * with a heightHint of SWT.DEFAULT otherwise. - */ - private GridData getHSliderGridData() { - GridData gd = new GridData(); - gd.grabExcessHorizontalSpace = true; - gd.horizontalAlignment = GridData.FILL; - gd.horizontalSpan = 1; - if (!hSliderVisible) { - gd.heightHint = 0; - } - return gd; - } - - private boolean vSliderVisible = false; - - /** - * Sets if the slider is visible or not. - * - * @param visible - * true if the slider should be visible; false otherwise. - */ - public void setVSliderVisible(boolean visible) { - this.vSliderVisible = visible; - vSliderHolder.setLayoutData(getVSliderGridData()); - if (visible) { - Display.getCurrent().addFilter(SWT.KeyDown, displayKeyDownFilter); - } else { - Display.getCurrent().removeFilter(SWT.KeyDown, displayKeyDownFilter); - } - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (!InternalCompositeTable.this.isDisposed() && - !vSliderHolder.isDisposed() && - !vSliderHolder.getParent().isDisposed()) - { - vSliderHolder.getParent().layout(true); - vSliderHolder.layout(true); - Point sliderHolderSize = vSliderHolder.getSize(); - vSlider.setBounds(0, 0, sliderHolderSize.x, sliderHolderSize.y); - } - } - }); - } - - /** - * Returns if the slider is visible. - * - * @return true if the slider is visible; false otherwise. - */ - public boolean isVSliderVisible() { - return vSliderVisible; - } - - private boolean hSliderVisible = false; - - /** - * Sets if the slider is visible or not. - * - * @param visible - * true if the slider should be visible; false otherwise. - */ - public void setHSliderVisible(boolean visible) { - this.hSliderVisible = visible; - hSliderHolder.setLayoutData(getHSliderGridData()); - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (!InternalCompositeTable.this.isDisposed() && - !hSliderHolder.isDisposed() && - !hSliderHolder.getParent().isDisposed()) - { - hSliderHolder.getParent().layout(true); - hSliderHolder.layout(true); - Point sliderHolderSize = hSliderHolder.getSize(); - hSlider.setBounds(0, 0, sliderHolderSize.x, sliderHolderSize.y); - } - } - }); - } - - /** - * Returns if the slider is visible. - * - * @return true if the slider is visible; false otherwise. - */ - public boolean isHSliderVisible() { - return hSliderVisible; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.swt.widgets.Widget#dispose() - */ - public void dispose() { - disposeRows(rows); - disposeRows(spareRows); - super.dispose(); - } - - /** - * Disposes all the row objects in the specified LinkedList. - * - * @param rowsCollection - * The collection containing TableRow objects to dispose. - */ - private void disposeRows(LinkedList rowsCollection) { - for (Iterator rowsIter = rowsCollection.iterator(); rowsIter.hasNext();) { - TableRow row = (TableRow) rowsIter.next(); - if (row instanceof IRowFocusListener) { - parent.removeRowFocusListener((IRowFocusListener) row); - } - if (row instanceof IRowContentProvider) { - parent.removeRowContentProvider((IRowContentProvider) row); - } - row.dispose(); - } - } - - // Row object layout - // -------------------------------------------------------------------------- - - /** - * Layout the child controls within the controlHolder Composite. - */ - protected void layoutControlHolder() { - if (myHeader != null) { - layoutHeaderOrRow(myHeader); - } - for (Iterator rowsIter = rows.iterator(); rowsIter.hasNext();) { - TableRow row = (TableRow) rowsIter.next(); - layoutHeaderOrRow(row.getRowControl()); - } - updateVisibleRows(); - } - - private void layoutHeaderOrRow(Control control) { - if (control instanceof Composite) { - Composite headerOrRow = (Composite) control; - headerOrRow.layout(true); - } - } - - // Table control layout -- utility methods - // ---------------------------------------------------- - - /** - * Construct a header or row object on demand. Logs an error and returns - * null on failure. - * - * @param parent - * The SWT parent. - * @param constructor - * The header or row object's constructor. - * @return The constructed control or null if none could be constructed. - */ - private Control createInternalControl(Composite parent, - Constructor constructor) { - Control result = null; - try { - if (!constructor.isAccessible()) { - constructor.setAccessible(true); - } - result = (Control) constructor.newInstance(new Object[] { parent, - new Integer(SWT.NULL) }); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to construct control"); //$NON-NLS-1$ - } - if (result instanceof IRowFocusListener) { - this.parent.addRowFocusListener((IRowFocusListener) result); - } - if (result instanceof IRowContentProvider) { - this.parent.addRowContentProvider((IRowContentProvider) result); - } - return result; - } - - /** - * If the header control hasn't been created yet, create and show it. - */ - private void showHeader() { - if (myHeader == null && headerConstructor != null) { - myHeader = createInternalControl(controlHolder, headerConstructor); - fireHeaderConstructionEvent(myHeader); - if (myHeader instanceof Composite) { - Composite headerComp = (Composite) myHeader; - if (headerComp.getLayout() instanceof GridRowLayout) { - headerComp.addPaintListener(headerPaintListener); - } - } - layoutHeaderOrRow(myHeader); - } - } - - // Table control layout -- main refresh algorithm - // --------------------------------------------- - - /** - * Main refresh algorithm entry point. This method refreshes everything in - * the table: - * - *

    - *
  • Makes sure the correct number of rows are visible - *
  • Makes sure each row has been refreshed with data from the underlying - * model - *
- */ - void updateVisibleRows() { - // If we don't have our prototype row object yet, bail out - if (rowControl == null) { - return; - } - - clientAreaHeight = controlHolder.getSize().y; - if (clientAreaHeight <= 0) { - return; - } - - int topPosition = 0; - - int headerHeight = 0; - if (myHeader != null) { - headerHeight = headerControl.getSize().y + 3; - clientAreaHeight -= headerHeight; - topPosition += headerHeight; - } - numRowsInDisplay = clientAreaHeight / getRowHeight(clientAreaHeight); - - // Make sure we have something to lay out to begin with - int userScrollDirection = 0; - if (numRowsInCollection > 0) { - numRowsVisible = numRowsInDisplay; - - disposeEmptyTablePlaceholder(); - - int displayableRows = numRowsInCollection - topRow; - if (numRowsVisible > displayableRows) { - numRowsVisible = displayableRows; - } - if (numRowsVisible > maxRowsVisible) { - numRowsVisible = maxRowsVisible; - } - if (numRowsVisible < 1) { - numRowsVisible = 1; - } - - // Keep track of if we're scrolling forwards or backwards - if (currentVisibleTopRow - topRow > 0) { - userScrollDirection = ScrollEvent.BACKWARD; - } else if (topRow - currentVisibleTopRow > 0) { - userScrollDirection = ScrollEvent.FORWARD; - } - - // Scroll the view so that the right number of row - // objects are showing and they have the right data - if (rows.size() - Math.abs(currentVisibleTopRow - topRow) > 0) { -// if (currentRow >= numRowsVisible) { -// deleteRowAt(0); -// ++currentVisibleTopRow; -// ++topRow; -// --currentRow; -// } - scrollTop(); - fixNumberOfRows(); - } else { - currentVisibleTopRow = topRow; - fixNumberOfRows(); - refreshAllRows(); - } - } else { - numRowsVisible = 0; - topRow = 0; - currentRow = 0; - currentColumn = 0; - currentVisibleTopRow = 0; - numRowsVisible = 0; - - if (emptyTablePlaceholder == null) { - fixNumberOfRows(); - createEmptyTablePlaceholer(); - } - } - - // Make sure that the currentRow is within the visible range - // (after PgDn, it could wind up outside the visible range) - if (currentRow >= numRowsVisible && getNumRowsVisible() < numRowsInDisplay) { - currentRow = numRowsVisible-1; - } - - // Show, hide, reset the scroll bar - if (numRowsVisible < numRowsInCollection) { - int extra = numRowsInCollection - numRowsVisible; - int pageIncrement = numRowsVisible; - if (pageIncrement > extra) - pageIncrement = extra; - - vSlider.setMaximum(numRowsInCollection); - vSlider.setMinimum(0); - vSlider.setIncrement(1); - vSlider.setPageIncrement(pageIncrement); - vSlider.setThumb(numRowsInCollection - - (numRowsInCollection - numRowsVisible)); - - vSlider.setSelection(topRow); - - if (!isVSliderVisible()) { - setVSliderVisible(true); - } - } else { - setVSliderVisible(false); - } - - // Lay out the header and rows correctly in the display - int width = controlHolder.getSize().x; - - // First, the header... - if (myHeader != null) { - myHeader.setBounds(0, 0, width, headerHeight); - } - - // Make sure we have rows to lay out... - if (numRowsInCollection < 1) { - return; - } - - // Now the rows. - int rowHeight = getRowHeight(clientAreaHeight); - - // We have to move the controls front-to-back if we're scrolling - // forwards and back-to-front if we're scrolling backwards to avoid ugly - // screen refresh artifacts. - if (userScrollDirection == ScrollEvent.FORWARD || userScrollDirection == ScrollEvent.NONE) { - for (Iterator rowsIter = rows.iterator(); rowsIter.hasNext();) { - TableRow row = (TableRow) rowsIter.next(); - Control rowControl = row.getRowControl(); - rowControl.setBounds(0, topPosition, width, rowHeight); - layoutHeaderOrRow(rowControl); - topPosition += rowHeight; - } - } else { - ListIterator rowsIter = rows.listIterator(); - while (rowsIter.hasNext()) { - rowsIter.next(); - } - topPosition += rowHeight * (rows.size() - 1); - while (rowsIter.hasPrevious()) { - TableRow row = (TableRow) rowsIter.previous(); - Control rowControl = row.getRowControl(); - rowControl.setBounds(0, topPosition, width, rowHeight); - layoutHeaderOrRow(rowControl); - topPosition -= rowHeight; - } - } - - // If we scrolled, tell clients about it - if (userScrollDirection != ScrollEvent.NONE) { - fireScrollEvent(new ScrollEvent(userScrollDirection, parent)); - } - } - - int getRowHeight(int clientAreaHeight) { - int rowControlHeight = rowControl.getSize().y; - if (maxRowsVisible == Integer.MAX_VALUE) { - return rowControlHeight; - } - return rowControlHeight; - } - - /** - * Utility method: Makes sure that the currently visible top row is the same - * as the top row specified in the TopRow property. - */ - private void scrollTop() { - while (currentVisibleTopRow < topRow) { - deleteRowAt(0); - ++currentVisibleTopRow; - } - while (currentVisibleTopRow > topRow) { - --currentVisibleTopRow; - insertRowAt(0); - } - } - - /** - * Utility method: Makes sure that the number of rows that are visible - * correspond with what should be visible given the table control's size, - * where it is scrolled, and the number of rows in the underlying - * collection. - */ - private void fixNumberOfRows() { - int numRows = rows.size(); - while (numRows > numRowsVisible) { - deleteRowAt(numRows - 1); - numRows = rows.size(); - } - while (numRows < numRowsVisible) { - insertRowAt(numRows); - numRows = rows.size(); - } - } - - /** - * Fire the refresh event on all visible rows. - */ - void refreshAllRows() { - int row = 0; - for (Iterator rowsIter = rows.iterator(); rowsIter.hasNext();) { - TableRow rowControl = (TableRow) rowsIter.next(); - fireRefreshEvent(topRow + row, rowControl.getRowControl()); - ++row; - } - resetFocus(); - } - - void refreshRow(int row) { - if (topRow > -1) { - if (isRowVisible(row)) { - fireRefreshEvent(row + topRow, ((TableRow) rows.get(row)).getRowControl()); - } - } - } - - private boolean isRowVisible(int row) { - return row >= 0 && row < numRowsVisible; - } - - /** - * Make sure that something sane inside the table has focus. - */ - private void resetFocus() { - /* - * FEATURE IN WINDOWS: When we refresh all rows and one already has - * focus, Windows gets into a schizophrenic state where some part of - * Windows thinks that the current control has focus and another part of - * Windows thinks that the current control doesn't have focus. - * - * The symptom is that the current control stops receiving events from - * Windows but Windows still thinks the current control has focus and so - * it won't give the control complete focus if you click on it. - * - * The workaround is to set the focus away from the currently-focused - * control and to set it back. - */ - if (numRowsVisible < 1 || currentRow < 0) { - return; - } - Control control = null; - if (currentRow < numRowsVisible) { - control = getControl(currentColumn, currentRow); - } else if (currentRow > 0) { - control = getControl(currentColumn, numRowsVisible - 1); - } - if (control != null && control.isFocusControl()) { - this.setFocus(); - deferredSetFocus(control, true); - } - } - - /** - * Insert a new row object at the specified 0-based position relatve to the - * topmost row. - * - * @param position - * The 0-based position relative to the topmost row. - */ - private void insertRowAt(int position) { - TableRow newRow = getNewRow(); - if (position > rows.size()) { - position = rows.size(); - } - rows.add(position, newRow); - fireRefreshEvent(currentVisibleTopRow + position, newRow - .getRowControl()); - } - - /** - * Delete the row at the specified 0-based position relative to the topmost - * row. - * - * @param position - * The 0-based position relative to the topmost row. - */ - private void deleteRowAt(int position) { - TableRow row = (TableRow) rows.remove(position); - row.setVisible(false); - spareRows.addLast(row); - } - - /** - * Utility method: Creates a new row object or recycles one that had been - * previously created but was no longer needed. - * - * @return The new row object. - */ - private TableRow getNewRow() { - if (spareRows.size() > 0) { - TableRow recycledRow = (TableRow) spareRows.removeFirst(); - recycledRow.setVisible(true); - return recycledRow; - } - Control newControl = createInternalControl(controlHolder, - rowConstructor); - if (menu != null) { - newControl.setMenu(menu); - } - fireRowConstructionEvent(newControl); - TableRow newRow = new TableRow(this, newControl); - if (newRow.getRowControl() instanceof Composite) { - Composite rowComp = (Composite) newRow.getRowControl(); - if (rowComp.getLayout() instanceof GridRowLayout) { - rowComp.setBackground(getBackground()); - rowComp.addPaintListener(rowPaintListener); - } - } - return newRow; - } - - // Property getters/setters - // -------------------------------------------------------------- - - /* - * These are internal API.

Plese refer to the JavaDoc on CompositeTable - * for detailed description of these property methods. - */ - - /** - * (non-API) Method getHeaderControl. Return the prototype control being - * used as a header. - * - * @return The header control - */ - public Control getHeaderControl() { - return headerControl; - } - - /** - * Returns the actual header control (not the prototype). - * - * @return a control instance or null, if no header is available - */ - Control getHeader() { - return myHeader; - } - - /** - * Method setMaxRowsVisible. Sets the maximum number of rows that will be - * permitted in the table at once. For example, setting this property to 1 - * will have the effect of creating a single editing area with a scroll bar - * on the right allowing the user to scroll through all rows using either - * the mouse or the PgUp/PgDn keys. The default value is Integer.MAX_VALUE. - * - * @param maxRowsVisible - * the maximum number of rows that are permitted to be visible at - * one time, regardless of the control's size. - */ - public void setMaxRowsVisible(int maxRowsVisible) { - this.maxRowsVisible = maxRowsVisible; - updateVisibleRows(); - } - - /** - * Method getNumRowsVisible. Returns the actual number of rows that are - * currently visible. Normally CompositeTable displays as many rows as will - * fit vertically given the control's size. This value can be clamped to a - * maximum using the MaxRowsVisible property. - * - * @return the actual number of rows that are currently visible. - */ - public int getNumRowsVisible() { - return rows.size(); - } - - /** - * Method setNumRowsInCollection. Sets the number of rows in the data - * structure that is being edited. - * - * @param numRowsInCollection - * the number of rows represented by the underlying data - * structure. - */ - public void setNumRowsInCollection(int numRowsInCollection) { - this.topRow = 0; - if (topRow + currentRow > numRowsInCollection) { - if (topRow < numRowsInCollection) { - currentRow = numRowsInCollection - topRow; - } else { - topRow = numRowsInCollection - 1; - currentRow = 0; - } - deferredSetFocus(getCurrentRowControl(), false); - } - this.numRowsInCollection = numRowsInCollection; - updateVisibleRows(); - refreshAllRows(); - } - - private void doSetTopRow(int topRow, int currentRow) { -// fireRowDepartEvent(); - this.topRow = topRow; - this.currentRow = currentRow; - updateVisibleRows(); -// fireRowArriveEvent(); - } - - /** - * Method setTopRow. Set the number of the line that is being displayed in - * the top row of the CompositeTable editor (0-based). If the new top row is - * not equal to the current top row, the table will automatically be - * scrolled to the new position. This number must be greater than 0 and less - * than NumRowsInCollection. - * - * @param topRow - * the line number of the new top row. - */ - public void setTopRow(int topRow) { - fireRowDepartEvent(); - int topRowDelta = this.topRow - topRow; - doSetTopRow(topRow, currentRow + topRowDelta); - fireRowArriveEvent(); - } - - /** - * Method getTopRow. Return the number of the line that is being displayed - * in the top row of the CompositeTable editor (0-based). - * - * @return the number of the top line. - */ - public int getTopRow() { - return topRow; - } - - /** - * Method getSelection. Returns the currently-selected (column, row) pair - * where the row specifies the offset from the top of the table window. In - * order to get the current row in the underlying data structure, use - * getSelection().y + getCurrentRow(). - * - * @return the currently-selected (column, row) pair where the row specifies - * the offset from the top of the table window, or null if no - * selection is available. - */ - public Point getSelection() { - return currentRow != -1 ? new Point(currentColumn, currentRow) : null; - } - - /** - * Method setSelection. Sets the currently-selected (column, row) pair where - * the row specifies the offset from the top of the table window. In order - * to get the current row in the underlying data structure, use - * getSelection().y + getCurrentRow(). - * - * @param column - * the column to select - * @param row - * the row to select - */ - public void setSelection(int column, int row) { - int topRowDelta = computeTopRowDelta(row); - if (topRowDelta != 0) { - doSetTopRow(topRow + topRowDelta, currentRow); - row += -1 * topRowDelta; - internalSetSelection(column, row, true); - } else { - if (row == currentRow) - internalSetSelection(column, row, false); - else { - if (fireRequestRowChangeEvent()) - internalSetSelection(column, row, true); - } - } - } - - /** - * (non-API) See {@link CompositeTable#clearSelection()} instead. - */ - public void clearSelection() { - Point currentSelection = getSelection(); - if(currentSelection != null) { - fireRowDepartEvent(); - currentRow = -1; - } - } - - /** - * Method setWeights. Indicates that the column weights were just set and we - * should re-layout the control holder object. - */ - public void setWeights() { - layoutControlHolder(); - } - - // Refresh Event API - // -------------------------------------------------------------------------- - - /** - * Adds the specified listener to the set of listeners that will be notified - * when a row refresh event occurs. - * - * @param listener - * the listener to add. - */ - public void addRefreshContentProvider(IRowContentProvider listener) { - parent.contentProviders.add(listener); - } - - /** - * Remove the specified listener from the set of listeners that will be - * notified when a row refresh event occurs. - * - * @param listener - * the listener to remove. - */ - public void removeRefreshContentProvider(IRowContentProvider listener) { - parent.contentProviders.remove(listener); - } - - private void fireRefreshEvent(int positionInCollection, Control rowControl) { - if (numRowsInCollection < 1) { - return; - } - for (Iterator refreshListenersIter = parent.contentProviders.iterator(); refreshListenersIter - .hasNext();) { - IRowContentProvider listener = (IRowContentProvider) refreshListenersIter - .next(); - listener.refresh(parent, positionInCollection, rowControl); - } - } - - // Empty table placeholder - // -------------------------------------------------------------------- - - private void createEmptyTablePlaceholer() { - emptyTablePlaceholder = new EmptyTablePlaceholder(controlHolder, - SWT.NULL); - if (rowControl != null) - emptyTablePlaceholder.setBackground(rowControl.getBackground()); - emptyTablePlaceholder.setMessage(parent.getInsertHint()); - } - - private void disposeEmptyTablePlaceholder() { - if (emptyTablePlaceholder != null) { - emptyTablePlaceholder.dispose(); - emptyTablePlaceholder = null; - } - } - - // Event Handling - // ----------------------------------------------------------------------------- - - private boolean needToRequestRC = true; - - private Listener displayKeyDownFilter = new Listener() { - public void handleEvent(Event event) { - if (rowControl.getClass().isAssignableFrom(event.widget.getClass())) { - doMakeFocusedRowVisible(); - } - } - }; - - - - /** - * Handle a keyPressed event on any row control. - * - * @param sender - * The row that is sending the event - * @param e - * the actual KeyEvent - */ - public void keyPressed(TableRow sender, KeyEvent e) { - if (doMakeFocusedRowVisible()) return; - - if ((e.stateMask & SWT.CONTROL) != 0) { - switch (e.keyCode) { - case SWT.HOME: - doFocusInitialRow(); - return; - case SWT.END: - doFocusLastRow(); - return; - case SWT.INSERT: - doInsertRow(); - return; - case SWT.DEL: - doDeleteRow(); - return; - default: - return; - } - } - switch (e.keyCode) { - case SWT.ARROW_UP: - doRowUp(); - return; - case SWT.ARROW_DOWN: - doRowDown(); - return; - case SWT.PAGE_UP: - doPageUp(); - return; - case SWT.PAGE_DOWN: - doPageDown(); - return; - } - } - - /** - * Handle the keyTraversed event on any child control in the table. - * - * @param sender - * The row sending the event. - * @param e - * The SWT TraverseEvent - */ - public void keyTraversed(TableRow sender, TraverseEvent e) { - if (doMakeFocusedRowVisible()) return; - - if (parent.isTraverseOnTabsEnabled()) { - if (e.detail == SWT.TRAVERSE_TAB_NEXT) { - if (currentColumn >= sender.getNumColumns() - 1) { - e.detail = SWT.TRAVERSE_NONE; - handleNextRowNavigation(); - } - } else if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS) { - if (currentColumn == 0) { - e.detail = SWT.TRAVERSE_NONE; - handlePreviousRowNavigation(sender); - } - } else if (e.detail == SWT.TRAVERSE_RETURN) { - e.detail = SWT.TRAVERSE_NONE; - if (currentColumn >= sender.getNumColumns() - 1) { - handleNextRowNavigation(); - } else { - deferredSetFocus(getControl(currentColumn + 1, currentRow), - false); - } - } - } else { - if (e.detail == SWT.TRAVERSE_TAB_NEXT) { - if (currentColumn >= sender.getNumColumns() - 1) { - e.detail = SWT.TRAVERSE_NONE; - } - } else if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS) { - if (currentColumn == 0) { - e.detail = SWT.TRAVERSE_NONE; - } - } - } - } - - /** - * Makes sure that the focused row is visible - * - * @return true if the display needed to be scrolled; false otherwise - */ - public boolean doMakeFocusedRowVisible() { - if (numRowsVisible < 1) { - return false; - } - int topRowDelta = computeTopRowDelta(currentRow); - if (topRowDelta == 0) { - return false; - } -// currentRow += -1 * topRowDelta; - - doSetTopRow(topRow + topRowDelta, currentRow + (-1 * topRowDelta)); - Control control = getControl(currentColumn, currentRow); - if (control != null) { - control.setFocus(); // ?? Can I get away with avoiding asyncExec here ?? - } - return true; - } - - private int computeTopRowDelta(int row) { - int topRowDelta; - if (row < 0) { - topRowDelta = row; - } else if (row >= getNumRowsVisible()) { - topRowDelta = row - getNumRowsVisible() + 1; - } else { - return 0; - } - return topRowDelta; - } - - /** - * The SelectionListener for the table's vertical slider control. - */ - private SelectionListener sliderSelectionListener = new SelectionListener() { - public void widgetSelected(SelectionEvent e) { - if (vSlider.getSelection() == topRow) { - return; - } - - if (!fireRequestRowChangeEvent()) { - vSlider.setSelection(topRow); - return; - } - - deselectCurrentRowIfVisible(); - - int delta = topRow - vSlider.getSelection(); - int oldCurrentRow = currentRow; - currentRow = vSlider.getSelection(); - -// setTopRow(vSlider.getSelection()); // Removed as a result of patch - doSetTopRow(vSlider.getSelection(), currentRow + delta); - - // If the focused row just became visible, show the focus - if (oldCurrentRow < 0 || oldCurrentRow >= getNumRowsVisible()) { - if (currentRow >= 0 && currentRow < getNumRowsVisible()) { - Control newFocusControl = getControl(currentColumn, currentRow); - if (newFocusControl == null) { - return; - } - if (newFocusControl.isFocusControl()) { - newFocusControl.notifyListeners(SWT.FocusIn, new Event()); - } else { - deferredSetFocus(newFocusControl, true); - } - } - } else { - // If the new viewport doesn't overlap the old one, hide the focus - if (currentRow < 0 || currentRow >= getNumRowsVisible()) { - // deleteRowAt(oldCurrentRow); -// getControl(currentColumn, oldCurrentRow).getParent().setVisible(false); -// getControl(currentColumn, oldCurrentRow).getParent().setVisible(true); - Control control = getControl(currentColumn, oldCurrentRow); - if (control != null) { - control.notifyListeners(SWT.FocusOut, new Event()); - } - } - } - } - - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - } - }; - - private SelectionListener hSliderSelectionListener = new SelectionListener() { - /* (non-Javadoc) - * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) - */ - public void widgetSelected(SelectionEvent e) { - Point scrollerSize = hScroller.getSize(); - int preferredWidth = controlHolder.computeSize(SWT.DEFAULT, - SWT.DEFAULT, true).x; - Rectangle controlHolderBounds = - new Rectangle(-1 * hSlider.getSelection(), 0, preferredWidth, - scrollerSize.y); - controlHolder.setBounds(controlHolderBounds); - } - - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - } - }; - - /** - * Scroll wheel event handling. - */ - public void handleEvent(Event event) { - event.doit = false; - if (event.count > 0) { // scroll up - if (topRow > 0) { - if (!fireRequestRowChangeEvent()) { - return; - } - deselectCurrentRowIfVisible(); - doSetTopRow(topRow - 1, currentRow + 1); - if (isRowVisible(currentRow)) { - deferredSetFocus(getControl(currentColumn, currentRow), true); - } - } - } else { // scroll down - if (topRow < numRowsInCollection - numRowsVisible) { - if (!fireRequestRowChangeEvent()) { - return; - } - deselectCurrentRowIfVisible(); - doSetTopRow(topRow + 1, currentRow - 1); - if (isRowVisible(currentRow)) { - deferredSetFocus(getControl(currentColumn, currentRow), true); - } - } - } -// if (event.count > 0) { // Old code (before patch) -// if (topRow > 0) { -// if (!fireRequestRowChangeEvent()) { -// return; -// } -// deselectCurrentRowIfVisible(); -// setTopRow(topRow - 1); -// ++currentRow; -// if (currentRow == 0) { -// deferredSetFocus(getControl(currentColumn, currentRow), true); -// } -// } -// } else { -// if (topRow < numRowsInCollection - numRowsVisible) { -// if (!fireRequestRowChangeEvent()) { -// return; -// } -// deselectCurrentRowIfVisible(); -// setTopRow(topRow + 1); -// --currentRow; -// if (currentRow == getNumRowsVisible()-1) { -// deferredSetFocus(getControl(currentColumn, currentRow), true); -// } -// } -// } - } - - private void deselectCurrentRowIfVisible() { - if (currentRow >= 0 && currentRow < numRowsVisible) { - Control control = getControl(currentColumn, currentRow); - if (control != null) { - deselect(control); - } - } - } - - /** - * Handle focusLost events on any child control. This is not currently used. - * - * @param sender - * The row containing the sending control. - * @param e - * The SWT FocusEvent. - */ - public void focusLost(TableRow sender, FocusEvent e) { - } - - /** - * Handle focusGained events on any child control. - * - * FIXME: Needs to automatically scroll horizontally if the newly-focused - * control is fully or partially occluded. - * - * @param sender - * The row containing the sending control. - * @param e - * The SWT FocusEvent. - */ - public void focusGained(TableRow sender, FocusEvent e) { - boolean rowChanged = false; - int senderRowNumber = getRowNumber(sender); - if (senderRowNumber != currentRow) { - if (needToRequestRC) { - if (!fireRequestRowChangeEvent()) { - // Go back if we're not allowed to be here - deferredSetFocus(getControl(currentColumn, currentRow), - false); - } - } else { - needToRequestRC = true; - } - rowChanged = true; - } - - currentRow = senderRowNumber; - currentColumn = sender.getColumnNumber((Control) e.widget); - - if (rowChanged) - fireRowArriveEvent(); - } - - private PaintListener headerPaintListener = new PaintListener() { - public void paintControl(PaintEvent e) { - if (parent.linesVisible) { - drawGridLines(e, true); - } - } - }; - - private PaintListener rowPaintListener = new PaintListener() { - public void paintControl(PaintEvent e) { - if (parent.linesVisible) { - drawGridLines(e, false); - } - } - }; - - private void drawGridLines(PaintEvent e, boolean isHeader) { - Color oldColor = e.gc.getForeground(); - try { - // Get the colors we need - Display display = Display.getCurrent(); - Color lineColor = display - .getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW); - Color secondaryColor = display - .getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); - Color hilightColor = display - .getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); - if (!isHeader) { - lineColor = display - .getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW); - } - - // Get the control - Control toPaint = (Control) e.widget; - Point controlSize = toPaint.getSize(); - - // Draw the bottom line(s) - e.gc.setForeground(lineColor); - e.gc.drawLine(0, controlSize.y - 1, controlSize.x, - controlSize.y - 1); - if (isHeader) { - e.gc.setForeground(secondaryColor); - e.gc.drawLine(0, controlSize.y - 2, controlSize.x, - controlSize.y - 2); - e.gc.setForeground(hilightColor); - e.gc.drawLine(0, 1, controlSize.x, 1); - } - - // Now draw lines around the child controls, if there are any - if (toPaint instanceof Composite) { - Composite row = (Composite) toPaint; - Control[] children = row.getChildren(); - for (int i = 0; i < children.length; i++) { - Rectangle childBounds = children[i].getBounds(); - - // Paint the beginning lines - if (isHeader) { - e.gc.setForeground(hilightColor); - e.gc.drawLine(childBounds.x - 2, 1, childBounds.x - 2, - controlSize.y - 2); - } - - // Paint the ending lines - e.gc.setForeground(lineColor); - int lineLeft = childBounds.x + childBounds.width + 1; - e.gc.drawLine(lineLeft, 0, lineLeft, controlSize.y); - if (isHeader) { - e.gc.setForeground(secondaryColor); - e.gc.drawLine(lineLeft - 1, 0, lineLeft - 1, - controlSize.y - 1); - } - } - } - } finally { - e.gc.setForeground(oldColor); - } - } - - // Event Firing - // ------------------------------------------------------------------------------- - - /** - * Fire the row construction event - * - * @param newControl - * The new row's SWT control - */ - private void fireRowConstructionEvent(Control newControl) { - for (Iterator rowConstructionListenersIter = parent.rowConstructionListeners - .iterator(); rowConstructionListenersIter.hasNext();) { - RowConstructionListener listener = (RowConstructionListener) rowConstructionListenersIter - .next(); - listener.rowConstructed(newControl); - } - } - - /** - * Fire the row construction event - * - * @param newControl - * The new row's SWT control - */ - private void fireHeaderConstructionEvent(Control newControl) { - for (Iterator rowConstructionListenersIter = parent.rowConstructionListeners - .iterator(); rowConstructionListenersIter.hasNext();) { - RowConstructionListener listener = (RowConstructionListener) rowConstructionListenersIter - .next(); - listener.headerConstructed(newControl); - } - } - - /** - * Indicate to listeners that the focus is arriving on the specified row - */ - private void fireRowArriveEvent() { - if (rows.size() < 1 || !isRowVisible(currentRow)) { - return; - } - for (Iterator rowChangeListenersIter = parent.rowFocusListeners - .iterator(); rowChangeListenersIter.hasNext();) { - IRowFocusListener listener = - (IRowFocusListener) rowChangeListenersIter.next(); - // currentRow() can be null if it's scrolled off the top or bottom - TableRow row = currentRow(); - Control control = row != null ? row.getRowControl() : null; - listener.arrive(parent, topRow + currentRow, control); - } - - } - - /** - * Request permission from all listeners to leave the current row. - * - * @return true if all listeners permit the row change; false otherwise. - */ - private boolean fireRequestRowChangeEvent() { - if (rows.size() < 1 || !isRowVisible(currentRow)) { - return true; - } - if (currentRow > rows.size() - 1) { - // (if the other row is already gone) - return true; - } - for (Iterator rowChangeListenersIter = parent.rowFocusListeners - .iterator(); rowChangeListenersIter.hasNext();) { - IRowFocusListener listener = (IRowFocusListener) rowChangeListenersIter - .next(); - // currentRow() can be null if it's scrolled off the top or bottom - TableRow row = currentRow(); - Control control = row != null ? row.getRowControl() : null; - if (!listener.requestRowChange(parent, topRow + currentRow, - control)) { - return false; - } - } - fireRowDepartEvent(); - return true; - } - - /** - * Indicate to listeners that the focus is about to leave the current row. - */ - private void fireRowDepartEvent() { - if (rows.size() < 1 || !isRowVisible(currentRow)) { - return; - } - for (Iterator rowChangeListenersIter = parent.rowFocusListeners - .iterator(); rowChangeListenersIter.hasNext();) { - IRowFocusListener listener = (IRowFocusListener) rowChangeListenersIter - .next(); - // currentRow() can be null if it's scrolled off the top or bottom - TableRow row = currentRow(); - Control control = row != null ? row.getRowControl() : null; - if (control != null) - listener.depart(parent, topRow + currentRow, control); - } - } - - /** - * Request deletion of the current row from the underlying data structure. - * - * @return true if the deletion was successful; false otherwise. - */ - private boolean fireDeleteEvent() { - if (parent.deleteHandlers.size() < 1) { - return false; - } - - int absoluteRow = topRow + currentRow; - for (Iterator deleteHandlersIter = parent.deleteHandlers.iterator(); deleteHandlersIter - .hasNext();) { - IDeleteHandler handler = (IDeleteHandler) deleteHandlersIter.next(); - if (!handler.canDelete(absoluteRow)) { - return false; - } - } - for (Iterator deleteHandlersIter = parent.deleteHandlers.iterator(); deleteHandlersIter - .hasNext();) { - IDeleteHandler handler = (IDeleteHandler) deleteHandlersIter.next(); - handler.deleteRow(absoluteRow); - } - return true; - } - - private void fireRowDeletedEvent() { - int absoluteRow = topRow + currentRow; - for (Iterator deleteHandlersIter = parent.deleteHandlers.iterator(); deleteHandlersIter - .hasNext();) { - IDeleteHandler handler = (IDeleteHandler) deleteHandlersIter.next(); - handler.rowDeleted(absoluteRow); - } - } - - /** - * Request that the model insert a new row into itself. - * - * @return The 0-based offset of the new row from the start of the - * collection or -1 if a new row could not be inserted. - */ - private int fireInsertEvent() { - if (parent.insertHandlers.size() < 1) { - return -1; - } - - for (Iterator insertHandlersIter = parent.insertHandlers.iterator(); insertHandlersIter - .hasNext();) { - IInsertHandler handler = (IInsertHandler) insertHandlersIter.next(); - int resultRow = handler.insert(topRow + currentRow); - if (resultRow >= 0) { - return resultRow; - } - } - - return -1; - } - - /** - * Tell listeners that we just scrolled. - * @param scrollEvent TODO - */ - private void fireScrollEvent(ScrollEvent scrollEvent) { - if (parent.scrollListeners.size() < 1) { - return; - } - - for (Iterator scrollListenersIter = parent.scrollListeners.iterator(); scrollListenersIter.hasNext();) { - ScrollListener scrollListener = (ScrollListener) scrollListenersIter.next(); - scrollListener.tableScrolled(scrollEvent); - } - } - - // Event Handling, utility methods - // ------------------------------------------------------------ - - /** - * Set the widget's selection to an empty selection. - * - * @param widget - * The widget to deselect - */ - private void deselect(Widget widget) { - if (DuckType.instanceOf(ISelectableRegionControl.class, widget)) { - ISelectableRegionControl control = (ISelectableRegionControl) DuckType - .implement(ISelectableRegionControl.class, widget); - control.setSelection(0, 0); - } - } - - /** - * Try to go to the next row in the collection. - */ - private void handleNextRowNavigation() { - if (currentRow < numRowsVisible - 1) { - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - deselect(getControl(currentColumn, currentRow)); - - deferredSetFocus(getControl(0, currentRow + 1), false); - } else { - if (topRow + numRowsVisible >= numRowsInCollection) { - // We're at the end; don't go anywhere - return; - } - // We have to scroll forwards - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - deselect(getControl(currentColumn, currentRow)); - - doSetTopRow(topRow + 1, currentRow); - deferredSetFocus(getControl(0, currentRow), true); - } - } - - /** - * Try to go to the previous row in the collection. - * - * @param row - * The current table row. - */ - private void handlePreviousRowNavigation(TableRow row) { - if (currentRow == 0) { - if (topRow == 0) { - // We're at the beginning of the table; don't go anywhere - return; - } - // We have to scroll backwards - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - deselect(getControl(currentColumn, currentRow)); - - doSetTopRow(topRow - 1, currentRow); - deferredSetFocus(getControl(row.getNumColumns() - 1, 0), true); - } else { - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - deselect(getControl(currentColumn, currentRow)); - - deferredSetFocus( - getControl(row.getNumColumns() - 1, currentRow - 1), false); - } - } - - /** - * Gets the current TableRow. - * - * @return the current TableRow - */ - private TableRow currentRow() { - if (currentRow < 0 || currentRow > rows.size() - 1) { - return null; - } - return (TableRow) rows.get(currentRow); - } - - /** - * Returns the SWT control corresponding to the current row. - * - * @return the current row control. - */ - public Control getCurrentRowControl() { - TableRow currentRow = currentRow(); - if (currentRow == null) { - return null; - } - return currentRow().getRowControl(); - } - - /** - * Method getRowControls. Returns an array of SWT controls where each - * control represents a row control in the CompositeTable's current scrolled - * position. If CompositeTable is resized, scrolled, such that the rows that - * the CompositeTable control is displaying change in any way, the array - * that is returned by this method will become out of date and need to be - * retrieved again. - * - * @return Control[] An array of SWT Control objects, each representing an - * SWT row object. - */ - public Control[] getRowControls() { - Control[] rowControls = new Control[rows.size()]; - for (int i = 0; i < rowControls.length; i++) { - rowControls[i] = getRowByNumber(i).getRowControl(); - } - return rowControls; - } - - private Menu menu = null; - - /* (non-Javadoc) - * @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu) - */ - public void setMenu(final Menu menu) { - this.menu = menu; - setMenuOnCollection(rows, menu); - setMenuOnCollection(spareRows, menu); - } - - private void setMenuOnCollection(LinkedList collection, Menu menu) { - for (Iterator rowsIter = collection.iterator(); rowsIter.hasNext();) { - TableRow row = (TableRow) rowsIter.next(); - row.getRowControl().setMenu(menu); - } - } - - - - /** - * Method getControlRow. Given a row control, returns its row number - * relative to the topRow. - * - * @param rowControl The row object to find - * @return The row number of the rowControl relative to the topRow (0-based) - * @throws IllegalArgumentException if rowControl is not currently visible - */ - public int getControlRow(Control rowControl) { - for (int row = 0; row < rows.size(); row++) { - if (getRowByNumber(row).getRowControl() == rowControl) { - return row; - } - } - throw new IllegalArgumentException("getControlRow passed a control that is not visible inside CompositeTable"); - } - - /** - * Method getControlRowObject. Given a row control, returns its row number - * relative to the topRow. - * - * @param rowControl The row object to find - * @return The row object managing the rowControl - * @throws IllegalArgumentException if rowControl is not currently visible - */ - public TableRow getControlRowObject(Control rowControl) { - for (Iterator rowsIter = rows.iterator(); rowsIter.hasNext();) { - TableRow row = (TableRow) rowsIter.next(); - if (row.getRowControl() == rowControl) { - return row; - } - } - throw new IllegalArgumentException("getControlRowObject passed a control that is not visible inside CompositeTable"); - } - - /** - * Returns the TableRow by the specified 0-based offset from the top visible - * row. - * - * @param rowNumber - * 0-based offset of the requested fow starting from the top - * visible row. - * @return The corresponding TableRow or null if there is none. - */ - private TableRow getRowByNumber(int rowNumber) { - if (rowNumber > rows.size() - 1 || rowNumber < 0) { - return null; - } - return (TableRow) rows.get(rowNumber); - } - - /** - * Return the SWT control at (column, row), where row is a 0-based number - * starting from the top visible row. - * - * @param column - * the 0-based column. - * @param row - * the 0-based row starting from the top visible row. - * @return the SWT control at (column, row) - */ - private Control getControl(int column, int row) { - TableRow rowObject = getRowByNumber(row); - if (rowObject == null) { - throw new IndexOutOfBoundsException("Request for a nonexistent row"); //$NON-NLS-1$ - } - Control result = rowObject.getColumnControl(column); - return result; - } - - /** - * Return the 0-based row number corresponding to a particular TableRow - * object. - * - * @param row - * The TableRow to translate to row coordinates. - * @return the 0-based row number or -1 if the specified TableRow is not - * visible. - */ - private int getRowNumber(TableRow row) { - int rowNumber = 0; - for (Iterator rowIter = rows.iterator(); rowIter.hasNext();) { - TableRow candidate = (TableRow) rowIter.next(); - if (candidate == row) { - return rowNumber; - } - ++rowNumber; - } - return -1; - } - - /** - * Set the focus to the specified (column, row). If rowChange is true, fire - * a row change event, otherwise be silent. - * - * @param column - * The 0-based column to focus - * @param row - * The 0-based row to focus - * @param rowChange - * true if a row change event should be fired; false otherwise. - */ - private void internalSetSelection(int column, int row, boolean rowChange) { - Control toFocus = getControl(column, row); - if (toFocus == null) { - return; - } - if (toFocus.isFocusControl()) { - toFocus.notifyListeners(SWT.FocusIn, new Event()); - } else { - deferredSetFocus(toFocus, rowChange); - } - } - - /** - * Set the focus to the specified control after allowing all pending events - * to complete first. If rowChange is true, fire a row arrive event after - * the focus has been set. - * - * @param toFocus - * The SWT Control to focus - * @param rowChange - * true if the rowArrive event should be fired; false otherwise. - */ - private void deferredSetFocus(final Control toFocus, final boolean rowChange) { - if (toFocus == null) { - return; - } - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (toFocus.isDisposed()) return; - toFocus.setFocus(); - if (rowChange) { - fireRowArriveEvent(); - } - } - }); - } - - public void doFocusInitialRow() { - if (topRow <= 0) { - return; - } - - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - Widget widget = getDisplay().getFocusControl(); - deselect(widget); // Used to be e.widget - - // If the focus is already in the top visible row, we will need - // to explicitly - // fire an arrive event. - boolean needToArrive = true; - if (currentRow > 0) { - needToArrive = false; - } - - doSetTopRow(0, currentRow); - - if (needToArrive) { - internalSetSelection(currentColumn, 0, true); - } else { - internalSetSelection(currentColumn, 0, false); - } - } - - public void doFocusLastRow() { - if (topRow + numRowsVisible < numRowsInCollection) { - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - Widget widget = getDisplay().getFocusControl(); - deselect(widget); // Used to be e.widget - - // If the focus is already in the last visible row, we will - // need to explicitly - // fire an arrive event. - boolean needToArrive = true; - if (currentRow < numRowsVisible - 1) { - needToArrive = false; - } - - doSetTopRow(numRowsInCollection - numRowsVisible, currentRow); - - if (needToArrive) { - internalSetSelection(currentColumn, numRowsVisible - 1, - true); - } else { - internalSetSelection(currentColumn, numRowsVisible - 1, - false); - } - } - } - - public void doPageUp() { - if (topRow > 0) { - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - int newTopRow = topRow - numRowsInDisplay; - if (newTopRow < 0) { - newTopRow = 0; - } - doSetTopRow(newTopRow, 0); - internalSetSelection(currentColumn, currentRow, true); - } - } - - public void doPageDown() { - if (topRow + numRowsVisible < numRowsInCollection) { - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - int newTopRow = topRow + numRowsVisible; - if (newTopRow >= numRowsInCollection - 1) { - newTopRow = numRowsInCollection - 1; - } - doSetTopRow(newTopRow, numRowsVisible - 1); - internalSetSelection(currentColumn, currentRow, true); - } - } - - public void doRowUp() { - if (maxRowsVisible <= 1) - return; - - if (currentRow > 0) { - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - Widget widget = getDisplay().getFocusControl(); - deselect(widget); // Used to be e.widget - - internalSetSelection(currentColumn, currentRow - 1, false); - return; - } - if (topRow > 0) { - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - Widget widget = getDisplay().getFocusControl(); - deselect(widget); // Used to be e.widget - - doSetTopRow(topRow - 1, currentRow); - internalSetSelection(currentColumn, currentRow, true); - return; - } - } - - public void doRowDown() { - if (maxRowsVisible <= 1) - return; - - if (currentRow < numRowsVisible - 1) { - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - Widget widget = getDisplay().getFocusControl(); - deselect(widget); // Used to be e.widget - - internalSetSelection(currentColumn, currentRow + 1, false); - return; - } - if (topRow + numRowsVisible < numRowsInCollection) { - if (!fireRequestRowChangeEvent()) { - return; - } - needToRequestRC = false; - - Widget widget = getDisplay().getFocusControl(); - deselect(widget); // Used to be e.widget - - doSetTopRow(topRow + 1, currentRow); - internalSetSelection(currentColumn, currentRow, true); - return; - } - } - - public boolean doInsertRow() { - // If no insertHandler has been registered, bail out - if (parent.insertHandlers.size() < 1) { - return false; - } - - // Make sure we can leave the current row - if (!fireRequestRowChangeEvent()) { - return false; - } - needToRequestRC = false; - - // Insert the new object - int newRowPosition = fireInsertEvent(); - if (newRowPosition < 0) { - // This should never happen, but... - throw new IllegalArgumentException("Insert < row 0???"); - } - - disposeEmptyTablePlaceholder(); - - // If the current widget has a selection, deselect it - Widget widget = getDisplay().getFocusControl(); - deselect(widget); // Used to be e.widget - - // If the new row is in the visible space, refresh it - if (topRow <= newRowPosition - && numRowsVisible > newRowPosition - topRow) { - insertRowAt(newRowPosition - topRow); - ++numRowsInCollection; - updateVisibleRows(); - int newRowNumber = newRowPosition - topRow; - if (newRowNumber != currentRow) { - internalSetSelection(currentColumn, newRowNumber, false); - } else { - internalSetSelection(currentColumn, newRowNumber, true); - } - return true; - } - - // else... - - ++numRowsInCollection; - - // If the new row is above us, scroll up to it - if (newRowPosition < topRow + currentRow) { - doSetTopRow(newRowPosition, currentRow); - Display.getDefault().asyncExec(new Runnable() { - public void run() { - updateVisibleRows(); - if (currentRow != 0) { - internalSetSelection(currentColumn, 0, false); - } else { - internalSetSelection(currentColumn, 0, true); - } - } - }); - } else { - // If we're appending - if (numRowsInDisplay > numRowsVisible) { - updateVisibleRows(); - int newRowNumber = newRowPosition - topRow; - if (newRowNumber != currentRow) { - internalSetSelection(currentColumn, newRowNumber, - false); - } else { - internalSetSelection(currentColumn, newRowNumber, - true); - } - } else { - // It's somewhere in the middle below us; scroll down to - // it - doSetTopRow(newRowPosition - numRowsVisible + 1, currentRow); - int newRowNumber = numRowsVisible - 1; - if (newRowNumber != currentRow) { - internalSetSelection(currentColumn, newRowNumber, - false); - } else { - internalSetSelection(currentColumn, newRowNumber, - true); - } - } - } - return false; - } - - public boolean doDeleteRow() { - if (fireDeleteEvent()) { - // We know the object is gone if we made it here, so now - // refresh the display... - --numRowsInCollection; - - // If we deleted the last row in the list - if (currentRow >= numRowsVisible - 1) { - // If that wasn't the last row in the collection, move - // the focus - if (numRowsInCollection > 0) { - - // If we're only displaying one row, scroll first - if (currentRow < 1) { - needToRequestRC = false; - deleteRowAt(currentRow); - doSetTopRow(topRow - 1, currentRow); - internalSetSelection(currentColumn, currentRow, - true); - } else { - needToRequestRC = false; - internalSetSelection(currentColumn, - currentRow - 1, false); - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - deleteRowAt(currentRow + 1); - updateVisibleRows(); - } - }); - } - } else { - // Otherwise, show the placeholder object and give - // it focus - deleteRowAt(currentRow); - --numRowsVisible; - createEmptyTablePlaceholer(); - emptyTablePlaceholder.setFocus(); - currentRow = -1; - } - } else { - // else, keep the focus where it was - deleteRowAt(currentRow); - updateVisibleRows(); - internalSetSelection(currentColumn, currentRow, true); - } - fireRowDeletedEvent(); - } - return false; - } - - +/* + * Copyright (C) 2005 David Orme + * + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * David Orme - Initial API and implementation + * Elias Volanakis - 267316 + */ +package org.eclipse.nebula.widgets.compositetable; + +import java.lang.reflect.Constructor; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.ListIterator; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.nebula.widgets.compositetable.internal.DuckType; +import org.eclipse.nebula.widgets.compositetable.internal.ISelectableRegionControl; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Slider; +import org.eclipse.swt.widgets.Widget; + +/** + * (non-API) Class InternalCompositeTable. This is the run-time + * CompositeTableControl. It gets its prototype row and (optional) header + * objects from its SWT parent, then uses them to implement an SWT virtual table + * control. + * + * @author djo + */ +class InternalCompositeTable extends Composite implements Listener { + // The internal UI controls that make up this control. + private Composite controlHolder = null; + private Composite vSliderHolder = null; + private Slider vSlider = null; + private Composite hScroller; + private Composite hSliderHolder = null; + private Slider hSlider = null; + EmptyTablePlaceholder emptyTablePlaceholder = null; + + // My parent CompositeTable + private CompositeTable parent; + + // Property fields + private int maxRowsVisible; + private int numRowsInDisplay; + private int numRowsInCollection; + private int topRow; + private int currentRow; + private int currentColumn; + + // The visible/invisible row objects and bookeeping info about them + private int currentVisibleTopRow = 0; + private int numRowsVisible = 0; + private LinkedList rows = new LinkedList(); + private LinkedList spareRows = new LinkedList(); + int clientAreaHeight; + + // The prototype header/row objects and Constructors so we can duplicate + // them + private Constructor headerConstructor; + private Constructor rowConstructor; + private Control headerControl; + private Control myHeader = null; + private Control rowControl; + + /** + * Constructor InternalCompositeTable. The usual SWT constructor. The same + * style bits are allowed here as are allowed on Composite. + * + * @param parentControl + * The SWT parent. + * @param style + * Style bits. + */ + public InternalCompositeTable(Composite parentControl, int style) { + super(parentControl, style); + initialize(); + + this.parent = (CompositeTable) parentControl; + + setBackground(parentControl.getBackground()); + controlHolder.addListener(SWT.MouseWheel, this); + + maxRowsVisible = parent.getMaxRowsVisible(); + numRowsInCollection = parent.getNumRowsInCollection(); + topRow = parent.getTopRow(); + + headerConstructor = parent.getHeaderConstructor(); + rowConstructor = parent.getRowConstructor(); + headerControl = parent.getHeaderControl(); + rowControl = parent.getRowControl(); + + setMenu(parent.getMenu()); + + currentVisibleTopRow = topRow; + showHeader(); + updateVisibleRows(); + + if (numRowsVisible < 1) { + createEmptyTablePlaceholer(); + } + currentRow = -1; // initialize to undefined + } + + public void setBackground(Color color) { + super.setBackground(color); + controlHolder.setBackground(color); + } + + /** + * Initialize the overall table UI. + */ + private void initialize() { + GridLayout gl = new GridLayout(); + gl.numColumns = 2; + gl.verticalSpacing = 0; + gl.marginWidth = 0; + gl.marginHeight = 0; + // borderWidth times two, since border steals pixels from both sides + int borderInPixels = getParent().getBorderWidth() * 2; + gl.marginRight = borderInPixels; + gl.marginBottom = borderInPixels; + gl.horizontalSpacing = 0; + this.setLayout(gl); + createControlHolder(); + createVSliderHolder(); + createHSliderHolder(); + } + + /** + * Initialize the controlHolder, which is the holder Composite for the + * header object (if applicable) and the row objects. + */ + private void createControlHolder() { + hScroller = new Composite(this, SWT.NULL); + GridData gridData = new GridData(); + gridData.horizontalAlignment = GridData.FILL; + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + gridData.verticalAlignment = GridData.FILL; + hScroller.setLayoutData(gridData); + + controlHolder = new Composite(hScroller, SWT.NONE); + + controlHolder.setLayout(new Layout() { + protected Point computeSize(Composite composite, int wHint, + int hHint, boolean flushCache) { + if (rowControl != null) { + int height = 0; + int width = 0; + if (headerControl != null) { + Point headerSize = headerControl.computeSize(wHint, hHint, flushCache); + width = headerSize.x; + height = headerSize.y; + } + Point rowSize = rowControl.computeSize(wHint, hHint, flushCache); + height += rowSize.y * 2; + if (width < rowSize.x) { + width = rowSize.x; + } + return new Point(width, height); + } + return new Point(50, 50); + } + + protected void layout(Composite composite, boolean flushCache) { + layoutControlHolder(); + } + }); + + hScroller.addControlListener(scrollerResizeHandler); + } + + ControlAdapter scrollerResizeHandler = new ControlAdapter() { + public void controlResized(ControlEvent e) { + Point size = hScroller.getSize(); + + int preferredWidth = controlHolder.computeSize(SWT.DEFAULT, + SWT.DEFAULT, true).x; + + if (preferredWidth > size.x && !isHSliderVisible()) { + setHSliderVisible(true); + } + if (preferredWidth <= size.x && isHSliderVisible()) { + setHSliderVisible(false); + } + + if (preferredWidth <= size.x) { + controlHolder.setBounds(0, 0, size.x, size.y); + return; + } + + if (isHSliderVisible()) { + hSlider.setMaximum(preferredWidth); + hSlider.setPageIncrement(size.x); + hSlider.setThumb(preferredWidth - (preferredWidth - size.x)); + int currentSelection = hSlider.getSelection(); + if (preferredWidth - currentSelection < size.x) { + hSlider.setSelection(preferredWidth - size.x); + } + } + hSlider.notifyListeners(SWT.Selection, new Event()); + } + }; + + + /** + * Initialize the sliderHolder and slider. The SliderHolder is a Composite + * that is responsible for showing and hiding the vertical slider upon + * request. + */ + private void createVSliderHolder() { + GridData gd = getVSliderGridData(); + vSliderHolder = new Composite(this, SWT.NULL); + vSlider = new Slider(vSliderHolder, SWT.VERTICAL); + vSlider.addSelectionListener(sliderSelectionListener); + vSliderHolder.setLayout(new FillLayout()); + vSliderHolder.setLayoutData(gd); + vSliderHolder.setTabList(new Control[] {}); + } + + /** + * Initialize the sliderHolder and slider. The SliderHolder is a Composite + * that is responsible for showing and hiding the vertical slider upon + * request. + */ + private void createHSliderHolder() { + GridData gd = getHSliderGridData(); + hSliderHolder = new Composite(this, SWT.NULL); + hSlider = new Slider(hSliderHolder, SWT.HORIZONTAL); + hSlider.setMinimum(0); + hSlider.setIncrement(20); + hSlider.addSelectionListener(sliderSelectionListener); + hSliderHolder.setLayout(new FillLayout()); + hSliderHolder.setLayoutData(gd); + hSliderHolder.setTabList(new Control[] {}); + hSlider.addSelectionListener(hSliderSelectionListener); + } + + // Slider utility methods + // --------------------------------------------------------------------- + + /** + * Returns a GridData for the SliderHolder appropriate for if the slider is + * visible or not. + * + * @return A GridData with a widthHint of 0 if the slider is not visible or + * with a widthHint of SWT.DEFAULT otherwise. + */ + private GridData getVSliderGridData() { + GridData gd = new GridData(); + gd.grabExcessVerticalSpace = true; + gd.verticalAlignment = GridData.FILL; + gd.verticalSpan = 1; + if (!vSliderVisible) { + gd.widthHint = 0; + } + return gd; + } + + /** + * Returns a GridData for the SliderHolder appropriate for if the slider is + * visible or not. + * + * @return A GridData with a heightHint of 0 if the slider is not visible or + * with a heightHint of SWT.DEFAULT otherwise. + */ + private GridData getHSliderGridData() { + GridData gd = new GridData(); + gd.grabExcessHorizontalSpace = true; + gd.horizontalAlignment = GridData.FILL; + gd.horizontalSpan = 1; + if (!hSliderVisible) { + gd.heightHint = 0; + } + return gd; + } + + private boolean vSliderVisible = false; + + /** + * Sets if the slider is visible or not. + * + * @param visible + * true if the slider should be visible; false otherwise. + */ + public void setVSliderVisible(boolean visible) { + this.vSliderVisible = visible; + vSliderHolder.setLayoutData(getVSliderGridData()); + if (visible) { + Display.getCurrent().addFilter(SWT.KeyDown, displayKeyDownFilter); + } else { + Display.getCurrent().removeFilter(SWT.KeyDown, displayKeyDownFilter); + } + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (!InternalCompositeTable.this.isDisposed() && + !vSliderHolder.isDisposed() && + !vSliderHolder.getParent().isDisposed()) + { + vSliderHolder.getParent().layout(true); + vSliderHolder.layout(true); + Point sliderHolderSize = vSliderHolder.getSize(); + vSlider.setBounds(0, 0, sliderHolderSize.x, sliderHolderSize.y); + } + } + }); + } + + /** + * Returns if the slider is visible. + * + * @return true if the slider is visible; false otherwise. + */ + public boolean isVSliderVisible() { + return vSliderVisible; + } + + private boolean hSliderVisible = false; + + /** + * Sets if the slider is visible or not. + * + * @param visible + * true if the slider should be visible; false otherwise. + */ + public void setHSliderVisible(boolean visible) { + this.hSliderVisible = visible; + hSliderHolder.setLayoutData(getHSliderGridData()); + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (!InternalCompositeTable.this.isDisposed() && + !hSliderHolder.isDisposed() && + !hSliderHolder.getParent().isDisposed()) + { + hSliderHolder.getParent().layout(true); + hSliderHolder.layout(true); + Point sliderHolderSize = hSliderHolder.getSize(); + hSlider.setBounds(0, 0, sliderHolderSize.x, sliderHolderSize.y); + } + } + }); + } + + /** + * Returns if the slider is visible. + * + * @return true if the slider is visible; false otherwise. + */ + public boolean isHSliderVisible() { + return hSliderVisible; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.widgets.Widget#dispose() + */ + public void dispose() { + disposeRows(rows); + disposeRows(spareRows); + super.dispose(); + } + + /** + * Disposes all the row objects in the specified LinkedList. + * + * @param rowsCollection + * The collection containing TableRow objects to dispose. + */ + private void disposeRows(LinkedList rowsCollection) { + for (Iterator rowsIter = rowsCollection.iterator(); rowsIter.hasNext();) { + TableRow row = (TableRow) rowsIter.next(); + if (row instanceof IRowFocusListener) { + parent.removeRowFocusListener((IRowFocusListener) row); + } + if (row instanceof IRowContentProvider) { + parent.removeRowContentProvider((IRowContentProvider) row); + } + row.dispose(); + } + } + + // Row object layout + // -------------------------------------------------------------------------- + + /** + * Layout the child controls within the controlHolder Composite. + */ + protected void layoutControlHolder() { + if (myHeader != null) { + layoutHeaderOrRow(myHeader); + } + for (Iterator rowsIter = rows.iterator(); rowsIter.hasNext();) { + TableRow row = (TableRow) rowsIter.next(); + layoutHeaderOrRow(row.getRowControl()); + } + updateVisibleRows(); + } + + private void layoutHeaderOrRow(Control control) { + if (control instanceof Composite) { + Composite headerOrRow = (Composite) control; + headerOrRow.layout(true); + } + } + + // Table control layout -- utility methods + // ---------------------------------------------------- + + /** + * Construct a header or row object on demand. Logs an error and returns + * null on failure. + * + * @param parent + * The SWT parent. + * @param constructor + * The header or row object's constructor. + * @return The constructed control or null if none could be constructed. + */ + private Control createInternalControl(Composite parent, + Constructor constructor) { + Control result = null; + try { + if (!constructor.isAccessible()) { + constructor.setAccessible(true); + } + result = (Control) constructor.newInstance(new Object[] { parent, + new Integer(SWT.NULL) }); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to construct control"); //$NON-NLS-1$ + } + if (result instanceof IRowFocusListener) { + this.parent.addRowFocusListener((IRowFocusListener) result); + } + if (result instanceof IRowContentProvider) { + this.parent.addRowContentProvider((IRowContentProvider) result); + } + return result; + } + + /** + * If the header control hasn't been created yet, create and show it. + */ + private void showHeader() { + if (myHeader == null && headerConstructor != null) { + myHeader = createInternalControl(controlHolder, headerConstructor); + fireHeaderConstructionEvent(myHeader); + if (myHeader instanceof Composite) { + Composite headerComp = (Composite) myHeader; + if (headerComp.getLayout() instanceof GridRowLayout) { + headerComp.addPaintListener(headerPaintListener); + } + } + layoutHeaderOrRow(myHeader); + } + } + + // Table control layout -- main refresh algorithm + // --------------------------------------------- + + /** + * Main refresh algorithm entry point. This method refreshes everything in + * the table: + * + *

    + *
  • Makes sure the correct number of rows are visible + *
  • Makes sure each row has been refreshed with data from the underlying + * model + *
+ */ + void updateVisibleRows() { + // If we don't have our prototype row object yet, bail out + if (rowControl == null) { + return; + } + + clientAreaHeight = controlHolder.getSize().y; + if (clientAreaHeight <= 0) { + return; + } + + int topPosition = 0; + + int headerHeight = 0; + if (myHeader != null) { + headerHeight = headerControl.getSize().y + 3; + clientAreaHeight -= headerHeight; + topPosition += headerHeight; + } + numRowsInDisplay = clientAreaHeight / getRowHeight(clientAreaHeight); + + // Make sure we have something to lay out to begin with + int userScrollDirection = 0; + if (numRowsInCollection > 0) { + numRowsVisible = numRowsInDisplay; + + disposeEmptyTablePlaceholder(); + + int displayableRows = numRowsInCollection - topRow; + if (numRowsVisible > displayableRows) { + numRowsVisible = displayableRows; + } + if (numRowsVisible > maxRowsVisible) { + numRowsVisible = maxRowsVisible; + } + if (numRowsVisible < 1) { + numRowsVisible = 1; + } + + // Keep track of if we're scrolling forwards or backwards + if (currentVisibleTopRow - topRow > 0) { + userScrollDirection = ScrollEvent.BACKWARD; + } else if (topRow - currentVisibleTopRow > 0) { + userScrollDirection = ScrollEvent.FORWARD; + } + + // Scroll the view so that the right number of row + // objects are showing and they have the right data + if (rows.size() - Math.abs(currentVisibleTopRow - topRow) > 0) { +// if (currentRow >= numRowsVisible) { +// deleteRowAt(0); +// ++currentVisibleTopRow; +// ++topRow; +// --currentRow; +// } + scrollTop(); + fixNumberOfRows(); + } else { + currentVisibleTopRow = topRow; + fixNumberOfRows(); + refreshAllRows(); + } + } else { + numRowsVisible = 0; + topRow = 0; + currentRow = 0; + currentColumn = 0; + currentVisibleTopRow = 0; + numRowsVisible = 0; + + if (emptyTablePlaceholder == null) { + fixNumberOfRows(); + createEmptyTablePlaceholer(); + } + } + + // Make sure that the currentRow is within the visible range + // (after PgDn, it could wind up outside the visible range) + if (currentRow >= numRowsVisible && getNumRowsVisible() < numRowsInDisplay) { + currentRow = numRowsVisible-1; + } + + // Show, hide, reset the scroll bar + if (numRowsVisible < numRowsInCollection) { + int extra = numRowsInCollection - numRowsVisible; + int pageIncrement = numRowsVisible; + if (pageIncrement > extra) + pageIncrement = extra; + + vSlider.setMaximum(numRowsInCollection); + vSlider.setMinimum(0); + vSlider.setIncrement(1); + vSlider.setPageIncrement(pageIncrement); + vSlider.setThumb(numRowsInCollection + - (numRowsInCollection - numRowsVisible)); + + vSlider.setSelection(topRow); + + if (!isVSliderVisible()) { + setVSliderVisible(true); + } + } else { + setVSliderVisible(false); + } + + // Lay out the header and rows correctly in the display + int width = controlHolder.getSize().x; + + // First, the header... + if (myHeader != null) { + myHeader.setBounds(0, 0, width, headerHeight); + } + + // Make sure we have rows to lay out... + if (numRowsInCollection < 1) { + return; + } + + // Now the rows. + int rowHeight = getRowHeight(clientAreaHeight); + + // We have to move the controls front-to-back if we're scrolling + // forwards and back-to-front if we're scrolling backwards to avoid ugly + // screen refresh artifacts. + if (userScrollDirection == ScrollEvent.FORWARD || userScrollDirection == ScrollEvent.NONE) { + for (Iterator rowsIter = rows.iterator(); rowsIter.hasNext();) { + TableRow row = (TableRow) rowsIter.next(); + Control rowControl = row.getRowControl(); + rowControl.setBounds(0, topPosition, width, rowHeight); + layoutHeaderOrRow(rowControl); + topPosition += rowHeight; + } + } else { + ListIterator rowsIter = rows.listIterator(); + while (rowsIter.hasNext()) { + rowsIter.next(); + } + topPosition += rowHeight * (rows.size() - 1); + while (rowsIter.hasPrevious()) { + TableRow row = (TableRow) rowsIter.previous(); + Control rowControl = row.getRowControl(); + rowControl.setBounds(0, topPosition, width, rowHeight); + layoutHeaderOrRow(rowControl); + topPosition -= rowHeight; + } + } + + // If we scrolled, tell clients about it + if (userScrollDirection != ScrollEvent.NONE) { + fireScrollEvent(new ScrollEvent(userScrollDirection, parent)); + } + } + + int getRowHeight(int clientAreaHeight) { + int rowControlHeight = rowControl.getSize().y; + if (maxRowsVisible == Integer.MAX_VALUE) { + return rowControlHeight; + } + return rowControlHeight; + } + + /** + * Utility method: Makes sure that the currently visible top row is the same + * as the top row specified in the TopRow property. + */ + private void scrollTop() { + while (currentVisibleTopRow < topRow) { + deleteRowAt(0); + ++currentVisibleTopRow; + } + while (currentVisibleTopRow > topRow) { + --currentVisibleTopRow; + insertRowAt(0); + } + } + + /** + * Utility method: Makes sure that the number of rows that are visible + * correspond with what should be visible given the table control's size, + * where it is scrolled, and the number of rows in the underlying + * collection. + */ + private void fixNumberOfRows() { + int numRows = rows.size(); + while (numRows > numRowsVisible) { + deleteRowAt(numRows - 1); + numRows = rows.size(); + } + while (numRows < numRowsVisible) { + insertRowAt(numRows); + numRows = rows.size(); + } + } + + /** + * Fire the refresh event on all visible rows. + */ + void refreshAllRows() { + int row = 0; + for (Iterator rowsIter = rows.iterator(); rowsIter.hasNext();) { + TableRow rowControl = (TableRow) rowsIter.next(); + fireRefreshEvent(topRow + row, rowControl.getRowControl()); + ++row; + } + resetFocus(); + } + + void refreshRow(int row) { + if (topRow > -1) { + if (isRowVisible(row)) { + fireRefreshEvent(row + topRow, ((TableRow) rows.get(row)).getRowControl()); + } + } + } + + private boolean isRowVisible(int row) { + return row >= 0 && row < numRowsVisible; + } + + /** + * Make sure that something sane inside the table has focus. + */ + private void resetFocus() { + /* + * FEATURE IN WINDOWS: When we refresh all rows and one already has + * focus, Windows gets into a schizophrenic state where some part of + * Windows thinks that the current control has focus and another part of + * Windows thinks that the current control doesn't have focus. + * + * The symptom is that the current control stops receiving events from + * Windows but Windows still thinks the current control has focus and so + * it won't give the control complete focus if you click on it. + * + * The workaround is to set the focus away from the currently-focused + * control and to set it back. + */ + if (numRowsVisible < 1 || currentRow < 0) { + return; + } + Control control = null; + if (currentRow < numRowsVisible) { + control = getControl(currentColumn, currentRow); + } else if (currentRow > 0) { + control = getControl(currentColumn, numRowsVisible - 1); + } + if (control != null && control.isFocusControl()) { + this.setFocus(); + deferredSetFocus(control, true); + } + } + + /** + * Insert a new row object at the specified 0-based position relatve to the + * topmost row. + * + * @param position + * The 0-based position relative to the topmost row. + */ + private void insertRowAt(int position) { + TableRow newRow = getNewRow(); + if (position > rows.size()) { + position = rows.size(); + } + rows.add(position, newRow); + fireRefreshEvent(currentVisibleTopRow + position, newRow + .getRowControl()); + } + + /** + * Delete the row at the specified 0-based position relative to the topmost + * row. + * + * @param position + * The 0-based position relative to the topmost row. + */ + private void deleteRowAt(int position) { + TableRow row = (TableRow) rows.remove(position); + row.setVisible(false); + spareRows.addLast(row); + } + + /** + * Utility method: Creates a new row object or recycles one that had been + * previously created but was no longer needed. + * + * @return The new row object. + */ + private TableRow getNewRow() { + if (spareRows.size() > 0) { + TableRow recycledRow = (TableRow) spareRows.removeFirst(); + recycledRow.setVisible(true); + return recycledRow; + } + Control newControl = createInternalControl(controlHolder, + rowConstructor); + if (menu != null) { + newControl.setMenu(menu); + } + fireRowConstructionEvent(newControl); + TableRow newRow = new TableRow(this, newControl); + if (newRow.getRowControl() instanceof Composite) { + Composite rowComp = (Composite) newRow.getRowControl(); + if (rowComp.getLayout() instanceof GridRowLayout) { + rowComp.setBackground(getBackground()); + rowComp.addPaintListener(rowPaintListener); + } + } + return newRow; + } + + // Property getters/setters + // -------------------------------------------------------------- + + /* + * These are internal API.

Plese refer to the JavaDoc on CompositeTable + * for detailed description of these property methods. + */ + + /** + * (non-API) Method getHeaderControl. Return the prototype control being + * used as a header. + * + * @return The header control + */ + public Control getHeaderControl() { + return headerControl; + } + + /** + * Returns the actual header control (not the prototype). + * + * @return a control instance or null, if no header is available + */ + Control getHeader() { + return myHeader; + } + + /** + * Method setMaxRowsVisible. Sets the maximum number of rows that will be + * permitted in the table at once. For example, setting this property to 1 + * will have the effect of creating a single editing area with a scroll bar + * on the right allowing the user to scroll through all rows using either + * the mouse or the PgUp/PgDn keys. The default value is Integer.MAX_VALUE. + * + * @param maxRowsVisible + * the maximum number of rows that are permitted to be visible at + * one time, regardless of the control's size. + */ + public void setMaxRowsVisible(int maxRowsVisible) { + this.maxRowsVisible = maxRowsVisible; + updateVisibleRows(); + } + + /** + * Method getNumRowsVisible. Returns the actual number of rows that are + * currently visible. Normally CompositeTable displays as many rows as will + * fit vertically given the control's size. This value can be clamped to a + * maximum using the MaxRowsVisible property. + * + * @return the actual number of rows that are currently visible. + */ + public int getNumRowsVisible() { + return rows.size(); + } + + /** + * Method setNumRowsInCollection. Sets the number of rows in the data + * structure that is being edited. + * + * @param numRowsInCollection + * the number of rows represented by the underlying data + * structure. + */ + public void setNumRowsInCollection(int numRowsInCollection) { + this.topRow = 0; + if (topRow + currentRow > numRowsInCollection) { + if (topRow < numRowsInCollection) { + currentRow = numRowsInCollection - topRow; + } else { + topRow = numRowsInCollection - 1; + currentRow = 0; + } + deferredSetFocus(getCurrentRowControl(), false); + } + this.numRowsInCollection = numRowsInCollection; + updateVisibleRows(); + refreshAllRows(); + } + + private void doSetTopRow(int topRow, int currentRow) { +// fireRowDepartEvent(); + this.topRow = topRow; + this.currentRow = currentRow; + updateVisibleRows(); +// fireRowArriveEvent(); + } + + /** + * Method setTopRow. Set the number of the line that is being displayed in + * the top row of the CompositeTable editor (0-based). If the new top row is + * not equal to the current top row, the table will automatically be + * scrolled to the new position. This number must be greater than 0 and less + * than NumRowsInCollection. + * + * @param topRow + * the line number of the new top row. + */ + public void setTopRow(int topRow) { + fireRowDepartEvent(); + int topRowDelta = this.topRow - topRow; + doSetTopRow(topRow, currentRow + topRowDelta); + fireRowArriveEvent(); + } + + /** + * Method getTopRow. Return the number of the line that is being displayed + * in the top row of the CompositeTable editor (0-based). + * + * @return the number of the top line. + */ + public int getTopRow() { + return topRow; + } + + /** + * Method getSelection. Returns the currently-selected (column, row) pair + * where the row specifies the offset from the top of the table window. In + * order to get the current row in the underlying data structure, use + * getSelection().y + getCurrentRow(). + * + * @return the currently-selected (column, row) pair where the row specifies + * the offset from the top of the table window, or null if no + * selection is available. + */ + public Point getSelection() { + return currentRow != -1 ? new Point(currentColumn, currentRow) : null; + } + + /** + * Method setSelection. Sets the currently-selected (column, row) pair where + * the row specifies the offset from the top of the table window. In order + * to get the current row in the underlying data structure, use + * getSelection().y + getCurrentRow(). + * + * @param column + * the column to select + * @param row + * the row to select + */ + public void setSelection(int column, int row) { + int topRowDelta = computeTopRowDelta(row); + if (topRowDelta != 0) { + doSetTopRow(topRow + topRowDelta, currentRow); + row += -1 * topRowDelta; + internalSetSelection(column, row, true); + } else { + if (row == currentRow) + internalSetSelection(column, row, false); + else { + if (fireRequestRowChangeEvent()) + internalSetSelection(column, row, true); + } + } + } + + /** + * (non-API) See {@link CompositeTable#clearSelection()} instead. + */ + public void clearSelection() { + Point currentSelection = getSelection(); + if(currentSelection != null) { + fireRowDepartEvent(); + currentRow = -1; + } + } + + /** + * Method setWeights. Indicates that the column weights were just set and we + * should re-layout the control holder object. + */ + public void setWeights() { + layoutControlHolder(); + } + + // Refresh Event API + // -------------------------------------------------------------------------- + + /** + * Adds the specified listener to the set of listeners that will be notified + * when a row refresh event occurs. + * + * @param listener + * the listener to add. + */ + public void addRefreshContentProvider(IRowContentProvider listener) { + parent.contentProviders.add(listener); + } + + /** + * Remove the specified listener from the set of listeners that will be + * notified when a row refresh event occurs. + * + * @param listener + * the listener to remove. + */ + public void removeRefreshContentProvider(IRowContentProvider listener) { + parent.contentProviders.remove(listener); + } + + private void fireRefreshEvent(int positionInCollection, Control rowControl) { + if (numRowsInCollection < 1) { + return; + } + for (Iterator refreshListenersIter = parent.contentProviders.iterator(); refreshListenersIter + .hasNext();) { + IRowContentProvider listener = (IRowContentProvider) refreshListenersIter + .next(); + listener.refresh(parent, positionInCollection, rowControl); + } + } + + // Empty table placeholder + // -------------------------------------------------------------------- + + private void createEmptyTablePlaceholer() { + emptyTablePlaceholder = new EmptyTablePlaceholder(controlHolder, + SWT.NULL); + if (rowControl != null) + emptyTablePlaceholder.setBackground(rowControl.getBackground()); + emptyTablePlaceholder.setMessage(parent.getInsertHint()); + } + + private void disposeEmptyTablePlaceholder() { + if (emptyTablePlaceholder != null) { + emptyTablePlaceholder.dispose(); + emptyTablePlaceholder = null; + } + } + + // Event Handling + // ----------------------------------------------------------------------------- + + private boolean needToRequestRC = true; + + private Listener displayKeyDownFilter = new Listener() { + public void handleEvent(Event event) { + if (rowControl.getClass().isAssignableFrom(event.widget.getClass())) { + doMakeFocusedRowVisible(); + } + } + }; + + + + /** + * Handle a keyPressed event on any row control. + * + * @param sender + * The row that is sending the event + * @param e + * the actual KeyEvent + */ + public void keyPressed(TableRow sender, KeyEvent e) { + if (doMakeFocusedRowVisible()) return; + + if ((e.stateMask & SWT.CONTROL) != 0) { + switch (e.keyCode) { + case SWT.HOME: + doFocusInitialRow(); + return; + case SWT.END: + doFocusLastRow(); + return; + case SWT.INSERT: + doInsertRow(); + return; + case SWT.DEL: + doDeleteRow(); + return; + default: + return; + } + } + switch (e.keyCode) { + case SWT.ARROW_UP: + doRowUp(); + return; + case SWT.ARROW_DOWN: + doRowDown(); + return; + case SWT.PAGE_UP: + doPageUp(); + return; + case SWT.PAGE_DOWN: + doPageDown(); + return; + } + } + + /** + * Handle the keyTraversed event on any child control in the table. + * + * @param sender + * The row sending the event. + * @param e + * The SWT TraverseEvent + */ + public void keyTraversed(TableRow sender, TraverseEvent e) { + if (doMakeFocusedRowVisible()) return; + + if (parent.isTraverseOnTabsEnabled()) { + if (e.detail == SWT.TRAVERSE_TAB_NEXT) { + if (currentColumn >= sender.getNumColumns() - 1) { + e.detail = SWT.TRAVERSE_NONE; + handleNextRowNavigation(); + } + } else if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS) { + if (currentColumn == 0) { + e.detail = SWT.TRAVERSE_NONE; + handlePreviousRowNavigation(sender); + } + } else if (e.detail == SWT.TRAVERSE_RETURN) { + e.detail = SWT.TRAVERSE_NONE; + if (currentColumn >= sender.getNumColumns() - 1) { + handleNextRowNavigation(); + } else { + deferredSetFocus(getControl(currentColumn + 1, currentRow), + false); + } + } + } else { + if (e.detail == SWT.TRAVERSE_TAB_NEXT) { + if (currentColumn >= sender.getNumColumns() - 1) { + e.detail = SWT.TRAVERSE_NONE; + } + } else if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS) { + if (currentColumn == 0) { + e.detail = SWT.TRAVERSE_NONE; + } + } + } + } + + /** + * Makes sure that the focused row is visible + * + * @return true if the display needed to be scrolled; false otherwise + */ + public boolean doMakeFocusedRowVisible() { + if (numRowsVisible < 1) { + return false; + } + int topRowDelta = computeTopRowDelta(currentRow); + if (topRowDelta == 0) { + return false; + } +// currentRow += -1 * topRowDelta; + + doSetTopRow(topRow + topRowDelta, currentRow + (-1 * topRowDelta)); + Control control = getControl(currentColumn, currentRow); + if (control != null) { + control.setFocus(); // ?? Can I get away with avoiding asyncExec here ?? + } + return true; + } + + private int computeTopRowDelta(int row) { + int topRowDelta; + if (row < 0) { + topRowDelta = row; + } else if (row >= getNumRowsVisible()) { + topRowDelta = row - getNumRowsVisible() + 1; + } else { + return 0; + } + return topRowDelta; + } + + /** + * The SelectionListener for the table's vertical slider control. + */ + private SelectionListener sliderSelectionListener = new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + if (vSlider.getSelection() == topRow) { + return; + } + + if (!fireRequestRowChangeEvent()) { + vSlider.setSelection(topRow); + return; + } + + deselectCurrentRowIfVisible(); + + int delta = topRow - vSlider.getSelection(); + int oldCurrentRow = currentRow; + currentRow = vSlider.getSelection(); + +// setTopRow(vSlider.getSelection()); // Removed as a result of patch + doSetTopRow(vSlider.getSelection(), currentRow + delta); + + // If the focused row just became visible, show the focus + if (oldCurrentRow < 0 || oldCurrentRow >= getNumRowsVisible()) { + if (currentRow >= 0 && currentRow < getNumRowsVisible()) { + Control newFocusControl = getControl(currentColumn, currentRow); + if (newFocusControl == null) { + return; + } + if (newFocusControl.isFocusControl()) { + newFocusControl.notifyListeners(SWT.FocusIn, new Event()); + } else { + deferredSetFocus(newFocusControl, true); + } + } + } else { + // If the new viewport doesn't overlap the old one, hide the focus + if (currentRow < 0 || currentRow >= getNumRowsVisible()) { + // deleteRowAt(oldCurrentRow); +// getControl(currentColumn, oldCurrentRow).getParent().setVisible(false); +// getControl(currentColumn, oldCurrentRow).getParent().setVisible(true); + Control control = getControl(currentColumn, oldCurrentRow); + if (control != null) { + control.notifyListeners(SWT.FocusOut, new Event()); + } + } + } + } + + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + }; + + private SelectionListener hSliderSelectionListener = new SelectionListener() { + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + Point scrollerSize = hScroller.getSize(); + int preferredWidth = controlHolder.computeSize(SWT.DEFAULT, + SWT.DEFAULT, true).x; + Rectangle controlHolderBounds = + new Rectangle(-1 * hSlider.getSelection(), 0, preferredWidth, + scrollerSize.y); + controlHolder.setBounds(controlHolderBounds); + } + + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + }; + + /** + * Scroll wheel event handling. + */ + public void handleEvent(Event event) { + event.doit = false; + if (event.count > 0) { // scroll up + if (topRow > 0) { + if (!fireRequestRowChangeEvent()) { + return; + } + deselectCurrentRowIfVisible(); + doSetTopRow(topRow - 1, currentRow + 1); + if (isRowVisible(currentRow)) { + deferredSetFocus(getControl(currentColumn, currentRow), true); + } + } + } else { // scroll down + if (topRow < numRowsInCollection - numRowsVisible) { + if (!fireRequestRowChangeEvent()) { + return; + } + deselectCurrentRowIfVisible(); + doSetTopRow(topRow + 1, currentRow - 1); + if (isRowVisible(currentRow)) { + deferredSetFocus(getControl(currentColumn, currentRow), true); + } + } + } +// if (event.count > 0) { // Old code (before patch) +// if (topRow > 0) { +// if (!fireRequestRowChangeEvent()) { +// return; +// } +// deselectCurrentRowIfVisible(); +// setTopRow(topRow - 1); +// ++currentRow; +// if (currentRow == 0) { +// deferredSetFocus(getControl(currentColumn, currentRow), true); +// } +// } +// } else { +// if (topRow < numRowsInCollection - numRowsVisible) { +// if (!fireRequestRowChangeEvent()) { +// return; +// } +// deselectCurrentRowIfVisible(); +// setTopRow(topRow + 1); +// --currentRow; +// if (currentRow == getNumRowsVisible()-1) { +// deferredSetFocus(getControl(currentColumn, currentRow), true); +// } +// } +// } + } + + private void deselectCurrentRowIfVisible() { + if (currentRow >= 0 && currentRow < numRowsVisible) { + Control control = getControl(currentColumn, currentRow); + if (control != null) { + deselect(control); + } + } + } + + /** + * Handle focusLost events on any child control. This is not currently used. + * + * @param sender + * The row containing the sending control. + * @param e + * The SWT FocusEvent. + */ + public void focusLost(TableRow sender, FocusEvent e) { + } + + /** + * Handle focusGained events on any child control. + * + * FIXME: Needs to automatically scroll horizontally if the newly-focused + * control is fully or partially occluded. + * + * @param sender + * The row containing the sending control. + * @param e + * The SWT FocusEvent. + */ + public void focusGained(TableRow sender, FocusEvent e) { + boolean rowChanged = false; + int senderRowNumber = getRowNumber(sender); + if (senderRowNumber != currentRow) { + if (needToRequestRC) { + if (!fireRequestRowChangeEvent()) { + // Go back if we're not allowed to be here + deferredSetFocus(getControl(currentColumn, currentRow), + false); + } + } else { + needToRequestRC = true; + } + rowChanged = true; + } + + currentRow = senderRowNumber; + currentColumn = sender.getColumnNumber((Control) e.widget); + + if (rowChanged) + fireRowArriveEvent(); + } + + private PaintListener headerPaintListener = new PaintListener() { + public void paintControl(PaintEvent e) { + if (parent.linesVisible) { + drawGridLines(e, true); + } + } + }; + + private PaintListener rowPaintListener = new PaintListener() { + public void paintControl(PaintEvent e) { + if (parent.linesVisible) { + drawGridLines(e, false); + } + } + }; + + private void drawGridLines(PaintEvent e, boolean isHeader) { + Color oldColor = e.gc.getForeground(); + try { + // Get the colors we need + Display display = Display.getCurrent(); + Color lineColor = display + .getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW); + Color secondaryColor = display + .getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); + Color hilightColor = display + .getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); + if (!isHeader) { + lineColor = display + .getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW); + } + + // Get the control + Control toPaint = (Control) e.widget; + Point controlSize = toPaint.getSize(); + + // Draw the bottom line(s) + e.gc.setForeground(lineColor); + e.gc.drawLine(0, controlSize.y - 1, controlSize.x, + controlSize.y - 1); + if (isHeader) { + e.gc.setForeground(secondaryColor); + e.gc.drawLine(0, controlSize.y - 2, controlSize.x, + controlSize.y - 2); + e.gc.setForeground(hilightColor); + e.gc.drawLine(0, 1, controlSize.x, 1); + } + + // Now draw lines around the child controls, if there are any + if (toPaint instanceof Composite) { + Composite row = (Composite) toPaint; + Control[] children = row.getChildren(); + for (int i = 0; i < children.length; i++) { + Rectangle childBounds = children[i].getBounds(); + + // Paint the beginning lines + if (isHeader) { + e.gc.setForeground(hilightColor); + e.gc.drawLine(childBounds.x - 2, 1, childBounds.x - 2, + controlSize.y - 2); + } + + // Paint the ending lines + e.gc.setForeground(lineColor); + int lineLeft = childBounds.x + childBounds.width + 1; + e.gc.drawLine(lineLeft, 0, lineLeft, controlSize.y); + if (isHeader) { + e.gc.setForeground(secondaryColor); + e.gc.drawLine(lineLeft - 1, 0, lineLeft - 1, + controlSize.y - 1); + } + } + } + } finally { + e.gc.setForeground(oldColor); + } + } + + // Event Firing + // ------------------------------------------------------------------------------- + + /** + * Fire the row construction event + * + * @param newControl + * The new row's SWT control + */ + private void fireRowConstructionEvent(Control newControl) { + for (Iterator rowConstructionListenersIter = parent.rowConstructionListeners + .iterator(); rowConstructionListenersIter.hasNext();) { + RowConstructionListener listener = (RowConstructionListener) rowConstructionListenersIter + .next(); + listener.rowConstructed(newControl); + } + } + + /** + * Fire the row construction event + * + * @param newControl + * The new row's SWT control + */ + private void fireHeaderConstructionEvent(Control newControl) { + for (Iterator rowConstructionListenersIter = parent.rowConstructionListeners + .iterator(); rowConstructionListenersIter.hasNext();) { + RowConstructionListener listener = (RowConstructionListener) rowConstructionListenersIter + .next(); + listener.headerConstructed(newControl); + } + } + + /** + * Indicate to listeners that the focus is arriving on the specified row + */ + private void fireRowArriveEvent() { + if (rows.size() < 1 || !isRowVisible(currentRow)) { + return; + } + for (Iterator rowChangeListenersIter = parent.rowFocusListeners + .iterator(); rowChangeListenersIter.hasNext();) { + IRowFocusListener listener = + (IRowFocusListener) rowChangeListenersIter.next(); + // currentRow() can be null if it's scrolled off the top or bottom + TableRow row = currentRow(); + Control control = row != null ? row.getRowControl() : null; + listener.arrive(parent, topRow + currentRow, control); + } + + } + + /** + * Request permission from all listeners to leave the current row. + * + * @return true if all listeners permit the row change; false otherwise. + */ + private boolean fireRequestRowChangeEvent() { + if (rows.size() < 1 || !isRowVisible(currentRow)) { + return true; + } + if (currentRow > rows.size() - 1) { + // (if the other row is already gone) + return true; + } + for (Iterator rowChangeListenersIter = parent.rowFocusListeners + .iterator(); rowChangeListenersIter.hasNext();) { + IRowFocusListener listener = (IRowFocusListener) rowChangeListenersIter + .next(); + // currentRow() can be null if it's scrolled off the top or bottom + TableRow row = currentRow(); + Control control = row != null ? row.getRowControl() : null; + if (!listener.requestRowChange(parent, topRow + currentRow, + control)) { + return false; + } + } + fireRowDepartEvent(); + return true; + } + + /** + * Indicate to listeners that the focus is about to leave the current row. + */ + private void fireRowDepartEvent() { + if (rows.size() < 1 || !isRowVisible(currentRow)) { + return; + } + for (Iterator rowChangeListenersIter = parent.rowFocusListeners + .iterator(); rowChangeListenersIter.hasNext();) { + IRowFocusListener listener = (IRowFocusListener) rowChangeListenersIter + .next(); + // currentRow() can be null if it's scrolled off the top or bottom + TableRow row = currentRow(); + Control control = row != null ? row.getRowControl() : null; + if (control != null) + listener.depart(parent, topRow + currentRow, control); + } + } + + /** + * Request deletion of the current row from the underlying data structure. + * + * @return true if the deletion was successful; false otherwise. + */ + private boolean fireDeleteEvent() { + if (parent.deleteHandlers.size() < 1) { + return false; + } + + int absoluteRow = topRow + currentRow; + for (Iterator deleteHandlersIter = parent.deleteHandlers.iterator(); deleteHandlersIter + .hasNext();) { + IDeleteHandler handler = (IDeleteHandler) deleteHandlersIter.next(); + if (!handler.canDelete(absoluteRow)) { + return false; + } + } + for (Iterator deleteHandlersIter = parent.deleteHandlers.iterator(); deleteHandlersIter + .hasNext();) { + IDeleteHandler handler = (IDeleteHandler) deleteHandlersIter.next(); + handler.deleteRow(absoluteRow); + } + return true; + } + + private void fireRowDeletedEvent() { + int absoluteRow = topRow + currentRow; + for (Iterator deleteHandlersIter = parent.deleteHandlers.iterator(); deleteHandlersIter + .hasNext();) { + IDeleteHandler handler = (IDeleteHandler) deleteHandlersIter.next(); + handler.rowDeleted(absoluteRow); + } + } + + /** + * Request that the model insert a new row into itself. + * + * @return The 0-based offset of the new row from the start of the + * collection or -1 if a new row could not be inserted. + */ + private int fireInsertEvent() { + if (parent.insertHandlers.size() < 1) { + return -1; + } + + for (Iterator insertHandlersIter = parent.insertHandlers.iterator(); insertHandlersIter + .hasNext();) { + IInsertHandler handler = (IInsertHandler) insertHandlersIter.next(); + int resultRow = handler.insert(topRow + currentRow); + if (resultRow >= 0) { + return resultRow; + } + } + + return -1; + } + + /** + * Tell listeners that we just scrolled. + * @param scrollEvent TODO + */ + private void fireScrollEvent(ScrollEvent scrollEvent) { + if (parent.scrollListeners.size() < 1) { + return; + } + + for (Iterator scrollListenersIter = parent.scrollListeners.iterator(); scrollListenersIter.hasNext();) { + ScrollListener scrollListener = (ScrollListener) scrollListenersIter.next(); + scrollListener.tableScrolled(scrollEvent); + } + } + + // Event Handling, utility methods + // ------------------------------------------------------------ + + /** + * Set the widget's selection to an empty selection. + * + * @param widget + * The widget to deselect + */ + private void deselect(Widget widget) { + if (DuckType.instanceOf(ISelectableRegionControl.class, widget)) { + ISelectableRegionControl control = (ISelectableRegionControl) DuckType + .implement(ISelectableRegionControl.class, widget); + control.setSelection(0, 0); + } + } + + /** + * Try to go to the next row in the collection. + */ + private void handleNextRowNavigation() { + if (currentRow < numRowsVisible - 1) { + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + deselect(getControl(currentColumn, currentRow)); + + deferredSetFocus(getControl(0, currentRow + 1), false); + } else { + if (topRow + numRowsVisible >= numRowsInCollection) { + // We're at the end; don't go anywhere + return; + } + // We have to scroll forwards + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + deselect(getControl(currentColumn, currentRow)); + + doSetTopRow(topRow + 1, currentRow); + deferredSetFocus(getControl(0, currentRow), true); + } + } + + /** + * Try to go to the previous row in the collection. + * + * @param row + * The current table row. + */ + private void handlePreviousRowNavigation(TableRow row) { + if (currentRow == 0) { + if (topRow == 0) { + // We're at the beginning of the table; don't go anywhere + return; + } + // We have to scroll backwards + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + deselect(getControl(currentColumn, currentRow)); + + doSetTopRow(topRow - 1, currentRow); + deferredSetFocus(getControl(row.getNumColumns() - 1, 0), true); + } else { + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + deselect(getControl(currentColumn, currentRow)); + + deferredSetFocus( + getControl(row.getNumColumns() - 1, currentRow - 1), false); + } + } + + /** + * Gets the current TableRow. + * + * @return the current TableRow + */ + private TableRow currentRow() { + if (currentRow < 0 || currentRow > rows.size() - 1) { + return null; + } + return (TableRow) rows.get(currentRow); + } + + /** + * Returns the SWT control corresponding to the current row. + * + * @return the current row control. + */ + public Control getCurrentRowControl() { + TableRow currentRow = currentRow(); + if (currentRow == null) { + return null; + } + return currentRow().getRowControl(); + } + + /** + * Method getRowControls. Returns an array of SWT controls where each + * control represents a row control in the CompositeTable's current scrolled + * position. If CompositeTable is resized, scrolled, such that the rows that + * the CompositeTable control is displaying change in any way, the array + * that is returned by this method will become out of date and need to be + * retrieved again. + * + * @return Control[] An array of SWT Control objects, each representing an + * SWT row object. + */ + public Control[] getRowControls() { + Control[] rowControls = new Control[rows.size()]; + for (int i = 0; i < rowControls.length; i++) { + rowControls[i] = getRowByNumber(i).getRowControl(); + } + return rowControls; + } + + private Menu menu = null; + + /* (non-Javadoc) + * @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu) + */ + public void setMenu(final Menu menu) { + this.menu = menu; + setMenuOnCollection(rows, menu); + setMenuOnCollection(spareRows, menu); + } + + private void setMenuOnCollection(LinkedList collection, Menu menu) { + for (Iterator rowsIter = collection.iterator(); rowsIter.hasNext();) { + TableRow row = (TableRow) rowsIter.next(); + row.getRowControl().setMenu(menu); + } + } + + + + /** + * Method getControlRow. Given a row control, returns its row number + * relative to the topRow. + * + * @param rowControl The row object to find + * @return The row number of the rowControl relative to the topRow (0-based) + * @throws IllegalArgumentException if rowControl is not currently visible + */ + public int getControlRow(Control rowControl) { + for (int row = 0; row < rows.size(); row++) { + if (getRowByNumber(row).getRowControl() == rowControl) { + return row; + } + } + throw new IllegalArgumentException("getControlRow passed a control that is not visible inside CompositeTable"); + } + + /** + * Method getControlRowObject. Given a row control, returns its row number + * relative to the topRow. + * + * @param rowControl The row object to find + * @return The row object managing the rowControl + * @throws IllegalArgumentException if rowControl is not currently visible + */ + public TableRow getControlRowObject(Control rowControl) { + for (Iterator rowsIter = rows.iterator(); rowsIter.hasNext();) { + TableRow row = (TableRow) rowsIter.next(); + if (row.getRowControl() == rowControl) { + return row; + } + } + throw new IllegalArgumentException("getControlRowObject passed a control that is not visible inside CompositeTable"); + } + + /** + * Returns the TableRow by the specified 0-based offset from the top visible + * row. + * + * @param rowNumber + * 0-based offset of the requested fow starting from the top + * visible row. + * @return The corresponding TableRow or null if there is none. + */ + private TableRow getRowByNumber(int rowNumber) { + if (rowNumber > rows.size() - 1 || rowNumber < 0) { + return null; + } + return (TableRow) rows.get(rowNumber); + } + + /** + * Return the SWT control at (column, row), where row is a 0-based number + * starting from the top visible row. + * + * @param column + * the 0-based column. + * @param row + * the 0-based row starting from the top visible row. + * @return the SWT control at (column, row) + */ + private Control getControl(int column, int row) { + TableRow rowObject = getRowByNumber(row); + if (rowObject == null) { + throw new IndexOutOfBoundsException("Request for a nonexistent row"); //$NON-NLS-1$ + } + Control result = rowObject.getColumnControl(column); + return result; + } + + /** + * Return the 0-based row number corresponding to a particular TableRow + * object. + * + * @param row + * The TableRow to translate to row coordinates. + * @return the 0-based row number or -1 if the specified TableRow is not + * visible. + */ + private int getRowNumber(TableRow row) { + int rowNumber = 0; + for (Iterator rowIter = rows.iterator(); rowIter.hasNext();) { + TableRow candidate = (TableRow) rowIter.next(); + if (candidate == row) { + return rowNumber; + } + ++rowNumber; + } + return -1; + } + + /** + * Set the focus to the specified (column, row). If rowChange is true, fire + * a row change event, otherwise be silent. + * + * @param column + * The 0-based column to focus + * @param row + * The 0-based row to focus + * @param rowChange + * true if a row change event should be fired; false otherwise. + */ + private void internalSetSelection(int column, int row, boolean rowChange) { + Control toFocus = getControl(column, row); + if (toFocus == null) { + return; + } + if (toFocus.isFocusControl()) { + toFocus.notifyListeners(SWT.FocusIn, new Event()); + } else { + deferredSetFocus(toFocus, rowChange); + } + } + + /** + * Set the focus to the specified control after allowing all pending events + * to complete first. If rowChange is true, fire a row arrive event after + * the focus has been set. + * + * @param toFocus + * The SWT Control to focus + * @param rowChange + * true if the rowArrive event should be fired; false otherwise. + */ + private void deferredSetFocus(final Control toFocus, final boolean rowChange) { + if (toFocus == null) { + return; + } + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (toFocus.isDisposed()) return; + toFocus.setFocus(); + if (rowChange) { + fireRowArriveEvent(); + } + } + }); + } + + public void doFocusInitialRow() { + if (topRow <= 0) { + return; + } + + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + Widget widget = getDisplay().getFocusControl(); + deselect(widget); // Used to be e.widget + + // If the focus is already in the top visible row, we will need + // to explicitly + // fire an arrive event. + boolean needToArrive = true; + if (currentRow > 0) { + needToArrive = false; + } + + doSetTopRow(0, currentRow); + + if (needToArrive) { + internalSetSelection(currentColumn, 0, true); + } else { + internalSetSelection(currentColumn, 0, false); + } + } + + public void doFocusLastRow() { + if (topRow + numRowsVisible < numRowsInCollection) { + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + Widget widget = getDisplay().getFocusControl(); + deselect(widget); // Used to be e.widget + + // If the focus is already in the last visible row, we will + // need to explicitly + // fire an arrive event. + boolean needToArrive = true; + if (currentRow < numRowsVisible - 1) { + needToArrive = false; + } + + doSetTopRow(numRowsInCollection - numRowsVisible, currentRow); + + if (needToArrive) { + internalSetSelection(currentColumn, numRowsVisible - 1, + true); + } else { + internalSetSelection(currentColumn, numRowsVisible - 1, + false); + } + } + } + + public void doPageUp() { + if (topRow > 0) { + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + int newTopRow = topRow - numRowsInDisplay; + if (newTopRow < 0) { + newTopRow = 0; + } + doSetTopRow(newTopRow, 0); + internalSetSelection(currentColumn, currentRow, true); + } + } + + public void doPageDown() { + if (topRow + numRowsVisible < numRowsInCollection) { + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + int newTopRow = topRow + numRowsVisible; + if (newTopRow >= numRowsInCollection - 1) { + newTopRow = numRowsInCollection - 1; + } + doSetTopRow(newTopRow, numRowsVisible - 1); + internalSetSelection(currentColumn, currentRow, true); + } + } + + public void doRowUp() { + if (maxRowsVisible <= 1) + return; + + if (currentRow > 0) { + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + Widget widget = getDisplay().getFocusControl(); + deselect(widget); // Used to be e.widget + + internalSetSelection(currentColumn, currentRow - 1, false); + return; + } + if (topRow > 0) { + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + Widget widget = getDisplay().getFocusControl(); + deselect(widget); // Used to be e.widget + + doSetTopRow(topRow - 1, currentRow); + internalSetSelection(currentColumn, currentRow, true); + return; + } + } + + public void doRowDown() { + if (maxRowsVisible <= 1) + return; + + if (currentRow < numRowsVisible - 1) { + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + Widget widget = getDisplay().getFocusControl(); + deselect(widget); // Used to be e.widget + + internalSetSelection(currentColumn, currentRow + 1, false); + return; + } + if (topRow + numRowsVisible < numRowsInCollection) { + if (!fireRequestRowChangeEvent()) { + return; + } + needToRequestRC = false; + + Widget widget = getDisplay().getFocusControl(); + deselect(widget); // Used to be e.widget + + doSetTopRow(topRow + 1, currentRow); + internalSetSelection(currentColumn, currentRow, true); + return; + } + } + + public boolean doInsertRow() { + // If no insertHandler has been registered, bail out + if (parent.insertHandlers.size() < 1) { + return false; + } + + // Make sure we can leave the current row + if (!fireRequestRowChangeEvent()) { + return false; + } + needToRequestRC = false; + + // Insert the new object + int newRowPosition = fireInsertEvent(); + if (newRowPosition < 0) { + // This should never happen, but... + throw new IllegalArgumentException("Insert < row 0???"); + } + + disposeEmptyTablePlaceholder(); + + // If the current widget has a selection, deselect it + Widget widget = getDisplay().getFocusControl(); + deselect(widget); // Used to be e.widget + + // If the new row is in the visible space, refresh it + if (topRow <= newRowPosition + && numRowsVisible > newRowPosition - topRow) { + insertRowAt(newRowPosition - topRow); + ++numRowsInCollection; + updateVisibleRows(); + int newRowNumber = newRowPosition - topRow; + if (newRowNumber != currentRow) { + internalSetSelection(currentColumn, newRowNumber, false); + } else { + internalSetSelection(currentColumn, newRowNumber, true); + } + return true; + } + + // else... + + ++numRowsInCollection; + + // If the new row is above us, scroll up to it + if (newRowPosition < topRow + currentRow) { + doSetTopRow(newRowPosition, currentRow); + Display.getDefault().asyncExec(new Runnable() { + public void run() { + updateVisibleRows(); + if (currentRow != 0) { + internalSetSelection(currentColumn, 0, false); + } else { + internalSetSelection(currentColumn, 0, true); + } + } + }); + } else { + // If we're appending + if (numRowsInDisplay > numRowsVisible) { + updateVisibleRows(); + int newRowNumber = newRowPosition - topRow; + if (newRowNumber != currentRow) { + internalSetSelection(currentColumn, newRowNumber, + false); + } else { + internalSetSelection(currentColumn, newRowNumber, + true); + } + } else { + // It's somewhere in the middle below us; scroll down to + // it + doSetTopRow(newRowPosition - numRowsVisible + 1, currentRow); + int newRowNumber = numRowsVisible - 1; + if (newRowNumber != currentRow) { + internalSetSelection(currentColumn, newRowNumber, + false); + } else { + internalSetSelection(currentColumn, newRowNumber, + true); + } + } + } + return false; + } + + public boolean doDeleteRow() { + if (fireDeleteEvent()) { + // We know the object is gone if we made it here, so now + // refresh the display... + --numRowsInCollection; + + // If we deleted the last row in the list + if (currentRow >= numRowsVisible - 1) { + // If that wasn't the last row in the collection, move + // the focus + if (numRowsInCollection > 0) { + + // If we're only displaying one row, scroll first + if (currentRow < 1) { + needToRequestRC = false; + deleteRowAt(currentRow); + doSetTopRow(topRow - 1, currentRow); + internalSetSelection(currentColumn, currentRow, + true); + } else { + needToRequestRC = false; + internalSetSelection(currentColumn, + currentRow - 1, false); + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + deleteRowAt(currentRow + 1); + updateVisibleRows(); + } + }); + } + } else { + // Otherwise, show the placeholder object and give + // it focus + deleteRowAt(currentRow); + --numRowsVisible; + createEmptyTablePlaceholer(); + emptyTablePlaceholder.setFocus(); + currentRow = -1; + } + } else { + // else, keep the focus where it was + deleteRowAt(currentRow); + updateVisibleRows(); + internalSetSelection(currentColumn, currentRow, true); + } + fireRowDeletedEvent(); + } + return false; + } + + } \ No newline at end of file diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/ResizableGridRowLayout.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/ResizableGridRowLayout.java index d79485648..f9130fd87 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/ResizableGridRowLayout.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/ResizableGridRowLayout.java @@ -1,189 +1,189 @@ -package org.eclipse.nebula.widgets.compositetable; - -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Widget; - -/** - * ResizableGridRowLayout works with HeaderLayout to implement column resizing - * semantics for CompositeTable UIs. - *

- * Use a ResizableGridRowLayout when you have used a ResizableGridHeaderLayout - * on the Header object. ResizableGridRowLayout gets all of its layout settings - * from the ResizableGridHeaderLayout object, so there is no need to set any - * additional layout information on the ResizableGridRowLayout itself. - * - * @author djo - */ -public class ResizableGridRowLayout extends GridRowLayout { - - private AbstractGridRowLayout delegate = null; - private int[] columnOrder; - private Composite control; - - /** - * Constructor ResizableGridRowLayout. Create a ResizableGridRowLayout - * object. Since a ResizableGridRowLayout object will automatically find - * the associated HeaderLayout, no properties need to be set on a - * ResizableGridRowLayout. - */ - public ResizableGridRowLayout() {} - - protected Point computeSize(Composite composite, int wHint, int hHint, - boolean flushCache) { - this.control = composite; - getLayoutDelegate(composite); - return super.computeSize(composite, wHint, hHint, flushCache); - } - - protected void layout(Composite composite, boolean flushCache) { - this.control = composite; - getLayoutDelegate(composite); - super.layout(composite, flushCache); - } - - public int[] getWeights() { - if (delegate == null) { - return super.getWeights(); - } - return delegate.getWeights(); - } - - public AbstractGridRowLayout setWeights(int[] weights) { - if (delegate == null) { - return super.setWeights(weights); - } - return delegate.setWeights(weights); - } - - public int getSumOfAllWeights() { - if (delegate == null) { - return super.getSumOfAllWeights(); - } - return delegate.getSumOfAllWeights(); - } - - public boolean isFittingHorizontally() { - if (delegate == null) { - return super.isFittingHorizontally(); - } - return delegate.isFittingHorizontally(); - } - - public AbstractGridRowLayout setFittingHorizontally(boolean fittingHorizontally) { - if (delegate == null) { - return super.setFittingHorizontally(fittingHorizontally); - } - return delegate.setFittingHorizontally(fittingHorizontally); - } - - protected Widget getColumnAt(Composite rowOrHeader, int offset) { - if (columnOrder == null) { - return super.getColumnAt(rowOrHeader, offset); - } - Control[] children = rowOrHeader.getChildren(); - return children[columnOrder[offset]]; - } - - private CompositeTableLayout getLayoutDelegate(Composite composite) { - if (delegate != null) return delegate; - - findHeader(composite); - if (delegate != null) { - return delegate; - } - createNullLayout(composite); - return delegate; - } - - private void createNullLayout(Composite composite) { - int numChildren = composite.getChildren().length; - delegate = new GridRowLayout(new int[numChildren], true); - } - - private void findHeader(Composite row) { - Control[] children = row.getParent().getChildren(); - for (int i = 0; i < children.length; i++) { - if (children[i] instanceof Composite) { - Composite child = (Composite) children[i]; - Layout layout = child.getLayout(); - - if (layout instanceof HeaderLayout) { - delegate = (HeaderLayout) layout; - addListenersToDelegate(row, (HeaderLayout) layout); - return; - } - } - } - } - - private void addListenersToDelegate(Composite row, HeaderLayout delegate) { - delegate.addColumnControlListener(new GridColumnControlListener(row)); - } - - private class GridColumnControlListener extends ColumnControlListener { - private final Composite row; - - private int savedResizedColNum; - private int savedResizedColWidth; - private int savedColToRightOfResizedColWidth; - boolean runnableQueueIsClear = true; - - public GridColumnControlListener(Composite row) { - this.row = row; - } - public void columnMoved(int[] newColumnOrder) { - ResizableGridRowLayout.this.columnOrder = newColumnOrder; - control.layout(true); - } - public void columnResized(int resizedColumnPosition, - int resizedColumnWidth, - int columnToTheRightOfResizedColumnWidth) - { - /* - * FEATURE IN WINDOWS: If we resize the row immediately, Windows - * won't allow the row to repaint, resulting in cheese (ugly - * draw artifacts) all over the place until the user releases the - * mouse button. The workaround is to resize the row columns in the - * next idle event during an async runnable. Since this code will - * run on every mouseMove event, we are careful to queue at most one - * async runnable at a time. - */ - this.savedResizedColNum = resizedColumnPosition; - this.savedResizedColWidth = resizedColumnWidth; - this.savedColToRightOfResizedColWidth = columnToTheRightOfResizedColumnWidth; - - if (runnableQueueIsClear) { - runnableQueueIsClear = false; - row.getDisplay().asyncExec(new Runnable() { - public void run() { - if (row.isDisposed()) return; - - Control[] children = row.getChildren(); - - Control resizedColumn = (Control) getColumnAt(row, savedResizedColNum); - // Control resizedColumn = children[savedResizedColNum]; - Point resizedColumnSize = resizedColumn.getSize(); - int adjustedResizedColumnWidth = savedResizedColWidth - 2 * - CELL_BORDER_WIDTH; - int resizedColumnWidthChange = adjustedResizedColumnWidth - - resizedColumnSize.x; - resizedColumn.setSize(adjustedResizedColumnWidth, - resizedColumnSize.y); - Control columnToTheRightOfResizedColumn = (Control) getColumnAt(row, savedResizedColNum+1); - // Control columnToTheRightOfResizedColumn = children[savedResizedColNum + 1]; - Rectangle rightBounds = columnToTheRightOfResizedColumn.getBounds(); - columnToTheRightOfResizedColumn.setBounds(rightBounds.x - + resizedColumnWidthChange, rightBounds.y, - savedColToRightOfResizedColWidth, - rightBounds.height); - runnableQueueIsClear = true; - } - }); - } - } - }; -} +package org.eclipse.nebula.widgets.compositetable; + +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Widget; + +/** + * ResizableGridRowLayout works with HeaderLayout to implement column resizing + * semantics for CompositeTable UIs. + *

+ * Use a ResizableGridRowLayout when you have used a ResizableGridHeaderLayout + * on the Header object. ResizableGridRowLayout gets all of its layout settings + * from the ResizableGridHeaderLayout object, so there is no need to set any + * additional layout information on the ResizableGridRowLayout itself. + * + * @author djo + */ +public class ResizableGridRowLayout extends GridRowLayout { + + private AbstractGridRowLayout delegate = null; + private int[] columnOrder; + private Composite control; + + /** + * Constructor ResizableGridRowLayout. Create a ResizableGridRowLayout + * object. Since a ResizableGridRowLayout object will automatically find + * the associated HeaderLayout, no properties need to be set on a + * ResizableGridRowLayout. + */ + public ResizableGridRowLayout() {} + + protected Point computeSize(Composite composite, int wHint, int hHint, + boolean flushCache) { + this.control = composite; + getLayoutDelegate(composite); + return super.computeSize(composite, wHint, hHint, flushCache); + } + + protected void layout(Composite composite, boolean flushCache) { + this.control = composite; + getLayoutDelegate(composite); + super.layout(composite, flushCache); + } + + public int[] getWeights() { + if (delegate == null) { + return super.getWeights(); + } + return delegate.getWeights(); + } + + public AbstractGridRowLayout setWeights(int[] weights) { + if (delegate == null) { + return super.setWeights(weights); + } + return delegate.setWeights(weights); + } + + public int getSumOfAllWeights() { + if (delegate == null) { + return super.getSumOfAllWeights(); + } + return delegate.getSumOfAllWeights(); + } + + public boolean isFittingHorizontally() { + if (delegate == null) { + return super.isFittingHorizontally(); + } + return delegate.isFittingHorizontally(); + } + + public AbstractGridRowLayout setFittingHorizontally(boolean fittingHorizontally) { + if (delegate == null) { + return super.setFittingHorizontally(fittingHorizontally); + } + return delegate.setFittingHorizontally(fittingHorizontally); + } + + protected Widget getColumnAt(Composite rowOrHeader, int offset) { + if (columnOrder == null) { + return super.getColumnAt(rowOrHeader, offset); + } + Control[] children = rowOrHeader.getChildren(); + return children[columnOrder[offset]]; + } + + private CompositeTableLayout getLayoutDelegate(Composite composite) { + if (delegate != null) return delegate; + + findHeader(composite); + if (delegate != null) { + return delegate; + } + createNullLayout(composite); + return delegate; + } + + private void createNullLayout(Composite composite) { + int numChildren = composite.getChildren().length; + delegate = new GridRowLayout(new int[numChildren], true); + } + + private void findHeader(Composite row) { + Control[] children = row.getParent().getChildren(); + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof Composite) { + Composite child = (Composite) children[i]; + Layout layout = child.getLayout(); + + if (layout instanceof HeaderLayout) { + delegate = (HeaderLayout) layout; + addListenersToDelegate(row, (HeaderLayout) layout); + return; + } + } + } + } + + private void addListenersToDelegate(Composite row, HeaderLayout delegate) { + delegate.addColumnControlListener(new GridColumnControlListener(row)); + } + + private class GridColumnControlListener extends ColumnControlListener { + private final Composite row; + + private int savedResizedColNum; + private int savedResizedColWidth; + private int savedColToRightOfResizedColWidth; + boolean runnableQueueIsClear = true; + + public GridColumnControlListener(Composite row) { + this.row = row; + } + public void columnMoved(int[] newColumnOrder) { + ResizableGridRowLayout.this.columnOrder = newColumnOrder; + control.layout(true); + } + public void columnResized(int resizedColumnPosition, + int resizedColumnWidth, + int columnToTheRightOfResizedColumnWidth) + { + /* + * FEATURE IN WINDOWS: If we resize the row immediately, Windows + * won't allow the row to repaint, resulting in cheese (ugly + * draw artifacts) all over the place until the user releases the + * mouse button. The workaround is to resize the row columns in the + * next idle event during an async runnable. Since this code will + * run on every mouseMove event, we are careful to queue at most one + * async runnable at a time. + */ + this.savedResizedColNum = resizedColumnPosition; + this.savedResizedColWidth = resizedColumnWidth; + this.savedColToRightOfResizedColWidth = columnToTheRightOfResizedColumnWidth; + + if (runnableQueueIsClear) { + runnableQueueIsClear = false; + row.getDisplay().asyncExec(new Runnable() { + public void run() { + if (row.isDisposed()) return; + + Control[] children = row.getChildren(); + + Control resizedColumn = (Control) getColumnAt(row, savedResizedColNum); + // Control resizedColumn = children[savedResizedColNum]; + Point resizedColumnSize = resizedColumn.getSize(); + int adjustedResizedColumnWidth = savedResizedColWidth - 2 * + CELL_BORDER_WIDTH; + int resizedColumnWidthChange = adjustedResizedColumnWidth + - resizedColumnSize.x; + resizedColumn.setSize(adjustedResizedColumnWidth, + resizedColumnSize.y); + Control columnToTheRightOfResizedColumn = (Control) getColumnAt(row, savedResizedColNum+1); + // Control columnToTheRightOfResizedColumn = children[savedResizedColNum + 1]; + Rectangle rightBounds = columnToTheRightOfResizedColumn.getBounds(); + columnToTheRightOfResizedColumn.setBounds(rightBounds.x + + resizedColumnWidthChange, rightBounds.y, + savedColToRightOfResizedColWidth, + rightBounds.height); + runnableQueueIsClear = true; + } + }); + } + } + }; +} diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/day/DayEditor.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/day/DayEditor.java index bea9af6ab..db865bffe 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/day/DayEditor.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/day/DayEditor.java @@ -1,1523 +1,1523 @@ -/******************************************************************************* - * Copyright (c) 2006 The Pampered Chef and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * The Pampered Chef - initial API and implementation - ******************************************************************************/ -package org.eclipse.nebula.widgets.compositetable.day; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import org.eclipse.nebula.widgets.compositetable.CompositeTable; -import org.eclipse.nebula.widgets.compositetable.IRowContentProvider; -import org.eclipse.nebula.widgets.compositetable.RowConstructionListener; -import org.eclipse.nebula.widgets.compositetable.ScrollEvent; -import org.eclipse.nebula.widgets.compositetable.ScrollListener; -import org.eclipse.nebula.widgets.compositetable.day.internal.DayEditorCalendarableItemControl; -import org.eclipse.nebula.widgets.compositetable.day.internal.EventLayoutComputer; -import org.eclipse.nebula.widgets.compositetable.day.internal.TimeSlice; -import org.eclipse.nebula.widgets.compositetable.day.internal.TimeSlot; -import org.eclipse.nebula.widgets.compositetable.timeeditor.AbstractEventEditor; -import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem; -import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableModel; -import org.eclipse.nebula.widgets.compositetable.timeeditor.EventContentProvider; -import org.eclipse.nebula.widgets.compositetable.timeeditor.EventCountProvider; -import org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.CLabel; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.FocusAdapter; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Menu; - -/** - * A DayEditor is an SWT control that can display events on a time line that can - * span one or more days. This class is not intended to be subclassed. - * - * @since 3.2 - */ -public class DayEditor extends AbstractEventEditor implements IEventEditor { - private CompositeTable compositeTable = null; - private CalendarableModel model = new CalendarableModel(); - private List recycledCalendarableEventControls = new LinkedList<>(); - protected TimeSlice daysHeader = null; - private final boolean headerDisabled; - private boolean showEventsWithPrecision = false; - - /** - * NO_HEADER constant. A style bit constant to indicate that no header should be - * displayed at the top of the editor window. - */ - public static final int NO_HEADER = SWT.NO_TRIM; - - /** - * Constructor DayEditor. Constructs a calendar control that can display events - * on one or more days. - * - * @param parent - * @param style - * DayEditor.NO_HEADER or SWT.NO_TRIM means not to display a header. - */ - public DayEditor(Composite parent, int style) { - super(parent, SWT.NULL); - if ((style & NO_HEADER) != 0) { - headerDisabled = true; - } else { - headerDisabled = false; - } - setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setTimeBreakdown(int, - * int) - */ - public void setTimeBreakdown(int numberOfDays, int numberOfDivisionsInHour) { - checkWidget(); - model.setTimeBreakdown(numberOfDays, numberOfDivisionsInHour); - - if (compositeTable != null) { - compositeTable.dispose(); - } - - createCompositeTable(numberOfDays, numberOfDivisionsInHour); - } - - /** - * This method initializes compositeTable - * - * @param numberOfDays - * The number of day columns to display - */ - private void createCompositeTable(final int numberOfDays, final int numberOfDivisionsInHour) { - - compositeTable = new CompositeTable(this, SWT.NONE); - if (background != null) { - compositeTable.setBackground(background); - } - compositeTable.setTraverseOnTabsEnabled(false); - - if (!headerDisabled) { - new TimeSlice(compositeTable, SWT.BORDER); // The prototype header - } - new TimeSlice(compositeTable, SWT.NONE); // The prototype row - - compositeTable.setNumRowsInCollection(computeNumRowsInCollection(numberOfDivisionsInHour)); - - compositeTable.addRowConstructionListener(new RowConstructionListener() { - @SuppressWarnings("unchecked") - public void headerConstructed(Control newHeader) { - daysHeader = (TimeSlice) newHeader; - daysHeader.setHeaderControl(true); - daysHeader.setNumberOfColumns(numberOfDays); - if (model.getStartDate() == null) { - return; - } - refreshColumnHeaders(daysHeader.getColumns()); - } - - public void rowConstructed(Control newRow) { - TimeSlice timeSlice = (TimeSlice) newRow; - timeSlice.setNumberOfColumns(numberOfDays); - timeSlice.addCellFocusListener(cellFocusListener); - timeSlice.addKeyListener(keyListener); - timeSlice.addMouseListener(cellMouseListener); - } - }); - compositeTable.addRowContentProvider(new IRowContentProvider() { - public void refresh(CompositeTable sender, int currentObjectOffset, Control row) { - TimeSlice timeSlice = (TimeSlice) row; - refreshRow(currentObjectOffset, timeSlice); - } - }); - compositeTable.addScrollListener(new ScrollListener() { - public void tableScrolled(ScrollEvent scrollEvent) { - layoutEventControls(); - } - }); - addControlListener(new ControlAdapter() { - public void controlResized(ControlEvent e) { - Rectangle bounds = DayEditor.this.getBounds(); - compositeTable.setBounds(0, 0, bounds.width, bounds.height); - layoutEventControlsDeferred(); - } - }); - - compositeTable.setRunTime(true); - } - - private Menu menu = null; - - /** - * @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu) - */ - @SuppressWarnings("unchecked") - public void setMenu(final Menu menu) { - checkWidget(); - Display.getCurrent().asyncExec(() -> { - if (isDisposed()) - return; - DayEditor.super.setMenu(menu); - DayEditor.this.menu = menu; - compositeTable.setMenu(menu); - setMenuOnCollection(recycledCalendarableEventControls, menu); - for (int day = 0; day < model.getNumberOfDays(); ++day) { - List calendarablesForDay = model.getCalendarableItems(day); - setMenuOnCollection(calendarablesForDay, menu); - } - }); - } - - private void setMenuOnCollection(List collection, Menu menu) { - for (Iterator controls = collection.iterator(); controls.hasNext();) { - ICalendarableItemControl control = controls.next(); - control.setMenu(menu); - } - } - - private ArrayList keyListeners = new ArrayList<>(); - - /** - * @see org.eclipse.swt.widgets.Control#addKeyListener(org.eclipse.swt.events.KeyListener) - */ - public void addKeyListener(KeyListener listener) { - checkWidget(); - keyListeners.add(listener); - } - - /** - * @see org.eclipse.swt.widgets.Control#removeKeyListener(org.eclipse.swt.events.KeyListener) - */ - public void removeKeyListener(KeyListener listener) { - checkWidget(); - keyListeners.remove(listener); - } - - private KeyListener keyListener = new KeyAdapter() { - public void keyReleased(KeyEvent e) { - for (Iterator i = keyListeners.iterator(); i.hasNext();) { - KeyListener keyListener = i.next(); - keyListener.keyReleased(e); - if (!e.doit) - return; - } - } - - public void keyPressed(KeyEvent e) { - for (Iterator i = keyListeners.iterator(); i.hasNext();) { - KeyListener keyListener = i.next(); - keyListener.keyPressed(e); - if (!e.doit) - return; - } - CalendarableItem selection = selectedCalendarable; - int selectedRow; - int selectedDay; - boolean allDayEventRowSelected = false; - int compositeTableRow = compositeTable.getSelection().y + compositeTable.getTopRow(); - if (compositeTableRow < numberOfAllDayEventRows) { - allDayEventRowSelected = true; - } - - if (selection == null) { - selectedRow = convertViewportRowToDayRow(compositeTable.getCurrentRow()); - selectedDay = compositeTable.getCurrentColumn(); - } else { - selectedDay = model.getDay(selection); - if (allDayEventRowSelected) { - selectedRow = compositeTableRow; - } else { - Point selectedCoordinates = selection.getUpperLeftPositionInDayRowCoordinates(); - if (selectedCoordinates == null) { - return; - } - selectedRow = selectedCoordinates.y; - } - } - - switch (e.character) { - case SWT.TAB: - if ((e.stateMask & SWT.SHIFT) != 0) { - CalendarableItem newSelection = model.findPreviousCalendarable(selectedDay, selectedRow, selection, - allDayEventRowSelected); - if (newSelection == null) { - // There was only 0 or one visible event--nothing to scroll to - return; - } - int newTopRow = computeNewTopRowBasedOnSelection(newSelection); - if (newTopRow != compositeTable.getTopRow()) { - compositeTable.setTopRow(newTopRow); - } - setSelection(newSelection); - } else { - CalendarableItem newSelection = model.findNextCalendarable(selectedDay, selectedRow, selection, - allDayEventRowSelected); - if (newSelection == null) { - // There was only 0 or one visible event--nothing to scroll to - return; - } - int newTopRow = computeNewTopRowBasedOnSelection(newSelection); - if (newTopRow != compositeTable.getTopRow()) { - compositeTable.setTopRow(newTopRow); - } - setSelection(newSelection); - } - } - } - }; - - private ArrayList mouseListeners = new ArrayList<>(); - - /* - * (non-Javadoc) - * - * @see org.eclipse.swt.widgets.Control#addMouseListener(org.eclipse.swt.events. - * MouseListener) - */ - public void addMouseListener(MouseListener listener) { - checkWidget(); - mouseListeners.add(listener); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.widgets.Control#removeMouseListener(org.eclipse.swt.events. - * MouseListener) - */ - public void removeMouseListener(MouseListener listener) { - checkWidget(); - mouseListeners.remove(listener); - } - - private MouseListener cellMouseListener = new MouseListener() { - public void mouseDoubleClick(MouseEvent e) { - fireMouseDoubleClickEvent(e); - } - - public void mouseDown(MouseEvent e) { - fireMouseDownEvent(e); - } - - public void mouseUp(MouseEvent e) { - fireMouseUpEvent(e); - } - }; - - protected void fireMouseDownEvent(MouseEvent e) { - for (Iterator i = mouseListeners.iterator(); i.hasNext();) { - MouseListener mouseListener = i.next(); - mouseListener.mouseDown(e); - } - } - - protected void fireMouseUpEvent(MouseEvent e) { - for (Iterator i = mouseListeners.iterator(); i.hasNext();) { - MouseListener mouseListener = i.next(); - mouseListener.mouseUp(e); - } - } - - protected void fireMouseDoubleClickEvent(MouseEvent e) { - for (Iterator i = mouseListeners.iterator(); i.hasNext();) { - MouseListener mouseListener = i.next(); - mouseListener.mouseDoubleClick(e); - } - } - - private int computeNewTopRowBasedOnSelection(CalendarableItem newSelection) { - int topRow = compositeTable.getTopRow(); - int numberOfRowsInDisplay = compositeTable.getNumRowsVisible(); - int newTopRow = topRow; - - Point endRowPoint = newSelection.getLowerRightPositionInDayRowCoordinates(); - if (endRowPoint != null) { - int endRow = convertDayRowToViewportCoordinates(endRowPoint.y); - if (endRow >= newTopRow + numberOfRowsInDisplay) { - newTopRow += (endRow - (newTopRow + numberOfRowsInDisplay)) + 1; - } - int startRow = newSelection.getUpperLeftPositionInDayRowCoordinates().y; - startRow = convertDayRowToViewportCoordinates(startRow); - if (startRow < newTopRow) { - newTopRow = startRow; - } - } - return newTopRow; - } - - private boolean selectCalendarableControlOnSetFocus = true; - - private FocusListener cellFocusListener = new FocusAdapter() { - public void focusGained(FocusEvent e) { - TimeSlice sendingRow = (TimeSlice) ((Composite) e.widget).getParent(); - int day = sendingRow.getControlColumn(e.widget); - int row = compositeTable.getControlRow(sendingRow); - if (selectCalendarableControlOnSetFocus) { - setSelectionByDayAndRow(day, row, null); - } else { - selectCalendarableControlOnSetFocus = true; - } - } - }; - - private void setSelectionByDayAndRow(int day, int row, CalendarableItem aboutToSelect) { - int dayRow = convertViewportRowToDayRow(row); - if (aboutToSelect == null && dayRow >= 0) - aboutToSelect = getFirstCalendarableAt(day, dayRow); - if (aboutToSelect == null || dayRow < 0) { - aboutToSelect = getAllDayCalendarableAt(day, row + compositeTable.getTopRow()); - } - selectCalenderableControl(aboutToSelect); - aboutToSelect = null; - } - - /** - * (non-API) Method getFirstCalendarableAt. Finds the calendarable event at the - * specified day/row in DayRow coordinates. If no calendarable exists at the - * specified coordinates, does nothing. - * - * @param day - * The day offset - * @param row - * The row offset in DayRow coordinates - * @return the first Calendarable in the specified (day, row) or null if none. - */ - protected CalendarableItem getFirstCalendarableAt(int day, int row) { - CalendarableItem[][] eventLayout = model.getEventLayout(day); - CalendarableItem selectedCalendarable = null; - for (int column = 0; column < eventLayout.length; ++column) { - CalendarableItem calendarable = eventLayout[column][row]; - if (calendarable != null) { - if (selectedCalendarable == null) { - selectedCalendarable = calendarable; - } else if (calendarable.getStartTime().after(selectedCalendarable.getStartTime())) { - selectedCalendarable = calendarable; - } - } - } - return selectedCalendarable; - } - - /** - * Find the all day event that is positioned at the specified day and row in - * viewport coordinates - * - * @param day - * @param row - * @return The found Calendarable or null if none - */ - protected CalendarableItem getAllDayCalendarableAt(int day, int row) { - CalendarableItem[] allDayEvents = model.getAllDayCalendarables(day); - for (int allDayEventRow = 0; allDayEventRow < allDayEvents.length; allDayEventRow++) { - CalendarableItem candidate = allDayEvents[allDayEventRow]; - if (allDayEventRow == row) { - return candidate; - } - } - // int allDayEventRow = 0; - // for (Iterator calendarablesIter = - // model.getCalendarableEvents(day).iterator(); calendarablesIter.hasNext();) { - // Calendarable candidate = (Calendarable) calendarablesIter.next(); - // if (candidate.isAllDayEvent()) { - // if (allDayEventRow == row) { - // return candidate; - // } - // ++allDayEventRow; - // } - // } - return null; - } - - private CalendarableItem selectedCalendarable = null; - - /** - * Method selectCalendarable. Selects the specified Calendarable event. - * - * @param newSelection - * The Calendarable to select. - */ - public void setSelection(CalendarableItem newSelection) { - checkWidget(); - if (newSelection != null) { - int day = model.getDay(newSelection); - int row = computeRowForCalendarable(newSelection, day); - selectCalendarableControlOnSetFocus = false; - compositeTable.setSelection(day, row); - selectCalenderableControl(newSelection); - } else { - selectCalenderableControl(null); - } - } - - private void selectCalenderableControl(CalendarableItem newSelection) { - if (selectedCalendarable == newSelection) { - return; - } - if (selectedCalendarable != null) { - // The control could be null if it just got scrolled off the screen top or - // bottom - if (selectedCalendarable.getControl() != null) { - selectedCalendarable.getControl().setSelected(false); - } - } - - CalendarableItem oldSelection = selectedCalendarable; - selectedCalendarable = newSelection; - - if (newSelection != null && newSelection.getControl() != null) { - newSelection.getControl().setSelected(true); - } - fireSelectionChangeEvent(oldSelection, newSelection); - } - - /** - * Method getSelection. Returns the selection. This is computed as follows: - *

    - *
  1. If a CalendarableItem is currently selected, it is returned. - *
  2. If the selection rectangle is in an all-day event row, null is returned. - *
  3. Otherwise, the date/time corresponding to the selection rectangle is - * returned as a java.util.Date. - *
- * - * @return the current DayEditorSelection - */ - public DayEditorSelection getSelection() { - checkWidget(); - DayEditorSelection selection = new DayEditorSelection(); - Point compositeTableSelection = compositeTable.getSelection(); - - int visibleAllDayEventRows = model.computeNumberOfAllDayEventRows(); - visibleAllDayEventRows -= compositeTable.getTopRow(); - - if (selectedCalendarable != null) { - selection.setSelectedCalendarable(selectedCalendarable); - if (selectedCalendarable.isAllDayEvent()) { - selection.setAllDay(true); - } - } else { - if (visibleAllDayEventRows > 0) { - if (compositeTableSelection.y < visibleAllDayEventRows) { - selection.setAllDay(true); - } - } - } - selection.setDateTime(computeDateTimeFromViewportCoordinates(compositeTableSelection, visibleAllDayEventRows)); - return selection; - } - - private List selectionChangeListeners = new ArrayList<>(); - - private void fireSelectionChangeEvent(CalendarableItem currentSelection, CalendarableItem newSelection) { - SelectionChangeEvent sce = new SelectionChangeEvent(currentSelection, newSelection); - for (Iterator listenersIter = selectionChangeListeners - .iterator(); listenersIter.hasNext();) { - CalendarableSelectionChangeListener listener = listenersIter.next(); - listener.selectionChanged(sce); - } - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the receiver's selection changes, by sending it one of the messages defined - * in the CalendarableSelectionChangeListener interface. - *

- * selectionChanged is called when the selection changes. - *

- * - * @param listener - * the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- * - * @see CalendarableSelectionChangeListener - * @see #removeSelectionChangeListener - * @see SelectionChangeEvent - */ - public void addSelectionChangeListener(CalendarableSelectionChangeListener l) { - checkWidget(); - if (l == null) { - throw new IllegalArgumentException("The argument cannot be null"); - } - if (isDisposed()) { - throw new SWTException("Widget is disposed"); - } - selectionChangeListeners.add(l); - } - - private boolean fireEvents(CalendarableItem calendarableItem, List handlers) { - CalendarableItemEvent e = new CalendarableItemEvent(); - e.calendarableItem = calendarableItem; - for (Iterator iter = handlers.iterator(); iter.hasNext();) { - CalendarableItemEventHandler handler = iter.next(); - handler.handleRequest(e); - if (!e.doit) { - break; - } - } - for (Iterator i = handlers.iterator(); i.hasNext();) { - CalendarableItemEventHandler h = i.next(); - h.requestHandled(e); - if (!e.doit) { - break; - } - } - return e.doit; - } - - private List editHandlers = new ArrayList<>(); - - /** - * Fire the itemEdit event. - * - * @param toEdit - * The CalendarableItem to edit. - * @return true if the object represented by the CalendarableItem was changed; - * false otherwise. - */ - public boolean fireEdit(CalendarableItem toEdit) { - checkWidget(); - CalendarableItemEvent e = new CalendarableItemEvent(); - e.calendarableItem = toEdit; - boolean changed = fireEvents(e, editHandlers); - if (changed) { - // TODO: only refresh the days that are necessary - refresh(); - } - return changed; - } - - /** - * Adds the handler to the collection of handlers who will hand editing of - * calendarable events, by sending it one of the messages defined in the - * CalendarableItemInsertHandler abstract class. - *

- * itemInserted is called when the CalendarableItem is inserted. - *

- * - * @param handler - * the handler which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- * - * @see CalendarableItemInsertHandler - * @see #removeItemInsertHandler - */ - public void addItemEditHandler(CalendarableItemEventHandler handler) { - checkWidget(); - if (handler == null) { - throw new IllegalArgumentException("The argument cannot be null"); - } - if (isDisposed()) { - throw new SWTException("Widget is disposed"); - } - editHandlers.add(handler); - } - - /** - * Removes the handler from the collection of handlers who will hand editing of - * calendarable events, by sending it one of the messages defined in the - * CalendarableItemInsertHandler abstract class. - *

- * itemInserted is called when the CalendarableItem is inserted. - *

- * - * @param handler - * the handler which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- * - * @see CalendarableItemInsertHandler - * @see #removeItemInsertHandler - */ - public void removeItemEditHandler(CalendarableItemEventHandler handler) { - checkWidget(); - if (handler == null) { - throw new IllegalArgumentException("The argument cannot be null"); - } - if (isDisposed()) { - throw new SWTException("Widget is disposed"); - } - editHandlers.remove(handler); - } - - private List deleteHandlers = new ArrayList<>(); - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#fireDelete(org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem) - */ - public boolean fireDelete(CalendarableItem item) { - checkWidget(); - boolean result = fireEvents(item, deleteHandlers); - if (result) { - // TODO: Only refresh the affected days. - refresh(); - } - return result; - } - - /** - * Adds the handler to the collection of handlers who will be notified when a - * CalendarableItem is deleted from the receiver, by sending it one of the - * messages defined in the CalendarableItemEventHandler abstract - * class. - *

- * itemDeleted is called when the CalendarableItem is deleted. - *

- * - * @param handler - * the handler which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- * - * @see CalendarableItemEventHandler - * @see #removeDeleteItemHandler - */ - public void addItemDeleteHandler(CalendarableItemEventHandler handler) { - checkWidget(); - if (handler == null) { - throw new IllegalArgumentException("The argument cannot be null"); - } - if (isDisposed()) { - throw new SWTException("Widget is disposed"); - } - deleteHandlers.add(handler); - } - - /** - * Removes the handler from the collection of handlers who will be notified when - * a CalendarableItem is deleted from the receiver, by sending it one of the - * messages defined in the CalendarableItemEventHandler abstract - * class. - *

- * itemDeleted is called when the CalendarableItem is deleted. - *

- * - * @param handler - * the handler which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- * - * @see CalendarableItemEventHandler - * @see #addDeleteItemHandler - */ - public void removeItemDeleteHandler(CalendarableItemEventHandler handler) { - checkWidget(); - deleteHandlers.remove(handler); - } - - private List itemDisposeHandlers = new ArrayList<>(); - - private boolean fireDisposeItemStrategy(CalendarableItem item) { - return fireEvents(item, itemDisposeHandlers); - } - - /** - * Adds the handler to the collection of handler who will be notified when a - * CalendarableItem's control is disposed, by sending it one of the messages - * defined in the CalendarableItemEventHandler abstract class. This - * is normally used to remove any data bindings that may be attached to the - * (now-unused) CalendarableItem. - *

- * itemDeleted is called when the CalendarableItem is deleted. - *

- * - * @param handler - * the handler which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- * - * @see CalendarableItemEventHandler - * @see #removeCalendarableItemDisposeHandler - */ - public void addItemDisposeHandler(CalendarableItemEventHandler handler) { - checkWidget(); - if (handler == null) { - throw new IllegalArgumentException("The argument cannot be null"); - } - if (isDisposed()) { - throw new SWTException("Widget is disposed"); - } - itemDisposeHandlers.add(handler); - } - - /** - * Removes the handler from the collection of handlers who will be notified when - * a CalendarableItem is disposed, by sending it one of the messages defined in - * the CalendarableItemEventHandler abstract class. This is - * normally used to remove any data bindings that may be attached to the - * (now-unused) CalendarableItem. - *

- * itemDeleted is called when the CalendarableItem is deleted. - *

- * - * @param handler - * the handler which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- * - * @see CalendarableItemEventHandler - * @see #removeDeleteListener - */ - public void removeItemDisposeHandler(CalendarableItemEventHandler handler) { - checkWidget(); - itemDisposeHandlers.remove(handler); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the receiver's selection changes, by sending it one of the messages - * defined in the CalendarableSelectionChangeListener interface. - *

- * selectionChanged is called when the selection changes. - *

- * - * @param listener - * the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- * - * @see CalendarableSelectionChangeListener - * @see #addSelectionChangeListener - * @see SelectionChangeEvent - */ - public void removeSelectionChangeListener(CalendarableSelectionChangeListener l) { - checkWidget(); - if (l == null) { - throw new IllegalArgumentException("The argument cannot be null"); - } - if (isDisposed()) { - throw new SWTException("Widget is disposed"); - } - selectionChangeListeners.remove(l); - } - - /** - * @return Returns the defaultStartHour. - */ - public int getDefaultStartHour() { - return model.getDefaultStartHour(); - } - - /** - * @param defaultStartHour - * The defaultStartHour to set. - */ - public void setDefaultStartHour(int defaultStartHour) { - checkWidget(); - model.setDefaultStartHour(defaultStartHour); - updateVisibleRows(); - layoutEventControls(); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.examples.databinding.compositetable.timeeditor.IEventEditor - * #setDayEventCountProvider(org.eclipse.jface.examples.databinding. - * compositetable.timeeditor.EventCountProvider) - */ - public void setEventCountProvider(EventCountProvider eventCountProvider) { - checkWidget(); - model.setEventCountProvider(eventCountProvider); - updateVisibleRows(); - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (isDisposed()) - return; - layoutEventControls(); - } - }); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.jface.examples.databinding.compositetable.timeeditor.IEventEditor - * #setEventContentProvider(org.eclipse.jface.examples.databinding. - * compositetable.timeeditor.EventContentProvider) - */ - public void setEventContentProvider(EventContentProvider eventContentProvider) { - checkWidget(); - model.setEventContentProvider(eventContentProvider); - updateVisibleRows(); - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - if (isDisposed()) - return; - layoutEventControls(); - } - }); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setStartDate(java.util.Date) - */ - @SuppressWarnings("unchecked") - public void setStartDate(Date startDate) { - checkWidget(); - List removedDays = model.setStartDate(startDate); - computeEventRowsForNewDays(); - if (daysHeader != null) { - refreshColumnHeaders(daysHeader.getColumns()); - } - updateVisibleRows(); - freeObsoleteCalendarableEventControls((List) removedDays); - if (compositeTable.getNumRowsVisible() > 0) { - layoutEventControls(); - } - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getStartDate() - */ - public Date getStartDate() { - checkWidget(); - return model.getStartDate(); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#refresh(java.util.Date) - */ - public void refresh(Date date) { - checkWidget(); - computeLayoutFor(date); - layoutEventControls(); - } - - @SuppressWarnings("unchecked") - private void computeLayoutFor(Date date) { - List removedDays = model.refresh(date); - freeObsoleteCalendarableEventControls((List) removedDays); - updateVisibleRows(); - computeEventRowsForDate(date); - } - - private boolean refreshing = false; - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.AbstractEventEditor#refresh() - */ - public void refresh() { - checkWidget(); - if (!refreshing) { - refreshing = true; - Display.getCurrent().asyncExec(() -> { - if (isDisposed()) - return; - Date dateToRefresh = getStartDate(); - GregorianCalendar gc = new GregorianCalendar(); - gc.setTime(dateToRefresh); - for (int i = 0; i < getNumberOfDays(); ++i) { - computeLayoutFor(gc.getTime()); - gc.add(Calendar.DATE, 1); - } - layoutEventControls(); - refreshing = false; - }); - } - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getNumberOfDays() - */ - public int getNumberOfDays() { - checkWidget(); - return model.getNumberOfDays(); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getNumberOfDivisionsInHour() - */ - public int getNumberOfDivisionsInHour() { - checkWidget(); - return model.getNumberOfDivisionsInHour(); - } - - // Display Refresh logic here ---------------------------------------------- - - /* - * There are four main coordinate systems the refresh algorithm has to deal - * with: - * - * 1) Rows starting from midnight (the way the DayModel computes the layout). - * These are called Day Row coordinates. - * - * 2) Rows starting from the top visible row, taking into account all-day event - * rows. These are called Viewport Row coordinates - * - * 3) Pixel coordinates for each TimeSlot, relative to its parent TimeSlice (the - * CompositeTable row object) row. This is relevant because these are - * transformed into #4 in order to place CalendarableEventControls. - * - * 4) Pixel coordinates relative to the top left (the origin) of the entire - * DayEditor control. - */ - - private int numberOfAllDayEventRows = 0; - Calendar calendar = new GregorianCalendar(); - - private int computeNumRowsInCollection(final int numberOfDivisionsInHour) { - numberOfAllDayEventRows = model.computeNumberOfAllDayEventRows(); - return (DISPLAYED_HOURS - model.computeStartHour()) * numberOfDivisionsInHour + numberOfAllDayEventRows; - } - - private int convertViewportRowToDayRow(int row) { - int topRowOffset = compositeTable.getTopRow() - numberOfAllDayEventRows; - int startOfDayOffset = model.computeStartHour() * model.getNumberOfDivisionsInHour(); - return row + topRowOffset + startOfDayOffset; - } - - private int convertDayRowToViewportCoordinates(int row) { - row -= model.computeStartHour() * model.getNumberOfDivisionsInHour() - numberOfAllDayEventRows; - return row; - } - - private Date computeDateTimeFromViewportCoordinates(Point viewportSelection, int visibleAllDayEventRows) { - Date startDate = model.calculateDate(getStartDate(), viewportSelection.x); - GregorianCalendar calendar = new GregorianCalendar(); - calendar.setTime(startDate); - calendar.set(Calendar.HOUR_OF_DAY, model.computeHourFromRow(viewportSelection.y - visibleAllDayEventRows)); - calendar.set(Calendar.MINUTE, model.computeMinuteFromRow(viewportSelection.y - visibleAllDayEventRows)); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - return calendar.getTime(); - } - - /** - * @param calendarable - * @param day - * @return The row in DayRow coordinates - */ - private int computeRowForCalendarable(CalendarableItem calendarable, int day) { - int row = 0; - if (calendarable.isAllDayEvent()) { - CalendarableItem[] allDayEvents = model.getAllDayCalendarables(day); - for (int allDayEventRow = 0; allDayEventRow < allDayEvents.length; allDayEventRow++) { - if (allDayEvents[allDayEventRow] == calendarable) { - row = allDayEventRow - compositeTable.getTopRow(); - break; - } - } - } else { - // Convert to viewport coordinates - Point upperLeft = calendarable.getUpperLeftPositionInDayRowCoordinates(); - int topRowOffset = compositeTable.getTopRow() - numberOfAllDayEventRows; - int startOfDayOffset = model.computeStartHour() * model.getNumberOfDivisionsInHour(); - row = upperLeft.y - topRowOffset - startOfDayOffset; - if (row < 0) { - row = 0; - } - } - return row; - } - - /* - * Update the number of rows that are displayed inside the CompositeTable - * control - */ - private void updateVisibleRows() { - compositeTable.setNumRowsInCollection(computeNumRowsInCollection(getNumberOfDivisionsInHour())); - } - - private void refreshRow(int currentObjectOffset, TimeSlice timeSlice) { - // Decrement currentObjectOffset for each all-day event line we need. - for (int allDayEventRow = 0; allDayEventRow < numberOfAllDayEventRows; ++allDayEventRow) { - --currentObjectOffset; - } - - if (currentObjectOffset < 0) { - timeSlice.setCurrentTime(null); - } else { - calendar.set(Calendar.HOUR_OF_DAY, model.computeHourFromRow(currentObjectOffset)); - calendar.set(Calendar.MINUTE, model.computeMinuteFromRow(currentObjectOffset)); - timeSlice.setCurrentTime(calendar.getTime()); - } - } - - /** - * (non-API) Method initializeColumnHeaders. Called internally when the column - * header text needs to be updated. - * - * @param columns - * A LinkedList of CLabels representing the column objects - */ - protected void refreshColumnHeaders(LinkedList columns) { - Date startDate = getStartDate(); - GregorianCalendar gc = new GregorianCalendar(); - gc.setTime(startDate); - - SimpleDateFormat formatter = new SimpleDateFormat("EE, MMM d"); - formatter.applyLocalizedPattern(formatter.toLocalizedPattern()); - - for (Iterator iter = columns.iterator(); iter.hasNext();) { - CLabel headerLabel = iter.next(); - headerLabel.setText(formatter.format(gc.getTime())); - gc.add(Calendar.DATE, 1); - } - } - - private void freeObsoleteCalendarableEventControls(List removedCalendarables) { - for (Iterator removedCalendarablesIter = removedCalendarables - .iterator(); removedCalendarablesIter.hasNext();) { - CalendarableItem toRemove = removedCalendarablesIter.next(); - if (selectedCalendarable == toRemove) { - setSelection(null); - } - freeCalendarableControl(toRemove); - } - } - - private void computeEventRowsForDate(Date date) { - GregorianCalendar targetDate = new GregorianCalendar(); - targetDate.setTime(date); - GregorianCalendar target = new GregorianCalendar(); - target.setTime(model.getStartDate()); - EventLayoutComputer dayModel = new EventLayoutComputer(model.getNumberOfDivisionsInHour()); - for (int dayOffset = 0; dayOffset < model.getNumberOfDays(); ++dayOffset) { - if (target.get(Calendar.DATE) == targetDate.get(Calendar.DATE) - && target.get(Calendar.MONTH) == targetDate.get(Calendar.MONTH) - && target.get(Calendar.YEAR) == targetDate.get(Calendar.YEAR)) { - computeEventLayout(dayModel, dayOffset); - break; - } - target.add(Calendar.DATE, 1); - } - } - - private void computeEventRowsForNewDays() { - EventLayoutComputer dayModel = new EventLayoutComputer(model.getNumberOfDivisionsInHour()); - for (int dayOffset = 0; dayOffset < model.getNumberOfDays(); ++dayOffset) { - if (model.getNumberOfColumnsWithinDay(dayOffset) == -1) { - computeEventLayout(dayModel, dayOffset); - } - } - } - - @SuppressWarnings("unchecked") - private void computeEventLayout(EventLayoutComputer dayModel, int dayOffset) { - List events = model.getCalendarableItems(dayOffset); - CalendarableItem[][] eventLayout = dayModel.computeEventLayout(events); - model.setEventLayout(dayOffset, eventLayout); - } - - private void layoutEventControlsDeferred() { - if (getStartDate() == null) { - return; - } - refreshEventControlPositions.run(); - Display.getCurrent().asyncExec(refreshEventControlPositions); - } - - private void layoutEventControls() { - if (getStartDate() == null) { - return; - } - refreshEventControlPositions.run(); - } - - @SuppressWarnings("unchecked") - private Runnable refreshEventControlPositions = () -> { - if (isDisposed()) - return; - - Control[] gridRows = compositeTable.getRowControls(); - - for (int day = 0; day < model.getNumberOfDays(); ++day) { - int columnsWithinDay = model.getNumberOfColumnsWithinDay(day); - Point[] columnPositions = computeColumns(day, columnsWithinDay, gridRows); - - int allDayEventRow = 0; - - for (Iterator calendarablesIter = model.getCalendarableItems(day) - .iterator(); calendarablesIter.hasNext();) { - CalendarableItem calendarable = calendarablesIter.next(); - if (calendarable.isAllDayEvent()) { - layoutAllDayEvent(day, allDayEventRow, calendarable, gridRows); - ++allDayEventRow; - } else { - layoutTimedEvent(day, columnPositions, calendarable, gridRows); - } - } - } - }; - - protected Point[] computeColumns(int day, int numberOfColumns, Control[] gridRows) { - Point[] columns = new Point[numberOfColumns]; - Rectangle timeSliceBounds = getTimeSliceBounds(day, compositeTable.getTopRow(), gridRows); - timeSliceBounds.x += TimeSlot.TIME_BAR_WIDTH + 1; - timeSliceBounds.width -= TimeSlot.TIME_BAR_WIDTH + 2; - - int baseWidth = timeSliceBounds.width / numberOfColumns; - int extraWidth = timeSliceBounds.width % numberOfColumns; - - int startingPosition = timeSliceBounds.x; - for (int column = 0; column < columns.length; column++) { - int columnStart = startingPosition; - int columnWidth = baseWidth; - if (extraWidth > 0) { - ++columnWidth; - --extraWidth; - } - columns[column] = new Point(columnStart, columnWidth); - startingPosition += columnWidth; - } - return columns; - } - - private void fillControlData(CalendarableItem calendarable, int clippingStyle) { - calendarable.getControl().setText(calendarable.getText()); - calendarable.getControl().setToolTipText(calendarable.getToolTipText()); - calendarable.getControl().setClipping(clippingStyle); - } - - private DayEditorCalendarableItemControl getControl(CalendarableItem item) { - return (DayEditorCalendarableItemControl) item.getControl(); - } - - private void layoutAllDayEvent(int day, int allDayEventRow, CalendarableItem calendarable, Control[] gridRows) { - if (eventRowIsVisible(allDayEventRow)) { - createCalendarableControl(calendarable); - fillControlData(calendarable, SWT.NULL); - - Rectangle timeSliceBounds = getTimeSliceBounds(day, allDayEventRow, gridRows); - int gutterWidth = TimeSlot.TIME_BAR_WIDTH + 1; - timeSliceBounds.x += gutterWidth; - timeSliceBounds.width -= gutterWidth; - getControl(calendarable).setBounds(timeSliceBounds); - getControl(calendarable).moveAbove(compositeTable); - } else { - freeCalendarableControl(calendarable); - } - } - - private void layoutTimedEvent(int day, Point[] columnPositions, CalendarableItem calendarable, Control[] gridRows) { - int firstVisibleRow = model.computeStartHour() * model.getNumberOfDivisionsInHour(); - - int scrolledRows = compositeTable.getTopRow() - numberOfAllDayEventRows; - int visibleAllDayEventRows = 0; - if (scrolledRows < 0) { - visibleAllDayEventRows = -1 * scrolledRows; - scrolledRows = 0; - } - firstVisibleRow += scrolledRows; - int lastVisibleRow = firstVisibleRow + compositeTable.getNumRowsVisible() - visibleAllDayEventRows - 1; - - int startRow = calendarable.getUpperLeftPositionInDayRowCoordinates().y; - int endRow = calendarable.getLowerRightPositionInDayRowCoordinates().y; - - if (timedEventIsVisible(firstVisibleRow, lastVisibleRow, startRow, endRow)) { - int clippingStyle = SWT.NULL; - - if (startRow < firstVisibleRow) { - startRow = firstVisibleRow; - clippingStyle |= SWT.TOP; - } - - if (endRow > lastVisibleRow) { - endRow = lastVisibleRow; - clippingStyle |= SWT.BOTTOM; - } - - startRow = convertDayRowToViewportCoordinates(startRow); - endRow = convertDayRowToViewportCoordinates(endRow); - - createCalendarableControl(calendarable); - fillControlData(calendarable, clippingStyle); - - Rectangle startRowBounds = getTimeSliceBounds(day, startRow, gridRows); - Rectangle endRowBounds = getTimeSliceBounds(day, endRow, gridRows); - - int leftmostColumn = calendarable.getUpperLeftPositionInDayRowCoordinates().x; - int rightmostColumn = calendarable.getLowerRightPositionInDayRowCoordinates().x; - - int left = columnPositions[leftmostColumn].x; - int top = startRowBounds.y + 1; - int width = columnPositions[rightmostColumn].x - columnPositions[leftmostColumn].x - + columnPositions[rightmostColumn].y; - int height = endRowBounds.y - startRowBounds.y + endRowBounds.height - 1; - - Rectangle finalPosition = new Rectangle(left, top, width, height); - if (showEventsWithPrecision) { - int startRowDiff = startRowDiff(calendarable); - top += startRowDiff; - height += (endRowDiff(calendarable) - (startRowDiff)); - } - getControl(calendarable).setBounds(finalPosition); - getControl(calendarable).moveAbove(compositeTable); - } else { - freeCalendarableControl(calendarable); - } - } - - private int startRowDiff(CalendarableItem calendarable) { - Date d = calendarable.getStartTime(); - Calendar c = Calendar.getInstance(); - c.setTime(d); - return findRowDiff(calendarable, c, false);// add difference - } - - private int endRowDiff(CalendarableItem calendarable) { - Date d = calendarable.getEndTime(); - Calendar c = Calendar.getInstance(); - c.setTime(d); - // an extra row of padding is added to end if beyond FIRST division for the - // hour? - if (c.get(Calendar.MINUTE) > (60 / getNumberOfDivisionsInHour())) { - return findRowDiff(calendarable, c, true);// subtract difference - } - return findRowDiff(calendarable, c, false);// add difference - } - - /** - * For finding the pixel difference between filling the entire row, and filling - * only partially. Used For rendering more accurate & precise event durations. - * - * @param calendarable - * @param time - * @param subtractDiff - * set to true to subtract rather than add - * @return - */ - private int findRowDiff(CalendarableItem calendarable, Calendar time, boolean subtractDiff) { - int rowSize = compositeTable.getRowControl().getSize().y; - int min = time.get(Calendar.MINUTE); - double div = 60 / getNumberOfDivisionsInHour(); - double diff = min % div;// the number of partial minutes in a row - - if (subtractDiff) { - diff = -(div - diff); - } - - if (diff != 0) { - double i = ((diff) / (div)); - int in = (int) (i * rowSize); - return in; - } - return 0; - } - - private boolean eventRowIsVisible(int eventRow) { - int topRow = compositeTable.getTopRow(); - if (topRow <= eventRow) { - if (eventRow < compositeTable.getNumRowsVisible() - topRow) { - return true; - } - } - return false; - } - - private boolean timedEventIsVisible(int firstVisibleRow, int lastVisibleRow, int startRow, int endRow) { - if (startRow < firstVisibleRow && endRow < firstVisibleRow) - return false; - - if (startRow > lastVisibleRow && endRow > lastVisibleRow) - return false; - - return true; - } - - private void createCalendarableControl(CalendarableItem calendarable) { - if (calendarable.getControl() == null) { - calendarable.setControl(newCEC()); - if (calendarable == selectedCalendarable) { - calendarable.getControl().setSelected(true); - } - } - } - - private Rectangle getTimeSliceBounds(int day, int eventRow, Control[] gridRows) { - int row = eventRow - compositeTable.getTopRow(); - TimeSlice rowObject = (TimeSlice) gridRows[row]; - Control slot = rowObject.getColumnControl(day); - return getBoundsInDayEditorCoordinates(slot); - } - - private void freeCalendarableControl(CalendarableItem calendarableItem) { - if (calendarableItem.getControl() != null) { - freeCEC(getControl(calendarableItem)); - calendarableItem.setControl(null); - fireDisposeItemStrategy(calendarableItem); - } - } - - private Rectangle getBoundsInDayEditorCoordinates(Control slot) { - return Display.getCurrent().map(slot.getParent(), this, slot.getBounds()); - } - - // CalendarableItemControl construction/destruction here ----------------- - - MouseAdapter selectCompositeTableOnMouseDownAdapter = new MouseAdapter() { - /** - * @see org.eclipse.swt.events.MouseAdapter#mouseDown(org.eclipse.swt.events.MouseEvent) - */ - public void mouseDown(MouseEvent e) { - fireMouseDownEvent(e); - ICalendarableItemControl control = (ICalendarableItemControl) e.widget; - CalendarableItem aboutToSelect = control.getCalendarableItem(); - setSelection(aboutToSelect); - } - - /** - * @see org.eclipse.swt.events.MouseAdapter#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) - */ - public void mouseDoubleClick(MouseEvent e) { - fireMouseDoubleClickEvent(e); - } - - /** - * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent) - */ - public void mouseUp(MouseEvent e) { - fireMouseUpEvent(e); - } - }; - - private DayEditorCalendarableItemControl newCEC() { - if (recycledCalendarableEventControls.size() > 0) { - DayEditorCalendarableItemControl result = recycledCalendarableEventControls.remove(0); - result.setVisible(true); - return result; - } - DayEditorCalendarableItemControl dayEditorCalendarableItemControl = new DayEditorCalendarableItemControl(this, - SWT.NULL); - if (menu != null) { - dayEditorCalendarableItemControl.setMenu(menu); - } - dayEditorCalendarableItemControl.addMouseListener(selectCompositeTableOnMouseDownAdapter); - return dayEditorCalendarableItemControl; - } - - private void freeCEC(DayEditorCalendarableItemControl control) { - control.setSelected(false); - control.setCalendarableItem(null); - control.setVisible(false); - recycledCalendarableEventControls.add(control); - } - - private Color background = null; - - - /** - * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) - */ - public void setBackground(Color color) { - checkWidget(); - super.setBackground(color); - this.background = color; - if (compositeTable != null) { - compositeTable.setBackground(color); - } - } - - /** - * @see org.eclipse.swt.widgets.Composite#setFocus() - */ - public boolean setFocus() { - checkWidget(); - if (!compositeTable.setFocus()) { - return super.setFocus(); - } - return true; - } - - public void showEventsWithPrecision(boolean option) { - showEventsWithPrecision = option; - } - -} // @jve:decl-index=0:visual-constraint="10,10" +/******************************************************************************* + * Copyright (c) 2006 The Pampered Chef and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * The Pampered Chef - initial API and implementation + ******************************************************************************/ +package org.eclipse.nebula.widgets.compositetable.day; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.nebula.widgets.compositetable.CompositeTable; +import org.eclipse.nebula.widgets.compositetable.IRowContentProvider; +import org.eclipse.nebula.widgets.compositetable.RowConstructionListener; +import org.eclipse.nebula.widgets.compositetable.ScrollEvent; +import org.eclipse.nebula.widgets.compositetable.ScrollListener; +import org.eclipse.nebula.widgets.compositetable.day.internal.DayEditorCalendarableItemControl; +import org.eclipse.nebula.widgets.compositetable.day.internal.EventLayoutComputer; +import org.eclipse.nebula.widgets.compositetable.day.internal.TimeSlice; +import org.eclipse.nebula.widgets.compositetable.day.internal.TimeSlot; +import org.eclipse.nebula.widgets.compositetable.timeeditor.AbstractEventEditor; +import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem; +import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableModel; +import org.eclipse.nebula.widgets.compositetable.timeeditor.EventContentProvider; +import org.eclipse.nebula.widgets.compositetable.timeeditor.EventCountProvider; +import org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; + +/** + * A DayEditor is an SWT control that can display events on a time line that can + * span one or more days. This class is not intended to be subclassed. + * + * @since 3.2 + */ +public class DayEditor extends AbstractEventEditor implements IEventEditor { + private CompositeTable compositeTable = null; + private CalendarableModel model = new CalendarableModel(); + private List recycledCalendarableEventControls = new LinkedList<>(); + protected TimeSlice daysHeader = null; + private final boolean headerDisabled; + private boolean showEventsWithPrecision = false; + + /** + * NO_HEADER constant. A style bit constant to indicate that no header should be + * displayed at the top of the editor window. + */ + public static final int NO_HEADER = SWT.NO_TRIM; + + /** + * Constructor DayEditor. Constructs a calendar control that can display events + * on one or more days. + * + * @param parent + * @param style + * DayEditor.NO_HEADER or SWT.NO_TRIM means not to display a header. + */ + public DayEditor(Composite parent, int style) { + super(parent, SWT.NULL); + if ((style & NO_HEADER) != 0) { + headerDisabled = true; + } else { + headerDisabled = false; + } + setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setTimeBreakdown(int, + * int) + */ + public void setTimeBreakdown(int numberOfDays, int numberOfDivisionsInHour) { + checkWidget(); + model.setTimeBreakdown(numberOfDays, numberOfDivisionsInHour); + + if (compositeTable != null) { + compositeTable.dispose(); + } + + createCompositeTable(numberOfDays, numberOfDivisionsInHour); + } + + /** + * This method initializes compositeTable + * + * @param numberOfDays + * The number of day columns to display + */ + private void createCompositeTable(final int numberOfDays, final int numberOfDivisionsInHour) { + + compositeTable = new CompositeTable(this, SWT.NONE); + if (background != null) { + compositeTable.setBackground(background); + } + compositeTable.setTraverseOnTabsEnabled(false); + + if (!headerDisabled) { + new TimeSlice(compositeTable, SWT.BORDER); // The prototype header + } + new TimeSlice(compositeTable, SWT.NONE); // The prototype row + + compositeTable.setNumRowsInCollection(computeNumRowsInCollection(numberOfDivisionsInHour)); + + compositeTable.addRowConstructionListener(new RowConstructionListener() { + @SuppressWarnings("unchecked") + public void headerConstructed(Control newHeader) { + daysHeader = (TimeSlice) newHeader; + daysHeader.setHeaderControl(true); + daysHeader.setNumberOfColumns(numberOfDays); + if (model.getStartDate() == null) { + return; + } + refreshColumnHeaders(daysHeader.getColumns()); + } + + public void rowConstructed(Control newRow) { + TimeSlice timeSlice = (TimeSlice) newRow; + timeSlice.setNumberOfColumns(numberOfDays); + timeSlice.addCellFocusListener(cellFocusListener); + timeSlice.addKeyListener(keyListener); + timeSlice.addMouseListener(cellMouseListener); + } + }); + compositeTable.addRowContentProvider(new IRowContentProvider() { + public void refresh(CompositeTable sender, int currentObjectOffset, Control row) { + TimeSlice timeSlice = (TimeSlice) row; + refreshRow(currentObjectOffset, timeSlice); + } + }); + compositeTable.addScrollListener(new ScrollListener() { + public void tableScrolled(ScrollEvent scrollEvent) { + layoutEventControls(); + } + }); + addControlListener(new ControlAdapter() { + public void controlResized(ControlEvent e) { + Rectangle bounds = DayEditor.this.getBounds(); + compositeTable.setBounds(0, 0, bounds.width, bounds.height); + layoutEventControlsDeferred(); + } + }); + + compositeTable.setRunTime(true); + } + + private Menu menu = null; + + /** + * @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu) + */ + @SuppressWarnings("unchecked") + public void setMenu(final Menu menu) { + checkWidget(); + Display.getCurrent().asyncExec(() -> { + if (isDisposed()) + return; + DayEditor.super.setMenu(menu); + DayEditor.this.menu = menu; + compositeTable.setMenu(menu); + setMenuOnCollection(recycledCalendarableEventControls, menu); + for (int day = 0; day < model.getNumberOfDays(); ++day) { + List calendarablesForDay = model.getCalendarableItems(day); + setMenuOnCollection(calendarablesForDay, menu); + } + }); + } + + private void setMenuOnCollection(List collection, Menu menu) { + for (Iterator controls = collection.iterator(); controls.hasNext();) { + ICalendarableItemControl control = controls.next(); + control.setMenu(menu); + } + } + + private ArrayList keyListeners = new ArrayList<>(); + + /** + * @see org.eclipse.swt.widgets.Control#addKeyListener(org.eclipse.swt.events.KeyListener) + */ + public void addKeyListener(KeyListener listener) { + checkWidget(); + keyListeners.add(listener); + } + + /** + * @see org.eclipse.swt.widgets.Control#removeKeyListener(org.eclipse.swt.events.KeyListener) + */ + public void removeKeyListener(KeyListener listener) { + checkWidget(); + keyListeners.remove(listener); + } + + private KeyListener keyListener = new KeyAdapter() { + public void keyReleased(KeyEvent e) { + for (Iterator i = keyListeners.iterator(); i.hasNext();) { + KeyListener keyListener = i.next(); + keyListener.keyReleased(e); + if (!e.doit) + return; + } + } + + public void keyPressed(KeyEvent e) { + for (Iterator i = keyListeners.iterator(); i.hasNext();) { + KeyListener keyListener = i.next(); + keyListener.keyPressed(e); + if (!e.doit) + return; + } + CalendarableItem selection = selectedCalendarable; + int selectedRow; + int selectedDay; + boolean allDayEventRowSelected = false; + int compositeTableRow = compositeTable.getSelection().y + compositeTable.getTopRow(); + if (compositeTableRow < numberOfAllDayEventRows) { + allDayEventRowSelected = true; + } + + if (selection == null) { + selectedRow = convertViewportRowToDayRow(compositeTable.getCurrentRow()); + selectedDay = compositeTable.getCurrentColumn(); + } else { + selectedDay = model.getDay(selection); + if (allDayEventRowSelected) { + selectedRow = compositeTableRow; + } else { + Point selectedCoordinates = selection.getUpperLeftPositionInDayRowCoordinates(); + if (selectedCoordinates == null) { + return; + } + selectedRow = selectedCoordinates.y; + } + } + + switch (e.character) { + case SWT.TAB: + if ((e.stateMask & SWT.SHIFT) != 0) { + CalendarableItem newSelection = model.findPreviousCalendarable(selectedDay, selectedRow, selection, + allDayEventRowSelected); + if (newSelection == null) { + // There was only 0 or one visible event--nothing to scroll to + return; + } + int newTopRow = computeNewTopRowBasedOnSelection(newSelection); + if (newTopRow != compositeTable.getTopRow()) { + compositeTable.setTopRow(newTopRow); + } + setSelection(newSelection); + } else { + CalendarableItem newSelection = model.findNextCalendarable(selectedDay, selectedRow, selection, + allDayEventRowSelected); + if (newSelection == null) { + // There was only 0 or one visible event--nothing to scroll to + return; + } + int newTopRow = computeNewTopRowBasedOnSelection(newSelection); + if (newTopRow != compositeTable.getTopRow()) { + compositeTable.setTopRow(newTopRow); + } + setSelection(newSelection); + } + } + } + }; + + private ArrayList mouseListeners = new ArrayList<>(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.widgets.Control#addMouseListener(org.eclipse.swt.events. + * MouseListener) + */ + public void addMouseListener(MouseListener listener) { + checkWidget(); + mouseListeners.add(listener); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.widgets.Control#removeMouseListener(org.eclipse.swt.events. + * MouseListener) + */ + public void removeMouseListener(MouseListener listener) { + checkWidget(); + mouseListeners.remove(listener); + } + + private MouseListener cellMouseListener = new MouseListener() { + public void mouseDoubleClick(MouseEvent e) { + fireMouseDoubleClickEvent(e); + } + + public void mouseDown(MouseEvent e) { + fireMouseDownEvent(e); + } + + public void mouseUp(MouseEvent e) { + fireMouseUpEvent(e); + } + }; + + protected void fireMouseDownEvent(MouseEvent e) { + for (Iterator i = mouseListeners.iterator(); i.hasNext();) { + MouseListener mouseListener = i.next(); + mouseListener.mouseDown(e); + } + } + + protected void fireMouseUpEvent(MouseEvent e) { + for (Iterator i = mouseListeners.iterator(); i.hasNext();) { + MouseListener mouseListener = i.next(); + mouseListener.mouseUp(e); + } + } + + protected void fireMouseDoubleClickEvent(MouseEvent e) { + for (Iterator i = mouseListeners.iterator(); i.hasNext();) { + MouseListener mouseListener = i.next(); + mouseListener.mouseDoubleClick(e); + } + } + + private int computeNewTopRowBasedOnSelection(CalendarableItem newSelection) { + int topRow = compositeTable.getTopRow(); + int numberOfRowsInDisplay = compositeTable.getNumRowsVisible(); + int newTopRow = topRow; + + Point endRowPoint = newSelection.getLowerRightPositionInDayRowCoordinates(); + if (endRowPoint != null) { + int endRow = convertDayRowToViewportCoordinates(endRowPoint.y); + if (endRow >= newTopRow + numberOfRowsInDisplay) { + newTopRow += (endRow - (newTopRow + numberOfRowsInDisplay)) + 1; + } + int startRow = newSelection.getUpperLeftPositionInDayRowCoordinates().y; + startRow = convertDayRowToViewportCoordinates(startRow); + if (startRow < newTopRow) { + newTopRow = startRow; + } + } + return newTopRow; + } + + private boolean selectCalendarableControlOnSetFocus = true; + + private FocusListener cellFocusListener = new FocusAdapter() { + public void focusGained(FocusEvent e) { + TimeSlice sendingRow = (TimeSlice) ((Composite) e.widget).getParent(); + int day = sendingRow.getControlColumn(e.widget); + int row = compositeTable.getControlRow(sendingRow); + if (selectCalendarableControlOnSetFocus) { + setSelectionByDayAndRow(day, row, null); + } else { + selectCalendarableControlOnSetFocus = true; + } + } + }; + + private void setSelectionByDayAndRow(int day, int row, CalendarableItem aboutToSelect) { + int dayRow = convertViewportRowToDayRow(row); + if (aboutToSelect == null && dayRow >= 0) + aboutToSelect = getFirstCalendarableAt(day, dayRow); + if (aboutToSelect == null || dayRow < 0) { + aboutToSelect = getAllDayCalendarableAt(day, row + compositeTable.getTopRow()); + } + selectCalenderableControl(aboutToSelect); + aboutToSelect = null; + } + + /** + * (non-API) Method getFirstCalendarableAt. Finds the calendarable event at the + * specified day/row in DayRow coordinates. If no calendarable exists at the + * specified coordinates, does nothing. + * + * @param day + * The day offset + * @param row + * The row offset in DayRow coordinates + * @return the first Calendarable in the specified (day, row) or null if none. + */ + protected CalendarableItem getFirstCalendarableAt(int day, int row) { + CalendarableItem[][] eventLayout = model.getEventLayout(day); + CalendarableItem selectedCalendarable = null; + for (int column = 0; column < eventLayout.length; ++column) { + CalendarableItem calendarable = eventLayout[column][row]; + if (calendarable != null) { + if (selectedCalendarable == null) { + selectedCalendarable = calendarable; + } else if (calendarable.getStartTime().after(selectedCalendarable.getStartTime())) { + selectedCalendarable = calendarable; + } + } + } + return selectedCalendarable; + } + + /** + * Find the all day event that is positioned at the specified day and row in + * viewport coordinates + * + * @param day + * @param row + * @return The found Calendarable or null if none + */ + protected CalendarableItem getAllDayCalendarableAt(int day, int row) { + CalendarableItem[] allDayEvents = model.getAllDayCalendarables(day); + for (int allDayEventRow = 0; allDayEventRow < allDayEvents.length; allDayEventRow++) { + CalendarableItem candidate = allDayEvents[allDayEventRow]; + if (allDayEventRow == row) { + return candidate; + } + } + // int allDayEventRow = 0; + // for (Iterator calendarablesIter = + // model.getCalendarableEvents(day).iterator(); calendarablesIter.hasNext();) { + // Calendarable candidate = (Calendarable) calendarablesIter.next(); + // if (candidate.isAllDayEvent()) { + // if (allDayEventRow == row) { + // return candidate; + // } + // ++allDayEventRow; + // } + // } + return null; + } + + private CalendarableItem selectedCalendarable = null; + + /** + * Method selectCalendarable. Selects the specified Calendarable event. + * + * @param newSelection + * The Calendarable to select. + */ + public void setSelection(CalendarableItem newSelection) { + checkWidget(); + if (newSelection != null) { + int day = model.getDay(newSelection); + int row = computeRowForCalendarable(newSelection, day); + selectCalendarableControlOnSetFocus = false; + compositeTable.setSelection(day, row); + selectCalenderableControl(newSelection); + } else { + selectCalenderableControl(null); + } + } + + private void selectCalenderableControl(CalendarableItem newSelection) { + if (selectedCalendarable == newSelection) { + return; + } + if (selectedCalendarable != null) { + // The control could be null if it just got scrolled off the screen top or + // bottom + if (selectedCalendarable.getControl() != null) { + selectedCalendarable.getControl().setSelected(false); + } + } + + CalendarableItem oldSelection = selectedCalendarable; + selectedCalendarable = newSelection; + + if (newSelection != null && newSelection.getControl() != null) { + newSelection.getControl().setSelected(true); + } + fireSelectionChangeEvent(oldSelection, newSelection); + } + + /** + * Method getSelection. Returns the selection. This is computed as follows: + *
    + *
  1. If a CalendarableItem is currently selected, it is returned. + *
  2. If the selection rectangle is in an all-day event row, null is returned. + *
  3. Otherwise, the date/time corresponding to the selection rectangle is + * returned as a java.util.Date. + *
+ * + * @return the current DayEditorSelection + */ + public DayEditorSelection getSelection() { + checkWidget(); + DayEditorSelection selection = new DayEditorSelection(); + Point compositeTableSelection = compositeTable.getSelection(); + + int visibleAllDayEventRows = model.computeNumberOfAllDayEventRows(); + visibleAllDayEventRows -= compositeTable.getTopRow(); + + if (selectedCalendarable != null) { + selection.setSelectedCalendarable(selectedCalendarable); + if (selectedCalendarable.isAllDayEvent()) { + selection.setAllDay(true); + } + } else { + if (visibleAllDayEventRows > 0) { + if (compositeTableSelection.y < visibleAllDayEventRows) { + selection.setAllDay(true); + } + } + } + selection.setDateTime(computeDateTimeFromViewportCoordinates(compositeTableSelection, visibleAllDayEventRows)); + return selection; + } + + private List selectionChangeListeners = new ArrayList<>(); + + private void fireSelectionChangeEvent(CalendarableItem currentSelection, CalendarableItem newSelection) { + SelectionChangeEvent sce = new SelectionChangeEvent(currentSelection, newSelection); + for (Iterator listenersIter = selectionChangeListeners + .iterator(); listenersIter.hasNext();) { + CalendarableSelectionChangeListener listener = listenersIter.next(); + listener.selectionChanged(sce); + } + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the receiver's selection changes, by sending it one of the messages defined + * in the CalendarableSelectionChangeListener interface. + *

+ * selectionChanged is called when the selection changes. + *

+ * + * @param listener + * the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ * + * @see CalendarableSelectionChangeListener + * @see #removeSelectionChangeListener + * @see SelectionChangeEvent + */ + public void addSelectionChangeListener(CalendarableSelectionChangeListener l) { + checkWidget(); + if (l == null) { + throw new IllegalArgumentException("The argument cannot be null"); + } + if (isDisposed()) { + throw new SWTException("Widget is disposed"); + } + selectionChangeListeners.add(l); + } + + private boolean fireEvents(CalendarableItem calendarableItem, List handlers) { + CalendarableItemEvent e = new CalendarableItemEvent(); + e.calendarableItem = calendarableItem; + for (Iterator iter = handlers.iterator(); iter.hasNext();) { + CalendarableItemEventHandler handler = iter.next(); + handler.handleRequest(e); + if (!e.doit) { + break; + } + } + for (Iterator i = handlers.iterator(); i.hasNext();) { + CalendarableItemEventHandler h = i.next(); + h.requestHandled(e); + if (!e.doit) { + break; + } + } + return e.doit; + } + + private List editHandlers = new ArrayList<>(); + + /** + * Fire the itemEdit event. + * + * @param toEdit + * The CalendarableItem to edit. + * @return true if the object represented by the CalendarableItem was changed; + * false otherwise. + */ + public boolean fireEdit(CalendarableItem toEdit) { + checkWidget(); + CalendarableItemEvent e = new CalendarableItemEvent(); + e.calendarableItem = toEdit; + boolean changed = fireEvents(e, editHandlers); + if (changed) { + // TODO: only refresh the days that are necessary + refresh(); + } + return changed; + } + + /** + * Adds the handler to the collection of handlers who will hand editing of + * calendarable events, by sending it one of the messages defined in the + * CalendarableItemInsertHandler abstract class. + *

+ * itemInserted is called when the CalendarableItem is inserted. + *

+ * + * @param handler + * the handler which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ * + * @see CalendarableItemInsertHandler + * @see #removeItemInsertHandler + */ + public void addItemEditHandler(CalendarableItemEventHandler handler) { + checkWidget(); + if (handler == null) { + throw new IllegalArgumentException("The argument cannot be null"); + } + if (isDisposed()) { + throw new SWTException("Widget is disposed"); + } + editHandlers.add(handler); + } + + /** + * Removes the handler from the collection of handlers who will hand editing of + * calendarable events, by sending it one of the messages defined in the + * CalendarableItemInsertHandler abstract class. + *

+ * itemInserted is called when the CalendarableItem is inserted. + *

+ * + * @param handler + * the handler which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ * + * @see CalendarableItemInsertHandler + * @see #removeItemInsertHandler + */ + public void removeItemEditHandler(CalendarableItemEventHandler handler) { + checkWidget(); + if (handler == null) { + throw new IllegalArgumentException("The argument cannot be null"); + } + if (isDisposed()) { + throw new SWTException("Widget is disposed"); + } + editHandlers.remove(handler); + } + + private List deleteHandlers = new ArrayList<>(); + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#fireDelete(org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem) + */ + public boolean fireDelete(CalendarableItem item) { + checkWidget(); + boolean result = fireEvents(item, deleteHandlers); + if (result) { + // TODO: Only refresh the affected days. + refresh(); + } + return result; + } + + /** + * Adds the handler to the collection of handlers who will be notified when a + * CalendarableItem is deleted from the receiver, by sending it one of the + * messages defined in the CalendarableItemEventHandler abstract + * class. + *

+ * itemDeleted is called when the CalendarableItem is deleted. + *

+ * + * @param handler + * the handler which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ * + * @see CalendarableItemEventHandler + * @see #removeDeleteItemHandler + */ + public void addItemDeleteHandler(CalendarableItemEventHandler handler) { + checkWidget(); + if (handler == null) { + throw new IllegalArgumentException("The argument cannot be null"); + } + if (isDisposed()) { + throw new SWTException("Widget is disposed"); + } + deleteHandlers.add(handler); + } + + /** + * Removes the handler from the collection of handlers who will be notified when + * a CalendarableItem is deleted from the receiver, by sending it one of the + * messages defined in the CalendarableItemEventHandler abstract + * class. + *

+ * itemDeleted is called when the CalendarableItem is deleted. + *

+ * + * @param handler + * the handler which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ * + * @see CalendarableItemEventHandler + * @see #addDeleteItemHandler + */ + public void removeItemDeleteHandler(CalendarableItemEventHandler handler) { + checkWidget(); + deleteHandlers.remove(handler); + } + + private List itemDisposeHandlers = new ArrayList<>(); + + private boolean fireDisposeItemStrategy(CalendarableItem item) { + return fireEvents(item, itemDisposeHandlers); + } + + /** + * Adds the handler to the collection of handler who will be notified when a + * CalendarableItem's control is disposed, by sending it one of the messages + * defined in the CalendarableItemEventHandler abstract class. This + * is normally used to remove any data bindings that may be attached to the + * (now-unused) CalendarableItem. + *

+ * itemDeleted is called when the CalendarableItem is deleted. + *

+ * + * @param handler + * the handler which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ * + * @see CalendarableItemEventHandler + * @see #removeCalendarableItemDisposeHandler + */ + public void addItemDisposeHandler(CalendarableItemEventHandler handler) { + checkWidget(); + if (handler == null) { + throw new IllegalArgumentException("The argument cannot be null"); + } + if (isDisposed()) { + throw new SWTException("Widget is disposed"); + } + itemDisposeHandlers.add(handler); + } + + /** + * Removes the handler from the collection of handlers who will be notified when + * a CalendarableItem is disposed, by sending it one of the messages defined in + * the CalendarableItemEventHandler abstract class. This is + * normally used to remove any data bindings that may be attached to the + * (now-unused) CalendarableItem. + *

+ * itemDeleted is called when the CalendarableItem is deleted. + *

+ * + * @param handler + * the handler which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the handler is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ * + * @see CalendarableItemEventHandler + * @see #removeDeleteListener + */ + public void removeItemDisposeHandler(CalendarableItemEventHandler handler) { + checkWidget(); + itemDisposeHandlers.remove(handler); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the receiver's selection changes, by sending it one of the messages + * defined in the CalendarableSelectionChangeListener interface. + *

+ * selectionChanged is called when the selection changes. + *

+ * + * @param listener + * the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ * + * @see CalendarableSelectionChangeListener + * @see #addSelectionChangeListener + * @see SelectionChangeEvent + */ + public void removeSelectionChangeListener(CalendarableSelectionChangeListener l) { + checkWidget(); + if (l == null) { + throw new IllegalArgumentException("The argument cannot be null"); + } + if (isDisposed()) { + throw new SWTException("Widget is disposed"); + } + selectionChangeListeners.remove(l); + } + + /** + * @return Returns the defaultStartHour. + */ + public int getDefaultStartHour() { + return model.getDefaultStartHour(); + } + + /** + * @param defaultStartHour + * The defaultStartHour to set. + */ + public void setDefaultStartHour(int defaultStartHour) { + checkWidget(); + model.setDefaultStartHour(defaultStartHour); + updateVisibleRows(); + layoutEventControls(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.examples.databinding.compositetable.timeeditor.IEventEditor + * #setDayEventCountProvider(org.eclipse.jface.examples.databinding. + * compositetable.timeeditor.EventCountProvider) + */ + public void setEventCountProvider(EventCountProvider eventCountProvider) { + checkWidget(); + model.setEventCountProvider(eventCountProvider); + updateVisibleRows(); + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (isDisposed()) + return; + layoutEventControls(); + } + }); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.examples.databinding.compositetable.timeeditor.IEventEditor + * #setEventContentProvider(org.eclipse.jface.examples.databinding. + * compositetable.timeeditor.EventContentProvider) + */ + public void setEventContentProvider(EventContentProvider eventContentProvider) { + checkWidget(); + model.setEventContentProvider(eventContentProvider); + updateVisibleRows(); + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + if (isDisposed()) + return; + layoutEventControls(); + } + }); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setStartDate(java.util.Date) + */ + @SuppressWarnings("unchecked") + public void setStartDate(Date startDate) { + checkWidget(); + List removedDays = model.setStartDate(startDate); + computeEventRowsForNewDays(); + if (daysHeader != null) { + refreshColumnHeaders(daysHeader.getColumns()); + } + updateVisibleRows(); + freeObsoleteCalendarableEventControls((List) removedDays); + if (compositeTable.getNumRowsVisible() > 0) { + layoutEventControls(); + } + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getStartDate() + */ + public Date getStartDate() { + checkWidget(); + return model.getStartDate(); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#refresh(java.util.Date) + */ + public void refresh(Date date) { + checkWidget(); + computeLayoutFor(date); + layoutEventControls(); + } + + @SuppressWarnings("unchecked") + private void computeLayoutFor(Date date) { + List removedDays = model.refresh(date); + freeObsoleteCalendarableEventControls((List) removedDays); + updateVisibleRows(); + computeEventRowsForDate(date); + } + + private boolean refreshing = false; + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.AbstractEventEditor#refresh() + */ + public void refresh() { + checkWidget(); + if (!refreshing) { + refreshing = true; + Display.getCurrent().asyncExec(() -> { + if (isDisposed()) + return; + Date dateToRefresh = getStartDate(); + GregorianCalendar gc = new GregorianCalendar(); + gc.setTime(dateToRefresh); + for (int i = 0; i < getNumberOfDays(); ++i) { + computeLayoutFor(gc.getTime()); + gc.add(Calendar.DATE, 1); + } + layoutEventControls(); + refreshing = false; + }); + } + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getNumberOfDays() + */ + public int getNumberOfDays() { + checkWidget(); + return model.getNumberOfDays(); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getNumberOfDivisionsInHour() + */ + public int getNumberOfDivisionsInHour() { + checkWidget(); + return model.getNumberOfDivisionsInHour(); + } + + // Display Refresh logic here ---------------------------------------------- + + /* + * There are four main coordinate systems the refresh algorithm has to deal + * with: + * + * 1) Rows starting from midnight (the way the DayModel computes the layout). + * These are called Day Row coordinates. + * + * 2) Rows starting from the top visible row, taking into account all-day event + * rows. These are called Viewport Row coordinates + * + * 3) Pixel coordinates for each TimeSlot, relative to its parent TimeSlice (the + * CompositeTable row object) row. This is relevant because these are + * transformed into #4 in order to place CalendarableEventControls. + * + * 4) Pixel coordinates relative to the top left (the origin) of the entire + * DayEditor control. + */ + + private int numberOfAllDayEventRows = 0; + Calendar calendar = new GregorianCalendar(); + + private int computeNumRowsInCollection(final int numberOfDivisionsInHour) { + numberOfAllDayEventRows = model.computeNumberOfAllDayEventRows(); + return (DISPLAYED_HOURS - model.computeStartHour()) * numberOfDivisionsInHour + numberOfAllDayEventRows; + } + + private int convertViewportRowToDayRow(int row) { + int topRowOffset = compositeTable.getTopRow() - numberOfAllDayEventRows; + int startOfDayOffset = model.computeStartHour() * model.getNumberOfDivisionsInHour(); + return row + topRowOffset + startOfDayOffset; + } + + private int convertDayRowToViewportCoordinates(int row) { + row -= model.computeStartHour() * model.getNumberOfDivisionsInHour() - numberOfAllDayEventRows; + return row; + } + + private Date computeDateTimeFromViewportCoordinates(Point viewportSelection, int visibleAllDayEventRows) { + Date startDate = model.calculateDate(getStartDate(), viewportSelection.x); + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(startDate); + calendar.set(Calendar.HOUR_OF_DAY, model.computeHourFromRow(viewportSelection.y - visibleAllDayEventRows)); + calendar.set(Calendar.MINUTE, model.computeMinuteFromRow(viewportSelection.y - visibleAllDayEventRows)); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTime(); + } + + /** + * @param calendarable + * @param day + * @return The row in DayRow coordinates + */ + private int computeRowForCalendarable(CalendarableItem calendarable, int day) { + int row = 0; + if (calendarable.isAllDayEvent()) { + CalendarableItem[] allDayEvents = model.getAllDayCalendarables(day); + for (int allDayEventRow = 0; allDayEventRow < allDayEvents.length; allDayEventRow++) { + if (allDayEvents[allDayEventRow] == calendarable) { + row = allDayEventRow - compositeTable.getTopRow(); + break; + } + } + } else { + // Convert to viewport coordinates + Point upperLeft = calendarable.getUpperLeftPositionInDayRowCoordinates(); + int topRowOffset = compositeTable.getTopRow() - numberOfAllDayEventRows; + int startOfDayOffset = model.computeStartHour() * model.getNumberOfDivisionsInHour(); + row = upperLeft.y - topRowOffset - startOfDayOffset; + if (row < 0) { + row = 0; + } + } + return row; + } + + /* + * Update the number of rows that are displayed inside the CompositeTable + * control + */ + private void updateVisibleRows() { + compositeTable.setNumRowsInCollection(computeNumRowsInCollection(getNumberOfDivisionsInHour())); + } + + private void refreshRow(int currentObjectOffset, TimeSlice timeSlice) { + // Decrement currentObjectOffset for each all-day event line we need. + for (int allDayEventRow = 0; allDayEventRow < numberOfAllDayEventRows; ++allDayEventRow) { + --currentObjectOffset; + } + + if (currentObjectOffset < 0) { + timeSlice.setCurrentTime(null); + } else { + calendar.set(Calendar.HOUR_OF_DAY, model.computeHourFromRow(currentObjectOffset)); + calendar.set(Calendar.MINUTE, model.computeMinuteFromRow(currentObjectOffset)); + timeSlice.setCurrentTime(calendar.getTime()); + } + } + + /** + * (non-API) Method initializeColumnHeaders. Called internally when the column + * header text needs to be updated. + * + * @param columns + * A LinkedList of CLabels representing the column objects + */ + protected void refreshColumnHeaders(LinkedList columns) { + Date startDate = getStartDate(); + GregorianCalendar gc = new GregorianCalendar(); + gc.setTime(startDate); + + SimpleDateFormat formatter = new SimpleDateFormat("EE, MMM d"); + formatter.applyLocalizedPattern(formatter.toLocalizedPattern()); + + for (Iterator iter = columns.iterator(); iter.hasNext();) { + CLabel headerLabel = iter.next(); + headerLabel.setText(formatter.format(gc.getTime())); + gc.add(Calendar.DATE, 1); + } + } + + private void freeObsoleteCalendarableEventControls(List removedCalendarables) { + for (Iterator removedCalendarablesIter = removedCalendarables + .iterator(); removedCalendarablesIter.hasNext();) { + CalendarableItem toRemove = removedCalendarablesIter.next(); + if (selectedCalendarable == toRemove) { + setSelection(null); + } + freeCalendarableControl(toRemove); + } + } + + private void computeEventRowsForDate(Date date) { + GregorianCalendar targetDate = new GregorianCalendar(); + targetDate.setTime(date); + GregorianCalendar target = new GregorianCalendar(); + target.setTime(model.getStartDate()); + EventLayoutComputer dayModel = new EventLayoutComputer(model.getNumberOfDivisionsInHour()); + for (int dayOffset = 0; dayOffset < model.getNumberOfDays(); ++dayOffset) { + if (target.get(Calendar.DATE) == targetDate.get(Calendar.DATE) + && target.get(Calendar.MONTH) == targetDate.get(Calendar.MONTH) + && target.get(Calendar.YEAR) == targetDate.get(Calendar.YEAR)) { + computeEventLayout(dayModel, dayOffset); + break; + } + target.add(Calendar.DATE, 1); + } + } + + private void computeEventRowsForNewDays() { + EventLayoutComputer dayModel = new EventLayoutComputer(model.getNumberOfDivisionsInHour()); + for (int dayOffset = 0; dayOffset < model.getNumberOfDays(); ++dayOffset) { + if (model.getNumberOfColumnsWithinDay(dayOffset) == -1) { + computeEventLayout(dayModel, dayOffset); + } + } + } + + @SuppressWarnings("unchecked") + private void computeEventLayout(EventLayoutComputer dayModel, int dayOffset) { + List events = model.getCalendarableItems(dayOffset); + CalendarableItem[][] eventLayout = dayModel.computeEventLayout(events); + model.setEventLayout(dayOffset, eventLayout); + } + + private void layoutEventControlsDeferred() { + if (getStartDate() == null) { + return; + } + refreshEventControlPositions.run(); + Display.getCurrent().asyncExec(refreshEventControlPositions); + } + + private void layoutEventControls() { + if (getStartDate() == null) { + return; + } + refreshEventControlPositions.run(); + } + + @SuppressWarnings("unchecked") + private Runnable refreshEventControlPositions = () -> { + if (isDisposed()) + return; + + Control[] gridRows = compositeTable.getRowControls(); + + for (int day = 0; day < model.getNumberOfDays(); ++day) { + int columnsWithinDay = model.getNumberOfColumnsWithinDay(day); + Point[] columnPositions = computeColumns(day, columnsWithinDay, gridRows); + + int allDayEventRow = 0; + + for (Iterator calendarablesIter = model.getCalendarableItems(day) + .iterator(); calendarablesIter.hasNext();) { + CalendarableItem calendarable = calendarablesIter.next(); + if (calendarable.isAllDayEvent()) { + layoutAllDayEvent(day, allDayEventRow, calendarable, gridRows); + ++allDayEventRow; + } else { + layoutTimedEvent(day, columnPositions, calendarable, gridRows); + } + } + } + }; + + protected Point[] computeColumns(int day, int numberOfColumns, Control[] gridRows) { + Point[] columns = new Point[numberOfColumns]; + Rectangle timeSliceBounds = getTimeSliceBounds(day, compositeTable.getTopRow(), gridRows); + timeSliceBounds.x += TimeSlot.TIME_BAR_WIDTH + 1; + timeSliceBounds.width -= TimeSlot.TIME_BAR_WIDTH + 2; + + int baseWidth = timeSliceBounds.width / numberOfColumns; + int extraWidth = timeSliceBounds.width % numberOfColumns; + + int startingPosition = timeSliceBounds.x; + for (int column = 0; column < columns.length; column++) { + int columnStart = startingPosition; + int columnWidth = baseWidth; + if (extraWidth > 0) { + ++columnWidth; + --extraWidth; + } + columns[column] = new Point(columnStart, columnWidth); + startingPosition += columnWidth; + } + return columns; + } + + private void fillControlData(CalendarableItem calendarable, int clippingStyle) { + calendarable.getControl().setText(calendarable.getText()); + calendarable.getControl().setToolTipText(calendarable.getToolTipText()); + calendarable.getControl().setClipping(clippingStyle); + } + + private DayEditorCalendarableItemControl getControl(CalendarableItem item) { + return (DayEditorCalendarableItemControl) item.getControl(); + } + + private void layoutAllDayEvent(int day, int allDayEventRow, CalendarableItem calendarable, Control[] gridRows) { + if (eventRowIsVisible(allDayEventRow)) { + createCalendarableControl(calendarable); + fillControlData(calendarable, SWT.NULL); + + Rectangle timeSliceBounds = getTimeSliceBounds(day, allDayEventRow, gridRows); + int gutterWidth = TimeSlot.TIME_BAR_WIDTH + 1; + timeSliceBounds.x += gutterWidth; + timeSliceBounds.width -= gutterWidth; + getControl(calendarable).setBounds(timeSliceBounds); + getControl(calendarable).moveAbove(compositeTable); + } else { + freeCalendarableControl(calendarable); + } + } + + private void layoutTimedEvent(int day, Point[] columnPositions, CalendarableItem calendarable, Control[] gridRows) { + int firstVisibleRow = model.computeStartHour() * model.getNumberOfDivisionsInHour(); + + int scrolledRows = compositeTable.getTopRow() - numberOfAllDayEventRows; + int visibleAllDayEventRows = 0; + if (scrolledRows < 0) { + visibleAllDayEventRows = -1 * scrolledRows; + scrolledRows = 0; + } + firstVisibleRow += scrolledRows; + int lastVisibleRow = firstVisibleRow + compositeTable.getNumRowsVisible() - visibleAllDayEventRows - 1; + + int startRow = calendarable.getUpperLeftPositionInDayRowCoordinates().y; + int endRow = calendarable.getLowerRightPositionInDayRowCoordinates().y; + + if (timedEventIsVisible(firstVisibleRow, lastVisibleRow, startRow, endRow)) { + int clippingStyle = SWT.NULL; + + if (startRow < firstVisibleRow) { + startRow = firstVisibleRow; + clippingStyle |= SWT.TOP; + } + + if (endRow > lastVisibleRow) { + endRow = lastVisibleRow; + clippingStyle |= SWT.BOTTOM; + } + + startRow = convertDayRowToViewportCoordinates(startRow); + endRow = convertDayRowToViewportCoordinates(endRow); + + createCalendarableControl(calendarable); + fillControlData(calendarable, clippingStyle); + + Rectangle startRowBounds = getTimeSliceBounds(day, startRow, gridRows); + Rectangle endRowBounds = getTimeSliceBounds(day, endRow, gridRows); + + int leftmostColumn = calendarable.getUpperLeftPositionInDayRowCoordinates().x; + int rightmostColumn = calendarable.getLowerRightPositionInDayRowCoordinates().x; + + int left = columnPositions[leftmostColumn].x; + int top = startRowBounds.y + 1; + int width = columnPositions[rightmostColumn].x - columnPositions[leftmostColumn].x + + columnPositions[rightmostColumn].y; + int height = endRowBounds.y - startRowBounds.y + endRowBounds.height - 1; + + Rectangle finalPosition = new Rectangle(left, top, width, height); + if (showEventsWithPrecision) { + int startRowDiff = startRowDiff(calendarable); + top += startRowDiff; + height += (endRowDiff(calendarable) - (startRowDiff)); + } + getControl(calendarable).setBounds(finalPosition); + getControl(calendarable).moveAbove(compositeTable); + } else { + freeCalendarableControl(calendarable); + } + } + + private int startRowDiff(CalendarableItem calendarable) { + Date d = calendarable.getStartTime(); + Calendar c = Calendar.getInstance(); + c.setTime(d); + return findRowDiff(calendarable, c, false);// add difference + } + + private int endRowDiff(CalendarableItem calendarable) { + Date d = calendarable.getEndTime(); + Calendar c = Calendar.getInstance(); + c.setTime(d); + // an extra row of padding is added to end if beyond FIRST division for the + // hour? + if (c.get(Calendar.MINUTE) > (60 / getNumberOfDivisionsInHour())) { + return findRowDiff(calendarable, c, true);// subtract difference + } + return findRowDiff(calendarable, c, false);// add difference + } + + /** + * For finding the pixel difference between filling the entire row, and filling + * only partially. Used For rendering more accurate & precise event durations. + * + * @param calendarable + * @param time + * @param subtractDiff + * set to true to subtract rather than add + * @return + */ + private int findRowDiff(CalendarableItem calendarable, Calendar time, boolean subtractDiff) { + int rowSize = compositeTable.getRowControl().getSize().y; + int min = time.get(Calendar.MINUTE); + double div = 60 / getNumberOfDivisionsInHour(); + double diff = min % div;// the number of partial minutes in a row + + if (subtractDiff) { + diff = -(div - diff); + } + + if (diff != 0) { + double i = ((diff) / (div)); + int in = (int) (i * rowSize); + return in; + } + return 0; + } + + private boolean eventRowIsVisible(int eventRow) { + int topRow = compositeTable.getTopRow(); + if (topRow <= eventRow) { + if (eventRow < compositeTable.getNumRowsVisible() - topRow) { + return true; + } + } + return false; + } + + private boolean timedEventIsVisible(int firstVisibleRow, int lastVisibleRow, int startRow, int endRow) { + if (startRow < firstVisibleRow && endRow < firstVisibleRow) + return false; + + if (startRow > lastVisibleRow && endRow > lastVisibleRow) + return false; + + return true; + } + + private void createCalendarableControl(CalendarableItem calendarable) { + if (calendarable.getControl() == null) { + calendarable.setControl(newCEC()); + if (calendarable == selectedCalendarable) { + calendarable.getControl().setSelected(true); + } + } + } + + private Rectangle getTimeSliceBounds(int day, int eventRow, Control[] gridRows) { + int row = eventRow - compositeTable.getTopRow(); + TimeSlice rowObject = (TimeSlice) gridRows[row]; + Control slot = rowObject.getColumnControl(day); + return getBoundsInDayEditorCoordinates(slot); + } + + private void freeCalendarableControl(CalendarableItem calendarableItem) { + if (calendarableItem.getControl() != null) { + freeCEC(getControl(calendarableItem)); + calendarableItem.setControl(null); + fireDisposeItemStrategy(calendarableItem); + } + } + + private Rectangle getBoundsInDayEditorCoordinates(Control slot) { + return Display.getCurrent().map(slot.getParent(), this, slot.getBounds()); + } + + // CalendarableItemControl construction/destruction here ----------------- + + MouseAdapter selectCompositeTableOnMouseDownAdapter = new MouseAdapter() { + /** + * @see org.eclipse.swt.events.MouseAdapter#mouseDown(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDown(MouseEvent e) { + fireMouseDownEvent(e); + ICalendarableItemControl control = (ICalendarableItemControl) e.widget; + CalendarableItem aboutToSelect = control.getCalendarableItem(); + setSelection(aboutToSelect); + } + + /** + * @see org.eclipse.swt.events.MouseAdapter#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + fireMouseDoubleClickEvent(e); + } + + /** + * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + public void mouseUp(MouseEvent e) { + fireMouseUpEvent(e); + } + }; + + private DayEditorCalendarableItemControl newCEC() { + if (recycledCalendarableEventControls.size() > 0) { + DayEditorCalendarableItemControl result = recycledCalendarableEventControls.remove(0); + result.setVisible(true); + return result; + } + DayEditorCalendarableItemControl dayEditorCalendarableItemControl = new DayEditorCalendarableItemControl(this, + SWT.NULL); + if (menu != null) { + dayEditorCalendarableItemControl.setMenu(menu); + } + dayEditorCalendarableItemControl.addMouseListener(selectCompositeTableOnMouseDownAdapter); + return dayEditorCalendarableItemControl; + } + + private void freeCEC(DayEditorCalendarableItemControl control) { + control.setSelected(false); + control.setCalendarableItem(null); + control.setVisible(false); + recycledCalendarableEventControls.add(control); + } + + private Color background = null; + + + /** + * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) + */ + public void setBackground(Color color) { + checkWidget(); + super.setBackground(color); + this.background = color; + if (compositeTable != null) { + compositeTable.setBackground(color); + } + } + + /** + * @see org.eclipse.swt.widgets.Composite#setFocus() + */ + public boolean setFocus() { + checkWidget(); + if (!compositeTable.setFocus()) { + return super.setFocus(); + } + return true; + } + + public void showEventsWithPrecision(boolean option) { + showEventsWithPrecision = option; + } + +} // @jve:decl-index=0:visual-constraint="10,10" diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/month/MonthCalendar.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/month/MonthCalendar.java index ae46acd13..bf03eccaa 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/month/MonthCalendar.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/month/MonthCalendar.java @@ -1,759 +1,759 @@ -/******************************************************************************* - * Copyright (c) 2006 The Pampered Chef and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * The Pampered Chef - initial API and implementation - ******************************************************************************/ -package org.eclipse.nebula.widgets.compositetable.month; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler; -import org.eclipse.nebula.widgets.compositetable.day.CalendarableSelectionChangeListener; -import org.eclipse.nebula.widgets.compositetable.month.internal.Day; -import org.eclipse.nebula.widgets.compositetable.month.internal.Week; -import org.eclipse.nebula.widgets.compositetable.month.internal.WeekHeader; -import org.eclipse.nebula.widgets.compositetable.timeeditor.AbstractEventEditor; -import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem; -import org.eclipse.nebula.widgets.compositetable.timeeditor.EventContentProvider; -import org.eclipse.nebula.widgets.compositetable.timeeditor.EventCountProvider; -import org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -/** - * An IEventEditor implementing a month calendar. This class is not intended - * to be subclassed. - */ -public class MonthCalendar extends AbstractEventEditor implements IEventEditor { - - private Date startDate; - private WeekHeader weekHeader = null; - private Composite weeksHolder = null; - private Week[] weeks; - - /** - * Constructor DayEditor. Constructs a calendar control that can display - * events on one or more days. - * - * @param parent - * @param style The same style bits as @see Composite - */ - public MonthCalendar(Composite parent, int style) { - super(parent, style); - initialize(); - weeks = new Week[0]; - setStartDate(new Date()); - } - - private void initialize() { - GridLayout gl = new GridLayout(); - gl.horizontalSpacing = 0; - gl.marginWidth = 0; - gl.verticalSpacing = 0; - gl.marginHeight = 0; - createWeekHeader(); - this.setLayout(gl); - createWeeksHolder(); - } - - /** - * This method initializes weekHeader - * - */ - private void createWeekHeader() { - GridData gridData = new GridData(); - gridData.horizontalAlignment = GridData.FILL; - gridData.grabExcessHorizontalSpace = true; - gridData.verticalAlignment = GridData.CENTER; - weekHeader = new WeekHeader(this, SWT.NONE); - weekHeader.setLayoutData(gridData); - } - - /** - * This method initializes composite - * - */ - private void createWeeksHolder() { - weeksHolder = new Composite(this, SWT.NONE); - - GridLayout gridLayout = new GridLayout(); - gridLayout.horizontalSpacing = 0; - gridLayout.marginWidth = 0; - gridLayout.verticalSpacing = 1; - gridLayout.marginHeight = 0; - weeksHolder.setLayout(gridLayout); - - GridData gd = new GridData(); - gd.horizontalAlignment = GridData.FILL; - gd.grabExcessHorizontalSpace = true; - gd.grabExcessVerticalSpace = true; - gd.verticalAlignment = GridData.FILL; - weeksHolder.setLayoutData(gd); - } - - /** - * This method initializes week - */ - private Week createWeek() { - GridData gd = new GridData(); - gd.horizontalAlignment = GridData.FILL; - gd.grabExcessHorizontalSpace = true; - gd.grabExcessVerticalSpace = true; - gd.verticalAlignment = GridData.FILL; - Week week = new Week(weeksHolder, SWT.NONE); - week.setLayoutData(gd); - return week; - } - - /** - * Sets the start date for this MonthCalendar. - *

- * The date is set to the first day of the specified month and the time part - * of the Date object is set to midnight before storing. Calling - * {@link #getStartDate()} will return this mutilated version instead of the - * original. - * - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setStartDate(java.util.Date) - */ - public void setStartDate(Date startDate) { - checkWidget(); - - Calendar c = new GregorianCalendar(); - c.setTime(startDate); - c.set(Calendar.DAY_OF_MONTH, 1); - c.set(Calendar.HOUR_OF_DAY, 0); - c.set(Calendar.MINUTE, 0); - c.set(Calendar.SECOND, 0); - c.set(Calendar.MILLISECOND, 0); - this.startDate = c.getTime(); - refresh(); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getStartDate() - */ - public Date getStartDate() { - checkWidget(); - - return startDate; - } - - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#refresh(java.util.Date) - */ - public void refresh(Date date) { - checkWidget(); - - if (date == null) { - refresh(); - return; - } - - Calendar currentDay = new GregorianCalendar(); - currentDay.setTime(startDate); - currentDay.set(Calendar.DAY_OF_MONTH, 1); - currentDay.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); - - Calendar endDay = new GregorianCalendar(); - endDay.setTime(date); - endDay.set(Calendar.HOUR_OF_DAY, 0); - endDay.set(Calendar.MINUTE, 0); - endDay.set(Calendar.SECOND, 0); - endDay.set(Calendar.MILLISECOND, 0); - Date targetDate = endDay.getTime(); - - Day currentDayControl = null; - for (int week = 0; week < weeks.length; week++) { - for (int day = 0; day < 7; day++) { - currentDayControl = weeks[week].getDay(day); - - currentDay.add(Calendar.DAY_OF_MONTH, 1); - if (currentDay.getTime().after(targetDate)) { - refresh(date, currentDayControl); - return; - } - } - } - } - - private void refresh(Date date, Day dayControl) { - dayControl.setDate(date); - if (eventCountProvider == null || eventContentProvider == null) { - return; - } - int numberOfEventsInDay = eventCountProvider.getNumberOfEventsInDay(date); - CalendarableItem controls[] = new CalendarableItem[numberOfEventsInDay]; - for (int i = 0; i < controls.length; i++) { - controls[i] = new CalendarableItem(date); - } - eventContentProvider.refresh(date, controls); - dayControl.setItems(controls); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.AbstractEventEditor#refresh() - */ - public void refresh() { - checkWidget(); - - Calendar c = new GregorianCalendar(); - c.setTime(startDate); - int currentMonth = c.get(Calendar.MONTH); - - Calendar nextMonthCalendar = new GregorianCalendar(); - nextMonthCalendar.setTime(c.getTime()); - nextMonthCalendar.add(Calendar.MONTH, 1); - Date nextMonth = nextMonthCalendar.getTime(); - - c.set(Calendar.DAY_OF_MONTH, 1); - c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); - - LinkedList newWeeksArray = new LinkedList<>(); - - for (int week = 0; c.getTime().before(nextMonth); week++) { - if (weeks.length > week) { - newWeeksArray.addLast(weeks[week]); - } else { - Week newWeek = createWeek(); - newWeeksArray.addLast(newWeek); - for (int day = 0; day < 7; day++) { - Day newDay = newWeek.getDay(day); - newDay.setMonthPosition(new Point(day, week)); - newDay.addKeyListener(dayKeyListener); - newDay.addMouseListener(dayMouseListener); - newDay.addFocusListener(dayFocusListener); - } - } - for (int day = 0; day < 7; day++) { - Day currentDay = ((Week) newWeeksArray.get(week)).getDay(day); - currentDay.setInCurrentMonth(c.get(Calendar.MONTH) == currentMonth); - currentDay.setDayNumber(c.get(Calendar.DAY_OF_MONTH)); - refresh(c.getTime(), currentDay); - currentDay.layout(true); - c.add(Calendar.DAY_OF_MONTH, 1); - } - } - if (weeks.length > newWeeksArray.size()) { - for (int extraWeek = newWeeksArray.size(); extraWeek < weeks.length; ++extraWeek) { - weeks[extraWeek].dispose(); - } - } - if (weeks.length != newWeeksArray.size()) { - weeksHolder.layout(true); - } - weeks = (Week[]) newWeeksArray.toArray(new Week[newWeeksArray.size()]); - } - - private EventContentProvider eventContentProvider = null; - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setEventContentProvider(org.eclipse.nebula.widgets.compositetable.timeeditor.EventContentProvider) - */ - public void setEventContentProvider(EventContentProvider eventContentProvider) { - checkWidget(); - - this.eventContentProvider = eventContentProvider; - } - - private EventCountProvider eventCountProvider = null; - - - public void setEventCountProvider(EventCountProvider eventCountProvider) { - checkWidget(); - - this.eventCountProvider = eventCountProvider; - } - - private List deleteHandlers = new ArrayList<>(); - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#addItemDeleteHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) - */ - public void addItemDeleteHandler(CalendarableItemEventHandler deleteHandler) { - checkWidget(); - - deleteHandlers.add(deleteHandler); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#removeItemDeleteHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) - */ - public void removeItemDeleteHandler(CalendarableItemEventHandler deleteHandler) { - checkWidget(); - - deleteHandlers.remove(deleteHandler); - } - - private List disposeHandlers = new ArrayList<>(); - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#addItemDisposeHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) - */ - public void addItemDisposeHandler(CalendarableItemEventHandler itemDisposeHandler) { - checkWidget(); - - disposeHandlers.add(itemDisposeHandler); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#removeItemDisposeHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) - */ - public void removeItemDisposeHandler(CalendarableItemEventHandler itemDisposeHandler) { - checkWidget(); - disposeHandlers.remove(itemDisposeHandler); - } - - private List itemEditHandlers = new ArrayList<>(); - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#addItemEditHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) - */ - public void addItemEditHandler(CalendarableItemEventHandler handler) { - checkWidget(); - - itemEditHandlers.add(handler); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#removeItemEditHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) - */ - public void removeItemEditHandler(CalendarableItemEventHandler handler) { - checkWidget(); - - itemEditHandlers.remove(handler); - } - - private List selectionChangeListeners = new ArrayList<>(); - - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#addSelectionChangeListener(org.eclipse.nebula.widgets.compositetable.day.CalendarableSelectionChangeListener) - */ - public void addSelectionChangeListener(CalendarableSelectionChangeListener l) { - checkWidget(); - - selectionChangeListeners.add(l); - } - - public void removeSelectionChangeListener(CalendarableSelectionChangeListener l) { - checkWidget(); - - selectionChangeListeners.remove(l); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#fireDelete(org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem) - */ - public boolean fireDelete(CalendarableItem toDelete) { - checkWidget(); - return false; - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setTimeBreakdown(int, int) - */ - public void setTimeBreakdown(int numberOfDays, int numberOfDivisionsInHour) { - checkWidget(); - // NOOP - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getNumberOfDays() - */ - public int getNumberOfDays() { - checkWidget(); - - // Return the number of days in the current month - Calendar c = new GregorianCalendar(); - c.setTime(startDate); - return c.getActualMaximum(Calendar.DAY_OF_MONTH); - } - - /** - * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getNumberOfDivisionsInHour() - */ - public int getNumberOfDivisionsInHour() { - checkWidget(); - // NOOP - return -1; - } - - private MonthCalendarSelectedDay selectedDay = null; - - /** - * Method getSelectedDay. Returns the currently-selected day. - * - * @return The current MonthCalendarSelection which represents the currently- - * selected day. - */ - public MonthCalendarSelectedDay getSelectedDay() { - checkWidget(); - - return selectedDay; - } - - private List focusListeners = new ArrayList<>(); - - /** - * Adds the listener to the collection of listeners who will - * be notified when the control gains or loses focus, by sending - * it one of the messages defined in the FocusListener - * interface. - *

- * In addition, e.data in the FocusEvent is the current MonthCalendarSelectedDay. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see FocusListener - * @see #removeFocusListener - * @see org.eclipse.swt.widgets.Control#addFocusListener(org.eclipse.swt.events.FocusListener) - */ - public void addFocusListener(FocusListener listener) { - checkWidget(); - - super.addFocusListener(listener); - focusListeners.add(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the control gains or loses focus. - *

- * In addition, e.data in the FocusEvent is the current MonthCalendarSelectedDay. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see FocusListener - * @see #addFocusListener - * @see org.eclipse.swt.widgets.Control#removeFocusListener(org.eclipse.swt.events.FocusListener) - */ - public void removeFocusListener(FocusListener listener) { - checkWidget(); - - super.removeFocusListener(listener); - focusListeners.remove(listener); - } - - private Day lastSelectedDay; - - private FocusListener dayFocusListener = new FocusListener() { - public void focusGained(FocusEvent e) { - Day day = (Day) e.widget; - if (lastSelectedDay != null && lastSelectedDay != day) { - lastSelectedDay.setFocusState(Day.NO_FOCUS); - lastSelectedDay.redraw(); - } - - Point coordinates = day.getMonthPosition(); - selectedDay = new MonthCalendarSelectedDay(day.getDate(), coordinates); - e.data = selectedDay; - - lastSelectedDay = day; - - for (Iterator focusListenersIter = focusListeners.iterator(); focusListenersIter.hasNext();) { - FocusListener listener = (FocusListener) focusListenersIter.next(); - listener.focusGained(e); - } - } - - public void focusLost(FocusEvent e) { - Day day = (Day) e.widget; - Point coordinates = day.getMonthPosition(); - e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); - - for (Iterator focusListenersIter = focusListeners.iterator(); focusListenersIter.hasNext();) { - FocusListener listener = (FocusListener) focusListenersIter.next(); - listener.focusLost(e); - } - } - }; - - private List mouseListeners = new ArrayList<>(); - - /** - * @see org.eclipse.swt.widgets.Control#addMouseListener(org.eclipse.swt.events.MouseListener) - */ - public void addMouseListener(MouseListener listener) { - checkWidget(); - - super.addMouseListener(listener); - mouseListeners.add(listener); - } - - /** - * @see org.eclipse.swt.widgets.Control#removeMouseListener(org.eclipse.swt.events.MouseListener) - */ - public void removeMouseListener(MouseListener listener) { - checkWidget(); - - super.removeMouseListener(listener); - mouseListeners.remove(listener); - } - - private MouseListener dayMouseListener = new MouseListener() { - private Day getDay(MouseEvent e) { - Control control = (Control) e.widget; - while (!(control instanceof Day)) { - control = control.getParent(); - } - Day day = (Day) control; - return day; - } - - public void mouseDown(MouseEvent e) { - Day day = getDay(e); - Point coordinates = day.getMonthPosition(); - e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); - - for (Iterator mouseListenersIter = mouseListeners.iterator(); mouseListenersIter.hasNext();) { - MouseListener listener = (MouseListener) mouseListenersIter.next(); - listener.mouseDown(e); - } - } - - public void mouseUp(MouseEvent e) { - Day day = getDay(e); - Point coordinates = day.getMonthPosition(); - e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); - - for (Iterator mouseListenersIter = mouseListeners.iterator(); mouseListenersIter.hasNext();) { - MouseListener listener = (MouseListener) mouseListenersIter.next(); - listener.mouseUp(e); - } - } - - public void mouseDoubleClick(MouseEvent e) { - Day day = getDay(e); - Point coordinates = day.getMonthPosition(); - e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); - - for (Iterator mouseListenersIter = mouseListeners.iterator(); mouseListenersIter.hasNext();) { - MouseListener listener = (MouseListener) mouseListenersIter.next(); - listener.mouseDoubleClick(e); - } - } - }; - - private List keyListeners = new ArrayList<>(); - - /** - * Adds the listener to the collection of listeners who will - * be notified when keys are pressed and released on the system keyboard, by - * sending it one of the messages defined in the KeyListener - * interface. - *

- * In addition to the usual KeyListener contract, MonthCalendar will honor - * e.doit and will not perform its usual key processing if any KeyListener - * sets e.doit to false. - *

- * In addition to the usual KeyEvent fields, e.data is set to the current - * MonthCalendarSelection. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see org.eclipse.swt.widgets.Control#addKeyListener(org.eclipse.swt.events.KeyListener) - */ - public void addKeyListener(KeyListener listener) { - checkWidget(); - - super.addKeyListener(listener); - keyListeners.add(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when keys are pressed and released on the system keyboard. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see KeyListener - * @see #addKeyListener - * @see org.eclipse.swt.widgets.Control#removeKeyListener(org.eclipse.swt.events.KeyListener) - */ - public void removeKeyListener(KeyListener listener) { - checkWidget(); - - super.removeKeyListener(listener); - keyListeners.remove(listener); - } - - private KeyListener dayKeyListener = new KeyAdapter() { - public void keyPressed(KeyEvent e) { - Day day = (Day) e.widget; - Point coordinates = day.getMonthPosition(); - e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); - - for (Iterator keyListenersIter = keyListeners.iterator(); keyListenersIter.hasNext();) { - KeyListener listener = (KeyListener) keyListenersIter.next(); - listener.keyPressed(e); - } - - if (!e.doit) { - return; - } - - switch (e.keyCode) { - case SWT.ARROW_UP: - if (coordinates.y > 0) { - Day newDay = weeks[coordinates.y - 1].getDay(coordinates.x); - newDay.setFocus(); - } - return; - case SWT.ARROW_DOWN: - if (coordinates.y < weeks.length - 1) { - Day newDay = weeks[coordinates.y + 1].getDay(coordinates.x); - newDay.setFocus(); - } - return; - } - } - - - /** - * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent) - */ - public void keyReleased(KeyEvent e) { - Day day = (Day) e.widget; - Point coordinates = day.getMonthPosition(); - e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); - - for (Iterator keyListenersIter = keyListeners.iterator(); keyListenersIter.hasNext();) { - KeyListener listener = (KeyListener) keyListenersIter.next(); - listener.keyReleased(e); - } - - // No need for this logic here yet, but leaving it commented - // as a reminder... - - // if (!e.doit) return; - } - }; - - - /** - * @see org.eclipse.swt.widgets.Composite#setFocus() - */ - public boolean setFocus() { - checkWidget(); - int week = 0; - int day = 0; - if (selectedDay != null) { - Point position = selectedDay.coordinates; - week = position.y; - day = position.x; - } else { - Calendar cal = GregorianCalendar.getInstance(); - week = cal.get(Calendar.WEEK_OF_MONTH) - 1; - day = cal.get(Calendar.DAY_OF_WEEK) - 1; - } - Day newDay = weeks[week].getDay(day); - return newDay.setFocus(); - } - - public void select(Date newDate) { - Calendar cal = GregorianCalendar.getInstance(); - cal.setTime(newDate); - int newMonth = cal.get(Calendar.MONTH); - int week = cal.get(Calendar.WEEK_OF_MONTH) - 1; - int day = cal.get(Calendar.DAY_OF_WEEK) - 1; - - Point coords = new Point(day, week); - MonthCalendarSelectedDay newSelectedDay = new MonthCalendarSelectedDay(newDate, coords); - - int state = Day.NONACTIVE_FOCUS; - - MonthCalendarSelectedDay oldSelectedDay = getSelectedDay(); - if (oldSelectedDay != null) { - Day oldDay = weeks[oldSelectedDay.coordinates.y].getDay(oldSelectedDay.coordinates.x); - state = oldDay.getFocusState(); - oldDay.setFocusState(Day.NO_FOCUS); - oldDay.redraw(); - } - - cal.clear(); - - cal.setTime(startDate); - int currentMonth = cal.get(Calendar.MONTH); - if (currentMonth != newMonth) { - setStartDate(newDate); - } - - Day newDay = weeks[week].getDay(day); - - if (state == Day.FOCUS) { - newDay.setFocus(); - } else { - newDay.setFocusState(Day.NONACTIVE_FOCUS); - newDay.redraw(); - selectedDay = newSelectedDay; - } - } - -} +/******************************************************************************* + * Copyright (c) 2006 The Pampered Chef and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * The Pampered Chef - initial API and implementation + ******************************************************************************/ +package org.eclipse.nebula.widgets.compositetable.month; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler; +import org.eclipse.nebula.widgets.compositetable.day.CalendarableSelectionChangeListener; +import org.eclipse.nebula.widgets.compositetable.month.internal.Day; +import org.eclipse.nebula.widgets.compositetable.month.internal.Week; +import org.eclipse.nebula.widgets.compositetable.month.internal.WeekHeader; +import org.eclipse.nebula.widgets.compositetable.timeeditor.AbstractEventEditor; +import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem; +import org.eclipse.nebula.widgets.compositetable.timeeditor.EventContentProvider; +import org.eclipse.nebula.widgets.compositetable.timeeditor.EventCountProvider; +import org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** + * An IEventEditor implementing a month calendar. This class is not intended + * to be subclassed. + */ +public class MonthCalendar extends AbstractEventEditor implements IEventEditor { + + private Date startDate; + private WeekHeader weekHeader = null; + private Composite weeksHolder = null; + private Week[] weeks; + + /** + * Constructor DayEditor. Constructs a calendar control that can display + * events on one or more days. + * + * @param parent + * @param style The same style bits as @see Composite + */ + public MonthCalendar(Composite parent, int style) { + super(parent, style); + initialize(); + weeks = new Week[0]; + setStartDate(new Date()); + } + + private void initialize() { + GridLayout gl = new GridLayout(); + gl.horizontalSpacing = 0; + gl.marginWidth = 0; + gl.verticalSpacing = 0; + gl.marginHeight = 0; + createWeekHeader(); + this.setLayout(gl); + createWeeksHolder(); + } + + /** + * This method initializes weekHeader + * + */ + private void createWeekHeader() { + GridData gridData = new GridData(); + gridData.horizontalAlignment = GridData.FILL; + gridData.grabExcessHorizontalSpace = true; + gridData.verticalAlignment = GridData.CENTER; + weekHeader = new WeekHeader(this, SWT.NONE); + weekHeader.setLayoutData(gridData); + } + + /** + * This method initializes composite + * + */ + private void createWeeksHolder() { + weeksHolder = new Composite(this, SWT.NONE); + + GridLayout gridLayout = new GridLayout(); + gridLayout.horizontalSpacing = 0; + gridLayout.marginWidth = 0; + gridLayout.verticalSpacing = 1; + gridLayout.marginHeight = 0; + weeksHolder.setLayout(gridLayout); + + GridData gd = new GridData(); + gd.horizontalAlignment = GridData.FILL; + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.verticalAlignment = GridData.FILL; + weeksHolder.setLayoutData(gd); + } + + /** + * This method initializes week + */ + private Week createWeek() { + GridData gd = new GridData(); + gd.horizontalAlignment = GridData.FILL; + gd.grabExcessHorizontalSpace = true; + gd.grabExcessVerticalSpace = true; + gd.verticalAlignment = GridData.FILL; + Week week = new Week(weeksHolder, SWT.NONE); + week.setLayoutData(gd); + return week; + } + + /** + * Sets the start date for this MonthCalendar. + *

+ * The date is set to the first day of the specified month and the time part + * of the Date object is set to midnight before storing. Calling + * {@link #getStartDate()} will return this mutilated version instead of the + * original. + * + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setStartDate(java.util.Date) + */ + public void setStartDate(Date startDate) { + checkWidget(); + + Calendar c = new GregorianCalendar(); + c.setTime(startDate); + c.set(Calendar.DAY_OF_MONTH, 1); + c.set(Calendar.HOUR_OF_DAY, 0); + c.set(Calendar.MINUTE, 0); + c.set(Calendar.SECOND, 0); + c.set(Calendar.MILLISECOND, 0); + this.startDate = c.getTime(); + refresh(); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getStartDate() + */ + public Date getStartDate() { + checkWidget(); + + return startDate; + } + + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#refresh(java.util.Date) + */ + public void refresh(Date date) { + checkWidget(); + + if (date == null) { + refresh(); + return; + } + + Calendar currentDay = new GregorianCalendar(); + currentDay.setTime(startDate); + currentDay.set(Calendar.DAY_OF_MONTH, 1); + currentDay.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); + + Calendar endDay = new GregorianCalendar(); + endDay.setTime(date); + endDay.set(Calendar.HOUR_OF_DAY, 0); + endDay.set(Calendar.MINUTE, 0); + endDay.set(Calendar.SECOND, 0); + endDay.set(Calendar.MILLISECOND, 0); + Date targetDate = endDay.getTime(); + + Day currentDayControl = null; + for (int week = 0; week < weeks.length; week++) { + for (int day = 0; day < 7; day++) { + currentDayControl = weeks[week].getDay(day); + + currentDay.add(Calendar.DAY_OF_MONTH, 1); + if (currentDay.getTime().after(targetDate)) { + refresh(date, currentDayControl); + return; + } + } + } + } + + private void refresh(Date date, Day dayControl) { + dayControl.setDate(date); + if (eventCountProvider == null || eventContentProvider == null) { + return; + } + int numberOfEventsInDay = eventCountProvider.getNumberOfEventsInDay(date); + CalendarableItem controls[] = new CalendarableItem[numberOfEventsInDay]; + for (int i = 0; i < controls.length; i++) { + controls[i] = new CalendarableItem(date); + } + eventContentProvider.refresh(date, controls); + dayControl.setItems(controls); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.AbstractEventEditor#refresh() + */ + public void refresh() { + checkWidget(); + + Calendar c = new GregorianCalendar(); + c.setTime(startDate); + int currentMonth = c.get(Calendar.MONTH); + + Calendar nextMonthCalendar = new GregorianCalendar(); + nextMonthCalendar.setTime(c.getTime()); + nextMonthCalendar.add(Calendar.MONTH, 1); + Date nextMonth = nextMonthCalendar.getTime(); + + c.set(Calendar.DAY_OF_MONTH, 1); + c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); + + LinkedList newWeeksArray = new LinkedList<>(); + + for (int week = 0; c.getTime().before(nextMonth); week++) { + if (weeks.length > week) { + newWeeksArray.addLast(weeks[week]); + } else { + Week newWeek = createWeek(); + newWeeksArray.addLast(newWeek); + for (int day = 0; day < 7; day++) { + Day newDay = newWeek.getDay(day); + newDay.setMonthPosition(new Point(day, week)); + newDay.addKeyListener(dayKeyListener); + newDay.addMouseListener(dayMouseListener); + newDay.addFocusListener(dayFocusListener); + } + } + for (int day = 0; day < 7; day++) { + Day currentDay = ((Week) newWeeksArray.get(week)).getDay(day); + currentDay.setInCurrentMonth(c.get(Calendar.MONTH) == currentMonth); + currentDay.setDayNumber(c.get(Calendar.DAY_OF_MONTH)); + refresh(c.getTime(), currentDay); + currentDay.layout(true); + c.add(Calendar.DAY_OF_MONTH, 1); + } + } + if (weeks.length > newWeeksArray.size()) { + for (int extraWeek = newWeeksArray.size(); extraWeek < weeks.length; ++extraWeek) { + weeks[extraWeek].dispose(); + } + } + if (weeks.length != newWeeksArray.size()) { + weeksHolder.layout(true); + } + weeks = (Week[]) newWeeksArray.toArray(new Week[newWeeksArray.size()]); + } + + private EventContentProvider eventContentProvider = null; + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setEventContentProvider(org.eclipse.nebula.widgets.compositetable.timeeditor.EventContentProvider) + */ + public void setEventContentProvider(EventContentProvider eventContentProvider) { + checkWidget(); + + this.eventContentProvider = eventContentProvider; + } + + private EventCountProvider eventCountProvider = null; + + + public void setEventCountProvider(EventCountProvider eventCountProvider) { + checkWidget(); + + this.eventCountProvider = eventCountProvider; + } + + private List deleteHandlers = new ArrayList<>(); + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#addItemDeleteHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) + */ + public void addItemDeleteHandler(CalendarableItemEventHandler deleteHandler) { + checkWidget(); + + deleteHandlers.add(deleteHandler); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#removeItemDeleteHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) + */ + public void removeItemDeleteHandler(CalendarableItemEventHandler deleteHandler) { + checkWidget(); + + deleteHandlers.remove(deleteHandler); + } + + private List disposeHandlers = new ArrayList<>(); + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#addItemDisposeHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) + */ + public void addItemDisposeHandler(CalendarableItemEventHandler itemDisposeHandler) { + checkWidget(); + + disposeHandlers.add(itemDisposeHandler); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#removeItemDisposeHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) + */ + public void removeItemDisposeHandler(CalendarableItemEventHandler itemDisposeHandler) { + checkWidget(); + disposeHandlers.remove(itemDisposeHandler); + } + + private List itemEditHandlers = new ArrayList<>(); + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#addItemEditHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) + */ + public void addItemEditHandler(CalendarableItemEventHandler handler) { + checkWidget(); + + itemEditHandlers.add(handler); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#removeItemEditHandler(org.eclipse.nebula.widgets.compositetable.day.CalendarableItemEventHandler) + */ + public void removeItemEditHandler(CalendarableItemEventHandler handler) { + checkWidget(); + + itemEditHandlers.remove(handler); + } + + private List selectionChangeListeners = new ArrayList<>(); + + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#addSelectionChangeListener(org.eclipse.nebula.widgets.compositetable.day.CalendarableSelectionChangeListener) + */ + public void addSelectionChangeListener(CalendarableSelectionChangeListener l) { + checkWidget(); + + selectionChangeListeners.add(l); + } + + public void removeSelectionChangeListener(CalendarableSelectionChangeListener l) { + checkWidget(); + + selectionChangeListeners.remove(l); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#fireDelete(org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem) + */ + public boolean fireDelete(CalendarableItem toDelete) { + checkWidget(); + return false; + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#setTimeBreakdown(int, int) + */ + public void setTimeBreakdown(int numberOfDays, int numberOfDivisionsInHour) { + checkWidget(); + // NOOP + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getNumberOfDays() + */ + public int getNumberOfDays() { + checkWidget(); + + // Return the number of days in the current month + Calendar c = new GregorianCalendar(); + c.setTime(startDate); + return c.getActualMaximum(Calendar.DAY_OF_MONTH); + } + + /** + * @see org.eclipse.nebula.widgets.compositetable.timeeditor.IEventEditor#getNumberOfDivisionsInHour() + */ + public int getNumberOfDivisionsInHour() { + checkWidget(); + // NOOP + return -1; + } + + private MonthCalendarSelectedDay selectedDay = null; + + /** + * Method getSelectedDay. Returns the currently-selected day. + * + * @return The current MonthCalendarSelection which represents the currently- + * selected day. + */ + public MonthCalendarSelectedDay getSelectedDay() { + checkWidget(); + + return selectedDay; + } + + private List focusListeners = new ArrayList<>(); + + /** + * Adds the listener to the collection of listeners who will + * be notified when the control gains or loses focus, by sending + * it one of the messages defined in the FocusListener + * interface. + *

+ * In addition, e.data in the FocusEvent is the current MonthCalendarSelectedDay. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see FocusListener + * @see #removeFocusListener + * @see org.eclipse.swt.widgets.Control#addFocusListener(org.eclipse.swt.events.FocusListener) + */ + public void addFocusListener(FocusListener listener) { + checkWidget(); + + super.addFocusListener(listener); + focusListeners.add(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the control gains or loses focus. + *

+ * In addition, e.data in the FocusEvent is the current MonthCalendarSelectedDay. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see FocusListener + * @see #addFocusListener + * @see org.eclipse.swt.widgets.Control#removeFocusListener(org.eclipse.swt.events.FocusListener) + */ + public void removeFocusListener(FocusListener listener) { + checkWidget(); + + super.removeFocusListener(listener); + focusListeners.remove(listener); + } + + private Day lastSelectedDay; + + private FocusListener dayFocusListener = new FocusListener() { + public void focusGained(FocusEvent e) { + Day day = (Day) e.widget; + if (lastSelectedDay != null && lastSelectedDay != day) { + lastSelectedDay.setFocusState(Day.NO_FOCUS); + lastSelectedDay.redraw(); + } + + Point coordinates = day.getMonthPosition(); + selectedDay = new MonthCalendarSelectedDay(day.getDate(), coordinates); + e.data = selectedDay; + + lastSelectedDay = day; + + for (Iterator focusListenersIter = focusListeners.iterator(); focusListenersIter.hasNext();) { + FocusListener listener = (FocusListener) focusListenersIter.next(); + listener.focusGained(e); + } + } + + public void focusLost(FocusEvent e) { + Day day = (Day) e.widget; + Point coordinates = day.getMonthPosition(); + e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); + + for (Iterator focusListenersIter = focusListeners.iterator(); focusListenersIter.hasNext();) { + FocusListener listener = (FocusListener) focusListenersIter.next(); + listener.focusLost(e); + } + } + }; + + private List mouseListeners = new ArrayList<>(); + + /** + * @see org.eclipse.swt.widgets.Control#addMouseListener(org.eclipse.swt.events.MouseListener) + */ + public void addMouseListener(MouseListener listener) { + checkWidget(); + + super.addMouseListener(listener); + mouseListeners.add(listener); + } + + /** + * @see org.eclipse.swt.widgets.Control#removeMouseListener(org.eclipse.swt.events.MouseListener) + */ + public void removeMouseListener(MouseListener listener) { + checkWidget(); + + super.removeMouseListener(listener); + mouseListeners.remove(listener); + } + + private MouseListener dayMouseListener = new MouseListener() { + private Day getDay(MouseEvent e) { + Control control = (Control) e.widget; + while (!(control instanceof Day)) { + control = control.getParent(); + } + Day day = (Day) control; + return day; + } + + public void mouseDown(MouseEvent e) { + Day day = getDay(e); + Point coordinates = day.getMonthPosition(); + e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); + + for (Iterator mouseListenersIter = mouseListeners.iterator(); mouseListenersIter.hasNext();) { + MouseListener listener = (MouseListener) mouseListenersIter.next(); + listener.mouseDown(e); + } + } + + public void mouseUp(MouseEvent e) { + Day day = getDay(e); + Point coordinates = day.getMonthPosition(); + e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); + + for (Iterator mouseListenersIter = mouseListeners.iterator(); mouseListenersIter.hasNext();) { + MouseListener listener = (MouseListener) mouseListenersIter.next(); + listener.mouseUp(e); + } + } + + public void mouseDoubleClick(MouseEvent e) { + Day day = getDay(e); + Point coordinates = day.getMonthPosition(); + e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); + + for (Iterator mouseListenersIter = mouseListeners.iterator(); mouseListenersIter.hasNext();) { + MouseListener listener = (MouseListener) mouseListenersIter.next(); + listener.mouseDoubleClick(e); + } + } + }; + + private List keyListeners = new ArrayList<>(); + + /** + * Adds the listener to the collection of listeners who will + * be notified when keys are pressed and released on the system keyboard, by + * sending it one of the messages defined in the KeyListener + * interface. + *

+ * In addition to the usual KeyListener contract, MonthCalendar will honor + * e.doit and will not perform its usual key processing if any KeyListener + * sets e.doit to false. + *

+ * In addition to the usual KeyEvent fields, e.data is set to the current + * MonthCalendarSelection. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see org.eclipse.swt.widgets.Control#addKeyListener(org.eclipse.swt.events.KeyListener) + */ + public void addKeyListener(KeyListener listener) { + checkWidget(); + + super.addKeyListener(listener); + keyListeners.add(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when keys are pressed and released on the system keyboard. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see KeyListener + * @see #addKeyListener + * @see org.eclipse.swt.widgets.Control#removeKeyListener(org.eclipse.swt.events.KeyListener) + */ + public void removeKeyListener(KeyListener listener) { + checkWidget(); + + super.removeKeyListener(listener); + keyListeners.remove(listener); + } + + private KeyListener dayKeyListener = new KeyAdapter() { + public void keyPressed(KeyEvent e) { + Day day = (Day) e.widget; + Point coordinates = day.getMonthPosition(); + e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); + + for (Iterator keyListenersIter = keyListeners.iterator(); keyListenersIter.hasNext();) { + KeyListener listener = (KeyListener) keyListenersIter.next(); + listener.keyPressed(e); + } + + if (!e.doit) { + return; + } + + switch (e.keyCode) { + case SWT.ARROW_UP: + if (coordinates.y > 0) { + Day newDay = weeks[coordinates.y - 1].getDay(coordinates.x); + newDay.setFocus(); + } + return; + case SWT.ARROW_DOWN: + if (coordinates.y < weeks.length - 1) { + Day newDay = weeks[coordinates.y + 1].getDay(coordinates.x); + newDay.setFocus(); + } + return; + } + } + + + /** + * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent) + */ + public void keyReleased(KeyEvent e) { + Day day = (Day) e.widget; + Point coordinates = day.getMonthPosition(); + e.data = new MonthCalendarSelectedDay(day.getDate(), coordinates); + + for (Iterator keyListenersIter = keyListeners.iterator(); keyListenersIter.hasNext();) { + KeyListener listener = (KeyListener) keyListenersIter.next(); + listener.keyReleased(e); + } + + // No need for this logic here yet, but leaving it commented + // as a reminder... + + // if (!e.doit) return; + } + }; + + + /** + * @see org.eclipse.swt.widgets.Composite#setFocus() + */ + public boolean setFocus() { + checkWidget(); + int week = 0; + int day = 0; + if (selectedDay != null) { + Point position = selectedDay.coordinates; + week = position.y; + day = position.x; + } else { + Calendar cal = GregorianCalendar.getInstance(); + week = cal.get(Calendar.WEEK_OF_MONTH) - 1; + day = cal.get(Calendar.DAY_OF_WEEK) - 1; + } + Day newDay = weeks[week].getDay(day); + return newDay.setFocus(); + } + + public void select(Date newDate) { + Calendar cal = GregorianCalendar.getInstance(); + cal.setTime(newDate); + int newMonth = cal.get(Calendar.MONTH); + int week = cal.get(Calendar.WEEK_OF_MONTH) - 1; + int day = cal.get(Calendar.DAY_OF_WEEK) - 1; + + Point coords = new Point(day, week); + MonthCalendarSelectedDay newSelectedDay = new MonthCalendarSelectedDay(newDate, coords); + + int state = Day.NONACTIVE_FOCUS; + + MonthCalendarSelectedDay oldSelectedDay = getSelectedDay(); + if (oldSelectedDay != null) { + Day oldDay = weeks[oldSelectedDay.coordinates.y].getDay(oldSelectedDay.coordinates.x); + state = oldDay.getFocusState(); + oldDay.setFocusState(Day.NO_FOCUS); + oldDay.redraw(); + } + + cal.clear(); + + cal.setTime(startDate); + int currentMonth = cal.get(Calendar.MONTH); + if (currentMonth != newMonth) { + setStartDate(newDate); + } + + Day newDay = weeks[week].getDay(day); + + if (state == Day.FOCUS) { + newDay.setFocus(); + } else { + newDay.setFocusState(Day.NONACTIVE_FOCUS); + newDay.redraw(); + selectedDay = newSelectedDay; + } + } + +} diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/month/internal/Day.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/month/internal/Day.java index 7eeb7ad0e..09a07d9a5 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/month/internal/Day.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/month/internal/Day.java @@ -1,433 +1,433 @@ -/******************************************************************************* - * Copyright (c) 2006 The Pampered Chef and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * The Pampered Chef - initial API and implementation - ******************************************************************************/ -package org.eclipse.nebula.widgets.compositetable.month.internal; - -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedList; - -import org.eclipse.swt.SWT; -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.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.TraverseEvent; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.nebula.widgets.compositetable.day.ICalendarableItemControl; -import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; - -/** - * An SWT custom control representing a single day in a month-mode calendar. - */ -public class Day extends Canvas implements PaintListener, DisposeListener { - private final Color FOCUS_RUBBERBAND; - private final Color NONACTIVE_FOCUS_RUBBERBAND; - private Color CURRENT_MONTH; - private Color OTHER_MONTH; - private Color CELL_BACKGROUND_LIGHT; - - private static final int FOCUS_LINE_WIDTH = 2; - - public static final int NONACTIVE_FOCUS = -1; - public static final int FOCUS = 0; - public static final int NO_FOCUS = 1; - private int focusState = NO_FOCUS; - - private static final int _SIZE_MULTIPLIER = 7; - private Label dayNumber = null; - private Label spacer = null; - private Point textBounds; - - private Point monthPosition = null; - - /** - * @param parent - * @param style - */ - public Day(Composite parent, int style) { - super(parent, style); - - Display display = Display.getCurrent(); - FOCUS_RUBBERBAND = new Color(display, lighten(saturate(display.getSystemColor(SWT.COLOR_TITLE_BACKGROUND).getRGB(), .85f), -.333f)); - NONACTIVE_FOCUS_RUBBERBAND = new Color(display, lighten(saturate(display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND).getRGB(), .0f), -.333f)); - CURRENT_MONTH = display.getSystemColor(SWT.COLOR_WHITE); - OTHER_MONTH = new Color(display, new RGB(230, 230, 230)); - CELL_BACKGROUND_LIGHT = new Color(display, new RGB(248, 248, 248)); - - initialize(); - - addTraverseListener(traverseListener); - addKeyListener(keyListener); - addMouseListener(mouseListener); - spacer.addMouseListener(mouseListener); - dayNumber.addMouseListener(mouseListener); - addFocusListener(focusListener); - addPaintListener(this); - addDisposeListener(this); - } - - /** - * Sets the color's saturation to the specified value. - * - * @param color The RGB of the color - * @param saturation the new saturation (between 0 and 1) - * @return a Color that is saturated by the specified amount - */ - private RGB saturate(RGB color, float saturation) { - float[] hsb = color.getHSB(); - return new RGB(hsb[0], saturation, hsb[2]); - } - - /** - * @param color The RGB of the color - * @param amount The amount to lighten as a percentage expresssed as a float between -1 and 1. - * @return The new RGB that is lightened by the specified amount - */ - private RGB lighten(RGB color, float amount) { - float[] hsb = color.getHSB(); - float b = hsb[2] + hsb[2] * amount; - if (b < 0) - b = 0; - if (b > 1) - b = 1; - return new RGB(hsb[0], hsb[1], b); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) - */ - public void widgetDisposed(DisposeEvent e) { - FOCUS_RUBBERBAND.dispose(); - NONACTIVE_FOCUS_RUBBERBAND.dispose(); - OTHER_MONTH.dispose(); - CELL_BACKGROUND_LIGHT.dispose(); - - removeTraverseListener(traverseListener); - removeKeyListener(keyListener); - removeMouseListener(mouseListener); - spacer.removeMouseListener(mouseListener); - dayNumber.removeMouseListener(mouseListener); - removeFocusListener(focusListener); - removePaintListener(this); - removeDisposeListener(this); - } - - private void initialize() { - GridData gd = new GridData(); - gd.horizontalSpan = 2; - gd.verticalAlignment = GridData.FILL; - gd.grabExcessVerticalSpace = true; - gd.grabExcessHorizontalSpace = true; - gd.horizontalAlignment = GridData.FILL; - GridData gridData = new GridData(); - gridData.horizontalAlignment = GridData.FILL; - gridData.grabExcessHorizontalSpace = true; - gridData.verticalAlignment = GridData.CENTER; - spacer = new Label(this, SWT.NONE); - spacer.setLayoutData(gridData); - spacer.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - GridLayout gridLayout = new GridLayout(); - gridLayout.numColumns = 2; - gridLayout.verticalSpacing = 0; - dayNumber = new Label(this, SWT.NONE); - dayNumber.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - dayNumber.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION)); - dayNumber.setText("31"); - textBounds = dayNumber.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); - this.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - this.setLayout(gridLayout); - setSize(new org.eclipse.swt.graphics.Point(106, 101)); - setBackground(CELL_BACKGROUND_LIGHT); - } - - public Point computeSize(int wHint, int hHint, boolean changed) { - Point size = new Point(0, 0); - size.x = textBounds.x * _SIZE_MULTIPLIER; - size.y = textBounds.y * _SIZE_MULTIPLIER / 2; - return size; - } - - /** - * @return The (day, week) of this day in the month. - */ - public Point getMonthPosition() { - return monthPosition; - } - - /** - * @param monthPosition The (day, week) of this day in the month. - */ - public void setMonthPosition(Point monthPosition) { - this.monthPosition = monthPosition; - } - - /** - * @return The day's number - */ - public int getDayNumber() { - return Integer.parseInt(dayNumber.getText()); - } - - /** - * @param dayNum the day number to set - */ - public void setDayNumber(int dayNum) { - dayNumber.setText(Integer.toString(dayNum)); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent) - */ - public void paintControl(PaintEvent e) { - GC gc = e.gc; - - // Save stuff we're about to change so we can restore it later - int oldLineStyle = gc.getLineStyle(); - int oldLineWidth = gc.getLineWidth(); - - // Draw focus rubberband if we're focused - try { - if (focusState != Day.NO_FOCUS) { - if (focusState == Day.NONACTIVE_FOCUS) { - gc.setForeground(NONACTIVE_FOCUS_RUBBERBAND); - } else { - gc.setForeground(FOCUS_RUBBERBAND); - } - gc.setLineStyle(SWT.LINE_DASH); - gc.setLineWidth(FOCUS_LINE_WIDTH); - Point parentSize = getSize(); - gc.drawRectangle(FOCUS_LINE_WIDTH, FOCUS_LINE_WIDTH, parentSize.x - 4, parentSize.y - 3); - } - } finally { - gc.setLineStyle(oldLineStyle); - gc.setLineWidth(oldLineWidth); - } - } - - private LinkedList mouseListeners = new LinkedList<>(); - - /* - * (non-Javadoc) - * - * @see org.eclipse.swt.widgets.Control#addMouseListener(org.eclipse.swt.events.MouseListener) - */ - public void addMouseListener(MouseListener listener) { - super.addMouseListener(listener); - if (listener != mouseListener) - mouseListeners.add(listener); - } - - public void removeMouseListener(MouseListener listener) { - super.removeMouseListener(listener); - if (listener != mouseListener) - mouseListeners.remove(listener); - } - - private MouseListener mouseListener = new MouseListener() { - public void mouseDown(MouseEvent e) { - setFocus(); - for (Iterator i = mouseListeners.iterator(); i.hasNext();) { - MouseListener listener = (MouseListener) i.next(); - listener.mouseDown(e); - } - } - - public void mouseUp(MouseEvent e) { - for (Iterator i = mouseListeners.iterator(); i.hasNext();) { - MouseListener listener = (MouseListener) i.next(); - listener.mouseUp(e); - } - } - - public void mouseDoubleClick(MouseEvent e) { - for (Iterator i = mouseListeners.iterator(); i.hasNext();) { - MouseListener listener = (MouseListener) i.next(); - listener.mouseDoubleClick(e); - } - } - }; - - private KeyListener keyListener = new KeyAdapter() { - public void keyPressed(KeyEvent e) { - switch (e.keyCode) { - case SWT.ARROW_LEFT: - if (monthPosition.x > 0) { - traverse(SWT.TRAVERSE_TAB_PREVIOUS); - } - return; - case SWT.ARROW_RIGHT: - if (monthPosition.x < 6) { - traverse(SWT.TRAVERSE_TAB_NEXT); - } - return; - case SWT.TAB: - if ((e.stateMask & SWT.SHIFT) != 0) { - traverse(SWT.TRAVERSE_TAB_PREVIOUS); - return; - } - traverse(SWT.TRAVERSE_TAB_NEXT); - return; - } - } - }; - - /** - * Permit focus events via keyboard. - */ - private TraverseListener traverseListener = new TraverseListener() { - public void keyTraversed(TraverseEvent e) { - // NOOP: this just lets us receive focus from SWT - } - }; - - /** - * When we gain/lose focus, redraw ourselves appropriately - */ - private FocusListener focusListener = new FocusListener() { - public void focusGained(FocusEvent e) { - focusState = Day.FOCUS; - Color background = getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(true); - resetAllBackgrounds(Day.this, background); - redraw(); - } - - public void focusLost(FocusEvent e) { - focusState = Day.NONACTIVE_FOCUS; - Color background = getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(false); - resetAllBackgrounds(Day.this, background); - redraw(); - } - }; - - private void resetAllBackgrounds(Composite composite, Color color) { - composite.setBackground(color); - Control[] children = composite.getChildren(); - for (int i = 0; i < children.length; i++) { - if (children[i] instanceof Composite) { - resetAllBackgrounds((Composite) children[i], color); - } else { - children[i].setBackground(color); - } - } - } - - private Color getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(boolean focused) { - if (inCurrentMonth && focused) { - return CURRENT_MONTH; - } - if (inCurrentMonth) { - return CELL_BACKGROUND_LIGHT; - } - return OTHER_MONTH; - } - - private boolean inCurrentMonth = false; - - /** - * @param inCurrentMonth - */ - public void setInCurrentMonth(boolean inCurrentMonth) { - this.inCurrentMonth = inCurrentMonth; - Color background = getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(false); - resetAllBackgrounds(this, background); - } - - private CalendarableItem[] controls = null; - - /** - * @param controls - */ - public void setItems(CalendarableItem[] controls) { - if (this.controls != null) { - for (int i = 0; i < this.controls.length; i++) { - ICalendarableItemControl control = this.controls[i].getControl(); - control.removeMouseListener(mouseListener); - control.dispose(); - } - } - this.controls = controls; - for (int i = 0; i < this.controls.length; i++) { - MonthCalendarableItemControl control = new MonthCalendarableItemControl(this, SWT.NULL); - getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(false); - control.setText(this.controls[i].getText()); - Image image = this.controls[i].getImage(); - if (image != null) { - control.setImage(image); - } - control.setToolTipText(this.controls[i].getToolTipText()); - control.addMouseListener(mouseListener); - GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false); - gd.horizontalSpan = 2; - control.setLayoutData(gd); - this.controls[i].setControl(control); - } - } - - private Date date; - - /** - * Sets the Date represented by this Day. - * - * @param date The date to set - */ - public void setDate(Date date) { - this.date = date; - } - - /** - * Returns the Date represented by this Day. - * - * @return This Day's date - */ - public Date getDate() { - return date; - } - - public int getFocusState() { - return focusState; - } - - public void setFocusState(int focusState) { - if (focusState > 0) - this.focusState = NO_FOCUS; - else if (focusState < 0) - this.focusState = NONACTIVE_FOCUS; - else - this.focusState = FOCUS; - } - -} // @jve:decl-index=0:visual-constraint="10,10" +/******************************************************************************* + * Copyright (c) 2006 The Pampered Chef and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * The Pampered Chef - initial API and implementation + ******************************************************************************/ +package org.eclipse.nebula.widgets.compositetable.month.internal; + +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; + +import org.eclipse.swt.SWT; +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.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.nebula.widgets.compositetable.day.ICalendarableItemControl; +import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; + +/** + * An SWT custom control representing a single day in a month-mode calendar. + */ +public class Day extends Canvas implements PaintListener, DisposeListener { + private final Color FOCUS_RUBBERBAND; + private final Color NONACTIVE_FOCUS_RUBBERBAND; + private Color CURRENT_MONTH; + private Color OTHER_MONTH; + private Color CELL_BACKGROUND_LIGHT; + + private static final int FOCUS_LINE_WIDTH = 2; + + public static final int NONACTIVE_FOCUS = -1; + public static final int FOCUS = 0; + public static final int NO_FOCUS = 1; + private int focusState = NO_FOCUS; + + private static final int _SIZE_MULTIPLIER = 7; + private Label dayNumber = null; + private Label spacer = null; + private Point textBounds; + + private Point monthPosition = null; + + /** + * @param parent + * @param style + */ + public Day(Composite parent, int style) { + super(parent, style); + + Display display = Display.getCurrent(); + FOCUS_RUBBERBAND = new Color(display, lighten(saturate(display.getSystemColor(SWT.COLOR_TITLE_BACKGROUND).getRGB(), .85f), -.333f)); + NONACTIVE_FOCUS_RUBBERBAND = new Color(display, lighten(saturate(display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND).getRGB(), .0f), -.333f)); + CURRENT_MONTH = display.getSystemColor(SWT.COLOR_WHITE); + OTHER_MONTH = new Color(display, new RGB(230, 230, 230)); + CELL_BACKGROUND_LIGHT = new Color(display, new RGB(248, 248, 248)); + + initialize(); + + addTraverseListener(traverseListener); + addKeyListener(keyListener); + addMouseListener(mouseListener); + spacer.addMouseListener(mouseListener); + dayNumber.addMouseListener(mouseListener); + addFocusListener(focusListener); + addPaintListener(this); + addDisposeListener(this); + } + + /** + * Sets the color's saturation to the specified value. + * + * @param color The RGB of the color + * @param saturation the new saturation (between 0 and 1) + * @return a Color that is saturated by the specified amount + */ + private RGB saturate(RGB color, float saturation) { + float[] hsb = color.getHSB(); + return new RGB(hsb[0], saturation, hsb[2]); + } + + /** + * @param color The RGB of the color + * @param amount The amount to lighten as a percentage expresssed as a float between -1 and 1. + * @return The new RGB that is lightened by the specified amount + */ + private RGB lighten(RGB color, float amount) { + float[] hsb = color.getHSB(); + float b = hsb[2] + hsb[2] * amount; + if (b < 0) + b = 0; + if (b > 1) + b = 1; + return new RGB(hsb[0], hsb[1], b); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + FOCUS_RUBBERBAND.dispose(); + NONACTIVE_FOCUS_RUBBERBAND.dispose(); + OTHER_MONTH.dispose(); + CELL_BACKGROUND_LIGHT.dispose(); + + removeTraverseListener(traverseListener); + removeKeyListener(keyListener); + removeMouseListener(mouseListener); + spacer.removeMouseListener(mouseListener); + dayNumber.removeMouseListener(mouseListener); + removeFocusListener(focusListener); + removePaintListener(this); + removeDisposeListener(this); + } + + private void initialize() { + GridData gd = new GridData(); + gd.horizontalSpan = 2; + gd.verticalAlignment = GridData.FILL; + gd.grabExcessVerticalSpace = true; + gd.grabExcessHorizontalSpace = true; + gd.horizontalAlignment = GridData.FILL; + GridData gridData = new GridData(); + gridData.horizontalAlignment = GridData.FILL; + gridData.grabExcessHorizontalSpace = true; + gridData.verticalAlignment = GridData.CENTER; + spacer = new Label(this, SWT.NONE); + spacer.setLayoutData(gridData); + spacer.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + gridLayout.verticalSpacing = 0; + dayNumber = new Label(this, SWT.NONE); + dayNumber.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + dayNumber.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION)); + dayNumber.setText("31"); + textBounds = dayNumber.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + this.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + this.setLayout(gridLayout); + setSize(new org.eclipse.swt.graphics.Point(106, 101)); + setBackground(CELL_BACKGROUND_LIGHT); + } + + public Point computeSize(int wHint, int hHint, boolean changed) { + Point size = new Point(0, 0); + size.x = textBounds.x * _SIZE_MULTIPLIER; + size.y = textBounds.y * _SIZE_MULTIPLIER / 2; + return size; + } + + /** + * @return The (day, week) of this day in the month. + */ + public Point getMonthPosition() { + return monthPosition; + } + + /** + * @param monthPosition The (day, week) of this day in the month. + */ + public void setMonthPosition(Point monthPosition) { + this.monthPosition = monthPosition; + } + + /** + * @return The day's number + */ + public int getDayNumber() { + return Integer.parseInt(dayNumber.getText()); + } + + /** + * @param dayNum the day number to set + */ + public void setDayNumber(int dayNum) { + dayNumber.setText(Integer.toString(dayNum)); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent) + */ + public void paintControl(PaintEvent e) { + GC gc = e.gc; + + // Save stuff we're about to change so we can restore it later + int oldLineStyle = gc.getLineStyle(); + int oldLineWidth = gc.getLineWidth(); + + // Draw focus rubberband if we're focused + try { + if (focusState != Day.NO_FOCUS) { + if (focusState == Day.NONACTIVE_FOCUS) { + gc.setForeground(NONACTIVE_FOCUS_RUBBERBAND); + } else { + gc.setForeground(FOCUS_RUBBERBAND); + } + gc.setLineStyle(SWT.LINE_DASH); + gc.setLineWidth(FOCUS_LINE_WIDTH); + Point parentSize = getSize(); + gc.drawRectangle(FOCUS_LINE_WIDTH, FOCUS_LINE_WIDTH, parentSize.x - 4, parentSize.y - 3); + } + } finally { + gc.setLineStyle(oldLineStyle); + gc.setLineWidth(oldLineWidth); + } + } + + private LinkedList mouseListeners = new LinkedList<>(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.widgets.Control#addMouseListener(org.eclipse.swt.events.MouseListener) + */ + public void addMouseListener(MouseListener listener) { + super.addMouseListener(listener); + if (listener != mouseListener) + mouseListeners.add(listener); + } + + public void removeMouseListener(MouseListener listener) { + super.removeMouseListener(listener); + if (listener != mouseListener) + mouseListeners.remove(listener); + } + + private MouseListener mouseListener = new MouseListener() { + public void mouseDown(MouseEvent e) { + setFocus(); + for (Iterator i = mouseListeners.iterator(); i.hasNext();) { + MouseListener listener = (MouseListener) i.next(); + listener.mouseDown(e); + } + } + + public void mouseUp(MouseEvent e) { + for (Iterator i = mouseListeners.iterator(); i.hasNext();) { + MouseListener listener = (MouseListener) i.next(); + listener.mouseUp(e); + } + } + + public void mouseDoubleClick(MouseEvent e) { + for (Iterator i = mouseListeners.iterator(); i.hasNext();) { + MouseListener listener = (MouseListener) i.next(); + listener.mouseDoubleClick(e); + } + } + }; + + private KeyListener keyListener = new KeyAdapter() { + public void keyPressed(KeyEvent e) { + switch (e.keyCode) { + case SWT.ARROW_LEFT: + if (monthPosition.x > 0) { + traverse(SWT.TRAVERSE_TAB_PREVIOUS); + } + return; + case SWT.ARROW_RIGHT: + if (monthPosition.x < 6) { + traverse(SWT.TRAVERSE_TAB_NEXT); + } + return; + case SWT.TAB: + if ((e.stateMask & SWT.SHIFT) != 0) { + traverse(SWT.TRAVERSE_TAB_PREVIOUS); + return; + } + traverse(SWT.TRAVERSE_TAB_NEXT); + return; + } + } + }; + + /** + * Permit focus events via keyboard. + */ + private TraverseListener traverseListener = new TraverseListener() { + public void keyTraversed(TraverseEvent e) { + // NOOP: this just lets us receive focus from SWT + } + }; + + /** + * When we gain/lose focus, redraw ourselves appropriately + */ + private FocusListener focusListener = new FocusListener() { + public void focusGained(FocusEvent e) { + focusState = Day.FOCUS; + Color background = getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(true); + resetAllBackgrounds(Day.this, background); + redraw(); + } + + public void focusLost(FocusEvent e) { + focusState = Day.NONACTIVE_FOCUS; + Color background = getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(false); + resetAllBackgrounds(Day.this, background); + redraw(); + } + }; + + private void resetAllBackgrounds(Composite composite, Color color) { + composite.setBackground(color); + Control[] children = composite.getChildren(); + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof Composite) { + resetAllBackgrounds((Composite) children[i], color); + } else { + children[i].setBackground(color); + } + } + } + + private Color getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(boolean focused) { + if (inCurrentMonth && focused) { + return CURRENT_MONTH; + } + if (inCurrentMonth) { + return CELL_BACKGROUND_LIGHT; + } + return OTHER_MONTH; + } + + private boolean inCurrentMonth = false; + + /** + * @param inCurrentMonth + */ + public void setInCurrentMonth(boolean inCurrentMonth) { + this.inCurrentMonth = inCurrentMonth; + Color background = getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(false); + resetAllBackgrounds(this, background); + } + + private CalendarableItem[] controls = null; + + /** + * @param controls + */ + public void setItems(CalendarableItem[] controls) { + if (this.controls != null) { + for (int i = 0; i < this.controls.length; i++) { + ICalendarableItemControl control = this.controls[i].getControl(); + control.removeMouseListener(mouseListener); + control.dispose(); + } + } + this.controls = controls; + for (int i = 0; i < this.controls.length; i++) { + MonthCalendarableItemControl control = new MonthCalendarableItemControl(this, SWT.NULL); + getBackgroundTakingIntoAccountIfWeAreInTheCurrentMonth(false); + control.setText(this.controls[i].getText()); + Image image = this.controls[i].getImage(); + if (image != null) { + control.setImage(image); + } + control.setToolTipText(this.controls[i].getToolTipText()); + control.addMouseListener(mouseListener); + GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false); + gd.horizontalSpan = 2; + control.setLayoutData(gd); + this.controls[i].setControl(control); + } + } + + private Date date; + + /** + * Sets the Date represented by this Day. + * + * @param date The date to set + */ + public void setDate(Date date) { + this.date = date; + } + + /** + * Returns the Date represented by this Day. + * + * @return This Day's date + */ + public Date getDate() { + return date; + } + + public int getFocusState() { + return focusState; + } + + public void setFocusState(int focusState) { + if (focusState > 0) + this.focusState = NO_FOCUS; + else if (focusState < 0) + this.focusState = NONACTIVE_FOCUS; + else + this.focusState = FOCUS; + } + +} // @jve:decl-index=0:visual-constraint="10,10" diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/viewers/IMonthCalendarContentProvider.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/viewers/IMonthCalendarContentProvider.java index 2679284cb..e63e9a8a8 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/viewers/IMonthCalendarContentProvider.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/viewers/IMonthCalendarContentProvider.java @@ -1,25 +1,25 @@ -/******************************************************************************* - * Copyright (c) 2008 Trevor S. Kaufman and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Trevor S. Kaufman - initial API and implementation - ******************************************************************************/ - -package org.eclipse.nebula.widgets.compositetable.viewers; - -import java.util.Date; - -import org.eclipse.jface.viewers.IContentProvider; - -public interface IMonthCalendarContentProvider extends IContentProvider { - - public Object[] getElements(Date date, Object inputElement); - -} +/******************************************************************************* + * Copyright (c) 2008 Trevor S. Kaufman and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Trevor S. Kaufman - initial API and implementation + ******************************************************************************/ + +package org.eclipse.nebula.widgets.compositetable.viewers; + +import java.util.Date; + +import org.eclipse.jface.viewers.IContentProvider; + +public interface IMonthCalendarContentProvider extends IContentProvider { + + public Object[] getElements(Date date, Object inputElement); + +} diff --git a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/viewers/MonthCalendarViewer.java b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/viewers/MonthCalendarViewer.java index e3e0eec54..f2adfb543 100644 --- a/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/viewers/MonthCalendarViewer.java +++ b/widgets/compositetable/org.eclipse.nebula.widgets.compositetable/src/org/eclipse/nebula/widgets/compositetable/viewers/MonthCalendarViewer.java @@ -1,189 +1,189 @@ -/******************************************************************************* - * Copyright (c) 2008 Trevor S. Kaufman and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Trevor S. Kaufman - initial API and implementation - ******************************************************************************/ - -package org.eclipse.nebula.widgets.compositetable.viewers; - -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; - -import org.eclipse.jface.viewers.ContentViewer; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.IContentProvider; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.nebula.widgets.compositetable.month.MonthCalendar; -import org.eclipse.nebula.widgets.compositetable.month.MonthCalendarSelectedDay; -import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem; -import org.eclipse.nebula.widgets.compositetable.timeeditor.EventContentProvider; -import org.eclipse.nebula.widgets.compositetable.timeeditor.EventCountProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -public class MonthCalendarViewer extends ContentViewer { - - MonthCalendar calendar = null; - private IStructuredSelection selection = StructuredSelection.EMPTY; - - private MouseListener mouseListener = new MouseAdapter() { - - public void mouseDown(MouseEvent e) { - System.out.println("mouseDown: MouseListener: " + e); - changeSelection(); - } - }; - - public MonthCalendarViewer(Composite parent, int style) { - this(new MonthCalendar(parent, style)); - } - - public MonthCalendarViewer(MonthCalendar monthCalendar) { - if (monthCalendar == null) { - throw new IllegalArgumentException("MonthCalendar cannot be null"); - } - - calendar = monthCalendar; - - calendar.setStartDate(new Date()); - - super.hookControl(calendar); - - calendar.addMouseListener(mouseListener); - } - - public Control getControl() { - return getMonthCalendar(); - } - - public MonthCalendar getMonthCalendar() { - return calendar; - } - - public ISelection getSelection() { - return selection; - } - - public void refresh() { - calendar.refresh(); - } - - protected void inputChanged(Object input, Object oldInput) { - refresh(); - } - - public void setSelection(ISelection selection, boolean reveal) { - if (selection instanceof IStructuredSelection) { - IStructuredSelection structuredSelection = (IStructuredSelection) selection; - if (this.selection.equals(structuredSelection)) { - return; - } - - Date selectedDate = null; - - if (structuredSelection.getFirstElement() instanceof MonthCalendarSelectedDay) { - selectedDate = ((MonthCalendarSelectedDay) structuredSelection.getFirstElement()).date; - } else if (structuredSelection.getFirstElement() instanceof Date) { - selectedDate = (Date) structuredSelection.getFirstElement(); - } else { - return; - } - - System.out.println("setSelection: selectedDate " + selectedDate); - - if (calendar.getSelectedDay().date.equals(selectedDate)) { - return; - } - - Calendar cal = GregorianCalendar.getInstance(); - cal.setTime(selectedDate); - Point monthPosition = new Point(cal.get(Calendar.DAY_OF_WEEK), cal.get(Calendar.WEEK_OF_MONTH)); - this.selection = new StructuredSelection(new MonthCalendarSelectedDay(selectedDate, monthPosition)); - - calendar.select(selectedDate); - - this.fireSelectionChanged(new SelectionChangedEvent(this, - this.selection)); - } - - } - - protected void changeSelection() { - MonthCalendarSelectedDay selectedDay = calendar.getSelectedDay(); - StructuredSelection sel = new StructuredSelection(selectedDay); - this.selection = sel; - this.fireSelectionChanged(new SelectionChangedEvent(this, - this.selection)); - } - - public void setContentProvider(IContentProvider contentProvider) { - if (!(contentProvider instanceof IMonthCalendarContentProvider)) { - throw new IllegalArgumentException( - "content provider must be of type IMonthCalendarContentProvider"); - } - super.setContentProvider(contentProvider); - calendar.setEventContentProvider(eventContentProvider); - calendar.setEventCountProvider(eventCountProvider); - } - - public void setLabelProvider(IBaseLabelProvider labelProvider) { - if (!(labelProvider instanceof ILabelProvider)) { - throw new IllegalArgumentException( - "label provider must be of type ILabelProvider"); - } - super.setLabelProvider(labelProvider); - } - - private EventContentProvider eventContentProvider = new EventContentProvider() { - - public void refresh(Date day, CalendarableItem[] controls) { - Object[] elements = ((IMonthCalendarContentProvider) getContentProvider()) - .getElements(day, getInput()); - int count = Math.min(elements.length, controls.length); - for (int i = 0; i < count; i++) { - if (controls[i] == null) - continue; - controls[i].setText(((ILabelProvider) getLabelProvider()) - .getText(elements[i])); - controls[i].setImage(((ILabelProvider) getLabelProvider()) - .getImage(elements[i])); - - // Not sure how to do this properly.. - // It appears that none of these fields matter for - // the display of the MonthCalendar.. - controls[i].setStartTime(day); - controls[i].setEndTime(day); - controls[i].setAllDayEvent(false); - controls[i].setContinued(SWT.NONE); - } - } - }; - - private EventCountProvider eventCountProvider = new EventCountProvider() { - - public int getNumberOfEventsInDay(Date day) { - return ((IMonthCalendarContentProvider) getContentProvider()) - .getElements(day, getInput()).length; - } - - }; - -} +/******************************************************************************* + * Copyright (c) 2008 Trevor S. Kaufman and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Trevor S. Kaufman - initial API and implementation + ******************************************************************************/ + +package org.eclipse.nebula.widgets.compositetable.viewers; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.eclipse.jface.viewers.ContentViewer; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.nebula.widgets.compositetable.month.MonthCalendar; +import org.eclipse.nebula.widgets.compositetable.month.MonthCalendarSelectedDay; +import org.eclipse.nebula.widgets.compositetable.timeeditor.CalendarableItem; +import org.eclipse.nebula.widgets.compositetable.timeeditor.EventContentProvider; +import org.eclipse.nebula.widgets.compositetable.timeeditor.EventCountProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +public class MonthCalendarViewer extends ContentViewer { + + MonthCalendar calendar = null; + private IStructuredSelection selection = StructuredSelection.EMPTY; + + private MouseListener mouseListener = new MouseAdapter() { + + public void mouseDown(MouseEvent e) { + System.out.println("mouseDown: MouseListener: " + e); + changeSelection(); + } + }; + + public MonthCalendarViewer(Composite parent, int style) { + this(new MonthCalendar(parent, style)); + } + + public MonthCalendarViewer(MonthCalendar monthCalendar) { + if (monthCalendar == null) { + throw new IllegalArgumentException("MonthCalendar cannot be null"); + } + + calendar = monthCalendar; + + calendar.setStartDate(new Date()); + + super.hookControl(calendar); + + calendar.addMouseListener(mouseListener); + } + + public Control getControl() { + return getMonthCalendar(); + } + + public MonthCalendar getMonthCalendar() { + return calendar; + } + + public ISelection getSelection() { + return selection; + } + + public void refresh() { + calendar.refresh(); + } + + protected void inputChanged(Object input, Object oldInput) { + refresh(); + } + + public void setSelection(ISelection selection, boolean reveal) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + if (this.selection.equals(structuredSelection)) { + return; + } + + Date selectedDate = null; + + if (structuredSelection.getFirstElement() instanceof MonthCalendarSelectedDay) { + selectedDate = ((MonthCalendarSelectedDay) structuredSelection.getFirstElement()).date; + } else if (structuredSelection.getFirstElement() instanceof Date) { + selectedDate = (Date) structuredSelection.getFirstElement(); + } else { + return; + } + + System.out.println("setSelection: selectedDate " + selectedDate); + + if (calendar.getSelectedDay().date.equals(selectedDate)) { + return; + } + + Calendar cal = GregorianCalendar.getInstance(); + cal.setTime(selectedDate); + Point monthPosition = new Point(cal.get(Calendar.DAY_OF_WEEK), cal.get(Calendar.WEEK_OF_MONTH)); + this.selection = new StructuredSelection(new MonthCalendarSelectedDay(selectedDate, monthPosition)); + + calendar.select(selectedDate); + + this.fireSelectionChanged(new SelectionChangedEvent(this, + this.selection)); + } + + } + + protected void changeSelection() { + MonthCalendarSelectedDay selectedDay = calendar.getSelectedDay(); + StructuredSelection sel = new StructuredSelection(selectedDay); + this.selection = sel; + this.fireSelectionChanged(new SelectionChangedEvent(this, + this.selection)); + } + + public void setContentProvider(IContentProvider contentProvider) { + if (!(contentProvider instanceof IMonthCalendarContentProvider)) { + throw new IllegalArgumentException( + "content provider must be of type IMonthCalendarContentProvider"); + } + super.setContentProvider(contentProvider); + calendar.setEventContentProvider(eventContentProvider); + calendar.setEventCountProvider(eventCountProvider); + } + + public void setLabelProvider(IBaseLabelProvider labelProvider) { + if (!(labelProvider instanceof ILabelProvider)) { + throw new IllegalArgumentException( + "label provider must be of type ILabelProvider"); + } + super.setLabelProvider(labelProvider); + } + + private EventContentProvider eventContentProvider = new EventContentProvider() { + + public void refresh(Date day, CalendarableItem[] controls) { + Object[] elements = ((IMonthCalendarContentProvider) getContentProvider()) + .getElements(day, getInput()); + int count = Math.min(elements.length, controls.length); + for (int i = 0; i < count; i++) { + if (controls[i] == null) + continue; + controls[i].setText(((ILabelProvider) getLabelProvider()) + .getText(elements[i])); + controls[i].setImage(((ILabelProvider) getLabelProvider()) + .getImage(elements[i])); + + // Not sure how to do this properly.. + // It appears that none of these fields matter for + // the display of the MonthCalendar.. + controls[i].setStartTime(day); + controls[i].setEndTime(day); + controls[i].setAllDayEvent(false); + controls[i].setContinued(SWT.NONE); + } + } + }; + + private EventCountProvider eventCountProvider = new EventCountProvider() { + + public int getNumberOfEventsInDay(Date day) { + return ((IMonthCalendarContentProvider) getContentProvider()) + .getElements(day, getInput()).length; + } + + }; + +} diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/.project b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/.project index f86387a57..160af590b 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/.project +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.ctreecombo.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.ctreecombo.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/build.properties b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/build.properties +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/feature.properties b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/feature.properties +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/feature.xml b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/feature.xml index 8dd7a0c78..a1cef959a 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/feature.xml +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/feature.xml @@ -1,34 +1,34 @@ - - - - - CTree Combo - - - - %license - - - - - - - - - - - + + + + + CTree Combo + + + + %license + + + + + + + + + + + diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/license.html b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/license.html index aa5a8fc03..225824a2a 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/license.html +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/license.html @@ -1,107 +1,107 @@ - - - - - -Eclipse Foundation Software User Agreement - - - -

Eclipse Foundation Software User Agreement

-

April 9, 2014

- -

Usage Of Content

- -

THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS - (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND - CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE - OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR - NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND - CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

- -

Applicable Licenses

- -

Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 - ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. - For purposes of the EPL, "Program" will mean the Content.

- -

Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code - repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").

- -
    -
  • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
  • -
  • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
  • -
  • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins - and/or Fragments associated with that Feature.
  • -
  • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
  • -
- -

The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and -Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module -including, but not limited to the following locations:

- -
    -
  • The top-level (root) directory
  • -
  • Plug-in and Fragment directories
  • -
  • Inside Plug-ins and Fragments packaged as JARs
  • -
  • Sub-directories of the directory named "src" of certain Plug-ins
  • -
  • Feature directories
  • -
- -

Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the -installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or -inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. -Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in -that directory.

- -

THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

- - - -

IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please -contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

- - -

Use of Provisioning Technology

- -

The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse - Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or - other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to - install, extend and update Eclipse-based products. Information about packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html - ("Specification").

- -

You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the - applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology - in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the - Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:

- -
    -
  1. A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology - on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based - product.
  2. -
  3. During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be - accessed and copied to the Target Machine.
  4. -
  5. Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable - Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target - Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern - the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such - indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.
  6. -
- -

Cryptography

- -

Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to - another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, - possession, or use, and re-export of encryption software, to see if this is permitted.

- -

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

- + + + + + +Eclipse Foundation Software User Agreement + + + +

Eclipse Foundation Software User Agreement

+

April 9, 2014

+ +

Usage Of Content

+ +

THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

+ +

Applicable Licenses

+ +

Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

+ +

Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code + repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").

+ +
    +
  • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
  • +
  • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
  • +
  • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
  • +
  • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
  • +
+ +

The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

+ +
    +
  • The top-level (root) directory
  • +
  • Plug-in and Fragment directories
  • +
  • Inside Plug-ins and Fragments packaged as JARs
  • +
  • Sub-directories of the directory named "src" of certain Plug-ins
  • +
  • Feature directories
  • +
+ +

Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

+ +

THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

+ + + +

IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

+ + +

Use of Provisioning Technology

+ +

The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse + Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or + other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to + install, extend and update Eclipse-based products. Information about packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html + ("Specification").

+ +

You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the + applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology + in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the + Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:

+ +
    +
  1. A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology + on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based + product.
  2. +
  3. During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be + accessed and copied to the Target Machine.
  4. +
  5. Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable + Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target + Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern + the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such + indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.
  6. +
+ +

Cryptography

+ +

Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

+ +

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

+ \ No newline at end of file diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/pom.xml b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/pom.xml index e55341186..880cbde86 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/pom.xml +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - ctreecombo - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.ctreecombo.feature - eclipse-feature - 1.0.0-SNAPSHOT - - CTreeCombo Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + ctreecombo + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.ctreecombo.feature + eclipse-feature + 1.0.0-SNAPSHOT + + CTreeCombo Feature + + diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.classpath b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.classpath +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.project b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.project index 99aad4f04..8b6586388 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.project +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.ctreecombo.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.ctreecombo.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/META-INF/MANIFEST.MF b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/META-INF/MANIFEST.MF index bb6505c3c..78358cccc 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/META-INF/MANIFEST.MF +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula CTree Combo Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.ctreecombo.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.ctreecombo;bundle-version="1.0.0", - org.eclipse.swt, - org.eclipse.jface -Automatic-Module-Name: org.eclipse.nebula.widgets.ctreecombo.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula CTree Combo Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.ctreecombo.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.ctreecombo;bundle-version="1.0.0", + org.eclipse.swt, + org.eclipse.jface +Automatic-Module-Name: org.eclipse.nebula.widgets.ctreecombo.snippets diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/build.properties b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/build.properties +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/pom.xml b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/pom.xml index 72c0a2bd7..64c0d395d 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/pom.xml +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - ctreecombo - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.ctreecombo.snippets - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + ctreecombo + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.ctreecombo.snippets + eclipse-plugin + + diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/src/org/eclipse/nebula/widgets/ctreecombo/snippets/CTreeComboSnippet.java b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/src/org/eclipse/nebula/widgets/ctreecombo/snippets/CTreeComboSnippet.java index 23e6afa59..9c0c315f1 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/src/org/eclipse/nebula/widgets/ctreecombo/snippets/CTreeComboSnippet.java +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/src/org/eclipse/nebula/widgets/ctreecombo/snippets/CTreeComboSnippet.java @@ -1,275 +1,275 @@ -/******************************************************************************* - * Copyright (c) 2019 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ctreecombo.snippets; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.nebula.widgets.ctreecombo.CTreeCombo; -import org.eclipse.nebula.widgets.ctreecombo.CTreeComboItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * This snippet demonstrates the CTreeComboSnippet widget - * - */ -public class CTreeComboSnippet { - private static class ItemSelected extends SelectionAdapter { - - private final CTreeCombo ctc; - private final String text; - - public ItemSelected(CTreeCombo ctc, String text) { - this.ctc = ctc; - this.text = text; - } - - @Override - public void widgetSelected(SelectionEvent e) { - listenerGroup.setText("Listener Results - (" + text + ")"); - listenerResults.setText(ctc.getText() == null ? "null" : ctc.getText()); - } - } - - private static Font boldFont; - private static Map images = new HashMap<>(); - private static Color darkRed; - private static Color darkBlue; - private static Color darkGreen; - private static List modelList; - private static Text listenerResults; - - private static Group listenerGroup; - - private static List loadModel() { - final List items = new ArrayList(); - items.add(new Country("Austria", "Thomas Schindl")); - items.add(new Country("France", "Laurent Caron", "Nicolas Richeton")); - items.add(new Country("Germany", "Dirk Fauth", "Johannes Faltermeier")); - items.add(new Country("Italy", "Mirko Paturzo")); - items.add(new Country("Netherlands", "Wim Jongman")); - items.add(new Country("Norway", "Hallvard Traetteberg")); - items.add(new Country("UK", "Jonah Graham", "Matthew Gerring", "Peter Chang")); - items.add(new Country("USA", "Donald Dunne")); - return items; - } - - private static void loadSingleDataset(CTreeCombo ctc) { - for (final Country country : modelList) { - final CTreeComboItem item = new CTreeComboItem(ctc, SWT.NONE); - item.setText(country.getName()); - - for (final String commiter : country.getCommiters()) { - final CTreeComboItem commiterItem = new CTreeComboItem(item, SWT.NONE); - commiterItem.setText(commiter); - } - } - } - - private static void loadSingleDatasetWithColorsAndFonts(CTreeCombo ctc) { - - int index = 0; - for (final Country country : modelList) { - final CTreeComboItem item = new CTreeComboItem(ctc, SWT.NONE); - item.setText(country.getName()); - - if (index % 3 == 0) { - item.setForeground(darkBlue); - } else if (index % 3 == 1) { - item.setForeground(darkGreen); - } else { - item.setForeground(darkRed); - } - - for (int j = 0; j < country.getCommiters().size(); j++) { - final String commiter = country.getCommiters().get(j); - final CTreeComboItem commiterItem = new CTreeComboItem(item, SWT.NONE); - commiterItem.setText(commiter); - if (j % 2 == 0) { - commiterItem.setFont(boldFont); - } - } - index++; - } - } - - private static void loadSingleDatasetWithImages(CTreeCombo ctc) { - for (final Country country : modelList) { - final CTreeComboItem item = new CTreeComboItem(ctc, SWT.NONE); - item.setText(country.getName()); - final String key = country.getName().toLowerCase(); - item.setImage(images.get(key)); - - for (final String commiter : country.getCommiters()) { - final CTreeComboItem commiterItem = new CTreeComboItem(item, SWT.NONE); - commiterItem.setText(commiter); - } - } - } - - /** - * @param args - */ - public static void main(final String[] args) { - // get display. - final Display display = new Display(); - - // create bold and italic font. - boldFont = new Font(display, "Arial", 8, SWT.BOLD | SWT.ITALIC); - - // create images - final String[] countries = new String[] { "austria", "france", "germany", "italy", "netherlands", "norway", "unitedkingdom", "usa" }; - for (final String country : countries) { - final Image img = ImageDescriptor.createFromFile(CTreeComboSnippet.class, "flags/" + country + ".png").createImage(); - images.put(country, img); - } - - // create colors - darkRed = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED); - darkBlue = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE); - darkGreen = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN); - - // load the model list. - modelList = loadModel(); - - // create a new shell. - final Shell shell = new Shell(display); - shell.setText("CTreeCombo Snippet (pure SWT)"); - shell.setSize(600, 400); - shell.setLayout(new GridLayout()); - - // create group - final Group group = new Group(shell, SWT.NONE); - group.setLayout(new GridLayout(2, false)); - group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - group.setText("Sample Group"); - - // create group - listenerGroup = new Group(shell, SWT.NONE); - listenerGroup.setLayout(new GridLayout(1, false)); - listenerGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - listenerGroup.setText("Listener Results"); - - listenerResults = new Text(listenerGroup, SWT.BORDER | SWT.MULTI); - final GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - gd.heightHint = 30; - listenerResults.setLayoutData(gd); - - //////////////////////////////////////////////////////////////////////// - // Sample #1 - //////////////////////////////////////////////////////////////////////// - Label label = new Label(group, SWT.NONE); - label.setText("No image, no font:"); - - // create TableCombo - CTreeCombo ctc = new CTreeCombo(group, SWT.BORDER | SWT.READ_ONLY); - ctc.setLayoutData(new GridData(200, SWT.DEFAULT)); - - // load the dataset. - loadSingleDataset(ctc); - - // add listener - ctc.addSelectionListener(new ItemSelected(ctc, "Sample1")); - - //////////////////////////////////////////////////////////////////////// - // Sample #2 - //////////////////////////////////////////////////////////////////////// - - label = new Label(group, SWT.NONE); - label.setText("Combo with images"); - - // create TableCombo - ctc = new CTreeCombo(group, SWT.BORDER | SWT.READ_ONLY); - ctc.setLayoutData(new GridData(200, SWT.DEFAULT)); - - // load the dataset. - loadSingleDatasetWithImages(ctc); - - // add listener - ctc.addSelectionListener(new ItemSelected(ctc, "Sample2")); - - //////////////////////////////////////////////////////////////////////// - // Sample #3 - //////////////////////////////////////////////////////////////////////// - // create label - label = new Label(group, SWT.NONE); - label.setText("Colors && Fonts :"); - - // create TableCombo - ctc = new CTreeCombo(group, SWT.BORDER | SWT.READ_ONLY); - ctc.setLayoutData(new GridData(200, SWT.DEFAULT)); - - // load the dataset. - loadSingleDatasetWithColorsAndFonts(ctc); - - // add listener - ctc.addSelectionListener(new ItemSelected(ctc, "Sample3")); - - //////////////////////////////////////////////////////////////////////// - // Sample #4 - //////////////////////////////////////////////////////////////////////// - // create label - label = new Label(group, SWT.NONE); - label.setText("Not readonly"); - - // create TableCombo - ctc = new CTreeCombo(group, SWT.BORDER); - ctc.setLayoutData(new GridData(200, SWT.DEFAULT)); - - // load the dataset. - loadSingleDatasetWithColorsAndFonts(ctc); - - // add listener - ctc.addSelectionListener(new ItemSelected(ctc, "Sample4")); - - // open the shell. - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - // dispose of the font - boldFont.dispose(); - - // dispose images - for (final Image img : images.values()) { - img.dispose(); - } - - // dispose colors - darkRed.dispose(); - darkBlue.dispose(); - darkGreen.dispose(); - - // dispose display - display.dispose(); - } -} +/******************************************************************************* + * Copyright (c) 2019 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ctreecombo.snippets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.nebula.widgets.ctreecombo.CTreeCombo; +import org.eclipse.nebula.widgets.ctreecombo.CTreeComboItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * This snippet demonstrates the CTreeComboSnippet widget + * + */ +public class CTreeComboSnippet { + private static class ItemSelected extends SelectionAdapter { + + private final CTreeCombo ctc; + private final String text; + + public ItemSelected(CTreeCombo ctc, String text) { + this.ctc = ctc; + this.text = text; + } + + @Override + public void widgetSelected(SelectionEvent e) { + listenerGroup.setText("Listener Results - (" + text + ")"); + listenerResults.setText(ctc.getText() == null ? "null" : ctc.getText()); + } + } + + private static Font boldFont; + private static Map images = new HashMap<>(); + private static Color darkRed; + private static Color darkBlue; + private static Color darkGreen; + private static List modelList; + private static Text listenerResults; + + private static Group listenerGroup; + + private static List loadModel() { + final List items = new ArrayList(); + items.add(new Country("Austria", "Thomas Schindl")); + items.add(new Country("France", "Laurent Caron", "Nicolas Richeton")); + items.add(new Country("Germany", "Dirk Fauth", "Johannes Faltermeier")); + items.add(new Country("Italy", "Mirko Paturzo")); + items.add(new Country("Netherlands", "Wim Jongman")); + items.add(new Country("Norway", "Hallvard Traetteberg")); + items.add(new Country("UK", "Jonah Graham", "Matthew Gerring", "Peter Chang")); + items.add(new Country("USA", "Donald Dunne")); + return items; + } + + private static void loadSingleDataset(CTreeCombo ctc) { + for (final Country country : modelList) { + final CTreeComboItem item = new CTreeComboItem(ctc, SWT.NONE); + item.setText(country.getName()); + + for (final String commiter : country.getCommiters()) { + final CTreeComboItem commiterItem = new CTreeComboItem(item, SWT.NONE); + commiterItem.setText(commiter); + } + } + } + + private static void loadSingleDatasetWithColorsAndFonts(CTreeCombo ctc) { + + int index = 0; + for (final Country country : modelList) { + final CTreeComboItem item = new CTreeComboItem(ctc, SWT.NONE); + item.setText(country.getName()); + + if (index % 3 == 0) { + item.setForeground(darkBlue); + } else if (index % 3 == 1) { + item.setForeground(darkGreen); + } else { + item.setForeground(darkRed); + } + + for (int j = 0; j < country.getCommiters().size(); j++) { + final String commiter = country.getCommiters().get(j); + final CTreeComboItem commiterItem = new CTreeComboItem(item, SWT.NONE); + commiterItem.setText(commiter); + if (j % 2 == 0) { + commiterItem.setFont(boldFont); + } + } + index++; + } + } + + private static void loadSingleDatasetWithImages(CTreeCombo ctc) { + for (final Country country : modelList) { + final CTreeComboItem item = new CTreeComboItem(ctc, SWT.NONE); + item.setText(country.getName()); + final String key = country.getName().toLowerCase(); + item.setImage(images.get(key)); + + for (final String commiter : country.getCommiters()) { + final CTreeComboItem commiterItem = new CTreeComboItem(item, SWT.NONE); + commiterItem.setText(commiter); + } + } + } + + /** + * @param args + */ + public static void main(final String[] args) { + // get display. + final Display display = new Display(); + + // create bold and italic font. + boldFont = new Font(display, "Arial", 8, SWT.BOLD | SWT.ITALIC); + + // create images + final String[] countries = new String[] { "austria", "france", "germany", "italy", "netherlands", "norway", "unitedkingdom", "usa" }; + for (final String country : countries) { + final Image img = ImageDescriptor.createFromFile(CTreeComboSnippet.class, "flags/" + country + ".png").createImage(); + images.put(country, img); + } + + // create colors + darkRed = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED); + darkBlue = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE); + darkGreen = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN); + + // load the model list. + modelList = loadModel(); + + // create a new shell. + final Shell shell = new Shell(display); + shell.setText("CTreeCombo Snippet (pure SWT)"); + shell.setSize(600, 400); + shell.setLayout(new GridLayout()); + + // create group + final Group group = new Group(shell, SWT.NONE); + group.setLayout(new GridLayout(2, false)); + group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + group.setText("Sample Group"); + + // create group + listenerGroup = new Group(shell, SWT.NONE); + listenerGroup.setLayout(new GridLayout(1, false)); + listenerGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + listenerGroup.setText("Listener Results"); + + listenerResults = new Text(listenerGroup, SWT.BORDER | SWT.MULTI); + final GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + gd.heightHint = 30; + listenerResults.setLayoutData(gd); + + //////////////////////////////////////////////////////////////////////// + // Sample #1 + //////////////////////////////////////////////////////////////////////// + Label label = new Label(group, SWT.NONE); + label.setText("No image, no font:"); + + // create TableCombo + CTreeCombo ctc = new CTreeCombo(group, SWT.BORDER | SWT.READ_ONLY); + ctc.setLayoutData(new GridData(200, SWT.DEFAULT)); + + // load the dataset. + loadSingleDataset(ctc); + + // add listener + ctc.addSelectionListener(new ItemSelected(ctc, "Sample1")); + + //////////////////////////////////////////////////////////////////////// + // Sample #2 + //////////////////////////////////////////////////////////////////////// + + label = new Label(group, SWT.NONE); + label.setText("Combo with images"); + + // create TableCombo + ctc = new CTreeCombo(group, SWT.BORDER | SWT.READ_ONLY); + ctc.setLayoutData(new GridData(200, SWT.DEFAULT)); + + // load the dataset. + loadSingleDatasetWithImages(ctc); + + // add listener + ctc.addSelectionListener(new ItemSelected(ctc, "Sample2")); + + //////////////////////////////////////////////////////////////////////// + // Sample #3 + //////////////////////////////////////////////////////////////////////// + // create label + label = new Label(group, SWT.NONE); + label.setText("Colors && Fonts :"); + + // create TableCombo + ctc = new CTreeCombo(group, SWT.BORDER | SWT.READ_ONLY); + ctc.setLayoutData(new GridData(200, SWT.DEFAULT)); + + // load the dataset. + loadSingleDatasetWithColorsAndFonts(ctc); + + // add listener + ctc.addSelectionListener(new ItemSelected(ctc, "Sample3")); + + //////////////////////////////////////////////////////////////////////// + // Sample #4 + //////////////////////////////////////////////////////////////////////// + // create label + label = new Label(group, SWT.NONE); + label.setText("Not readonly"); + + // create TableCombo + ctc = new CTreeCombo(group, SWT.BORDER); + ctc.setLayoutData(new GridData(200, SWT.DEFAULT)); + + // load the dataset. + loadSingleDatasetWithColorsAndFonts(ctc); + + // add listener + ctc.addSelectionListener(new ItemSelected(ctc, "Sample4")); + + // open the shell. + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + // dispose of the font + boldFont.dispose(); + + // dispose images + for (final Image img : images.values()) { + img.dispose(); + } + + // dispose colors + darkRed.dispose(); + darkBlue.dispose(); + darkGreen.dispose(); + + // dispose display + display.dispose(); + } +} diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/src/org/eclipse/nebula/widgets/ctreecombo/snippets/Country.java b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/src/org/eclipse/nebula/widgets/ctreecombo/snippets/Country.java index f9b7104d1..8c60235de 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/src/org/eclipse/nebula/widgets/ctreecombo/snippets/Country.java +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo.snippets/src/org/eclipse/nebula/widgets/ctreecombo/snippets/Country.java @@ -1,67 +1,67 @@ -package org.eclipse.nebula.widgets.ctreecombo.snippets; - -import java.util.Arrays; -import java.util.List; - -public class Country { - private String name; - private List commiters; - - public Country(String name, String...commiters) { - this.name = name; - this.commiters=Arrays.asList(commiters); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public List getCommiters() { - return commiters; - } - - public void setCommiters(List commiters) { - this.commiters = commiters; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((commiters == null) ? 0 : commiters.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Country other = (Country) obj; - if (commiters == null) { - if (other.commiters != null) - return false; - } else if (!commiters.equals(other.commiters)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } - - @Override - public String toString() { - return "Country [name=" + name + ", commiters=" + commiters + "]"; - } - -} +package org.eclipse.nebula.widgets.ctreecombo.snippets; + +import java.util.Arrays; +import java.util.List; + +public class Country { + private String name; + private List commiters; + + public Country(String name, String...commiters) { + this.name = name; + this.commiters=Arrays.asList(commiters); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getCommiters() { + return commiters; + } + + public void setCommiters(List commiters) { + this.commiters = commiters; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((commiters == null) ? 0 : commiters.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Country other = (Country) obj; + if (commiters == null) { + if (other.commiters != null) + return false; + } else if (!commiters.equals(other.commiters)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "Country [name=" + name + ", commiters=" + commiters + "]"; + } + +} diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.classpath b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.classpath +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.project b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.project index 700390c42..2d8945970 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.project +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.ctreecombo - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.ctreecombo + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.settings/org.eclipse.jdt.core.prefs b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/META-INF/MANIFEST.MF b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/META-INF/MANIFEST.MF index 1b6529fe6..2520e7721 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/META-INF/MANIFEST.MF +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/META-INF/MANIFEST.MF @@ -1,13 +1,13 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula CTree Combo Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.ctreecombo -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.swt, - org.eclipse.jface, - org.eclipse.core.runtime;bundle-version="3.13.0", - org.eclipse.core.databinding.observable -Export-Package: org.eclipse.nebula.widgets.ctreecombo -Automatic-Module-Name: org.eclipse.nebula.widgets.ctreecombo +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula CTree Combo Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.ctreecombo +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.swt, + org.eclipse.jface, + org.eclipse.core.runtime;bundle-version="3.13.0", + org.eclipse.core.databinding.observable +Export-Package: org.eclipse.nebula.widgets.ctreecombo +Automatic-Module-Name: org.eclipse.nebula.widgets.ctreecombo diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/build.properties b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/build.properties +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/pom.xml b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/pom.xml index b68c107f5..a3f045c09 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/pom.xml +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - ctreecombo - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.ctreecombo - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + ctreecombo + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.ctreecombo + eclipse-plugin + + diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeCombo.java b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeCombo.java index a5949d4d0..b30645d8f 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeCombo.java +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeCombo.java @@ -1,1557 +1,1557 @@ -/******************************************************************************* - * Copyright (c) 2019 Thomas Schindl & Laurent Caron. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API - * and implementation - * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, - * code cleaning and documentation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ctreecombo; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.accessibility.ACC; -import org.eclipse.swt.accessibility.AccessibleAdapter; -import org.eclipse.swt.accessibility.AccessibleControlAdapter; -import org.eclipse.swt.accessibility.AccessibleControlEvent; -import org.eclipse.swt.accessibility.AccessibleEvent; -import org.eclipse.swt.accessibility.AccessibleTextAdapter; -import org.eclipse.swt.accessibility.AccessibleTextEvent; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TreeEvent; -import org.eclipse.swt.events.TreeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.swt.widgets.TreeItem; -import org.eclipse.swt.widgets.TypedListener; -import org.eclipse.swt.widgets.Widget; - -public class CTreeCombo extends Composite { - static int checkStyle(int style) { - final int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; - return SWT.NO_FOCUS | style & mask; - } - - Text text; - Tree tree; - Button arrow; - Listener listener, filter; - Shell popup; - boolean hasFocus; - int visibleItemCount = 5; - Color foreground, background; - Font font; - List items = new ArrayList(); - List columns = new ArrayList(); - - List treeListeners = new ArrayList(); - - private final TreeListener hookListener = new TreeListener() { - - @Override - public void treeCollapsed(TreeEvent e) { - e.item = (Widget) e.item.getData(CTreeComboItem.DATA_ID); - e.widget = CTreeCombo.this; - for (final TreeListener l : treeListeners) { - l.treeCollapsed(e); - } - } - - @Override - public void treeExpanded(TreeEvent e) { - e.item = (Widget) e.item.getData(CTreeComboItem.DATA_ID); - e.widget = CTreeCombo.this; - for (final TreeListener l : treeListeners) { - l.treeExpanded(e); - } - } - - }; - - /** - * The CTreeCombo class represents a selectable user interface object - * that combines a text field and a tree and issues notification - * when an item is selected from the tree. - *

- * Note that although this class is a subclass of Composite, - * it does not make sense to add children to it, or set a layout on it. - *

- *
- *
Styles: - *
BORDER, READ_ONLY, FLAT
- *
Events: - *
DefaultSelection, Modify, Selection, Verify
- *
- */ - public CTreeCombo(Composite parent, int style) { - super(parent, style = checkStyle(style)); - - int textStyle = SWT.SINGLE; - if ((style & SWT.READ_ONLY) != 0) { - textStyle |= SWT.READ_ONLY; - } - if ((style & SWT.FLAT) != 0) { - textStyle |= SWT.FLAT; - } - text = new Text(this, textStyle); - int arrowStyle = SWT.ARROW | SWT.DOWN; - if ((style & SWT.FLAT) != 0) { - arrowStyle |= SWT.FLAT; - } - arrow = new Button(this, arrowStyle); - - listener = new Listener() { - @Override - public void handleEvent(Event event) { - if (popup == event.widget) { - popupEvent(event); - return; - } - if (text == event.widget) { - textEvent(event); - return; - } - if (tree == event.widget) { - treeEvent(event); - return; - } - if (arrow == event.widget) { - arrowEvent(event); - return; - } - if (CTreeCombo.this == event.widget) { - comboEvent(event); - return; - } - if (getShell() == event.widget) { - getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (isDisposed()) { - return; - } - handleFocus(SWT.FocusOut); - } - }); - } - } - }; - filter = (event) -> { - final Shell shell = ((Control) event.widget).getShell(); - if (shell == CTreeCombo.this.getShell()) { - handleFocus(SWT.FocusOut); - } - }; - - final int[] comboEvents = { SWT.Dispose, SWT.FocusIn, SWT.Move, SWT.Resize }; - for (int i = 0; i < comboEvents.length; i++) { - addListener(comboEvents[i], listener); - } - - final int[] textEvents = { SWT.DefaultSelection, SWT.KeyDown, SWT.KeyUp, SWT.MenuDetect, SWT.Modify, SWT.MouseDown, SWT.MouseUp, SWT.MouseDoubleClick, SWT.MouseWheel, SWT.Traverse, SWT.FocusIn, SWT.Verify }; - for (int i = 0; i < textEvents.length; i++) { - text.addListener(textEvents[i], listener); - } - - final int[] arrowEvents = { SWT.MouseDown, SWT.MouseUp, SWT.Selection, SWT.FocusIn }; - for (int i = 0; i < arrowEvents.length; i++) { - arrow.addListener(arrowEvents[i], listener); - } - - createPopup(null, null); - initAccessible(); - } - - char _findMnemonic(String string) { - if (string == null) { - return '\0'; - } - int index = 0; - final int length = string.length(); - do { - while (index < length && string.charAt(index) != '&') { - index++; - } - if (++index >= length) { - return '\0'; - } - if (string.charAt(index) != '&') { - return Character.toLowerCase(string.charAt(index)); - } - index++; - } while (index < length); - return '\0'; - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the user changes the receiver's selection, by sending it one of the messages - * defined in the SelectionListener interface. - *

- * widgetSelected is called when the combo's list selection - * changes. widgetDefaultSelected is typically called when ENTER is - * pressed the combo's text area. - *

- * - * @param listener - * the listener which should be notified when the user changes the - * receiver's selection - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - final TypedListener typedListener = new TypedListener(listener); - addListener(SWT.Selection, typedListener); - addListener(SWT.DefaultSelection, typedListener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when an item in the receiver is expanded or collapsed - * by sending it one of the messages defined in the TreeListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see TreeListener - * @see #removeTreeListener - */ - public void addTreeListener(TreeListener listener) { - checkWidget(); - treeListeners.add(listener); - } - - private void adjustShellSize() { - final Point size = getSize(); - final int itemCount = visibleItemCount; - final int itemHeight = tree.getItemHeight() * itemCount; - final Point listSize = tree.computeSize(SWT.DEFAULT, itemHeight, false); - tree.setBounds(1, 1, Math.max(size.x - 2, listSize.x), listSize.y); - - final Display display = getDisplay(); - final Rectangle listRect = tree.getBounds(); - final Rectangle parentRect = display.map(getParent(), null, getBounds()); - final Point comboSize = getSize(); - final Rectangle displayRect = getMonitor().getClientArea(); - final int width = Math.max(comboSize.x, listRect.width + 2); - final int height = listRect.height + 2; - int x = parentRect.x; - int y = parentRect.y + comboSize.y; - if (y + height > displayRect.y + displayRect.height) { - y = parentRect.y - height; - } - if (x + width > displayRect.x + displayRect.width) { - x = displayRect.x + displayRect.width - listRect.width; - } - popup.setBounds(x, y, width, height); - - } - - void arrowEvent(Event event) { - switch (event.type) { - case SWT.FocusIn: { - handleFocus(SWT.FocusIn); - break; - } - case SWT.MouseDown: { - final Event mouseEvent = new Event(); - mouseEvent.button = event.button; - mouseEvent.count = event.count; - mouseEvent.stateMask = event.stateMask; - mouseEvent.time = event.time; - mouseEvent.x = event.x; - mouseEvent.y = event.y; - notifyListeners(SWT.MouseDown, mouseEvent); - event.doit = mouseEvent.doit; - break; - } - case SWT.MouseUp: { - final Event mouseEvent = new Event(); - mouseEvent.button = event.button; - mouseEvent.count = event.count; - mouseEvent.stateMask = event.stateMask; - mouseEvent.time = event.time; - mouseEvent.x = event.x; - mouseEvent.y = event.y; - notifyListeners(SWT.MouseUp, mouseEvent); - event.doit = mouseEvent.doit; - break; - } - case SWT.Selection: { - text.setFocus(); - dropDown(!isDropped()); - break; - } - } - } - - /** - * Clears the item at the given zero-relative index in the receiver. - * The text, icon and other attributes of the item are set to the default - * value. If the tree was created with the SWT.VIRTUAL style, - * these attributes are requested again as needed. - * - * @param index the index of the item to clear - * @param all true if all child items of the indexed item should be - * cleared recursively, and false otherwise - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see SWT#VIRTUAL - * @see SWT#SetData - */ - public void clear(int index, boolean all) { - checkWidget(); - tree.clear(index, all); - } - - /** - * Clears all the items in the receiver. The text, icon and other - * attributes of the items are set to their default values. If the - * tree was created with the SWT.VIRTUAL style, these - * attributes are requested again as needed. - * - * @param all true if all child items should be cleared - * recursively, and false otherwise - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see SWT#VIRTUAL - * @see SWT#SetData - */ - public void clearAll(boolean all) { - checkWidget(); - tree.clearAll(all); - text.setFont(text.getFont()); - text.setText(""); //$NON-NLS-1$ - } - - void comboEvent(Event event) { - switch (event.type) { - case SWT.Dispose: - if (popup != null && !popup.isDisposed()) { - tree.removeListener(SWT.Dispose, listener); - popup.dispose(); - } - final Shell shell = getShell(); - shell.removeListener(SWT.Deactivate, listener); - final Display display = getDisplay(); - display.removeFilter(SWT.FocusIn, filter); - popup = null; - text = null; - tree = null; - arrow = null; - break; - case SWT.FocusIn: - final Control focusControl = getDisplay().getFocusControl(); - if (focusControl == arrow || focusControl == tree) { - return; - } - if (isDropped()) { - tree.setFocus(); - } else { - text.setFocus(); - } - break; - case SWT.Move: - dropDown(false); - break; - case SWT.Resize: - internalLayout(false); - break; - } - } - - /** - * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(int wHint, int hHint, boolean changed) { - checkWidget(); - int width = 0, height = 0; - final TreeItem[] items = tree.getItems(); - final GC gc = new GC(text); - final int spacer = gc.stringExtent(" ").x; //$NON-NLS-1$ - int textWidth = gc.stringExtent(text.getText()).x; - for (int i = 0; i < items.length; i++) { - textWidth = Math.max(gc.stringExtent(items[i].getText()).x, textWidth); - } - gc.dispose(); - final Point textSize = text.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); - final Point arrowSize = arrow.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); - final Point listSize = tree.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); - final int borderWidth = getBorderWidth(); - - height = Math.max(textSize.y, arrowSize.y + 5); - width = Math.max(textWidth + 2 * spacer + arrowSize.x + 2 * borderWidth, listSize.x); - if (wHint != SWT.DEFAULT) { - width = wHint; - } - if (hHint != SWT.DEFAULT) { - height = hHint; - } - return new Point(width + 2 * borderWidth, height + 2 * borderWidth); - } - - void createPopup(Collection items, CTreeComboItem selectedItem) { - // create shell and list - popup = new Shell(getShell(), SWT.NO_TRIM | SWT.ON_TOP); - final int style = getStyle(); - int listStyle = SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE; - if ((style & SWT.FLAT) != 0) { - listStyle |= SWT.FLAT; - } - if ((style & SWT.RIGHT_TO_LEFT) != 0) { - listStyle |= SWT.RIGHT_TO_LEFT; - } - if ((style & SWT.LEFT_TO_RIGHT) != 0) { - listStyle |= SWT.LEFT_TO_RIGHT; - } - tree = new Tree(popup, listStyle); - tree.addTreeListener(hookListener); - if (font != null) { - tree.setFont(font); - } - if (foreground != null) { - tree.setForeground(foreground); - } - if (background != null) { - tree.setBackground(background); - } - - final int[] popupEvents = { SWT.Close, SWT.Paint, SWT.Deactivate }; - for (int i = 0; i < popupEvents.length; i++) { - popup.addListener(popupEvents[i], listener); - } - final int[] listEvents = { SWT.MouseUp, SWT.Selection, SWT.Traverse, SWT.KeyDown, SWT.KeyUp, SWT.FocusIn, SWT.Dispose, SWT.Collapse, SWT.Expand }; - for (int i = 0; i < listEvents.length; i++) { - tree.addListener(listEvents[i], listener); - } - - for (final CTreeComboColumn c : columns) { - final TreeColumn col = new TreeColumn(tree, SWT.NONE); - c.setRealTreeColumn(col); - } - - if (items != null) { - createTreeItems(items.toArray(new CTreeComboItem[0])); - } - - if (selectedItem != null) { - tree.setSelection(selectedItem.getRealTreeItem()); - } - } - - private void createTreeItems(CTreeComboItem[] items) { - boolean isReadOnly = (getStyle() & SWT.READ_ONLY) != 0; - - for (final CTreeComboItem item : items) { - if (!isReadOnly && !match(item) && item.getItemCount() == 0) { - continue; - } - item.buildRealTreeItem(tree, columns.size()); - createTreeItems(item.getItems()); - if (!isReadOnly && !match(item) && item.getRealTreeItem().getItemCount() == 0) { - item.getRealTreeItem().dispose(); - } - } - } - - - private boolean match(final CTreeComboItem item) { - final String entry = text.getText().trim().toLowerCase(); - if (entry.equals("") || item.getText().trim().equals("")) { - return true; - } - - return item.getText().trim().toLowerCase().indexOf(entry) > -1; - } - - /** - * Deselects all selected items in the receiver. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void deselectAll() { - checkWidget(); - tree.deselectAll(); - } - - void dropDown(boolean drop) { - if (drop == isDropped() || !isVisible()) { - return; - } - if (!drop) { - popup.setVisible(false); - if (!isDisposed() && isFocusControl()) { - text.setFocus(); - } - return; - } - - CTreeComboItem selectionIndex = null; - if (getShell() != popup.getParent()) { - final TreeItem[] s = tree.getSelection(); - if (s.length > 0) { - selectionIndex = (CTreeComboItem) s[0].getData(CTreeComboItem.DATA_ID); - } - } - - // Rebuild the popup and filter data if the widget is not read-only (based on what is typed) - tree.removeListener(SWT.Dispose, listener); - popup.dispose(); - popup = null; - tree = null; - createPopup(items, selectionIndex); - - final TreeItem[] items = tree.getSelection(); - if (items.length != 0) { - tree.showItem(items[0]); - } - - adjustShellSize(); - popup.setVisible(true); - popup.setActive(); - if (isFocusControl()) { - tree.setFocus(); - } - } - - Label getAssociatedLabel() { - final Control[] siblings = getParent().getChildren(); - for (int i = 0; i < siblings.length; i++) { - if (siblings[i] == this) { - if (i > 0 && siblings[i - 1] instanceof Label) { - return (Label) siblings[i - 1]; - } - } - } - return null; - } - - /** - * Returns the column at the given, zero-relative index in the - * receiver. Throws an exception if the index is out of range. - * Columns are returned in the order that they were created. - * If no TreeColumns were created by the programmer, - * this method will throw ERROR_INVALID_RANGE despite - * the fact that a single column of data may be visible in the tree. - * This occurs when the programmer uses the tree like a list, adding - * items but never creating a column. - * - * @param index the index of the column to return - * @return the column at the given index - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - */ - public CTreeComboColumn getColumn(int columnIndex) { - checkWidget(); - return columns.get(columnIndex); - } - - /** - * Returns the number of columns contained in the receiver. - * If no TreeColumns were created by the programmer, - * this value is zero, despite the fact that visually, one column - * of items may be visible. This occurs when the programmer uses - * the tree like a list, adding items but never creating a column. - * - * @return the number of columns - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @since 3.1 - */ - public int getColumnCount() { - checkWidget(); - return tree.getColumnCount(); - } - - /** - * Returns an array of zero-relative integers that map - * the creation order of the receiver's items to the - * order in which they are currently being displayed. - *

- * Specifically, the indices of the returned array represent - * the current visual order of the items, and the contents - * of the array represent the creation order of the items. - *

- *

- * Note: This is not the actual structure used by the receiver - * to maintain its list of items, so modifying the array will - * not affect the receiver. - *

- * - * @return the current visual order of the receiver's items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - */ - public int[] getColumnOrder() { - checkWidget(); - return tree.getColumnOrder(); - } - - /** - * Gets the editable state. - * - * @return whether or not the receiver is editable - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public boolean getEditable() { - checkWidget(); - return text.getEditable(); - } - - /** - * Returns the item at the given, zero-relative index in the - * receiver. Throws an exception if the index is out of range. - * - * @param index the index of the item to return - * @return the item at the given index - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public CTreeComboItem getItem(int index) { - checkWidget(); - return items.get(index); - } - - /** - * Returns the item at the given point in the receiver - * or null if no such item exists. The point is in the - * coordinate system of the receiver. - *

- * The item that is returned represents an item that could be selected by the user. - * For example, if selection only occurs in items in the first column, then null is - * returned if the point is outside of the item. - * Note that the SWT.FULL_SELECTION style hint, which specifies the selection policy, - * determines the extent of the selection. - *

- * - * @param point the point used to locate the item - * @return the item at the given point, or null if the point is not in a selectable item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the point is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public CTreeComboItem getItem(Point p) { - checkWidget(); - final TreeItem item = tree.getItem(p); - - if (item != null) { - item.getData(CTreeComboItem.DATA_ID); - } - return null; - } - - /** - * Returns the number of items contained in the receiver - * that are direct item children of the receiver. The - * number that is returned is the number of roots in the - * tree. - * - * @return the number of items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getItemCount() { - checkWidget(); - return tree.getItemCount(); - } - - /** - * Returns a (possibly empty) array of items contained in the - * receiver that are direct item children of the receiver. These - * are the roots of the tree. - *

- * Note: This is not the actual structure used by the receiver - * to maintain its list of items, so modifying the array will - * not affect the receiver. - *

- * - * @return the items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public CTreeComboItem[] getItems() { - checkWidget(); - return items.toArray(new CTreeComboItem[0]); - } - - /** - * Returns an array of CTreeComboItems that are currently - * selected in the receiver. The order of the items is unspecified. - * An empty array indicates that no items are selected.
- * This array could not have more than 1 element (because it is a single selection) - *

- * Note: This is not the actual structure used by the receiver - * to maintain its selection, so modifying the array will - * not affect the receiver. - *

- * - * @return an array representing the selection - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public CTreeComboItem[] getSelection() { - checkWidget(); - - final TreeItem[] items = tree.getSelection(); - if (items.length > 0) { - return new CTreeComboItem[] { (CTreeComboItem) items[0].getData(CTreeComboItem.DATA_ID) }; - } - - return new CTreeComboItem[0]; - } - - /** - * Returns a string containing a copy of the contents of the - * receiver's text field. - * - * @return the receiver's text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public String getText() { - checkWidget(); - return text.getText(); - } - - void handleFocus(int type) { - if (isDisposed()) { - return; - } - switch (type) { - case SWT.FocusIn: { - if (hasFocus) { - return; - } - if (getEditable()) { - text.selectAll(); - } - hasFocus = true; - final Shell shell = getShell(); - shell.removeListener(SWT.Deactivate, listener); - shell.addListener(SWT.Deactivate, listener); - final Display display = getDisplay(); - display.removeFilter(SWT.FocusIn, filter); - display.addFilter(SWT.FocusIn, filter); - final Event e = new Event(); - notifyListeners(SWT.FocusIn, e); - break; - } - case SWT.FocusOut: { - if (!hasFocus) { - return; - } - final Control focusControl = getDisplay().getFocusControl(); - if (focusControl == arrow || focusControl == tree || focusControl == text) { - return; - } - hasFocus = false; - final Shell shell = getShell(); - shell.removeListener(SWT.Deactivate, listener); - final Display display = getDisplay(); - display.removeFilter(SWT.FocusIn, filter); - final Event e = new Event(); - notifyListeners(SWT.FocusOut, e); - break; - } - } - } - - /** - * Searches the receiver's list starting at the first column - * (index 0) until a column is found that is equal to the - * argument, and returns the index of that column. If no column - * is found, returns -1. - * - * @param column the search column - * @return the index of the column - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the column is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int indexOf(CTreeComboItem item) { - checkWidget(); - return tree.indexOf(item.getRealTreeItem()); - } - - void initAccessible() { - final AccessibleAdapter accessibleAdapter = new AccessibleAdapter() { - @Override - public void getHelp(AccessibleEvent e) { - e.result = getToolTipText(); - } - - @Override - public void getKeyboardShortcut(AccessibleEvent e) { - String shortcut = null; - final Label label = getAssociatedLabel(); - if (label != null) { - final String text = label.getText(); - if (text != null) { - final char mnemonic = _findMnemonic(text); - if (mnemonic != '\0') { - shortcut = "Alt+" + mnemonic; //$NON-NLS-1$ - } - } - } - e.result = shortcut; - } - - @Override - public void getName(AccessibleEvent e) { - String name = null; - final Label label = getAssociatedLabel(); - if (label != null) { - name = stripMnemonic(label.getText()); - } - e.result = name; - } - }; - getAccessible().addAccessibleListener(accessibleAdapter); - text.getAccessible().addAccessibleListener(accessibleAdapter); - tree.getAccessible().addAccessibleListener(accessibleAdapter); - - arrow.getAccessible().addAccessibleListener(new AccessibleAdapter() { - @Override - public void getHelp(AccessibleEvent e) { - e.result = getToolTipText(); - } - - @Override - public void getKeyboardShortcut(AccessibleEvent e) { - e.result = "Alt+Down Arrow"; //$NON-NLS-1$ - } - - @Override - public void getName(AccessibleEvent e) { - e.result = isDropped() ? SWT.getMessage("SWT_Close") : SWT.getMessage("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$ - } - }); - - getAccessible().addAccessibleTextListener(new AccessibleTextAdapter() { - @Override - public void getCaretOffset(AccessibleTextEvent e) { - e.offset = text.getCaretPosition(); - } - - @Override - public void getSelectionRange(AccessibleTextEvent e) { - final Point sel = text.getSelection(); - e.offset = sel.x; - e.length = sel.y - sel.x; - } - }); - - getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() { - @Override - public void getChildAtPoint(AccessibleControlEvent e) { - final Point testPoint = toControl(e.x, e.y); - if (getBounds().contains(testPoint)) { - e.childID = ACC.CHILDID_SELF; - } - } - - @Override - public void getChildCount(AccessibleControlEvent e) { - e.detail = 0; - } - - @Override - public void getLocation(AccessibleControlEvent e) { - final Rectangle location = getBounds(); - final Point pt = getParent().toDisplay(location.x, location.y); - e.x = pt.x; - e.y = pt.y; - e.width = location.width; - e.height = location.height; - } - - @Override - public void getRole(AccessibleControlEvent e) { - e.detail = ACC.ROLE_COMBOBOX; - } - - @Override - public void getState(AccessibleControlEvent e) { - e.detail = ACC.STATE_NORMAL; - } - - @Override - public void getValue(AccessibleControlEvent e) { - e.result = getText(); - } - }); - - text.getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() { - @Override - public void getRole(AccessibleControlEvent e) { - e.detail = text.getEditable() ? ACC.ROLE_TEXT : ACC.ROLE_LABEL; - } - }); - - arrow.getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() { - @Override - public void getDefaultAction(AccessibleControlEvent e) { - e.result = isDropped() ? SWT.getMessage("SWT_Close") : SWT.getMessage("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$ - } - }); - } - - private CTreeComboItem internalGetSelection() { - final CTreeComboItem[] is = getSelection(); - if (is.length != 0) { - return is[0]; - } - - return null; - } - - void internalLayout(boolean changed) { - if (isDropped()) { - dropDown(false); - } - final Rectangle rect = getClientArea(); - final int width = rect.width; - final int height = rect.height; - final Point arrowSize = arrow.computeSize(SWT.DEFAULT, height, changed); - text.setBounds(0, 0, width - arrowSize.x, height); - arrow.setBounds(width - arrowSize.x, 0, arrowSize.x, arrowSize.y); - } - - boolean isDropped() { - return popup.getVisible(); - } - - void popupEvent(Event event) { - switch (event.type) { - case SWT.Paint: - // draw black rectangle around list - final Rectangle listRect = tree.getBounds(); - final Color black = getDisplay().getSystemColor(SWT.COLOR_BLACK); - event.gc.setForeground(black); - event.gc.drawRectangle(0, 0, listRect.width + 1, listRect.height + 1); - break; - case SWT.Close: - event.doit = false; - dropDown(false); - break; - case SWT.Deactivate: - if (!"carbon".equals(SWT.getPlatform())) { - final Point point = arrow.toControl(getDisplay().getCursorLocation()); - final Point size = arrow.getSize(); - final Rectangle rect = new Rectangle(0, 0, size.x, size.y); - if (!rect.contains(point)) { - dropDown(false); - } - } else { - dropDown(false); - } - break; - } - } - - /** - * Removes all of the items from the receiver. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void removeAll() { - checkWidget(); - tree.removeAll(); - items.clear(); - text.setFont(text.getFont()); - text.setText(""); //$NON-NLS-1$ - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the user changes the receiver's selection. - * - * @param listener - * the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - removeListener(SWT.Selection, listener); - removeListener(SWT.DefaultSelection, listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when items in the receiver are expanded or collapsed. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see TreeListener - * @see #addTreeListener - */ - public void removeTreeListener(TreeListener listener) { - checkWidget(); - treeListeners.remove(listener); - } - - /** - * Selects an item in the receiver. If the item was already - * selected, it remains selected. - * - * @param item the item to be selected - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void select(CTreeComboItem item) { - checkWidget(); - if (item == null) { - tree.deselectAll(); - text.setFont(text.getFont()); - text.setText(""); //$NON-NLS-1$ - return; - } - - if (item != null) { - if (item != internalGetSelection()) { - text.setFont(text.getFont()); - text.setText(item.getText()); - text.selectAll(); - tree.select(item.getRealTreeItem()); - tree.showSelection(); - } - } - } - - /** - * Sets the number of root-level items contained in the receiver. - * - * @param count the number of items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - */ - public void setItemCount(int count) { - checkWidget(); - tree.setItemCount(count); - } - - /** - * Sets the receiver's selection to be the given array of items. - * The current selection is cleared before the new items are selected, - * and if necessary the receiver is scrolled to make the new selection visible. - *

- * Items that are not in the receiver are ignored. - * If the receiver is single-select and multiple items are specified, - * then all items are ignored. - *

- * - * @param items the array of items - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the array of items is null
  • - *
  • ERROR_INVALID_ARGUMENT - if one of the items has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * @see Tree#deselectAll() - */ - public void setSelection(CTreeComboItem[] newItems) { - checkWidget(); - final TreeItem[] items = new TreeItem[newItems.length]; - for (int i = 0; i < items.length; i++) { - items[i] = newItems[i].getRealTreeItem(); - } - if (items.length == 0) { - text.setFont(text.getFont()); - text.setText(""); //$NON-NLS-1$ - } else { - text.setFont(text.getFont()); - text.setText(items[0].getText()); - } - tree.setSelection(items); - } - - /** - * Shows the item. If the item is already showing in the receiver, - * this method simply returns. Otherwise, the items are scrolled - * and expanded until the item is visible. - * - * @param item the item to be shown - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see Tree#showSelection() - */ - public void showItem(CTreeComboItem item) { - checkWidget(); - tree.showItem(item.getRealTreeItem()); - } - - String stripMnemonic(String string) { - int index = 0; - final int length = string.length(); - do { - while (index < length && string.charAt(index) != '&') { - index++; - } - if (++index >= length) { - return string; - } - if (string.charAt(index) != '&') { - return string.substring(0, index - 1) + string.substring(index, length); - } - index++; - } while (index < length); - return string; - } - - void textEvent(Event event) { - switch (event.type) { - case SWT.FocusIn: { - handleFocus(SWT.FocusIn); - break; - } - case SWT.DefaultSelection: { - dropDown(false); - final Event e = new Event(); - e.time = event.time; - e.stateMask = event.stateMask; - notifyListeners(SWT.DefaultSelection, e); - break; - } - case SWT.KeyUp: { - final Event e = new Event(); - e.time = event.time; - e.character = event.character; - e.keyCode = event.keyCode; - e.stateMask = event.stateMask; - notifyListeners(SWT.KeyUp, e); - event.doit = e.doit; - break; - } - case SWT.MenuDetect: { - final Event e = new Event(); - e.time = event.time; - notifyListeners(SWT.MenuDetect, e); - break; - } - case SWT.Modify: { - tree.deselectAll(); - final Event e = new Event(); - e.time = event.time; - notifyListeners(SWT.Modify, e); - break; - } - case SWT.MouseDown: { - final Event mouseEvent = new Event(); - mouseEvent.button = event.button; - mouseEvent.count = event.count; - mouseEvent.stateMask = event.stateMask; - mouseEvent.time = event.time; - mouseEvent.x = event.x; - mouseEvent.y = event.y; - notifyListeners(SWT.MouseDown, mouseEvent); - if (isDisposed()) { - break; - } - event.doit = mouseEvent.doit; - if (!event.doit) { - break; - } - if (event.button != 1) { - return; - } - if (text.getEditable()) { - return; - } - final boolean dropped = isDropped(); - text.selectAll(); - if (!dropped) { - setFocus(); - } - dropDown(!dropped); - break; - } - case SWT.MouseUp: { - final Event mouseEvent = new Event(); - mouseEvent.button = event.button; - mouseEvent.count = event.count; - mouseEvent.stateMask = event.stateMask; - mouseEvent.time = event.time; - mouseEvent.x = event.x; - mouseEvent.y = event.y; - notifyListeners(SWT.MouseUp, mouseEvent); - if (isDisposed()) { - break; - } - event.doit = mouseEvent.doit; - if (!event.doit) { - break; - } - if (event.button != 1) { - return; - } - if (text.getEditable()) { - return; - } - text.selectAll(); - break; - } - case SWT.MouseDoubleClick: { - final Event mouseEvent = new Event(); - mouseEvent.button = event.button; - mouseEvent.count = event.count; - mouseEvent.stateMask = event.stateMask; - mouseEvent.time = event.time; - mouseEvent.x = event.x; - mouseEvent.y = event.y; - notifyListeners(SWT.MouseDoubleClick, mouseEvent); - break; - } - case SWT.Traverse: { - switch (event.detail) { - case SWT.TRAVERSE_ARROW_PREVIOUS: - case SWT.TRAVERSE_ARROW_NEXT: - // The enter causes default selection and - // the arrow keys are used to manipulate the list contents so - // do not use them for traversal. - event.doit = false; - break; - case SWT.TRAVERSE_TAB_PREVIOUS: - event.doit = traverse(SWT.TRAVERSE_TAB_PREVIOUS); - event.detail = SWT.TRAVERSE_NONE; - return; - } - final Event e = new Event(); - e.time = event.time; - e.detail = event.detail; - e.doit = event.doit; - e.character = event.character; - e.keyCode = event.keyCode; - notifyListeners(SWT.Traverse, e); - event.doit = e.doit; - event.detail = e.detail; - break; - } - case SWT.Verify: { - final Event e = new Event(); - e.text = event.text; - e.start = event.start; - e.end = event.end; - e.character = event.character; - e.keyCode = event.keyCode; - e.stateMask = event.stateMask; - notifyListeners(SWT.Verify, e); - event.doit = e.doit; - break; - } - } - } - - void treeEvent(Event event) { - switch (event.type) { - case SWT.Dispose: - if (getShell() != popup.getParent()) { - final CTreeComboItem selectionIndex = internalGetSelection(); - popup = null; - tree = null; - createPopup(items, selectionIndex); - } - break; - case SWT.FocusIn: { - handleFocus(SWT.FocusIn); - break; - } - case SWT.Selection: { - final TreeItem[] items = tree.getSelection(); - if (items.length != 1) { - return; - } - - if (items[0].getItemCount() != 0) { - return; - } - - text.setFont(text.getFont()); - text.setText(items[0].getText()); - text.selectAll(); - tree.setSelection(items); - final Event e = new Event(); - e.time = event.time; - e.stateMask = event.stateMask; - e.doit = event.doit; - if (event.item != null) { - e.data = event.item.getData(); - } - notifyListeners(SWT.Selection, e); - event.doit = e.doit; - dropDown(false); - break; - } - case SWT.Traverse: { - switch (event.detail) { - case SWT.TRAVERSE_RETURN: - case SWT.TRAVERSE_ESCAPE: - case SWT.TRAVERSE_ARROW_PREVIOUS: - case SWT.TRAVERSE_ARROW_NEXT: - event.doit = false; - break; - case SWT.TRAVERSE_TAB_NEXT: - case SWT.TRAVERSE_TAB_PREVIOUS: - event.doit = text.traverse(event.detail); - event.detail = SWT.TRAVERSE_NONE; - if (event.doit) { - dropDown(false); - } - return; - } - final Event e = new Event(); - e.time = event.time; - e.detail = event.detail; - e.doit = event.doit; - e.character = event.character; - e.keyCode = event.keyCode; - notifyListeners(SWT.Traverse, e); - event.doit = e.doit; - event.detail = e.detail; - break; - } - case SWT.KeyUp: { - final Event e = new Event(); - e.time = event.time; - e.character = event.character; - e.keyCode = event.keyCode; - e.stateMask = event.stateMask; - notifyListeners(SWT.KeyUp, e); - break; - } - case SWT.KeyDown: { - if (event.character == SWT.ESC) { - // Escape key cancels popup list - dropDown(false); - } - if ((event.stateMask & SWT.ALT) != 0 && (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_DOWN)) { - dropDown(false); - } - if (event.character == SWT.CR) { - // Enter causes default selection - dropDown(false); - final Event e = new Event(); - e.time = event.time; - e.stateMask = event.stateMask; - notifyListeners(SWT.DefaultSelection, e); - } - // At this point the widget may have been disposed. - // If so, do not continue. - if (isDisposed()) { - break; - } - final Event e = new Event(); - e.time = event.time; - e.character = event.character; - e.keyCode = event.keyCode; - e.stateMask = event.stateMask; - notifyListeners(SWT.KeyDown, e); - break; - - } - case SWT.Collapse: { - adjustShellSize(); - break; - } - case SWT.Expand: { - adjustShellSize(); - break; - } - } - } -} +/******************************************************************************* + * Copyright (c) 2019 Thomas Schindl & Laurent Caron. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API + * and implementation + * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, + * code cleaning and documentation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ctreecombo; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleControlAdapter; +import org.eclipse.swt.accessibility.AccessibleControlEvent; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.accessibility.AccessibleTextAdapter; +import org.eclipse.swt.accessibility.AccessibleTextEvent; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TreeEvent; +import org.eclipse.swt.events.TreeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.TypedListener; +import org.eclipse.swt.widgets.Widget; + +public class CTreeCombo extends Composite { + static int checkStyle(int style) { + final int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; + return SWT.NO_FOCUS | style & mask; + } + + Text text; + Tree tree; + Button arrow; + Listener listener, filter; + Shell popup; + boolean hasFocus; + int visibleItemCount = 5; + Color foreground, background; + Font font; + List items = new ArrayList(); + List columns = new ArrayList(); + + List treeListeners = new ArrayList(); + + private final TreeListener hookListener = new TreeListener() { + + @Override + public void treeCollapsed(TreeEvent e) { + e.item = (Widget) e.item.getData(CTreeComboItem.DATA_ID); + e.widget = CTreeCombo.this; + for (final TreeListener l : treeListeners) { + l.treeCollapsed(e); + } + } + + @Override + public void treeExpanded(TreeEvent e) { + e.item = (Widget) e.item.getData(CTreeComboItem.DATA_ID); + e.widget = CTreeCombo.this; + for (final TreeListener l : treeListeners) { + l.treeExpanded(e); + } + } + + }; + + /** + * The CTreeCombo class represents a selectable user interface object + * that combines a text field and a tree and issues notification + * when an item is selected from the tree. + *

+ * Note that although this class is a subclass of Composite, + * it does not make sense to add children to it, or set a layout on it. + *

+ *
+ *
Styles: + *
BORDER, READ_ONLY, FLAT
+ *
Events: + *
DefaultSelection, Modify, Selection, Verify
+ *
+ */ + public CTreeCombo(Composite parent, int style) { + super(parent, style = checkStyle(style)); + + int textStyle = SWT.SINGLE; + if ((style & SWT.READ_ONLY) != 0) { + textStyle |= SWT.READ_ONLY; + } + if ((style & SWT.FLAT) != 0) { + textStyle |= SWT.FLAT; + } + text = new Text(this, textStyle); + int arrowStyle = SWT.ARROW | SWT.DOWN; + if ((style & SWT.FLAT) != 0) { + arrowStyle |= SWT.FLAT; + } + arrow = new Button(this, arrowStyle); + + listener = new Listener() { + @Override + public void handleEvent(Event event) { + if (popup == event.widget) { + popupEvent(event); + return; + } + if (text == event.widget) { + textEvent(event); + return; + } + if (tree == event.widget) { + treeEvent(event); + return; + } + if (arrow == event.widget) { + arrowEvent(event); + return; + } + if (CTreeCombo.this == event.widget) { + comboEvent(event); + return; + } + if (getShell() == event.widget) { + getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (isDisposed()) { + return; + } + handleFocus(SWT.FocusOut); + } + }); + } + } + }; + filter = (event) -> { + final Shell shell = ((Control) event.widget).getShell(); + if (shell == CTreeCombo.this.getShell()) { + handleFocus(SWT.FocusOut); + } + }; + + final int[] comboEvents = { SWT.Dispose, SWT.FocusIn, SWT.Move, SWT.Resize }; + for (int i = 0; i < comboEvents.length; i++) { + addListener(comboEvents[i], listener); + } + + final int[] textEvents = { SWT.DefaultSelection, SWT.KeyDown, SWT.KeyUp, SWT.MenuDetect, SWT.Modify, SWT.MouseDown, SWT.MouseUp, SWT.MouseDoubleClick, SWT.MouseWheel, SWT.Traverse, SWT.FocusIn, SWT.Verify }; + for (int i = 0; i < textEvents.length; i++) { + text.addListener(textEvents[i], listener); + } + + final int[] arrowEvents = { SWT.MouseDown, SWT.MouseUp, SWT.Selection, SWT.FocusIn }; + for (int i = 0; i < arrowEvents.length; i++) { + arrow.addListener(arrowEvents[i], listener); + } + + createPopup(null, null); + initAccessible(); + } + + char _findMnemonic(String string) { + if (string == null) { + return '\0'; + } + int index = 0; + final int length = string.length(); + do { + while (index < length && string.charAt(index) != '&') { + index++; + } + if (++index >= length) { + return '\0'; + } + if (string.charAt(index) != '&') { + return Character.toLowerCase(string.charAt(index)); + } + index++; + } while (index < length); + return '\0'; + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the user changes the receiver's selection, by sending it one of the messages + * defined in the SelectionListener interface. + *

+ * widgetSelected is called when the combo's list selection + * changes. widgetDefaultSelected is typically called when ENTER is + * pressed the combo's text area. + *

+ * + * @param listener + * the listener which should be notified when the user changes the + * receiver's selection + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final TypedListener typedListener = new TypedListener(listener); + addListener(SWT.Selection, typedListener); + addListener(SWT.DefaultSelection, typedListener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when an item in the receiver is expanded or collapsed + * by sending it one of the messages defined in the TreeListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see TreeListener + * @see #removeTreeListener + */ + public void addTreeListener(TreeListener listener) { + checkWidget(); + treeListeners.add(listener); + } + + private void adjustShellSize() { + final Point size = getSize(); + final int itemCount = visibleItemCount; + final int itemHeight = tree.getItemHeight() * itemCount; + final Point listSize = tree.computeSize(SWT.DEFAULT, itemHeight, false); + tree.setBounds(1, 1, Math.max(size.x - 2, listSize.x), listSize.y); + + final Display display = getDisplay(); + final Rectangle listRect = tree.getBounds(); + final Rectangle parentRect = display.map(getParent(), null, getBounds()); + final Point comboSize = getSize(); + final Rectangle displayRect = getMonitor().getClientArea(); + final int width = Math.max(comboSize.x, listRect.width + 2); + final int height = listRect.height + 2; + int x = parentRect.x; + int y = parentRect.y + comboSize.y; + if (y + height > displayRect.y + displayRect.height) { + y = parentRect.y - height; + } + if (x + width > displayRect.x + displayRect.width) { + x = displayRect.x + displayRect.width - listRect.width; + } + popup.setBounds(x, y, width, height); + + } + + void arrowEvent(Event event) { + switch (event.type) { + case SWT.FocusIn: { + handleFocus(SWT.FocusIn); + break; + } + case SWT.MouseDown: { + final Event mouseEvent = new Event(); + mouseEvent.button = event.button; + mouseEvent.count = event.count; + mouseEvent.stateMask = event.stateMask; + mouseEvent.time = event.time; + mouseEvent.x = event.x; + mouseEvent.y = event.y; + notifyListeners(SWT.MouseDown, mouseEvent); + event.doit = mouseEvent.doit; + break; + } + case SWT.MouseUp: { + final Event mouseEvent = new Event(); + mouseEvent.button = event.button; + mouseEvent.count = event.count; + mouseEvent.stateMask = event.stateMask; + mouseEvent.time = event.time; + mouseEvent.x = event.x; + mouseEvent.y = event.y; + notifyListeners(SWT.MouseUp, mouseEvent); + event.doit = mouseEvent.doit; + break; + } + case SWT.Selection: { + text.setFocus(); + dropDown(!isDropped()); + break; + } + } + } + + /** + * Clears the item at the given zero-relative index in the receiver. + * The text, icon and other attributes of the item are set to the default + * value. If the tree was created with the SWT.VIRTUAL style, + * these attributes are requested again as needed. + * + * @param index the index of the item to clear + * @param all true if all child items of the indexed item should be + * cleared recursively, and false otherwise + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see SWT#VIRTUAL + * @see SWT#SetData + */ + public void clear(int index, boolean all) { + checkWidget(); + tree.clear(index, all); + } + + /** + * Clears all the items in the receiver. The text, icon and other + * attributes of the items are set to their default values. If the + * tree was created with the SWT.VIRTUAL style, these + * attributes are requested again as needed. + * + * @param all true if all child items should be cleared + * recursively, and false otherwise + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see SWT#VIRTUAL + * @see SWT#SetData + */ + public void clearAll(boolean all) { + checkWidget(); + tree.clearAll(all); + text.setFont(text.getFont()); + text.setText(""); //$NON-NLS-1$ + } + + void comboEvent(Event event) { + switch (event.type) { + case SWT.Dispose: + if (popup != null && !popup.isDisposed()) { + tree.removeListener(SWT.Dispose, listener); + popup.dispose(); + } + final Shell shell = getShell(); + shell.removeListener(SWT.Deactivate, listener); + final Display display = getDisplay(); + display.removeFilter(SWT.FocusIn, filter); + popup = null; + text = null; + tree = null; + arrow = null; + break; + case SWT.FocusIn: + final Control focusControl = getDisplay().getFocusControl(); + if (focusControl == arrow || focusControl == tree) { + return; + } + if (isDropped()) { + tree.setFocus(); + } else { + text.setFocus(); + } + break; + case SWT.Move: + dropDown(false); + break; + case SWT.Resize: + internalLayout(false); + break; + } + } + + /** + * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(int wHint, int hHint, boolean changed) { + checkWidget(); + int width = 0, height = 0; + final TreeItem[] items = tree.getItems(); + final GC gc = new GC(text); + final int spacer = gc.stringExtent(" ").x; //$NON-NLS-1$ + int textWidth = gc.stringExtent(text.getText()).x; + for (int i = 0; i < items.length; i++) { + textWidth = Math.max(gc.stringExtent(items[i].getText()).x, textWidth); + } + gc.dispose(); + final Point textSize = text.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); + final Point arrowSize = arrow.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); + final Point listSize = tree.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); + final int borderWidth = getBorderWidth(); + + height = Math.max(textSize.y, arrowSize.y + 5); + width = Math.max(textWidth + 2 * spacer + arrowSize.x + 2 * borderWidth, listSize.x); + if (wHint != SWT.DEFAULT) { + width = wHint; + } + if (hHint != SWT.DEFAULT) { + height = hHint; + } + return new Point(width + 2 * borderWidth, height + 2 * borderWidth); + } + + void createPopup(Collection items, CTreeComboItem selectedItem) { + // create shell and list + popup = new Shell(getShell(), SWT.NO_TRIM | SWT.ON_TOP); + final int style = getStyle(); + int listStyle = SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE; + if ((style & SWT.FLAT) != 0) { + listStyle |= SWT.FLAT; + } + if ((style & SWT.RIGHT_TO_LEFT) != 0) { + listStyle |= SWT.RIGHT_TO_LEFT; + } + if ((style & SWT.LEFT_TO_RIGHT) != 0) { + listStyle |= SWT.LEFT_TO_RIGHT; + } + tree = new Tree(popup, listStyle); + tree.addTreeListener(hookListener); + if (font != null) { + tree.setFont(font); + } + if (foreground != null) { + tree.setForeground(foreground); + } + if (background != null) { + tree.setBackground(background); + } + + final int[] popupEvents = { SWT.Close, SWT.Paint, SWT.Deactivate }; + for (int i = 0; i < popupEvents.length; i++) { + popup.addListener(popupEvents[i], listener); + } + final int[] listEvents = { SWT.MouseUp, SWT.Selection, SWT.Traverse, SWT.KeyDown, SWT.KeyUp, SWT.FocusIn, SWT.Dispose, SWT.Collapse, SWT.Expand }; + for (int i = 0; i < listEvents.length; i++) { + tree.addListener(listEvents[i], listener); + } + + for (final CTreeComboColumn c : columns) { + final TreeColumn col = new TreeColumn(tree, SWT.NONE); + c.setRealTreeColumn(col); + } + + if (items != null) { + createTreeItems(items.toArray(new CTreeComboItem[0])); + } + + if (selectedItem != null) { + tree.setSelection(selectedItem.getRealTreeItem()); + } + } + + private void createTreeItems(CTreeComboItem[] items) { + boolean isReadOnly = (getStyle() & SWT.READ_ONLY) != 0; + + for (final CTreeComboItem item : items) { + if (!isReadOnly && !match(item) && item.getItemCount() == 0) { + continue; + } + item.buildRealTreeItem(tree, columns.size()); + createTreeItems(item.getItems()); + if (!isReadOnly && !match(item) && item.getRealTreeItem().getItemCount() == 0) { + item.getRealTreeItem().dispose(); + } + } + } + + + private boolean match(final CTreeComboItem item) { + final String entry = text.getText().trim().toLowerCase(); + if (entry.equals("") || item.getText().trim().equals("")) { + return true; + } + + return item.getText().trim().toLowerCase().indexOf(entry) > -1; + } + + /** + * Deselects all selected items in the receiver. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void deselectAll() { + checkWidget(); + tree.deselectAll(); + } + + void dropDown(boolean drop) { + if (drop == isDropped() || !isVisible()) { + return; + } + if (!drop) { + popup.setVisible(false); + if (!isDisposed() && isFocusControl()) { + text.setFocus(); + } + return; + } + + CTreeComboItem selectionIndex = null; + if (getShell() != popup.getParent()) { + final TreeItem[] s = tree.getSelection(); + if (s.length > 0) { + selectionIndex = (CTreeComboItem) s[0].getData(CTreeComboItem.DATA_ID); + } + } + + // Rebuild the popup and filter data if the widget is not read-only (based on what is typed) + tree.removeListener(SWT.Dispose, listener); + popup.dispose(); + popup = null; + tree = null; + createPopup(items, selectionIndex); + + final TreeItem[] items = tree.getSelection(); + if (items.length != 0) { + tree.showItem(items[0]); + } + + adjustShellSize(); + popup.setVisible(true); + popup.setActive(); + if (isFocusControl()) { + tree.setFocus(); + } + } + + Label getAssociatedLabel() { + final Control[] siblings = getParent().getChildren(); + for (int i = 0; i < siblings.length; i++) { + if (siblings[i] == this) { + if (i > 0 && siblings[i - 1] instanceof Label) { + return (Label) siblings[i - 1]; + } + } + } + return null; + } + + /** + * Returns the column at the given, zero-relative index in the + * receiver. Throws an exception if the index is out of range. + * Columns are returned in the order that they were created. + * If no TreeColumns were created by the programmer, + * this method will throw ERROR_INVALID_RANGE despite + * the fact that a single column of data may be visible in the tree. + * This occurs when the programmer uses the tree like a list, adding + * items but never creating a column. + * + * @param index the index of the column to return + * @return the column at the given index + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + */ + public CTreeComboColumn getColumn(int columnIndex) { + checkWidget(); + return columns.get(columnIndex); + } + + /** + * Returns the number of columns contained in the receiver. + * If no TreeColumns were created by the programmer, + * this value is zero, despite the fact that visually, one column + * of items may be visible. This occurs when the programmer uses + * the tree like a list, adding items but never creating a column. + * + * @return the number of columns + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @since 3.1 + */ + public int getColumnCount() { + checkWidget(); + return tree.getColumnCount(); + } + + /** + * Returns an array of zero-relative integers that map + * the creation order of the receiver's items to the + * order in which they are currently being displayed. + *

+ * Specifically, the indices of the returned array represent + * the current visual order of the items, and the contents + * of the array represent the creation order of the items. + *

+ *

+ * Note: This is not the actual structure used by the receiver + * to maintain its list of items, so modifying the array will + * not affect the receiver. + *

+ * + * @return the current visual order of the receiver's items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + */ + public int[] getColumnOrder() { + checkWidget(); + return tree.getColumnOrder(); + } + + /** + * Gets the editable state. + * + * @return whether or not the receiver is editable + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public boolean getEditable() { + checkWidget(); + return text.getEditable(); + } + + /** + * Returns the item at the given, zero-relative index in the + * receiver. Throws an exception if the index is out of range. + * + * @param index the index of the item to return + * @return the item at the given index + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public CTreeComboItem getItem(int index) { + checkWidget(); + return items.get(index); + } + + /** + * Returns the item at the given point in the receiver + * or null if no such item exists. The point is in the + * coordinate system of the receiver. + *

+ * The item that is returned represents an item that could be selected by the user. + * For example, if selection only occurs in items in the first column, then null is + * returned if the point is outside of the item. + * Note that the SWT.FULL_SELECTION style hint, which specifies the selection policy, + * determines the extent of the selection. + *

+ * + * @param point the point used to locate the item + * @return the item at the given point, or null if the point is not in a selectable item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the point is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public CTreeComboItem getItem(Point p) { + checkWidget(); + final TreeItem item = tree.getItem(p); + + if (item != null) { + item.getData(CTreeComboItem.DATA_ID); + } + return null; + } + + /** + * Returns the number of items contained in the receiver + * that are direct item children of the receiver. The + * number that is returned is the number of roots in the + * tree. + * + * @return the number of items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getItemCount() { + checkWidget(); + return tree.getItemCount(); + } + + /** + * Returns a (possibly empty) array of items contained in the + * receiver that are direct item children of the receiver. These + * are the roots of the tree. + *

+ * Note: This is not the actual structure used by the receiver + * to maintain its list of items, so modifying the array will + * not affect the receiver. + *

+ * + * @return the items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public CTreeComboItem[] getItems() { + checkWidget(); + return items.toArray(new CTreeComboItem[0]); + } + + /** + * Returns an array of CTreeComboItems that are currently + * selected in the receiver. The order of the items is unspecified. + * An empty array indicates that no items are selected.
+ * This array could not have more than 1 element (because it is a single selection) + *

+ * Note: This is not the actual structure used by the receiver + * to maintain its selection, so modifying the array will + * not affect the receiver. + *

+ * + * @return an array representing the selection + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public CTreeComboItem[] getSelection() { + checkWidget(); + + final TreeItem[] items = tree.getSelection(); + if (items.length > 0) { + return new CTreeComboItem[] { (CTreeComboItem) items[0].getData(CTreeComboItem.DATA_ID) }; + } + + return new CTreeComboItem[0]; + } + + /** + * Returns a string containing a copy of the contents of the + * receiver's text field. + * + * @return the receiver's text + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public String getText() { + checkWidget(); + return text.getText(); + } + + void handleFocus(int type) { + if (isDisposed()) { + return; + } + switch (type) { + case SWT.FocusIn: { + if (hasFocus) { + return; + } + if (getEditable()) { + text.selectAll(); + } + hasFocus = true; + final Shell shell = getShell(); + shell.removeListener(SWT.Deactivate, listener); + shell.addListener(SWT.Deactivate, listener); + final Display display = getDisplay(); + display.removeFilter(SWT.FocusIn, filter); + display.addFilter(SWT.FocusIn, filter); + final Event e = new Event(); + notifyListeners(SWT.FocusIn, e); + break; + } + case SWT.FocusOut: { + if (!hasFocus) { + return; + } + final Control focusControl = getDisplay().getFocusControl(); + if (focusControl == arrow || focusControl == tree || focusControl == text) { + return; + } + hasFocus = false; + final Shell shell = getShell(); + shell.removeListener(SWT.Deactivate, listener); + final Display display = getDisplay(); + display.removeFilter(SWT.FocusIn, filter); + final Event e = new Event(); + notifyListeners(SWT.FocusOut, e); + break; + } + } + } + + /** + * Searches the receiver's list starting at the first column + * (index 0) until a column is found that is equal to the + * argument, and returns the index of that column. If no column + * is found, returns -1. + * + * @param column the search column + * @return the index of the column + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the column is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int indexOf(CTreeComboItem item) { + checkWidget(); + return tree.indexOf(item.getRealTreeItem()); + } + + void initAccessible() { + final AccessibleAdapter accessibleAdapter = new AccessibleAdapter() { + @Override + public void getHelp(AccessibleEvent e) { + e.result = getToolTipText(); + } + + @Override + public void getKeyboardShortcut(AccessibleEvent e) { + String shortcut = null; + final Label label = getAssociatedLabel(); + if (label != null) { + final String text = label.getText(); + if (text != null) { + final char mnemonic = _findMnemonic(text); + if (mnemonic != '\0') { + shortcut = "Alt+" + mnemonic; //$NON-NLS-1$ + } + } + } + e.result = shortcut; + } + + @Override + public void getName(AccessibleEvent e) { + String name = null; + final Label label = getAssociatedLabel(); + if (label != null) { + name = stripMnemonic(label.getText()); + } + e.result = name; + } + }; + getAccessible().addAccessibleListener(accessibleAdapter); + text.getAccessible().addAccessibleListener(accessibleAdapter); + tree.getAccessible().addAccessibleListener(accessibleAdapter); + + arrow.getAccessible().addAccessibleListener(new AccessibleAdapter() { + @Override + public void getHelp(AccessibleEvent e) { + e.result = getToolTipText(); + } + + @Override + public void getKeyboardShortcut(AccessibleEvent e) { + e.result = "Alt+Down Arrow"; //$NON-NLS-1$ + } + + @Override + public void getName(AccessibleEvent e) { + e.result = isDropped() ? SWT.getMessage("SWT_Close") : SWT.getMessage("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$ + } + }); + + getAccessible().addAccessibleTextListener(new AccessibleTextAdapter() { + @Override + public void getCaretOffset(AccessibleTextEvent e) { + e.offset = text.getCaretPosition(); + } + + @Override + public void getSelectionRange(AccessibleTextEvent e) { + final Point sel = text.getSelection(); + e.offset = sel.x; + e.length = sel.y - sel.x; + } + }); + + getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() { + @Override + public void getChildAtPoint(AccessibleControlEvent e) { + final Point testPoint = toControl(e.x, e.y); + if (getBounds().contains(testPoint)) { + e.childID = ACC.CHILDID_SELF; + } + } + + @Override + public void getChildCount(AccessibleControlEvent e) { + e.detail = 0; + } + + @Override + public void getLocation(AccessibleControlEvent e) { + final Rectangle location = getBounds(); + final Point pt = getParent().toDisplay(location.x, location.y); + e.x = pt.x; + e.y = pt.y; + e.width = location.width; + e.height = location.height; + } + + @Override + public void getRole(AccessibleControlEvent e) { + e.detail = ACC.ROLE_COMBOBOX; + } + + @Override + public void getState(AccessibleControlEvent e) { + e.detail = ACC.STATE_NORMAL; + } + + @Override + public void getValue(AccessibleControlEvent e) { + e.result = getText(); + } + }); + + text.getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() { + @Override + public void getRole(AccessibleControlEvent e) { + e.detail = text.getEditable() ? ACC.ROLE_TEXT : ACC.ROLE_LABEL; + } + }); + + arrow.getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() { + @Override + public void getDefaultAction(AccessibleControlEvent e) { + e.result = isDropped() ? SWT.getMessage("SWT_Close") : SWT.getMessage("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$ + } + }); + } + + private CTreeComboItem internalGetSelection() { + final CTreeComboItem[] is = getSelection(); + if (is.length != 0) { + return is[0]; + } + + return null; + } + + void internalLayout(boolean changed) { + if (isDropped()) { + dropDown(false); + } + final Rectangle rect = getClientArea(); + final int width = rect.width; + final int height = rect.height; + final Point arrowSize = arrow.computeSize(SWT.DEFAULT, height, changed); + text.setBounds(0, 0, width - arrowSize.x, height); + arrow.setBounds(width - arrowSize.x, 0, arrowSize.x, arrowSize.y); + } + + boolean isDropped() { + return popup.getVisible(); + } + + void popupEvent(Event event) { + switch (event.type) { + case SWT.Paint: + // draw black rectangle around list + final Rectangle listRect = tree.getBounds(); + final Color black = getDisplay().getSystemColor(SWT.COLOR_BLACK); + event.gc.setForeground(black); + event.gc.drawRectangle(0, 0, listRect.width + 1, listRect.height + 1); + break; + case SWT.Close: + event.doit = false; + dropDown(false); + break; + case SWT.Deactivate: + if (!"carbon".equals(SWT.getPlatform())) { + final Point point = arrow.toControl(getDisplay().getCursorLocation()); + final Point size = arrow.getSize(); + final Rectangle rect = new Rectangle(0, 0, size.x, size.y); + if (!rect.contains(point)) { + dropDown(false); + } + } else { + dropDown(false); + } + break; + } + } + + /** + * Removes all of the items from the receiver. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void removeAll() { + checkWidget(); + tree.removeAll(); + items.clear(); + text.setFont(text.getFont()); + text.setText(""); //$NON-NLS-1$ + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the user changes the receiver's selection. + * + * @param listener + * the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + removeListener(SWT.Selection, listener); + removeListener(SWT.DefaultSelection, listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when items in the receiver are expanded or collapsed. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see TreeListener + * @see #addTreeListener + */ + public void removeTreeListener(TreeListener listener) { + checkWidget(); + treeListeners.remove(listener); + } + + /** + * Selects an item in the receiver. If the item was already + * selected, it remains selected. + * + * @param item the item to be selected + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void select(CTreeComboItem item) { + checkWidget(); + if (item == null) { + tree.deselectAll(); + text.setFont(text.getFont()); + text.setText(""); //$NON-NLS-1$ + return; + } + + if (item != null) { + if (item != internalGetSelection()) { + text.setFont(text.getFont()); + text.setText(item.getText()); + text.selectAll(); + tree.select(item.getRealTreeItem()); + tree.showSelection(); + } + } + } + + /** + * Sets the number of root-level items contained in the receiver. + * + * @param count the number of items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + */ + public void setItemCount(int count) { + checkWidget(); + tree.setItemCount(count); + } + + /** + * Sets the receiver's selection to be the given array of items. + * The current selection is cleared before the new items are selected, + * and if necessary the receiver is scrolled to make the new selection visible. + *

+ * Items that are not in the receiver are ignored. + * If the receiver is single-select and multiple items are specified, + * then all items are ignored. + *

+ * + * @param items the array of items + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the array of items is null
  • + *
  • ERROR_INVALID_ARGUMENT - if one of the items has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * @see Tree#deselectAll() + */ + public void setSelection(CTreeComboItem[] newItems) { + checkWidget(); + final TreeItem[] items = new TreeItem[newItems.length]; + for (int i = 0; i < items.length; i++) { + items[i] = newItems[i].getRealTreeItem(); + } + if (items.length == 0) { + text.setFont(text.getFont()); + text.setText(""); //$NON-NLS-1$ + } else { + text.setFont(text.getFont()); + text.setText(items[0].getText()); + } + tree.setSelection(items); + } + + /** + * Shows the item. If the item is already showing in the receiver, + * this method simply returns. Otherwise, the items are scrolled + * and expanded until the item is visible. + * + * @param item the item to be shown + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see Tree#showSelection() + */ + public void showItem(CTreeComboItem item) { + checkWidget(); + tree.showItem(item.getRealTreeItem()); + } + + String stripMnemonic(String string) { + int index = 0; + final int length = string.length(); + do { + while (index < length && string.charAt(index) != '&') { + index++; + } + if (++index >= length) { + return string; + } + if (string.charAt(index) != '&') { + return string.substring(0, index - 1) + string.substring(index, length); + } + index++; + } while (index < length); + return string; + } + + void textEvent(Event event) { + switch (event.type) { + case SWT.FocusIn: { + handleFocus(SWT.FocusIn); + break; + } + case SWT.DefaultSelection: { + dropDown(false); + final Event e = new Event(); + e.time = event.time; + e.stateMask = event.stateMask; + notifyListeners(SWT.DefaultSelection, e); + break; + } + case SWT.KeyUp: { + final Event e = new Event(); + e.time = event.time; + e.character = event.character; + e.keyCode = event.keyCode; + e.stateMask = event.stateMask; + notifyListeners(SWT.KeyUp, e); + event.doit = e.doit; + break; + } + case SWT.MenuDetect: { + final Event e = new Event(); + e.time = event.time; + notifyListeners(SWT.MenuDetect, e); + break; + } + case SWT.Modify: { + tree.deselectAll(); + final Event e = new Event(); + e.time = event.time; + notifyListeners(SWT.Modify, e); + break; + } + case SWT.MouseDown: { + final Event mouseEvent = new Event(); + mouseEvent.button = event.button; + mouseEvent.count = event.count; + mouseEvent.stateMask = event.stateMask; + mouseEvent.time = event.time; + mouseEvent.x = event.x; + mouseEvent.y = event.y; + notifyListeners(SWT.MouseDown, mouseEvent); + if (isDisposed()) { + break; + } + event.doit = mouseEvent.doit; + if (!event.doit) { + break; + } + if (event.button != 1) { + return; + } + if (text.getEditable()) { + return; + } + final boolean dropped = isDropped(); + text.selectAll(); + if (!dropped) { + setFocus(); + } + dropDown(!dropped); + break; + } + case SWT.MouseUp: { + final Event mouseEvent = new Event(); + mouseEvent.button = event.button; + mouseEvent.count = event.count; + mouseEvent.stateMask = event.stateMask; + mouseEvent.time = event.time; + mouseEvent.x = event.x; + mouseEvent.y = event.y; + notifyListeners(SWT.MouseUp, mouseEvent); + if (isDisposed()) { + break; + } + event.doit = mouseEvent.doit; + if (!event.doit) { + break; + } + if (event.button != 1) { + return; + } + if (text.getEditable()) { + return; + } + text.selectAll(); + break; + } + case SWT.MouseDoubleClick: { + final Event mouseEvent = new Event(); + mouseEvent.button = event.button; + mouseEvent.count = event.count; + mouseEvent.stateMask = event.stateMask; + mouseEvent.time = event.time; + mouseEvent.x = event.x; + mouseEvent.y = event.y; + notifyListeners(SWT.MouseDoubleClick, mouseEvent); + break; + } + case SWT.Traverse: { + switch (event.detail) { + case SWT.TRAVERSE_ARROW_PREVIOUS: + case SWT.TRAVERSE_ARROW_NEXT: + // The enter causes default selection and + // the arrow keys are used to manipulate the list contents so + // do not use them for traversal. + event.doit = false; + break; + case SWT.TRAVERSE_TAB_PREVIOUS: + event.doit = traverse(SWT.TRAVERSE_TAB_PREVIOUS); + event.detail = SWT.TRAVERSE_NONE; + return; + } + final Event e = new Event(); + e.time = event.time; + e.detail = event.detail; + e.doit = event.doit; + e.character = event.character; + e.keyCode = event.keyCode; + notifyListeners(SWT.Traverse, e); + event.doit = e.doit; + event.detail = e.detail; + break; + } + case SWT.Verify: { + final Event e = new Event(); + e.text = event.text; + e.start = event.start; + e.end = event.end; + e.character = event.character; + e.keyCode = event.keyCode; + e.stateMask = event.stateMask; + notifyListeners(SWT.Verify, e); + event.doit = e.doit; + break; + } + } + } + + void treeEvent(Event event) { + switch (event.type) { + case SWT.Dispose: + if (getShell() != popup.getParent()) { + final CTreeComboItem selectionIndex = internalGetSelection(); + popup = null; + tree = null; + createPopup(items, selectionIndex); + } + break; + case SWT.FocusIn: { + handleFocus(SWT.FocusIn); + break; + } + case SWT.Selection: { + final TreeItem[] items = tree.getSelection(); + if (items.length != 1) { + return; + } + + if (items[0].getItemCount() != 0) { + return; + } + + text.setFont(text.getFont()); + text.setText(items[0].getText()); + text.selectAll(); + tree.setSelection(items); + final Event e = new Event(); + e.time = event.time; + e.stateMask = event.stateMask; + e.doit = event.doit; + if (event.item != null) { + e.data = event.item.getData(); + } + notifyListeners(SWT.Selection, e); + event.doit = e.doit; + dropDown(false); + break; + } + case SWT.Traverse: { + switch (event.detail) { + case SWT.TRAVERSE_RETURN: + case SWT.TRAVERSE_ESCAPE: + case SWT.TRAVERSE_ARROW_PREVIOUS: + case SWT.TRAVERSE_ARROW_NEXT: + event.doit = false; + break; + case SWT.TRAVERSE_TAB_NEXT: + case SWT.TRAVERSE_TAB_PREVIOUS: + event.doit = text.traverse(event.detail); + event.detail = SWT.TRAVERSE_NONE; + if (event.doit) { + dropDown(false); + } + return; + } + final Event e = new Event(); + e.time = event.time; + e.detail = event.detail; + e.doit = event.doit; + e.character = event.character; + e.keyCode = event.keyCode; + notifyListeners(SWT.Traverse, e); + event.doit = e.doit; + event.detail = e.detail; + break; + } + case SWT.KeyUp: { + final Event e = new Event(); + e.time = event.time; + e.character = event.character; + e.keyCode = event.keyCode; + e.stateMask = event.stateMask; + notifyListeners(SWT.KeyUp, e); + break; + } + case SWT.KeyDown: { + if (event.character == SWT.ESC) { + // Escape key cancels popup list + dropDown(false); + } + if ((event.stateMask & SWT.ALT) != 0 && (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_DOWN)) { + dropDown(false); + } + if (event.character == SWT.CR) { + // Enter causes default selection + dropDown(false); + final Event e = new Event(); + e.time = event.time; + e.stateMask = event.stateMask; + notifyListeners(SWT.DefaultSelection, e); + } + // At this point the widget may have been disposed. + // If so, do not continue. + if (isDisposed()) { + break; + } + final Event e = new Event(); + e.time = event.time; + e.character = event.character; + e.keyCode = event.keyCode; + e.stateMask = event.stateMask; + notifyListeners(SWT.KeyDown, e); + break; + + } + case SWT.Collapse: { + adjustShellSize(); + break; + } + case SWT.Expand: { + adjustShellSize(); + break; + } + } + } +} diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeComboColumn.java b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeComboColumn.java index af7890bfc..81b44760b 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeComboColumn.java +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeComboColumn.java @@ -1,216 +1,216 @@ -/******************************************************************************* - * Copyright (c) 2019 Thomas Schindl & Laurent Caron. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API - * and implementation - * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, - * code cleaning and documentation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ctreecombo; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.swt.widgets.Widget; - -/** - * Instances of this class represent a column in a ctreecombo widget. - *

- *
Styles:
- *
LEFT, RIGHT, CENTER
- *
Events:
- *
Move, Resize, Selection
- *
- *

- * Note: Only one of the styles LEFT, RIGHT and CENTER may be specified. - *

- * IMPORTANT: This class is not intended to be subclassed. - *

- * - * @noextend This class is not intended to be subclassed by clients. - */ - -public class CTreeComboColumn extends Item { - private TreeColumn realTreeColumn; - private CTreeCombo parent; - private int width; - - /** - * Constructs a new instance of this class given its parent - * (which must be a Tree) and a style value - * describing its behavior and appearance. The item is added - * to the end of the items maintained by its parent. - *

- * The style value is either one of the style constants defined in - * class SWT which is applicable to instances of this - * class, or must be built by bitwise OR'ing together - * (that is, using the int "|" operator) two or more - * of those SWT style constants. The class description - * lists the style constants that are applicable to the class. - * Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • - *
- * - * @see SWT#LEFT - * @see SWT#RIGHT - * @see SWT#CENTER - * @see Widget#checkSubclass - * @see Widget#getStyle - */ - public CTreeComboColumn(CTreeCombo parent, int style) { - super(parent, style); - this.parent = parent; - this.parent.columns.add(this); - - if (this.parent.tree != null && !this.parent.tree.isDisposed()) { - setRealTreeColumn(new TreeColumn(parent.tree, style)); - } - } - - /** - * Constructs a new instance of this class given its parent - * (which must be a Tree), a style value - * describing its behavior and appearance, and the index - * at which to place it in the items maintained by its parent. - *

- * The style value is either one of the style constants defined in - * class SWT which is applicable to instances of this - * class, or must be built by bitwise OR'ing together - * (that is, using the int "|" operator) two or more - * of those SWT style constants. The class description - * lists the style constants that are applicable to the class. - * Style bits are also inherited from superclasses. - *

- *

- * Note that due to a restriction on some platforms, the first column - * is always left aligned. - *

- * - * @param parent a composite control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * @param index the zero-relative index to store the receiver in its parent - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • - *
- * - * @see SWT#LEFT - * @see SWT#RIGHT - * @see SWT#CENTER - * @see Widget#checkSubclass - * @see Widget#getStyle - */ - public CTreeComboColumn(CTreeCombo parent, int style, int index) { - super(parent, style, index); - this.parent = parent; - this.parent.columns.add(this); - - if (this.parent.tree != null && !this.parent.tree.isDisposed()) { - setRealTreeColumn(new TreeColumn(parent.tree, style, index)); - } - } - - void setRealTreeColumn(TreeColumn realTreeColumn) { - this.realTreeColumn = realTreeColumn; - this.realTreeColumn.setText(getText()); - this.realTreeColumn.setWidth(width); - } - - TreeColumn getRealTreeColumn() { - return realTreeColumn; - } - - private boolean checkRealColumn() { - return realTreeColumn != null && !realTreeColumn.isDisposed(); - } - - /** - * Gets the width of the receiver. - * - * @return the width - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getWidth() { - checkWidget(); - if (checkRealColumn()) { - return realTreeColumn.getWidth(); - } - return 0; - } - - /** - * Sets the width of the receiver. - * - * @param width the new width - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setWidth(int width) { - checkWidget(); - this.width = width; - realTreeColumn.setWidth(width); - } - - /** - * Sets the receiver's text. - *

- * Note: If control characters like '\n', '\t' etc. are used - * in the string, then the behavior is platform dependent. - *

- * - * @param string the new text - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the text is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setText(String string) { - checkWidget(); - super.setText(string); - realTreeColumn.setText(string); - } - -} +/******************************************************************************* + * Copyright (c) 2019 Thomas Schindl & Laurent Caron. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API + * and implementation + * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, + * code cleaning and documentation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ctreecombo; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.Widget; + +/** + * Instances of this class represent a column in a ctreecombo widget. + *

+ *
Styles:
+ *
LEFT, RIGHT, CENTER
+ *
Events:
+ *
Move, Resize, Selection
+ *
+ *

+ * Note: Only one of the styles LEFT, RIGHT and CENTER may be specified. + *

+ * IMPORTANT: This class is not intended to be subclassed. + *

+ * + * @noextend This class is not intended to be subclassed by clients. + */ + +public class CTreeComboColumn extends Item { + private TreeColumn realTreeColumn; + private CTreeCombo parent; + private int width; + + /** + * Constructs a new instance of this class given its parent + * (which must be a Tree) and a style value + * describing its behavior and appearance. The item is added + * to the end of the items maintained by its parent. + *

+ * The style value is either one of the style constants defined in + * class SWT which is applicable to instances of this + * class, or must be built by bitwise OR'ing together + * (that is, using the int "|" operator) two or more + * of those SWT style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • + *
+ * + * @see SWT#LEFT + * @see SWT#RIGHT + * @see SWT#CENTER + * @see Widget#checkSubclass + * @see Widget#getStyle + */ + public CTreeComboColumn(CTreeCombo parent, int style) { + super(parent, style); + this.parent = parent; + this.parent.columns.add(this); + + if (this.parent.tree != null && !this.parent.tree.isDisposed()) { + setRealTreeColumn(new TreeColumn(parent.tree, style)); + } + } + + /** + * Constructs a new instance of this class given its parent + * (which must be a Tree), a style value + * describing its behavior and appearance, and the index + * at which to place it in the items maintained by its parent. + *

+ * The style value is either one of the style constants defined in + * class SWT which is applicable to instances of this + * class, or must be built by bitwise OR'ing together + * (that is, using the int "|" operator) two or more + * of those SWT style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + *

+ *

+ * Note that due to a restriction on some platforms, the first column + * is always left aligned. + *

+ * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * @param index the zero-relative index to store the receiver in its parent + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • + *
+ * + * @see SWT#LEFT + * @see SWT#RIGHT + * @see SWT#CENTER + * @see Widget#checkSubclass + * @see Widget#getStyle + */ + public CTreeComboColumn(CTreeCombo parent, int style, int index) { + super(parent, style, index); + this.parent = parent; + this.parent.columns.add(this); + + if (this.parent.tree != null && !this.parent.tree.isDisposed()) { + setRealTreeColumn(new TreeColumn(parent.tree, style, index)); + } + } + + void setRealTreeColumn(TreeColumn realTreeColumn) { + this.realTreeColumn = realTreeColumn; + this.realTreeColumn.setText(getText()); + this.realTreeColumn.setWidth(width); + } + + TreeColumn getRealTreeColumn() { + return realTreeColumn; + } + + private boolean checkRealColumn() { + return realTreeColumn != null && !realTreeColumn.isDisposed(); + } + + /** + * Gets the width of the receiver. + * + * @return the width + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getWidth() { + checkWidget(); + if (checkRealColumn()) { + return realTreeColumn.getWidth(); + } + return 0; + } + + /** + * Sets the width of the receiver. + * + * @param width the new width + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setWidth(int width) { + checkWidget(); + this.width = width; + realTreeColumn.setWidth(width); + } + + /** + * Sets the receiver's text. + *

+ * Note: If control characters like '\n', '\t' etc. are used + * in the string, then the behavior is platform dependent. + *

+ * + * @param string the new text + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the text is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setText(String string) { + checkWidget(); + super.setText(string); + realTreeColumn.setText(string); + } + +} diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeComboItem.java b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeComboItem.java index c924e2a3d..ce1090938 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeComboItem.java +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/CTreeComboItem.java @@ -1,1071 +1,1071 @@ -/******************************************************************************* - * Copyright (c) 2019 Thomas Schindl & Laurent Caron. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API - * and implementation - * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, - * code cleaning and documentation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ctreecombo; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeItem; -import org.eclipse.swt.widgets.Widget; - -/** - * Instances of this class represent a selectable user interface object - * that represents a hierarchy of tree items in a ctreecombo widget. - * - *
- *
Styles:
- *
(none)
- *
Events:
- *
(none)
- *
- *

- * IMPORTANT: This class is not intended to be subclassed. - *

- * - * @noextend This class is not intended to be subclassed by clients. - */ -public class CTreeComboItem extends Item { - static final String DATA_ID = "org.eclipse.nebula.widgets.ctreecombo.CTreeComboItem"; - private CTreeCombo parent; - private CTreeComboItem parentItem; - private List childItems = new ArrayList<>(); - private ArrayList backgroundColors = new ArrayList<>(); - private ArrayList foregroundColors = new ArrayList<>(); - private ArrayList fonts = new ArrayList<>(); - private ArrayList images = new ArrayList<>(); - private ArrayList texts = new ArrayList<>(); - private ArrayList bounds = new ArrayList<>(); - private ArrayList textbounds = new ArrayList<>(); - private ArrayList imageBounds = new ArrayList<>(); - private Color foreground, background; - private Font font; - private Rectangle bound; - - private TreeItem realTreeItem; - - /** - * Constructs a new instance of this class given its parent - * (which must be a CTreeComboItemItem), - * a style value describing its behavior and appearance, and the index - * at which to place it in the items maintained by its parent. - *

- * The style value is either one of the style constants defined in - * class SWT which is applicable to instances of this - * class, or must be built by bitwise OR'ing together - * (that is, using the int "|" operator) two or more - * of those SWT style constants. The class description - * lists the style constants that are applicable to the class. - * Style bits are also inherited from superclasses. - *

- * - * @param parentItem a CTreeComboItem which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * @param index the zero-relative index to store the receiver in its parent - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • - *
- * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ - public CTreeComboItem(CTreeComboItem parentItem, int style, int index) { - super(parentItem.parent, style); - this.parent = parentItem.parent; - this.parentItem = parentItem; - this.parentItem.childItems.add(index, this); - - if (parentItem.realTreeItem != null && !parentItem.realTreeItem.isDisposed()) { - setRealTreeItem(new TreeItem(parentItem.realTreeItem, style, index)); - } - } - - /** - * Constructs a new instance of this class given its parent - * (which must be a CTreeComboItem) - * and a style value describing its behavior and appearance. - * The item is added to the end of the items maintained by its parent. - *

- * The style value is either one of the style constants defined in - * class SWT which is applicable to instances of this - * class, or must be built by bitwise OR'ing together - * (that is, using the int "|" operator) two or more - * of those SWT style constants. The class description - * lists the style constants that are applicable to the class. - * Style bits are also inherited from superclasses. - *

- * - * @param parentItem a CTreeComboItem control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • - *
- * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ - public CTreeComboItem(CTreeComboItem parentItem, int style) { - super(parentItem.parent, style); - this.parent = parentItem.parent; - this.parentItem = parentItem; - this.parentItem.childItems.add(this); - - if (parentItem.realTreeItem != null && !parentItem.realTreeItem.isDisposed()) { - setRealTreeItem(new TreeItem(parentItem.realTreeItem, style)); - } - } - - /** - * Constructs a new instance of this class given its parent - * (which must be a CTreeCombo ), - * a style value describing its behavior and appearance, and the index - * at which to place it in the items maintained by its parent. - *

- * The style value is either one of the style constants defined in - * class SWT which is applicable to instances of this - * class, or must be built by bitwise OR'ing together - * (that is, using the int "|" operator) two or more - * of those SWT style constants. The class description - * lists the style constants that are applicable to the class. - * Style bits are also inherited from superclasses. - *

- * - * @param parent a CTreeCombo control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * @param index the zero-relative index to store the receiver in its parent - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • - *
- * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ - public CTreeComboItem(CTreeCombo parent, int style, int index) { - super(parent, style); - this.parent = parent; - this.parent.items.add(index, this); - - if (this.parent.tree != null && !this.parent.tree.isDisposed()) { - setRealTreeItem(new TreeItem(this.parent.tree, style, index)); - } - } - - /** - * Constructs a new instance of this class given its parent - * (which must be a CTreeCombo) - * and a style value describing its behavior and appearance. - * The item is added to the end of the items maintained by its parent. - *

- * The style value is either one of the style constants defined in - * class SWT which is applicable to instances of this - * class, or must be built by bitwise OR'ing together - * (that is, using the int "|" operator) two or more - * of those SWT style constants. The class description - * lists the style constants that are applicable to the class. - * Style bits are also inherited from superclasses. - *

- * - * @param parent a CTreeCombo control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • - *
- * - * @see SWT - * @see Widget#checkSubclass - * @see Widget#getStyle - */ - public CTreeComboItem(CTreeCombo parent, int style) { - super(parent, style); - this.parent = parent; - this.parent.items.add(this); - - if (this.parent.tree != null && !this.parent.tree.isDisposed()) { - setRealTreeItem(new TreeItem(this.parent.tree, style)); - } - } - - /** - * Disposes of the operating system resources associated with - * the receiver and all its descendants. After this method has - * been invoked, the receiver and all descendants will answer - * true when sent the message isDisposed(). - * Any internal connections between the widgets in the tree will - * have been removed to facilitate garbage collection. - * This method does nothing if the widget is already disposed. - *

- * NOTE: This method is not called recursively on the descendants - * of the receiver. This means that, widget implementers can not - * detect when a widget is being disposed of by re-implementing - * this method, but should instead listen for the Dispose - * event. - *

- * - * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see #addDisposeListener - * @see #removeDisposeListener - * @see #checkWidget - */ - public void dispose() { - super.dispose(); - if (realTreeItem != null && !realTreeItem.isDisposed()) { - realTreeItem.dispose(); - } - - if (this.parentItem != null && !this.parentItem.isDisposed()) { - this.parentItem.childItems.remove(this); - } - - for (CTreeComboItem child : childItems) { - child.dispose(); - } - } - - void setRealTreeItem(TreeItem realTreeItem) { - this.realTreeItem = realTreeItem; - this.realTreeItem.setData(DATA_ID, this); - } - - TreeItem getRealTreeItem() { - return this.realTreeItem; - } - - /** - * Returns a (possibly empty) array of CTreeComboItems which - * are the direct item children of the receiver. - *

- * Note: This is not the actual structure used by the receiver - * to maintain its list of items, so modifying the array will - * not affect the receiver. - *

- * - * @return the receiver's items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public CTreeComboItem[] getItems() { - checkWidget(); - return childItems.toArray(new CTreeComboItem[0]); - } - - private boolean checkRealItem() { - return realTreeItem != null && !realTreeItem.isDisposed(); - } - - /** - * Sets the receiver's image to the argument, which may be - * null indicating that no image should be displayed. - * - * @param image the image to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setImage(Image image) { - super.setImage(image); - } - - /** - * Sets the receiver's text. - *

- * Note: If control characters like '\n', '\t' etc. are used - * in the string, then the behavior is platform dependent. - *

- * - * @param string the new text - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the text is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setText(String string) { - super.setText(string); - } - - /** - * Returns a rectangle describing the receiver's size and location - * relative to its parent at a column in the tree. - * - * @param index the index that specifies the column - * @return the receiver's bounding column rectangle - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Rectangle getBounds(int index) { - checkWidget(); - if (index < 0 || index > (bounds.size() - 1)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return bounds.get(index); - } - - /** - * Returns a rectangle describing the size and location of the receiver's - * text relative to its parent. - * - * @return the bounding rectangle of the receiver's text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Rectangle getBounds() { - checkWidget(); - return bound; - } - - /** - * Returns the receiver's parent, which must be a CTreeCombo. - * - * @return the receiver's parent - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public CTreeCombo getParent() { - checkWidget(); - return parent; - } - - /** - * Returns the background color of the receiver. - * - * @return the background color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getBackground() { - checkWidget(); - return background; - } - - /** - * Returns the background color at the given column index in the receiver. - * - * @param index the column index - * @return the background color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getBackground(int index) { - checkWidget(); - if (index < 0 || index > (backgroundColors.size() - 1)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return backgroundColors.get(index); - } - - /** - * Returns the font that the receiver will use to paint textual information - * - * @return the receiver's font - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Font getFont() { - checkWidget(); - return font; - } - - /** - * Returns the font that the receiver will use to paint textual information - * for the specified cell in this item. - * - * @param index the column index - * @return the receiver's font - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Font getFont(int index) { - checkWidget(); - if (index < 0 || index > (fonts.size() - 1)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return fonts.get(index); - } - - /** - * - * Returns the foreground color of the receiver. - * - * @return the foreground color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getForeground() { - checkWidget(); - return foreground; - } - - /** - * - * Returns the foreground color at the given column index in the receiver. - * - * @param index the column index - * @return the foreground color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Color getForeground(int index) { - checkWidget(); - if (index < 0 || index > (foregroundColors.size() - 1)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return foregroundColors.get(index); - } - - /** - * Returns the image stored at the given column index in the receiver, - * or null if the image has not been set or if the column does not exist. - * - * @param index the column index - * @return the image stored at the given column index in the receiver - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Image getImage(int index) { - checkWidget(); - if (index < 0 || index > (images.size() - 1)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return images.get(index); - } - - /** - * Returns the text stored at the given column index in the receiver, - * or empty string if the text has not been set. - * - * @param index the column index - * @return the text stored at the given column index in the receiver - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public String getText(int index) { - checkWidget(); - if (index < 0 || index > (texts.size() - 1)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return texts.get(index); - } - - /** - * Sets the background color at the given column index in the receiver - * to the color specified by the argument, or to the default system color for the item - * if the argument is null. - * - * @param index the column index - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @since 3.1 - * - */ - public void setBackground(int index, Color color) { - checkWidget(); - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - ensureArraySizes(index); - backgroundColors.set(index, color); - } - - private void ensureArraySizes(int index) { - backgroundColors.ensureCapacity(index); - foregroundColors.ensureCapacity(index); - fonts.ensureCapacity(index); - images.ensureCapacity(index); - texts.ensureCapacity(index); - bounds.ensureCapacity(index); - textbounds.ensureCapacity(index); - imageBounds.ensureCapacity(index); - } - - /** - * Sets the background color at in the receiver to the color specified by the argument, - * or to the default system color for the item if the argument is null. - * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @since 3.1 - * - */ - public void setBackground(Color color) { - checkWidget(); - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.background = color; - } - - /** - * Sets the font that the receiver will use to paint textual information - * for the item to the font specified by the argument, or to the default - * font for that kind of control if the argument is null. - * - * @param font the new font (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @since 3.1 - */ - public void setFont(Font font) { - checkWidget(); - this.font = font; - } - - /** - * Sets the font that the receiver will use to paint textual information - * for the specified cell in this item to the font specified by the - * argument, or to the default font for that kind of control if the - * argument is null. - * - * @param index the column index - * @param font the new font (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @since 3.1 - */ - public void setFont(int index, Font font) { - checkWidget(); - if (font != null && font.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - ensureArraySizes(index); - fonts.set(index, font); - } - - /** - * Sets the foreground color at the given column index in the receiver - * to the color specified by the argument, or to the default system color for the item - * if the argument is null. - * - * @param index the column index - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setForeground(int index, Color color) { - checkWidget(); - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - ensureArraySizes(index); - foregroundColors.set(index, color); - } - - /** - * Sets the foreground color in the receiver to the color specified by the argument, - * or to the default system color for the item if the argument is null. - * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setForeground(Color color) { - checkWidget(); - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.foreground = color; - } - - /** - * Sets the receiver's image at a column. - * - * @param index the column index - * @param image the new image - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setImage(int index, Image image) { - checkWidget(); - if (image != null && image.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - ensureArraySizes(index); - images.set(index, image); - } - - /** - * Sets the receiver's text at a column - *

- * Note: If control characters like '\n', '\t' etc. are used - * in the string, then the behavior is platform dependent. - *

- * - * @param index the column index - * @param string the new text - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the text is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setText(int index, String string) { - checkWidget(); - ensureArraySizes(index); - texts.set(index, string == null ? "" : string); - } - - /** - * Returns the receiver's parent item, which must be a - * CTreeComboItem or null when the receiver is a - * root. - * - * @return the receiver's parent item - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public CTreeComboItem getParentItem() { - checkWidget(); - return parentItem; - } - - /** - * Returns true if the receiver is expanded, - * and false otherwise. - *

- * - * @return the expanded state - * - * @exception SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public boolean getExpanded() { - checkWidget(); - if (checkRealItem()) { - return realTreeItem.getExpanded(); - } - return false; - } - - /** - * Returns the number of items contained in the receiver - * that are direct item children of the receiver. - * - * @return the number of items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getItemCount() { - checkWidget(); - return childItems.size(); - } - - /** - * Returns the item at the given, zero-relative index in the - * receiver. Throws an exception if the index is out of range. - * - * @param index the index of the item to return - * @return the item at the given index - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public CTreeComboItem getItem(int index) { - checkWidget(); - return childItems.get(index); - } - - /** - * Searches the receiver's list starting at the first item - * (index 0) until an item is found that is equal to the - * argument, and returns the index of that item. If no item - * is found, returns -1. - * - * @param item the search item - * @return the index of the item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int indexOf(CTreeComboItem item) { - checkWidget(); - return childItems.indexOf(item); - } - - /** - * Returns a rectangle describing the size and location - * relative to its parent of the text at a column in the - * tree. - * - * @param index the index that specifies the column - * @return the receiver's bounding text rectangle - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Rectangle getTextBounds(int index) { - checkWidget(); - if (index < 0 || index > (textbounds.size() - 1)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return textbounds.get(index); - } - - /** - * Returns a rectangle describing the size and location - * relative to its parent of an image at a column in the - * tree. - * - * @param index the index that specifies the column - * @return the receiver's bounding image rectangle - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Rectangle getImageBounds(int index) { - checkWidget(); - if (index < 0 || index > (imageBounds.size() - 1)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return imageBounds.get(index); - } - - /** - * Sets the expanded state of the receiver. - *

- * - * @param expanded the new expanded state - * - * @exception SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setExpanded(boolean expand) { - checkWidget(); - if (checkRealItem()) { - realTreeItem.setExpanded(expand); - } - } - - /** - * Sets the number of child items contained in the receiver. - * - * @param count the number of items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setItemCount(int count) { - checkWidget(); - if (checkRealItem()) { - realTreeItem.setItemCount(count); - } - } - - /** - * Clears the item at the given zero-relative index in the receiver. - * The text, icon and other attributes of the item are set to the default - * value. If the tree was created with the SWT.VIRTUAL style, - * these attributes are requested again as needed. - * - * @param index the index of the item to clear - * @param all true if all child items of the indexed item should be - * cleared recursively, and false otherwise - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see SWT#VIRTUAL - * @see SWT#SetData - */ - public void clear(int index, boolean all) { - checkWidget(); - realTreeItem.clear(index, all); - } - - /** - * Clears all the items in the receiver. The text, icon and other - * attributes of the items are set to their default values. If the - * tree was created with the SWT.VIRTUAL style, these - * attributes are requested again as needed. - * - * @param all true if all child items should be cleared - * recursively, and false otherwise - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see SWT#VIRTUAL - * @see SWT#SetData - */ - public void clearAll(boolean all) { - checkWidget(); - realTreeItem.clearAll(all); - } - - public void buildRealTreeItem(Tree tree, int numberOfColumns) { - final TreeItem ti; - if (parentItem != null && parentItem.realTreeItem != null) { - ti = new TreeItem(parentItem.realTreeItem, getStyle()); - } else { - ti = new TreeItem(tree, getStyle()); - } - - if (getImage() != null) { - ti.setImage(getImage()); - } - if (getText() != null) { - ti.setText(getText()); - } - if (getBackground() != null) { - ti.setBackground(getBackground()); - } - if (getForeground() != null) { - ti.setForeground(getForeground()); - } - if (getFont() != null) { - ti.setFont(getFont()); - } - - for (int i = 0; i < numberOfColumns; i++) { - if (getFont(i) != null) { - ti.setFont(i, getFont(i)); - } - if (getBackground(i) != null) { - ti.setBackground(i, getBackground(i)); - } - if (getForeground(i) != null) { - ti.setForeground(i, getForeground(i)); - } - if (getImage(i) != null) { - ti.setImage(i, getImage(i)); - } - if (getText(i) != null) { - ti.setText(i, getText(i)); - } - } - setRealTreeItem(ti); - } +/******************************************************************************* + * Copyright (c) 2019 Thomas Schindl & Laurent Caron. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API + * and implementation + * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, + * code cleaning and documentation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ctreecombo; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; + +/** + * Instances of this class represent a selectable user interface object + * that represents a hierarchy of tree items in a ctreecombo widget. + * + *
+ *
Styles:
+ *
(none)
+ *
Events:
+ *
(none)
+ *
+ *

+ * IMPORTANT: This class is not intended to be subclassed. + *

+ * + * @noextend This class is not intended to be subclassed by clients. + */ +public class CTreeComboItem extends Item { + static final String DATA_ID = "org.eclipse.nebula.widgets.ctreecombo.CTreeComboItem"; + private CTreeCombo parent; + private CTreeComboItem parentItem; + private List childItems = new ArrayList<>(); + private ArrayList backgroundColors = new ArrayList<>(); + private ArrayList foregroundColors = new ArrayList<>(); + private ArrayList fonts = new ArrayList<>(); + private ArrayList images = new ArrayList<>(); + private ArrayList texts = new ArrayList<>(); + private ArrayList bounds = new ArrayList<>(); + private ArrayList textbounds = new ArrayList<>(); + private ArrayList imageBounds = new ArrayList<>(); + private Color foreground, background; + private Font font; + private Rectangle bound; + + private TreeItem realTreeItem; + + /** + * Constructs a new instance of this class given its parent + * (which must be a CTreeComboItemItem), + * a style value describing its behavior and appearance, and the index + * at which to place it in the items maintained by its parent. + *

+ * The style value is either one of the style constants defined in + * class SWT which is applicable to instances of this + * class, or must be built by bitwise OR'ing together + * (that is, using the int "|" operator) two or more + * of those SWT style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + *

+ * + * @param parentItem a CTreeComboItem which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * @param index the zero-relative index to store the receiver in its parent + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • + *
+ * + * @see SWT + * @see Widget#checkSubclass + * @see Widget#getStyle + */ + public CTreeComboItem(CTreeComboItem parentItem, int style, int index) { + super(parentItem.parent, style); + this.parent = parentItem.parent; + this.parentItem = parentItem; + this.parentItem.childItems.add(index, this); + + if (parentItem.realTreeItem != null && !parentItem.realTreeItem.isDisposed()) { + setRealTreeItem(new TreeItem(parentItem.realTreeItem, style, index)); + } + } + + /** + * Constructs a new instance of this class given its parent + * (which must be a CTreeComboItem) + * and a style value describing its behavior and appearance. + * The item is added to the end of the items maintained by its parent. + *

+ * The style value is either one of the style constants defined in + * class SWT which is applicable to instances of this + * class, or must be built by bitwise OR'ing together + * (that is, using the int "|" operator) two or more + * of those SWT style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + *

+ * + * @param parentItem a CTreeComboItem control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • + *
+ * + * @see SWT + * @see Widget#checkSubclass + * @see Widget#getStyle + */ + public CTreeComboItem(CTreeComboItem parentItem, int style) { + super(parentItem.parent, style); + this.parent = parentItem.parent; + this.parentItem = parentItem; + this.parentItem.childItems.add(this); + + if (parentItem.realTreeItem != null && !parentItem.realTreeItem.isDisposed()) { + setRealTreeItem(new TreeItem(parentItem.realTreeItem, style)); + } + } + + /** + * Constructs a new instance of this class given its parent + * (which must be a CTreeCombo ), + * a style value describing its behavior and appearance, and the index + * at which to place it in the items maintained by its parent. + *

+ * The style value is either one of the style constants defined in + * class SWT which is applicable to instances of this + * class, or must be built by bitwise OR'ing together + * (that is, using the int "|" operator) two or more + * of those SWT style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + *

+ * + * @param parent a CTreeCombo control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * @param index the zero-relative index to store the receiver in its parent + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • + *
+ * + * @see SWT + * @see Widget#checkSubclass + * @see Widget#getStyle + */ + public CTreeComboItem(CTreeCombo parent, int style, int index) { + super(parent, style); + this.parent = parent; + this.parent.items.add(index, this); + + if (this.parent.tree != null && !this.parent.tree.isDisposed()) { + setRealTreeItem(new TreeItem(this.parent.tree, style, index)); + } + } + + /** + * Constructs a new instance of this class given its parent + * (which must be a CTreeCombo) + * and a style value describing its behavior and appearance. + * The item is added to the end of the items maintained by its parent. + *

+ * The style value is either one of the style constants defined in + * class SWT which is applicable to instances of this + * class, or must be built by bitwise OR'ing together + * (that is, using the int "|" operator) two or more + * of those SWT style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + *

+ * + * @param parent a CTreeCombo control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • + *
+ * + * @see SWT + * @see Widget#checkSubclass + * @see Widget#getStyle + */ + public CTreeComboItem(CTreeCombo parent, int style) { + super(parent, style); + this.parent = parent; + this.parent.items.add(this); + + if (this.parent.tree != null && !this.parent.tree.isDisposed()) { + setRealTreeItem(new TreeItem(this.parent.tree, style)); + } + } + + /** + * Disposes of the operating system resources associated with + * the receiver and all its descendants. After this method has + * been invoked, the receiver and all descendants will answer + * true when sent the message isDisposed(). + * Any internal connections between the widgets in the tree will + * have been removed to facilitate garbage collection. + * This method does nothing if the widget is already disposed. + *

+ * NOTE: This method is not called recursively on the descendants + * of the receiver. This means that, widget implementers can not + * detect when a widget is being disposed of by re-implementing + * this method, but should instead listen for the Dispose + * event. + *

+ * + * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see #addDisposeListener + * @see #removeDisposeListener + * @see #checkWidget + */ + public void dispose() { + super.dispose(); + if (realTreeItem != null && !realTreeItem.isDisposed()) { + realTreeItem.dispose(); + } + + if (this.parentItem != null && !this.parentItem.isDisposed()) { + this.parentItem.childItems.remove(this); + } + + for (CTreeComboItem child : childItems) { + child.dispose(); + } + } + + void setRealTreeItem(TreeItem realTreeItem) { + this.realTreeItem = realTreeItem; + this.realTreeItem.setData(DATA_ID, this); + } + + TreeItem getRealTreeItem() { + return this.realTreeItem; + } + + /** + * Returns a (possibly empty) array of CTreeComboItems which + * are the direct item children of the receiver. + *

+ * Note: This is not the actual structure used by the receiver + * to maintain its list of items, so modifying the array will + * not affect the receiver. + *

+ * + * @return the receiver's items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public CTreeComboItem[] getItems() { + checkWidget(); + return childItems.toArray(new CTreeComboItem[0]); + } + + private boolean checkRealItem() { + return realTreeItem != null && !realTreeItem.isDisposed(); + } + + /** + * Sets the receiver's image to the argument, which may be + * null indicating that no image should be displayed. + * + * @param image the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setImage(Image image) { + super.setImage(image); + } + + /** + * Sets the receiver's text. + *

+ * Note: If control characters like '\n', '\t' etc. are used + * in the string, then the behavior is platform dependent. + *

+ * + * @param string the new text + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the text is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setText(String string) { + super.setText(string); + } + + /** + * Returns a rectangle describing the receiver's size and location + * relative to its parent at a column in the tree. + * + * @param index the index that specifies the column + * @return the receiver's bounding column rectangle + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Rectangle getBounds(int index) { + checkWidget(); + if (index < 0 || index > (bounds.size() - 1)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return bounds.get(index); + } + + /** + * Returns a rectangle describing the size and location of the receiver's + * text relative to its parent. + * + * @return the bounding rectangle of the receiver's text + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Rectangle getBounds() { + checkWidget(); + return bound; + } + + /** + * Returns the receiver's parent, which must be a CTreeCombo. + * + * @return the receiver's parent + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public CTreeCombo getParent() { + checkWidget(); + return parent; + } + + /** + * Returns the background color of the receiver. + * + * @return the background color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getBackground() { + checkWidget(); + return background; + } + + /** + * Returns the background color at the given column index in the receiver. + * + * @param index the column index + * @return the background color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getBackground(int index) { + checkWidget(); + if (index < 0 || index > (backgroundColors.size() - 1)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return backgroundColors.get(index); + } + + /** + * Returns the font that the receiver will use to paint textual information + * + * @return the receiver's font + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Font getFont() { + checkWidget(); + return font; + } + + /** + * Returns the font that the receiver will use to paint textual information + * for the specified cell in this item. + * + * @param index the column index + * @return the receiver's font + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Font getFont(int index) { + checkWidget(); + if (index < 0 || index > (fonts.size() - 1)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return fonts.get(index); + } + + /** + * + * Returns the foreground color of the receiver. + * + * @return the foreground color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getForeground() { + checkWidget(); + return foreground; + } + + /** + * + * Returns the foreground color at the given column index in the receiver. + * + * @param index the column index + * @return the foreground color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Color getForeground(int index) { + checkWidget(); + if (index < 0 || index > (foregroundColors.size() - 1)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return foregroundColors.get(index); + } + + /** + * Returns the image stored at the given column index in the receiver, + * or null if the image has not been set or if the column does not exist. + * + * @param index the column index + * @return the image stored at the given column index in the receiver + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Image getImage(int index) { + checkWidget(); + if (index < 0 || index > (images.size() - 1)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return images.get(index); + } + + /** + * Returns the text stored at the given column index in the receiver, + * or empty string if the text has not been set. + * + * @param index the column index + * @return the text stored at the given column index in the receiver + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public String getText(int index) { + checkWidget(); + if (index < 0 || index > (texts.size() - 1)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return texts.get(index); + } + + /** + * Sets the background color at the given column index in the receiver + * to the color specified by the argument, or to the default system color for the item + * if the argument is null. + * + * @param index the column index + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @since 3.1 + * + */ + public void setBackground(int index, Color color) { + checkWidget(); + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + ensureArraySizes(index); + backgroundColors.set(index, color); + } + + private void ensureArraySizes(int index) { + backgroundColors.ensureCapacity(index); + foregroundColors.ensureCapacity(index); + fonts.ensureCapacity(index); + images.ensureCapacity(index); + texts.ensureCapacity(index); + bounds.ensureCapacity(index); + textbounds.ensureCapacity(index); + imageBounds.ensureCapacity(index); + } + + /** + * Sets the background color at in the receiver to the color specified by the argument, + * or to the default system color for the item if the argument is null. + * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @since 3.1 + * + */ + public void setBackground(Color color) { + checkWidget(); + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.background = color; + } + + /** + * Sets the font that the receiver will use to paint textual information + * for the item to the font specified by the argument, or to the default + * font for that kind of control if the argument is null. + * + * @param font the new font (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @since 3.1 + */ + public void setFont(Font font) { + checkWidget(); + this.font = font; + } + + /** + * Sets the font that the receiver will use to paint textual information + * for the specified cell in this item to the font specified by the + * argument, or to the default font for that kind of control if the + * argument is null. + * + * @param index the column index + * @param font the new font (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @since 3.1 + */ + public void setFont(int index, Font font) { + checkWidget(); + if (font != null && font.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + ensureArraySizes(index); + fonts.set(index, font); + } + + /** + * Sets the foreground color at the given column index in the receiver + * to the color specified by the argument, or to the default system color for the item + * if the argument is null. + * + * @param index the column index + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setForeground(int index, Color color) { + checkWidget(); + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + ensureArraySizes(index); + foregroundColors.set(index, color); + } + + /** + * Sets the foreground color in the receiver to the color specified by the argument, + * or to the default system color for the item if the argument is null. + * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setForeground(Color color) { + checkWidget(); + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.foreground = color; + } + + /** + * Sets the receiver's image at a column. + * + * @param index the column index + * @param image the new image + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setImage(int index, Image image) { + checkWidget(); + if (image != null && image.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + ensureArraySizes(index); + images.set(index, image); + } + + /** + * Sets the receiver's text at a column + *

+ * Note: If control characters like '\n', '\t' etc. are used + * in the string, then the behavior is platform dependent. + *

+ * + * @param index the column index + * @param string the new text + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the text is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setText(int index, String string) { + checkWidget(); + ensureArraySizes(index); + texts.set(index, string == null ? "" : string); + } + + /** + * Returns the receiver's parent item, which must be a + * CTreeComboItem or null when the receiver is a + * root. + * + * @return the receiver's parent item + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public CTreeComboItem getParentItem() { + checkWidget(); + return parentItem; + } + + /** + * Returns true if the receiver is expanded, + * and false otherwise. + *

+ * + * @return the expanded state + * + * @exception SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public boolean getExpanded() { + checkWidget(); + if (checkRealItem()) { + return realTreeItem.getExpanded(); + } + return false; + } + + /** + * Returns the number of items contained in the receiver + * that are direct item children of the receiver. + * + * @return the number of items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getItemCount() { + checkWidget(); + return childItems.size(); + } + + /** + * Returns the item at the given, zero-relative index in the + * receiver. Throws an exception if the index is out of range. + * + * @param index the index of the item to return + * @return the item at the given index + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public CTreeComboItem getItem(int index) { + checkWidget(); + return childItems.get(index); + } + + /** + * Searches the receiver's list starting at the first item + * (index 0) until an item is found that is equal to the + * argument, and returns the index of that item. If no item + * is found, returns -1. + * + * @param item the search item + * @return the index of the item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int indexOf(CTreeComboItem item) { + checkWidget(); + return childItems.indexOf(item); + } + + /** + * Returns a rectangle describing the size and location + * relative to its parent of the text at a column in the + * tree. + * + * @param index the index that specifies the column + * @return the receiver's bounding text rectangle + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Rectangle getTextBounds(int index) { + checkWidget(); + if (index < 0 || index > (textbounds.size() - 1)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return textbounds.get(index); + } + + /** + * Returns a rectangle describing the size and location + * relative to its parent of an image at a column in the + * tree. + * + * @param index the index that specifies the column + * @return the receiver's bounding image rectangle + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Rectangle getImageBounds(int index) { + checkWidget(); + if (index < 0 || index > (imageBounds.size() - 1)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return imageBounds.get(index); + } + + /** + * Sets the expanded state of the receiver. + *

+ * + * @param expanded the new expanded state + * + * @exception SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setExpanded(boolean expand) { + checkWidget(); + if (checkRealItem()) { + realTreeItem.setExpanded(expand); + } + } + + /** + * Sets the number of child items contained in the receiver. + * + * @param count the number of items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setItemCount(int count) { + checkWidget(); + if (checkRealItem()) { + realTreeItem.setItemCount(count); + } + } + + /** + * Clears the item at the given zero-relative index in the receiver. + * The text, icon and other attributes of the item are set to the default + * value. If the tree was created with the SWT.VIRTUAL style, + * these attributes are requested again as needed. + * + * @param index the index of the item to clear + * @param all true if all child items of the indexed item should be + * cleared recursively, and false otherwise + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see SWT#VIRTUAL + * @see SWT#SetData + */ + public void clear(int index, boolean all) { + checkWidget(); + realTreeItem.clear(index, all); + } + + /** + * Clears all the items in the receiver. The text, icon and other + * attributes of the items are set to their default values. If the + * tree was created with the SWT.VIRTUAL style, these + * attributes are requested again as needed. + * + * @param all true if all child items should be cleared + * recursively, and false otherwise + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see SWT#VIRTUAL + * @see SWT#SetData + */ + public void clearAll(boolean all) { + checkWidget(); + realTreeItem.clearAll(all); + } + + public void buildRealTreeItem(Tree tree, int numberOfColumns) { + final TreeItem ti; + if (parentItem != null && parentItem.realTreeItem != null) { + ti = new TreeItem(parentItem.realTreeItem, getStyle()); + } else { + ti = new TreeItem(tree, getStyle()); + } + + if (getImage() != null) { + ti.setImage(getImage()); + } + if (getText() != null) { + ti.setText(getText()); + } + if (getBackground() != null) { + ti.setBackground(getBackground()); + } + if (getForeground() != null) { + ti.setForeground(getForeground()); + } + if (getFont() != null) { + ti.setFont(getFont()); + } + + for (int i = 0; i < numberOfColumns; i++) { + if (getFont(i) != null) { + ti.setFont(i, getFont(i)); + } + if (getBackground(i) != null) { + ti.setBackground(i, getBackground(i)); + } + if (getForeground(i) != null) { + ti.setForeground(i, getForeground(i)); + } + if (getImage(i) != null) { + ti.setImage(i, getImage(i)); + } + if (getText(i) != null) { + ti.setText(i, getText(i)); + } + } + setRealTreeItem(ti); + } } \ No newline at end of file diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/viewer/CTreeComboViewer.java b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/viewer/CTreeComboViewer.java index 6a4d21afd..63aafd666 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/viewer/CTreeComboViewer.java +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/viewer/CTreeComboViewer.java @@ -1,996 +1,996 @@ -/******************************************************************************* - * Copyright (c) 2019 Thomas Schindl & Laurent Caron. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API - * and implementation - * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, - * code cleaning and documentation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ctreecombo.viewer; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import org.eclipse.jface.util.Policy; -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.IContentProvider; -import org.eclipse.jface.viewers.ILazyTreeContentProvider; -import org.eclipse.jface.viewers.ILazyTreePathContentProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.TreeExpansionEvent; -import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.jface.viewers.ViewerCell; -import org.eclipse.jface.viewers.ViewerRow; -import org.eclipse.nebula.widgets.ctreecombo.CTreeCombo; -import org.eclipse.nebula.widgets.ctreecombo.CTreeComboItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.TreeEvent; -import org.eclipse.swt.events.TreeListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.Widget; - -/** - * A concrete viewer based either on an SWT CTreeCombo control. - */ -public class CTreeComboViewer extends AbstractTreeViewer { - - private static final String VIRTUAL_DISPOSE_KEY = Policy.JFACE + ".DISPOSE_LISTENER"; //$NON-NLS-1$ - - /** - * This viewer's control. - */ - private CTreeCombo tree; - - /** - * Flag for whether the tree has been disposed of. - */ - private boolean treeIsDisposed = false; - - private boolean contentProviderIsLazy; - - private boolean contentProviderIsTreeBased; - - /** - * The row object reused - */ - private CTreeComboViewerRow cachedRow; - - /** - * true if we are inside a preservingSelection() call - */ - private boolean preservingSelection; - - /** - * Creates a tree viewer on a newly-created tree control under the given - * parent. The tree control is created using the SWT style bits - * MULTI, H_SCROLL, V_SCROLL, and BORDER. The - * viewer has no input, no content provider, a default label provider, no - * sorter, and no filters. - * - * @param parent - * the parent control - */ - public CTreeComboViewer(Composite parent) { - this(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); - } - - /** - * Creates a CTreeComboViewer viewer on a newly-created tree control under the given - * parent. The CTreeCombo control is created using the given SWT style bits. The - * viewer has no input, no content provider, a default label provider, no - * sorter, and no filters. - * - * @param parent - * the parent control - * @param style - * the SWT style bits used to create the tree. - */ - public CTreeComboViewer(Composite parent, int style) { - this(new CTreeCombo(parent, style)); - } - - /** - * Creates a CTreeComboViewer viewer on the given tree control. The viewer has no input, - * no content provider, a default label provider, no sorter, and no filters. - * - * @param tree - * the tree control - */ - public CTreeComboViewer(CTreeCombo tree) { - super(); - this.tree = tree; - hookControl(tree); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#addTreeListener(org.eclipse.swt.widgets.Control, org.eclipse.swt.events.TreeListener) - */ - protected void addTreeListener(Control c, TreeListener listener) { - ((CTreeCombo) c).addTreeListener(listener); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getColumnViewerOwner(int) - */ - protected Widget getColumnViewerOwner(int columnIndex) { - if (columnIndex < 0 || (columnIndex > 0 && columnIndex >= getTree().getColumnCount())) { - return null; - } - - if (getTree().getColumnCount() == 0) - return getTree(); - - return getTree().getColumn(columnIndex); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChildren(org.eclipse.swt.widgets.Widget) - */ - protected Item[] getChildren(Widget o) { - if (o instanceof CTreeComboItem) { - return ((CTreeComboItem) o).getItems(); - } - if (o instanceof CTreeCombo) { - return ((CTreeCombo) o).getItems(); - } - return null; - } - - /** - * @see org.eclipse.jface.viewers.Viewer#getControl() - */ - public Control getControl() { - return tree; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getExpanded(org.eclipse.swt.widgets.Item) - */ - protected boolean getExpanded(Item item) { - return ((CTreeComboItem) item).getExpanded(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemAt(org.eclipse.swt.graphics.Point) - */ - protected Item getItemAt(Point p) { - CTreeComboItem[] selection = tree.getSelection(); - - if (selection.length == 1) { - int columnCount = tree.getColumnCount(); - - for (int i = 0; i < columnCount; i++) { - if (selection[0].getBounds(i).contains(p)) { - return selection[0]; - } - } - } - - return getTree().getItem(p); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemCount(org.eclipse.swt.widgets.Control) - */ - protected int getItemCount(Control widget) { - return ((CTreeCombo) widget).getItemCount(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemCount(org.eclipse.swt.widgets.Item) - */ - protected int getItemCount(Item item) { - return ((CTreeComboItem) item).getItemCount(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItems(org.eclipse.swt.widgets.Item) - */ - protected Item[] getItems(Item item) { - return ((CTreeComboItem) item).getItems(); - } - - /** - * @see org.eclipse.jface.viewers.ContentViewer#getLabelProvider() - */ - public IBaseLabelProvider getLabelProvider() { - return super.getLabelProvider(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getParentItem(org.eclipse.swt.widgets.Item) - */ - protected Item getParentItem(Item item) { - return ((CTreeComboItem) item).getParentItem(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getSelection(org.eclipse.swt.widgets.Control) - */ - protected Item[] getSelection(Control widget) { - return ((CTreeCombo) widget).getSelection(); - } - - /** - * Returns this CTreeCombo viewer's tree control. - * - * @return the ctreecombo control - */ - public CTreeCombo getTree() { - return tree; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#hookControl(org.eclipse.swt.widgets.Control) - */ - protected void hookControl(Control control) { - super.hookControl(control); - CTreeCombo treeControl = (CTreeCombo) control; - - if ((treeControl.getStyle() & SWT.VIRTUAL) != 0) { - treeControl.addListener(SWT.Dispose, (e) -> { - treeIsDisposed = true; - unmapAllElements(); - }); - treeControl.addListener(SWT.SetData, (event) -> { - if (contentProviderIsLazy) { - CTreeComboItem item = (CTreeComboItem) event.item; - CTreeComboItem parentItem = item.getParentItem(); - int index = event.index; - virtualLazyUpdateWidget(parentItem == null ? (Widget) getTree() : parentItem, index); - } - }); - } - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#createViewerEditor() - */ - protected ColumnViewerEditor createViewerEditor() { - return null; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#newItem(org.eclipse.swt.widgets.Widget, int, int) - */ - protected Item newItem(Widget parent, int flags, int ix) { - CTreeComboItem item; - - if (parent instanceof CTreeComboItem) { - item = (CTreeComboItem) createNewRowPart(getViewerRowFromItem(parent), flags, ix).getItem(); - } else { - item = (CTreeComboItem) createNewRowPart(null, flags, ix).getItem(); - } - - return item; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#removeAll(org.eclipse.swt.widgets.Control) - */ - protected void removeAll(Control widget) { - ((CTreeCombo) widget).removeAll(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#setExpanded(org.eclipse.swt.widgets.Item, boolean) - */ - protected void setExpanded(Item node, boolean expand) { - ((CTreeComboItem) node).setExpanded(expand); - if (contentProviderIsLazy) { - // force repaints to happen - getControl().update(); - } - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#setSelection(java.util.List) - */ - protected void setSelection(List items) { - Item[] current = getSelection(getTree()); - - // Don't bother resetting the same selection - if (isSameSelection(items, current)) { - return; - } - - CTreeComboItem[] newItems = new CTreeComboItem[items.size()]; - items.toArray(newItems); - getTree().setSelection(newItems); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#showItem(org.eclipse.swt.widgets.Item) - */ - protected void showItem(Item item) { - getTree().showItem((CTreeComboItem) item); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChild(org.eclipse.swt.widgets.Widget, int) - */ - protected Item getChild(Widget widget, int index) { - if (widget instanceof CTreeComboItem) { - return ((CTreeComboItem) widget).getItem(index); - } - if (widget instanceof CTreeCombo) { - return ((CTreeCombo) widget).getItem(index); - } - return null; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#assertContentProviderType(org.eclipse.jface.viewers.IContentProvider) - */ - protected void assertContentProviderType(IContentProvider provider) { - if (provider instanceof ILazyTreeContentProvider || provider instanceof ILazyTreePathContentProvider) { - return; - } - super.assertContentProviderType(provider); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getRawChildren(java.lang.Object) - */ - protected Object[] getRawChildren(Object parent) { - if (contentProviderIsLazy) { - return new Object[0]; - } - return super.getRawChildren(parent); - } - - /** - * For a CTreeComboViewer with a ctreecombo with the VIRTUAL style bit set, set the - * number of children of the given element or tree path. To set the number - * of children of the invisible root of the tree, you can pass the input - * object or an empty tree path. - * - * @param elementOrTreePath - * the element, or tree path - * @param count - */ - public void setChildCount(final Object elementOrTreePath, final int count) { - if (checkBusy()) - return; - preservingSelection(new Runnable() { - public void run() { - if (internalIsInputOrEmptyPath(elementOrTreePath)) { - getTree().setItemCount(count); - return; - } - Widget[] items = internalFindItems(elementOrTreePath); - for (int i = 0; i < items.length; i++) { - CTreeComboItem treeItem = (CTreeComboItem) items[i]; - treeItem.setItemCount(count); - } - } - }); - } - - /** - * For a CTreeComboViewer with a ctreecombo with the VIRTUAL style bit set, replace the - * given parent's child at index with the given element. If the given parent - * is this viewer's input or an empty tree path, this will replace the root - * element at the given index. - *

- * This method should be called by implementers of ILazyTreeContentProvider - * to populate this viewer. - *

- * - * @param parentElementOrTreePath - * the parent of the element that should be updated, or the tree - * path to that parent - * @param index - * the index in the parent's children - * @param element - * the new element - * - * @see #setChildCount(Object, int) - * @see ILazyTreeContentProvider - * @see ILazyTreePathContentProvider - */ - public void replace(final Object parentElementOrTreePath, final int index, final Object element) { - if (checkBusy()) - return; - Item[] selectedItems = getSelection(getControl()); - TreeSelection selection = (TreeSelection) getSelection(); - Widget[] itemsToDisassociate; - if (parentElementOrTreePath instanceof TreePath) { - TreePath elementPath = ((TreePath) parentElementOrTreePath).createChildPath(element); - itemsToDisassociate = internalFindItems(elementPath); - } else { - itemsToDisassociate = internalFindItems(element); - } - if (internalIsInputOrEmptyPath(parentElementOrTreePath)) { - if (index < tree.getItemCount()) { - CTreeComboItem item = tree.getItem(index); - selection = adjustSelectionForReplace(selectedItems, selection, item, element, getRoot()); - // disassociate any different item that represents the - // same element under the same parent (the tree) - for (int i = 0; i < itemsToDisassociate.length; i++) { - if (itemsToDisassociate[i] instanceof CTreeComboItem) { - CTreeComboItem itemToDisassociate = (CTreeComboItem) itemsToDisassociate[i]; - if (itemToDisassociate != item && itemToDisassociate.getParentItem() == null) { - int indexToDisassociate = getTree().indexOf(itemToDisassociate); - disassociate(itemToDisassociate); - getTree().clear(indexToDisassociate, true); - } - } - } - Object oldData = item.getData(); - updateItem(item, element); - if (!CTreeComboViewer.this.equals(oldData, element)) { - item.clearAll(true); - } - } - } else { - Widget[] parentItems = internalFindItems(parentElementOrTreePath); - for (int i = 0; i < parentItems.length; i++) { - CTreeComboItem parentItem = (CTreeComboItem) parentItems[i]; - if (index < parentItem.getItemCount()) { - CTreeComboItem item = parentItem.getItem(index); - selection = adjustSelectionForReplace(selectedItems, selection, item, element, parentItem.getData()); - // disassociate any different item that represents the - // same element under the same parent (the tree) - for (int j = 0; j < itemsToDisassociate.length; j++) { - if (itemsToDisassociate[j] instanceof CTreeComboItem) { - CTreeComboItem itemToDisassociate = (CTreeComboItem) itemsToDisassociate[j]; - if (itemToDisassociate != item && itemToDisassociate.getParentItem() == parentItem) { - int indexToDisaccociate = parentItem.indexOf(itemToDisassociate); - disassociate(itemToDisassociate); - parentItem.clear(indexToDisaccociate, true); - } - } - } - Object oldData = item.getData(); - updateItem(item, element); - if (!CTreeComboViewer.this.equals(oldData, element)) { - item.clearAll(true); - } - } - } - } - // Restore the selection if we are not already in a nested - // preservingSelection: - if (!preservingSelection) { - setSelectionToWidget(selection, false); - // send out notification if old and new differ - ISelection newSelection = getSelection(); - if (!newSelection.equals(selection)) { - handleInvalidSelection(selection, newSelection); - } - } - } - - private TreeSelection adjustSelectionForReplace(Item[] selectedItems, TreeSelection selection, CTreeComboItem item, Object element, Object parentElement) { - if (item.getData() != null || selectedItems.length == selection.size() || parentElement == null) { - // Don't do anything - we are not seeing an instance of bug 185673 - return selection; - } - for (int i = 0; i < selectedItems.length; i++) { - if (item == selectedItems[i]) { - // The current item was selected, but its data is null. - // The data will be replaced by the given element, so to keep - // it selected, we have to add it to the selection. - TreePath[] originalPaths = selection.getPaths(); - int length = originalPaths.length; - TreePath[] paths = new TreePath[length + 1]; - System.arraycopy(originalPaths, 0, paths, 0, length); - // set the element temporarily so that we can call - // getTreePathFromItem - item.setData(element); - paths[length] = getTreePathFromItem(item); - item.setData(null); - return new TreeSelection(paths, selection.getElementComparer()); - } - } - // The item was not selected, return the given selection - return selection; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#isExpandable(java.lang.Object) - */ - public boolean isExpandable(Object element) { - if (contentProviderIsLazy) { - CTreeComboItem treeItem = (CTreeComboItem) internalExpand(element, false); - if (treeItem == null) { - return false; - } - virtualMaterializeItem(treeItem); - return treeItem.getItemCount() > 0; - } - return super.isExpandable(element); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getParentElement(java.lang.Object) - */ - protected Object getParentElement(Object element) { - boolean oldBusy = isBusy(); - setBusy(true); - try { - if (contentProviderIsLazy && !contentProviderIsTreeBased && !(element instanceof TreePath)) { - ILazyTreeContentProvider lazyTreeContentProvider = (ILazyTreeContentProvider) getContentProvider(); - return lazyTreeContentProvider.getParent(element); - } - if (contentProviderIsLazy && contentProviderIsTreeBased && !(element instanceof TreePath)) { - ILazyTreePathContentProvider lazyTreePathContentProvider = (ILazyTreePathContentProvider) getContentProvider(); - TreePath[] parents = lazyTreePathContentProvider.getParents(element); - if (parents != null && parents.length > 0) { - return parents[0]; - } - } - return super.getParentElement(element); - } finally { - setBusy(oldBusy); - } - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#createChildren(org.eclipse.swt.widgets.Widget) - */ - protected void createChildren(Widget widget) { - if (contentProviderIsLazy) { - Object element = widget.getData(); - if (element == null && widget instanceof CTreeComboItem) { - // parent has not been materialized - virtualMaterializeItem((CTreeComboItem) widget); - // try getting the element now that updateElement was called - element = widget.getData(); - } - if (element == null) { - // give up because the parent is still not materialized - return; - } - Item[] children = getChildren(widget); - if (children.length == 1 && children[0].getData() == null) { - // found a dummy node - virtualLazyUpdateChildCount(widget, children.length); - children = getChildren(widget); - } - // touch all children to make sure they are materialized - for (int i = 0; i < children.length; i++) { - if (children[i].getData() == null) { - virtualLazyUpdateWidget(widget, i); - } - } - return; - } - super.createChildren(widget); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#internalAdd(org.eclipse.swt.widgets.Widget, java.lang.Object, java.lang.Object[]) - */ - protected void internalAdd(Widget widget, Object parentElement, Object[] childElements) { - if (contentProviderIsLazy) { - if (widget instanceof CTreeComboItem) { - CTreeComboItem ti = (CTreeComboItem) widget; - int count = ti.getItemCount() + childElements.length; - ti.setItemCount(count); - ti.clearAll(false); - } else { - CTreeCombo t = (CTreeCombo) widget; - t.setItemCount(t.getItemCount() + childElements.length); - t.clearAll(false); - } - return; - } - super.internalAdd(widget, parentElement, childElements); - } - - private void virtualMaterializeItem(CTreeComboItem treeItem) { - if (treeItem.getData() != null) { - // already materialized - return; - } - if (!contentProviderIsLazy) { - return; - } - int index; - Widget parent = treeItem.getParentItem(); - if (parent == null) { - parent = treeItem.getParent(); - } - Object parentElement = parent.getData(); - if (parentElement != null) { - if (parent instanceof CTreeCombo) { - index = ((CTreeCombo) parent).indexOf(treeItem); - } else { - index = ((CTreeComboItem) parent).indexOf(treeItem); - } - virtualLazyUpdateWidget(parent, index); - } - } - - /** - * @see org.eclipse.jface.viewers.StructuredViewer#mapElement(java.lang.Object, org.eclipse.swt.widgets.Widget) - */ - protected void mapElement(Object element, final Widget item) { - super.mapElement(element, item); - // make sure to unmap elements if the tree is virtual - if ((getTree().getStyle() & SWT.VIRTUAL) != 0) { - // only add a dispose listener if item hasn't already on assigned - // because it is reused - if (item.getData(VIRTUAL_DISPOSE_KEY) == null) { - item.setData(VIRTUAL_DISPOSE_KEY, Boolean.TRUE); - item.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - if (!treeIsDisposed) { - Object data = item.getData(); - if (usingElementMap() && data != null) { - unmapElement(data, item); - } - } - } - }); - } - } - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getViewerRowFromItem(org.eclipse.swt.widgets.Widget) - */ - protected ViewerRow getViewerRowFromItem(Widget item) { - if (cachedRow == null) { - cachedRow = new CTreeComboViewerRow((CTreeComboItem) item); - } else { - cachedRow.setItem((CTreeComboItem) item); - } - - return cachedRow; - } - - /** - * Create a new ViewerRow at rowIndex - * - * @param parent - * @param style - * @param rowIndex - * @return ViewerRow - */ - private ViewerRow createNewRowPart(ViewerRow parent, int style, int rowIndex) { - if (parent == null) { - if (rowIndex >= 0) { - return getViewerRowFromItem(new CTreeComboItem(tree, style, rowIndex)); - } - return getViewerRowFromItem(new CTreeComboItem(tree, style)); - } - - if (rowIndex >= 0) { - return getViewerRowFromItem(new CTreeComboItem((CTreeComboItem) parent.getItem(), SWT.NONE, rowIndex)); - } - - return getViewerRowFromItem(new CTreeComboItem((CTreeComboItem) parent.getItem(), SWT.NONE)); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#internalInitializeTree(org.eclipse.swt.widgets.Control) - */ - protected void internalInitializeTree(Control widget) { - if (contentProviderIsLazy) { - if (widget instanceof CTreeCombo && widget.getData() != null) { - virtualLazyUpdateChildCount(widget, 0); - return; - } - } - super.internalInitializeTree(tree); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#updatePlus(org.eclipse.swt.widgets.Item, java.lang.Object) - */ - protected void updatePlus(Item item, Object element) { - if (contentProviderIsLazy) { - Object data = item.getData(); - int itemCount = 0; - if (data != null) { - // item is already materialized - itemCount = ((CTreeComboItem) item).getItemCount(); - } - virtualLazyUpdateHasChildren(item, itemCount); - } else { - super.updatePlus(item, element); - } - } - - /** - * Removes the element at the specified index of the parent. The selection - * is updated if required. - * - * @param parentOrTreePath - * the parent element, the input element, or a tree path to the - * parent element - * @param index - * child index - */ - public void remove(final Object parentOrTreePath, final int index) { - if (checkBusy()) - return; - final List oldSelection = new LinkedList(Arrays.asList(((TreeSelection) getSelection()).getPaths())); - preservingSelection(new Runnable() { - public void run() { - TreePath removedPath = null; - if (internalIsInputOrEmptyPath(parentOrTreePath)) { - CTreeCombo tree = (CTreeCombo) getControl(); - if (index < tree.getItemCount()) { - CTreeComboItem item = tree.getItem(index); - if (item.getData() != null) { - removedPath = getTreePathFromItem(item); - disassociate(item); - } - item.dispose(); - } - } else { - Widget[] parentItems = internalFindItems(parentOrTreePath); - for (int i = 0; i < parentItems.length; i++) { - CTreeComboItem parentItem = (CTreeComboItem) parentItems[i]; - if (parentItem.isDisposed()) - continue; - if (index < parentItem.getItemCount()) { - CTreeComboItem item = parentItem.getItem(index); - if (item.getData() != null) { - removedPath = getTreePathFromItem(item); - disassociate(item); - } - item.dispose(); - } - } - } - if (removedPath != null) { - boolean removed = false; - for (Iterator it = oldSelection.iterator(); it.hasNext();) { - TreePath path = (TreePath) it.next(); - if (path.startsWith(removedPath, getComparer())) { - it.remove(); - removed = true; - } - } - if (removed) { - setSelection(new TreeSelection((TreePath[]) oldSelection.toArray(new TreePath[oldSelection.size()]), getComparer()), false); - } - - } - } - }); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#handleTreeExpand(org.eclipse.swt.events.TreeEvent) - */ - protected void handleTreeExpand(TreeEvent event) { - if (contentProviderIsLazy) { - if (event.item.getData() != null) { - Item[] children = getChildren(event.item); - if (children.length == 1 && children[0].getData() == null) { - // we have a dummy child node, ask for an updated child - // count - virtualLazyUpdateChildCount(event.item, children.length); - } - fireTreeExpanded(new TreeExpansionEvent(this, event.item.getData())); - } - return; - } - super.handleTreeExpand(event); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#setContentProvider(org.eclipse.jface.viewers.IContentProvider) - */ - public void setContentProvider(IContentProvider provider) { - contentProviderIsLazy = (provider instanceof ILazyTreeContentProvider) || (provider instanceof ILazyTreePathContentProvider); - contentProviderIsTreeBased = provider instanceof ILazyTreePathContentProvider; - super.setContentProvider(provider); - } - - /** - * For a TreeViewer with a tree with the VIRTUAL style bit set, inform the - * viewer about whether the given element or tree path has children. Avoid - * calling this method if the number of children has already been set. - * - * @param elementOrTreePath - * the element, or tree path - * @param hasChildren - * - */ - public void setHasChildren(final Object elementOrTreePath, final boolean hasChildren) { - if (checkBusy()) - return; - preservingSelection(new Runnable() { - public void run() { - if (internalIsInputOrEmptyPath(elementOrTreePath)) { - if (hasChildren) { - virtualLazyUpdateChildCount(getTree(), getChildren(getTree()).length); - } else { - setChildCount(elementOrTreePath, 0); - } - return; - } - Widget[] items = internalFindItems(elementOrTreePath); - for (int i = 0; i < items.length; i++) { - CTreeComboItem item = (CTreeComboItem) items[i]; - if (!hasChildren) { - item.setItemCount(0); - } else { - if (!item.getExpanded()) { - item.setItemCount(1); - CTreeComboItem child = item.getItem(0); - if (child.getData() != null) { - disassociate(child); - } - item.clear(0, true); - } else { - virtualLazyUpdateChildCount(item, item.getItemCount()); - } - } - } - } - }); - } - - /** - * Update the widget at index. - * - * @param widget - * @param index - */ - private void virtualLazyUpdateWidget(Widget widget, int index) { - boolean oldBusy = isBusy(); - setBusy(false); - try { - if (contentProviderIsTreeBased) { - TreePath treePath; - if (widget instanceof Item) { - if (widget.getData() == null) { - return; - } - treePath = getTreePathFromItem((Item) widget); - } else { - treePath = TreePath.EMPTY; - } - ((ILazyTreePathContentProvider) getContentProvider()).updateElement(treePath, index); - } else { - ((ILazyTreeContentProvider) getContentProvider()).updateElement(widget.getData(), index); - } - } finally { - setBusy(oldBusy); - } - } - - /** - * Update the child count - * - * @param widget - * @param currentChildCount - */ - private void virtualLazyUpdateChildCount(Widget widget, int currentChildCount) { - boolean oldBusy = isBusy(); - setBusy(false); - try { - if (contentProviderIsTreeBased) { - TreePath treePath; - if (widget instanceof Item) { - treePath = getTreePathFromItem((Item) widget); - } else { - treePath = TreePath.EMPTY; - } - ((ILazyTreePathContentProvider) getContentProvider()).updateChildCount(treePath, currentChildCount); - } else { - ((ILazyTreeContentProvider) getContentProvider()).updateChildCount(widget.getData(), currentChildCount); - } - } finally { - setBusy(oldBusy); - } - } - - /** - * Update the item with the current child count. - * - * @param item - * @param currentChildCount - */ - private void virtualLazyUpdateHasChildren(Item item, int currentChildCount) { - boolean oldBusy = isBusy(); - setBusy(false); - try { - if (contentProviderIsTreeBased) { - TreePath treePath; - treePath = getTreePathFromItem(item); - if (currentChildCount == 0) { - // item is not expanded (but may have a plus currently) - ((ILazyTreePathContentProvider) getContentProvider()).updateHasChildren(treePath); - } else { - ((ILazyTreePathContentProvider) getContentProvider()).updateChildCount(treePath, currentChildCount); - } - } else { - ((ILazyTreeContentProvider) getContentProvider()).updateChildCount(item.getData(), currentChildCount); - } - } finally { - setBusy(oldBusy); - } - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#disassociate(org.eclipse.swt.widgets.Item) - */ - protected void disassociate(Item item) { - if (contentProviderIsLazy) { - // avoid causing a callback: - item.setText(" "); //$NON-NLS-1$ - } - super.disassociate(item); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#doGetColumnCount() - */ - protected int doGetColumnCount() { - return tree.getColumnCount(); - } - - /** - * Sets a new selection for this viewer and optionally makes it visible. - *

- * Currently the reveal parameter is not honored because - * {@link Tree} does not provide an API to only select an item without - * scrolling it into view - *

- * - * @param selection - * the new selection - * @param reveal - * true if the selection is to be made visible, and - * false otherwise - */ - public void setSelection(ISelection selection, boolean reveal) { - super.setSelection(selection, reveal); - } - - /** - * @see org.eclipse.jface.viewers.ColumnViewer#editElement(java.lang.Object, int) - */ - public void editElement(Object element, int column) { - if (element instanceof TreePath) { - try { - getControl().setRedraw(false); - setSelection(new TreeSelection((TreePath) element)); - CTreeComboItem[] items = tree.getSelection(); - - if (items.length == 1) { - ViewerRow row = getViewerRowFromItem(items[0]); - - if (row != null) { - ViewerCell cell = row.getCell(column); - if (cell != null) { - triggerEditorActivationEvent(new ColumnViewerEditorActivationEvent(cell)); - } - } - } - } finally { - getControl().setRedraw(true); - } - } else { - super.editElement(element, column); - } - } -} +/******************************************************************************* + * Copyright (c) 2019 Thomas Schindl & Laurent Caron. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API + * and implementation + * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, + * code cleaning and documentation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ctreecombo.viewer; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.jface.util.Policy; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ILazyTreeContentProvider; +import org.eclipse.jface.viewers.ILazyTreePathContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeExpansionEvent; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.jface.viewers.ViewerRow; +import org.eclipse.nebula.widgets.ctreecombo.CTreeCombo; +import org.eclipse.nebula.widgets.ctreecombo.CTreeComboItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.TreeEvent; +import org.eclipse.swt.events.TreeListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.Widget; + +/** + * A concrete viewer based either on an SWT CTreeCombo control. + */ +public class CTreeComboViewer extends AbstractTreeViewer { + + private static final String VIRTUAL_DISPOSE_KEY = Policy.JFACE + ".DISPOSE_LISTENER"; //$NON-NLS-1$ + + /** + * This viewer's control. + */ + private CTreeCombo tree; + + /** + * Flag for whether the tree has been disposed of. + */ + private boolean treeIsDisposed = false; + + private boolean contentProviderIsLazy; + + private boolean contentProviderIsTreeBased; + + /** + * The row object reused + */ + private CTreeComboViewerRow cachedRow; + + /** + * true if we are inside a preservingSelection() call + */ + private boolean preservingSelection; + + /** + * Creates a tree viewer on a newly-created tree control under the given + * parent. The tree control is created using the SWT style bits + * MULTI, H_SCROLL, V_SCROLL, and BORDER. The + * viewer has no input, no content provider, a default label provider, no + * sorter, and no filters. + * + * @param parent + * the parent control + */ + public CTreeComboViewer(Composite parent) { + this(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + } + + /** + * Creates a CTreeComboViewer viewer on a newly-created tree control under the given + * parent. The CTreeCombo control is created using the given SWT style bits. The + * viewer has no input, no content provider, a default label provider, no + * sorter, and no filters. + * + * @param parent + * the parent control + * @param style + * the SWT style bits used to create the tree. + */ + public CTreeComboViewer(Composite parent, int style) { + this(new CTreeCombo(parent, style)); + } + + /** + * Creates a CTreeComboViewer viewer on the given tree control. The viewer has no input, + * no content provider, a default label provider, no sorter, and no filters. + * + * @param tree + * the tree control + */ + public CTreeComboViewer(CTreeCombo tree) { + super(); + this.tree = tree; + hookControl(tree); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#addTreeListener(org.eclipse.swt.widgets.Control, org.eclipse.swt.events.TreeListener) + */ + protected void addTreeListener(Control c, TreeListener listener) { + ((CTreeCombo) c).addTreeListener(listener); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getColumnViewerOwner(int) + */ + protected Widget getColumnViewerOwner(int columnIndex) { + if (columnIndex < 0 || (columnIndex > 0 && columnIndex >= getTree().getColumnCount())) { + return null; + } + + if (getTree().getColumnCount() == 0) + return getTree(); + + return getTree().getColumn(columnIndex); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChildren(org.eclipse.swt.widgets.Widget) + */ + protected Item[] getChildren(Widget o) { + if (o instanceof CTreeComboItem) { + return ((CTreeComboItem) o).getItems(); + } + if (o instanceof CTreeCombo) { + return ((CTreeCombo) o).getItems(); + } + return null; + } + + /** + * @see org.eclipse.jface.viewers.Viewer#getControl() + */ + public Control getControl() { + return tree; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getExpanded(org.eclipse.swt.widgets.Item) + */ + protected boolean getExpanded(Item item) { + return ((CTreeComboItem) item).getExpanded(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemAt(org.eclipse.swt.graphics.Point) + */ + protected Item getItemAt(Point p) { + CTreeComboItem[] selection = tree.getSelection(); + + if (selection.length == 1) { + int columnCount = tree.getColumnCount(); + + for (int i = 0; i < columnCount; i++) { + if (selection[0].getBounds(i).contains(p)) { + return selection[0]; + } + } + } + + return getTree().getItem(p); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemCount(org.eclipse.swt.widgets.Control) + */ + protected int getItemCount(Control widget) { + return ((CTreeCombo) widget).getItemCount(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemCount(org.eclipse.swt.widgets.Item) + */ + protected int getItemCount(Item item) { + return ((CTreeComboItem) item).getItemCount(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItems(org.eclipse.swt.widgets.Item) + */ + protected Item[] getItems(Item item) { + return ((CTreeComboItem) item).getItems(); + } + + /** + * @see org.eclipse.jface.viewers.ContentViewer#getLabelProvider() + */ + public IBaseLabelProvider getLabelProvider() { + return super.getLabelProvider(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getParentItem(org.eclipse.swt.widgets.Item) + */ + protected Item getParentItem(Item item) { + return ((CTreeComboItem) item).getParentItem(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getSelection(org.eclipse.swt.widgets.Control) + */ + protected Item[] getSelection(Control widget) { + return ((CTreeCombo) widget).getSelection(); + } + + /** + * Returns this CTreeCombo viewer's tree control. + * + * @return the ctreecombo control + */ + public CTreeCombo getTree() { + return tree; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#hookControl(org.eclipse.swt.widgets.Control) + */ + protected void hookControl(Control control) { + super.hookControl(control); + CTreeCombo treeControl = (CTreeCombo) control; + + if ((treeControl.getStyle() & SWT.VIRTUAL) != 0) { + treeControl.addListener(SWT.Dispose, (e) -> { + treeIsDisposed = true; + unmapAllElements(); + }); + treeControl.addListener(SWT.SetData, (event) -> { + if (contentProviderIsLazy) { + CTreeComboItem item = (CTreeComboItem) event.item; + CTreeComboItem parentItem = item.getParentItem(); + int index = event.index; + virtualLazyUpdateWidget(parentItem == null ? (Widget) getTree() : parentItem, index); + } + }); + } + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#createViewerEditor() + */ + protected ColumnViewerEditor createViewerEditor() { + return null; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#newItem(org.eclipse.swt.widgets.Widget, int, int) + */ + protected Item newItem(Widget parent, int flags, int ix) { + CTreeComboItem item; + + if (parent instanceof CTreeComboItem) { + item = (CTreeComboItem) createNewRowPart(getViewerRowFromItem(parent), flags, ix).getItem(); + } else { + item = (CTreeComboItem) createNewRowPart(null, flags, ix).getItem(); + } + + return item; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#removeAll(org.eclipse.swt.widgets.Control) + */ + protected void removeAll(Control widget) { + ((CTreeCombo) widget).removeAll(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#setExpanded(org.eclipse.swt.widgets.Item, boolean) + */ + protected void setExpanded(Item node, boolean expand) { + ((CTreeComboItem) node).setExpanded(expand); + if (contentProviderIsLazy) { + // force repaints to happen + getControl().update(); + } + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#setSelection(java.util.List) + */ + protected void setSelection(List items) { + Item[] current = getSelection(getTree()); + + // Don't bother resetting the same selection + if (isSameSelection(items, current)) { + return; + } + + CTreeComboItem[] newItems = new CTreeComboItem[items.size()]; + items.toArray(newItems); + getTree().setSelection(newItems); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#showItem(org.eclipse.swt.widgets.Item) + */ + protected void showItem(Item item) { + getTree().showItem((CTreeComboItem) item); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChild(org.eclipse.swt.widgets.Widget, int) + */ + protected Item getChild(Widget widget, int index) { + if (widget instanceof CTreeComboItem) { + return ((CTreeComboItem) widget).getItem(index); + } + if (widget instanceof CTreeCombo) { + return ((CTreeCombo) widget).getItem(index); + } + return null; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#assertContentProviderType(org.eclipse.jface.viewers.IContentProvider) + */ + protected void assertContentProviderType(IContentProvider provider) { + if (provider instanceof ILazyTreeContentProvider || provider instanceof ILazyTreePathContentProvider) { + return; + } + super.assertContentProviderType(provider); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getRawChildren(java.lang.Object) + */ + protected Object[] getRawChildren(Object parent) { + if (contentProviderIsLazy) { + return new Object[0]; + } + return super.getRawChildren(parent); + } + + /** + * For a CTreeComboViewer with a ctreecombo with the VIRTUAL style bit set, set the + * number of children of the given element or tree path. To set the number + * of children of the invisible root of the tree, you can pass the input + * object or an empty tree path. + * + * @param elementOrTreePath + * the element, or tree path + * @param count + */ + public void setChildCount(final Object elementOrTreePath, final int count) { + if (checkBusy()) + return; + preservingSelection(new Runnable() { + public void run() { + if (internalIsInputOrEmptyPath(elementOrTreePath)) { + getTree().setItemCount(count); + return; + } + Widget[] items = internalFindItems(elementOrTreePath); + for (int i = 0; i < items.length; i++) { + CTreeComboItem treeItem = (CTreeComboItem) items[i]; + treeItem.setItemCount(count); + } + } + }); + } + + /** + * For a CTreeComboViewer with a ctreecombo with the VIRTUAL style bit set, replace the + * given parent's child at index with the given element. If the given parent + * is this viewer's input or an empty tree path, this will replace the root + * element at the given index. + *

+ * This method should be called by implementers of ILazyTreeContentProvider + * to populate this viewer. + *

+ * + * @param parentElementOrTreePath + * the parent of the element that should be updated, or the tree + * path to that parent + * @param index + * the index in the parent's children + * @param element + * the new element + * + * @see #setChildCount(Object, int) + * @see ILazyTreeContentProvider + * @see ILazyTreePathContentProvider + */ + public void replace(final Object parentElementOrTreePath, final int index, final Object element) { + if (checkBusy()) + return; + Item[] selectedItems = getSelection(getControl()); + TreeSelection selection = (TreeSelection) getSelection(); + Widget[] itemsToDisassociate; + if (parentElementOrTreePath instanceof TreePath) { + TreePath elementPath = ((TreePath) parentElementOrTreePath).createChildPath(element); + itemsToDisassociate = internalFindItems(elementPath); + } else { + itemsToDisassociate = internalFindItems(element); + } + if (internalIsInputOrEmptyPath(parentElementOrTreePath)) { + if (index < tree.getItemCount()) { + CTreeComboItem item = tree.getItem(index); + selection = adjustSelectionForReplace(selectedItems, selection, item, element, getRoot()); + // disassociate any different item that represents the + // same element under the same parent (the tree) + for (int i = 0; i < itemsToDisassociate.length; i++) { + if (itemsToDisassociate[i] instanceof CTreeComboItem) { + CTreeComboItem itemToDisassociate = (CTreeComboItem) itemsToDisassociate[i]; + if (itemToDisassociate != item && itemToDisassociate.getParentItem() == null) { + int indexToDisassociate = getTree().indexOf(itemToDisassociate); + disassociate(itemToDisassociate); + getTree().clear(indexToDisassociate, true); + } + } + } + Object oldData = item.getData(); + updateItem(item, element); + if (!CTreeComboViewer.this.equals(oldData, element)) { + item.clearAll(true); + } + } + } else { + Widget[] parentItems = internalFindItems(parentElementOrTreePath); + for (int i = 0; i < parentItems.length; i++) { + CTreeComboItem parentItem = (CTreeComboItem) parentItems[i]; + if (index < parentItem.getItemCount()) { + CTreeComboItem item = parentItem.getItem(index); + selection = adjustSelectionForReplace(selectedItems, selection, item, element, parentItem.getData()); + // disassociate any different item that represents the + // same element under the same parent (the tree) + for (int j = 0; j < itemsToDisassociate.length; j++) { + if (itemsToDisassociate[j] instanceof CTreeComboItem) { + CTreeComboItem itemToDisassociate = (CTreeComboItem) itemsToDisassociate[j]; + if (itemToDisassociate != item && itemToDisassociate.getParentItem() == parentItem) { + int indexToDisaccociate = parentItem.indexOf(itemToDisassociate); + disassociate(itemToDisassociate); + parentItem.clear(indexToDisaccociate, true); + } + } + } + Object oldData = item.getData(); + updateItem(item, element); + if (!CTreeComboViewer.this.equals(oldData, element)) { + item.clearAll(true); + } + } + } + } + // Restore the selection if we are not already in a nested + // preservingSelection: + if (!preservingSelection) { + setSelectionToWidget(selection, false); + // send out notification if old and new differ + ISelection newSelection = getSelection(); + if (!newSelection.equals(selection)) { + handleInvalidSelection(selection, newSelection); + } + } + } + + private TreeSelection adjustSelectionForReplace(Item[] selectedItems, TreeSelection selection, CTreeComboItem item, Object element, Object parentElement) { + if (item.getData() != null || selectedItems.length == selection.size() || parentElement == null) { + // Don't do anything - we are not seeing an instance of bug 185673 + return selection; + } + for (int i = 0; i < selectedItems.length; i++) { + if (item == selectedItems[i]) { + // The current item was selected, but its data is null. + // The data will be replaced by the given element, so to keep + // it selected, we have to add it to the selection. + TreePath[] originalPaths = selection.getPaths(); + int length = originalPaths.length; + TreePath[] paths = new TreePath[length + 1]; + System.arraycopy(originalPaths, 0, paths, 0, length); + // set the element temporarily so that we can call + // getTreePathFromItem + item.setData(element); + paths[length] = getTreePathFromItem(item); + item.setData(null); + return new TreeSelection(paths, selection.getElementComparer()); + } + } + // The item was not selected, return the given selection + return selection; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#isExpandable(java.lang.Object) + */ + public boolean isExpandable(Object element) { + if (contentProviderIsLazy) { + CTreeComboItem treeItem = (CTreeComboItem) internalExpand(element, false); + if (treeItem == null) { + return false; + } + virtualMaterializeItem(treeItem); + return treeItem.getItemCount() > 0; + } + return super.isExpandable(element); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getParentElement(java.lang.Object) + */ + protected Object getParentElement(Object element) { + boolean oldBusy = isBusy(); + setBusy(true); + try { + if (contentProviderIsLazy && !contentProviderIsTreeBased && !(element instanceof TreePath)) { + ILazyTreeContentProvider lazyTreeContentProvider = (ILazyTreeContentProvider) getContentProvider(); + return lazyTreeContentProvider.getParent(element); + } + if (contentProviderIsLazy && contentProviderIsTreeBased && !(element instanceof TreePath)) { + ILazyTreePathContentProvider lazyTreePathContentProvider = (ILazyTreePathContentProvider) getContentProvider(); + TreePath[] parents = lazyTreePathContentProvider.getParents(element); + if (parents != null && parents.length > 0) { + return parents[0]; + } + } + return super.getParentElement(element); + } finally { + setBusy(oldBusy); + } + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#createChildren(org.eclipse.swt.widgets.Widget) + */ + protected void createChildren(Widget widget) { + if (contentProviderIsLazy) { + Object element = widget.getData(); + if (element == null && widget instanceof CTreeComboItem) { + // parent has not been materialized + virtualMaterializeItem((CTreeComboItem) widget); + // try getting the element now that updateElement was called + element = widget.getData(); + } + if (element == null) { + // give up because the parent is still not materialized + return; + } + Item[] children = getChildren(widget); + if (children.length == 1 && children[0].getData() == null) { + // found a dummy node + virtualLazyUpdateChildCount(widget, children.length); + children = getChildren(widget); + } + // touch all children to make sure they are materialized + for (int i = 0; i < children.length; i++) { + if (children[i].getData() == null) { + virtualLazyUpdateWidget(widget, i); + } + } + return; + } + super.createChildren(widget); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#internalAdd(org.eclipse.swt.widgets.Widget, java.lang.Object, java.lang.Object[]) + */ + protected void internalAdd(Widget widget, Object parentElement, Object[] childElements) { + if (contentProviderIsLazy) { + if (widget instanceof CTreeComboItem) { + CTreeComboItem ti = (CTreeComboItem) widget; + int count = ti.getItemCount() + childElements.length; + ti.setItemCount(count); + ti.clearAll(false); + } else { + CTreeCombo t = (CTreeCombo) widget; + t.setItemCount(t.getItemCount() + childElements.length); + t.clearAll(false); + } + return; + } + super.internalAdd(widget, parentElement, childElements); + } + + private void virtualMaterializeItem(CTreeComboItem treeItem) { + if (treeItem.getData() != null) { + // already materialized + return; + } + if (!contentProviderIsLazy) { + return; + } + int index; + Widget parent = treeItem.getParentItem(); + if (parent == null) { + parent = treeItem.getParent(); + } + Object parentElement = parent.getData(); + if (parentElement != null) { + if (parent instanceof CTreeCombo) { + index = ((CTreeCombo) parent).indexOf(treeItem); + } else { + index = ((CTreeComboItem) parent).indexOf(treeItem); + } + virtualLazyUpdateWidget(parent, index); + } + } + + /** + * @see org.eclipse.jface.viewers.StructuredViewer#mapElement(java.lang.Object, org.eclipse.swt.widgets.Widget) + */ + protected void mapElement(Object element, final Widget item) { + super.mapElement(element, item); + // make sure to unmap elements if the tree is virtual + if ((getTree().getStyle() & SWT.VIRTUAL) != 0) { + // only add a dispose listener if item hasn't already on assigned + // because it is reused + if (item.getData(VIRTUAL_DISPOSE_KEY) == null) { + item.setData(VIRTUAL_DISPOSE_KEY, Boolean.TRUE); + item.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + if (!treeIsDisposed) { + Object data = item.getData(); + if (usingElementMap() && data != null) { + unmapElement(data, item); + } + } + } + }); + } + } + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getViewerRowFromItem(org.eclipse.swt.widgets.Widget) + */ + protected ViewerRow getViewerRowFromItem(Widget item) { + if (cachedRow == null) { + cachedRow = new CTreeComboViewerRow((CTreeComboItem) item); + } else { + cachedRow.setItem((CTreeComboItem) item); + } + + return cachedRow; + } + + /** + * Create a new ViewerRow at rowIndex + * + * @param parent + * @param style + * @param rowIndex + * @return ViewerRow + */ + private ViewerRow createNewRowPart(ViewerRow parent, int style, int rowIndex) { + if (parent == null) { + if (rowIndex >= 0) { + return getViewerRowFromItem(new CTreeComboItem(tree, style, rowIndex)); + } + return getViewerRowFromItem(new CTreeComboItem(tree, style)); + } + + if (rowIndex >= 0) { + return getViewerRowFromItem(new CTreeComboItem((CTreeComboItem) parent.getItem(), SWT.NONE, rowIndex)); + } + + return getViewerRowFromItem(new CTreeComboItem((CTreeComboItem) parent.getItem(), SWT.NONE)); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#internalInitializeTree(org.eclipse.swt.widgets.Control) + */ + protected void internalInitializeTree(Control widget) { + if (contentProviderIsLazy) { + if (widget instanceof CTreeCombo && widget.getData() != null) { + virtualLazyUpdateChildCount(widget, 0); + return; + } + } + super.internalInitializeTree(tree); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#updatePlus(org.eclipse.swt.widgets.Item, java.lang.Object) + */ + protected void updatePlus(Item item, Object element) { + if (contentProviderIsLazy) { + Object data = item.getData(); + int itemCount = 0; + if (data != null) { + // item is already materialized + itemCount = ((CTreeComboItem) item).getItemCount(); + } + virtualLazyUpdateHasChildren(item, itemCount); + } else { + super.updatePlus(item, element); + } + } + + /** + * Removes the element at the specified index of the parent. The selection + * is updated if required. + * + * @param parentOrTreePath + * the parent element, the input element, or a tree path to the + * parent element + * @param index + * child index + */ + public void remove(final Object parentOrTreePath, final int index) { + if (checkBusy()) + return; + final List oldSelection = new LinkedList(Arrays.asList(((TreeSelection) getSelection()).getPaths())); + preservingSelection(new Runnable() { + public void run() { + TreePath removedPath = null; + if (internalIsInputOrEmptyPath(parentOrTreePath)) { + CTreeCombo tree = (CTreeCombo) getControl(); + if (index < tree.getItemCount()) { + CTreeComboItem item = tree.getItem(index); + if (item.getData() != null) { + removedPath = getTreePathFromItem(item); + disassociate(item); + } + item.dispose(); + } + } else { + Widget[] parentItems = internalFindItems(parentOrTreePath); + for (int i = 0; i < parentItems.length; i++) { + CTreeComboItem parentItem = (CTreeComboItem) parentItems[i]; + if (parentItem.isDisposed()) + continue; + if (index < parentItem.getItemCount()) { + CTreeComboItem item = parentItem.getItem(index); + if (item.getData() != null) { + removedPath = getTreePathFromItem(item); + disassociate(item); + } + item.dispose(); + } + } + } + if (removedPath != null) { + boolean removed = false; + for (Iterator it = oldSelection.iterator(); it.hasNext();) { + TreePath path = (TreePath) it.next(); + if (path.startsWith(removedPath, getComparer())) { + it.remove(); + removed = true; + } + } + if (removed) { + setSelection(new TreeSelection((TreePath[]) oldSelection.toArray(new TreePath[oldSelection.size()]), getComparer()), false); + } + + } + } + }); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#handleTreeExpand(org.eclipse.swt.events.TreeEvent) + */ + protected void handleTreeExpand(TreeEvent event) { + if (contentProviderIsLazy) { + if (event.item.getData() != null) { + Item[] children = getChildren(event.item); + if (children.length == 1 && children[0].getData() == null) { + // we have a dummy child node, ask for an updated child + // count + virtualLazyUpdateChildCount(event.item, children.length); + } + fireTreeExpanded(new TreeExpansionEvent(this, event.item.getData())); + } + return; + } + super.handleTreeExpand(event); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#setContentProvider(org.eclipse.jface.viewers.IContentProvider) + */ + public void setContentProvider(IContentProvider provider) { + contentProviderIsLazy = (provider instanceof ILazyTreeContentProvider) || (provider instanceof ILazyTreePathContentProvider); + contentProviderIsTreeBased = provider instanceof ILazyTreePathContentProvider; + super.setContentProvider(provider); + } + + /** + * For a TreeViewer with a tree with the VIRTUAL style bit set, inform the + * viewer about whether the given element or tree path has children. Avoid + * calling this method if the number of children has already been set. + * + * @param elementOrTreePath + * the element, or tree path + * @param hasChildren + * + */ + public void setHasChildren(final Object elementOrTreePath, final boolean hasChildren) { + if (checkBusy()) + return; + preservingSelection(new Runnable() { + public void run() { + if (internalIsInputOrEmptyPath(elementOrTreePath)) { + if (hasChildren) { + virtualLazyUpdateChildCount(getTree(), getChildren(getTree()).length); + } else { + setChildCount(elementOrTreePath, 0); + } + return; + } + Widget[] items = internalFindItems(elementOrTreePath); + for (int i = 0; i < items.length; i++) { + CTreeComboItem item = (CTreeComboItem) items[i]; + if (!hasChildren) { + item.setItemCount(0); + } else { + if (!item.getExpanded()) { + item.setItemCount(1); + CTreeComboItem child = item.getItem(0); + if (child.getData() != null) { + disassociate(child); + } + item.clear(0, true); + } else { + virtualLazyUpdateChildCount(item, item.getItemCount()); + } + } + } + } + }); + } + + /** + * Update the widget at index. + * + * @param widget + * @param index + */ + private void virtualLazyUpdateWidget(Widget widget, int index) { + boolean oldBusy = isBusy(); + setBusy(false); + try { + if (contentProviderIsTreeBased) { + TreePath treePath; + if (widget instanceof Item) { + if (widget.getData() == null) { + return; + } + treePath = getTreePathFromItem((Item) widget); + } else { + treePath = TreePath.EMPTY; + } + ((ILazyTreePathContentProvider) getContentProvider()).updateElement(treePath, index); + } else { + ((ILazyTreeContentProvider) getContentProvider()).updateElement(widget.getData(), index); + } + } finally { + setBusy(oldBusy); + } + } + + /** + * Update the child count + * + * @param widget + * @param currentChildCount + */ + private void virtualLazyUpdateChildCount(Widget widget, int currentChildCount) { + boolean oldBusy = isBusy(); + setBusy(false); + try { + if (contentProviderIsTreeBased) { + TreePath treePath; + if (widget instanceof Item) { + treePath = getTreePathFromItem((Item) widget); + } else { + treePath = TreePath.EMPTY; + } + ((ILazyTreePathContentProvider) getContentProvider()).updateChildCount(treePath, currentChildCount); + } else { + ((ILazyTreeContentProvider) getContentProvider()).updateChildCount(widget.getData(), currentChildCount); + } + } finally { + setBusy(oldBusy); + } + } + + /** + * Update the item with the current child count. + * + * @param item + * @param currentChildCount + */ + private void virtualLazyUpdateHasChildren(Item item, int currentChildCount) { + boolean oldBusy = isBusy(); + setBusy(false); + try { + if (contentProviderIsTreeBased) { + TreePath treePath; + treePath = getTreePathFromItem(item); + if (currentChildCount == 0) { + // item is not expanded (but may have a plus currently) + ((ILazyTreePathContentProvider) getContentProvider()).updateHasChildren(treePath); + } else { + ((ILazyTreePathContentProvider) getContentProvider()).updateChildCount(treePath, currentChildCount); + } + } else { + ((ILazyTreeContentProvider) getContentProvider()).updateChildCount(item.getData(), currentChildCount); + } + } finally { + setBusy(oldBusy); + } + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#disassociate(org.eclipse.swt.widgets.Item) + */ + protected void disassociate(Item item) { + if (contentProviderIsLazy) { + // avoid causing a callback: + item.setText(" "); //$NON-NLS-1$ + } + super.disassociate(item); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#doGetColumnCount() + */ + protected int doGetColumnCount() { + return tree.getColumnCount(); + } + + /** + * Sets a new selection for this viewer and optionally makes it visible. + *

+ * Currently the reveal parameter is not honored because + * {@link Tree} does not provide an API to only select an item without + * scrolling it into view + *

+ * + * @param selection + * the new selection + * @param reveal + * true if the selection is to be made visible, and + * false otherwise + */ + public void setSelection(ISelection selection, boolean reveal) { + super.setSelection(selection, reveal); + } + + /** + * @see org.eclipse.jface.viewers.ColumnViewer#editElement(java.lang.Object, int) + */ + public void editElement(Object element, int column) { + if (element instanceof TreePath) { + try { + getControl().setRedraw(false); + setSelection(new TreeSelection((TreePath) element)); + CTreeComboItem[] items = tree.getSelection(); + + if (items.length == 1) { + ViewerRow row = getViewerRowFromItem(items[0]); + + if (row != null) { + ViewerCell cell = row.getCell(column); + if (cell != null) { + triggerEditorActivationEvent(new ColumnViewerEditorActivationEvent(cell)); + } + } + } + } finally { + getControl().setRedraw(true); + } + } else { + super.editElement(element, column); + } + } +} diff --git a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/viewer/CTreeComboViewerRow.java b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/viewer/CTreeComboViewerRow.java index 48e1c08e1..286295170 100644 --- a/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/viewer/CTreeComboViewerRow.java +++ b/widgets/ctreecombo/org.eclipse.nebula.widgets.ctreecombo/src/org/eclipse/nebula/widgets/ctreecombo/viewer/CTreeComboViewerRow.java @@ -1,376 +1,376 @@ -/******************************************************************************* - * Copyright (c) 2019 Thomas Schindl & Laurent Caron. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API - * and implementation - * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, - * code cleaning and documentation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ctreecombo.viewer; - -import java.util.LinkedList; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.ViewerRow; -import org.eclipse.nebula.widgets.ctreecombo.CTreeCombo; -import org.eclipse.nebula.widgets.ctreecombo.CTreeComboItem; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Widget; - -/** - * CTreeComboViewerRow represents items in a CTreeCombo widget. - */ -public class CTreeComboViewerRow extends ViewerRow { - private CTreeComboItem item; - - /** - * Create a new instance of the receiver. - * - * @param item - */ - CTreeComboViewerRow(CTreeComboItem item) { - this.item = item; - } - - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getBounds(int) - */ - public Rectangle getBounds(int columnIndex) { - return item.getBounds(columnIndex); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getBounds() - */ - public Rectangle getBounds() { - return item.getBounds(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getColumnCount() - */ - public int getColumnCount() { - return item.getParent().getColumnCount(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getItem() - */ - public Widget getItem() { - return item; - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getBackground(int) - */ - public Color getBackground(int columnIndex) { - return item.getBackground(columnIndex); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getFont(int) - */ - public Font getFont(int columnIndex) { - return item.getFont(columnIndex); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getForeground(int) - */ - public Color getForeground(int columnIndex) { - return item.getForeground(columnIndex); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getImage(int) - */ - public Image getImage(int columnIndex) { - return item.getImage(columnIndex); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getText(int) - */ - public String getText(int columnIndex) { - return item.getText(columnIndex); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setBackground(int, org.eclipse.swt.graphics.Color) - */ - public void setBackground(int columnIndex, Color color) { - item.setBackground(columnIndex, color); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setFont(int, org.eclipse.swt.graphics.Font) - */ - public void setFont(int columnIndex, Font font) { - item.setFont(columnIndex, font); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setForeground(int, org.eclipse.swt.graphics.Color) - */ - public void setForeground(int columnIndex, Color color) { - item.setForeground(columnIndex, color); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setImage(int, org.eclipse.swt.graphics.Image) - */ - public void setImage(int columnIndex, Image image) { - Image oldImage = item.getImage(columnIndex); - if (image != oldImage) { - item.setImage(columnIndex, image); - } - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setText(int, java.lang.String) - */ - public void setText(int columnIndex, String text) { - item.setText(columnIndex, text == null ? "" : text); //$NON-NLS-1$ - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getControl() - */ - public Control getControl() { - return item.getParent(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getNeighbor(int, boolean) - */ - public ViewerRow getNeighbor(int direction, boolean sameLevel) { - if (direction == ViewerRow.ABOVE) { - return getRowAbove(sameLevel); - } else if (direction == ViewerRow.BELOW) { - return getRowBelow(sameLevel); - } else { - throw new IllegalArgumentException("Illegal value of direction argument."); //$NON-NLS-1$ - } - } - - private ViewerRow getRowBelow(boolean sameLevel) { - CTreeCombo tree = item.getParent(); - - // This means we have top-level item - if (item.getParentItem() == null) { - if (sameLevel || !item.getExpanded()) { - int index = tree.indexOf(item) + 1; - - if (index < tree.getItemCount()) { - return new CTreeComboViewerRow(tree.getItem(index)); - } - } else if (item.getExpanded() && item.getItemCount() > 0) { - return new CTreeComboViewerRow(item.getItem(0)); - } - } else { - if (sameLevel || !item.getExpanded()) { - CTreeComboItem parentItem = item.getParentItem(); - - int nextIndex = parentItem.indexOf(item) + 1; - int totalIndex = parentItem.getItemCount(); - - CTreeComboItem itemAfter; - - // This would mean that it was the last item - if (nextIndex == totalIndex) { - itemAfter = findNextItem(parentItem); - } else { - itemAfter = parentItem.getItem(nextIndex); - } - - if (itemAfter != null) { - return new CTreeComboViewerRow(itemAfter); - } - - } else if (item.getExpanded() && item.getItemCount() > 0) { - return new CTreeComboViewerRow(item.getItem(0)); - } - } - - return null; - } - - private ViewerRow getRowAbove(boolean sameLevel) { - CTreeCombo tree = item.getParent(); - - // This means we have top-level item - if (item.getParentItem() == null) { - int index = tree.indexOf(item) - 1; - CTreeComboItem nextTopItem = null; - - if (index >= 0) { - nextTopItem = tree.getItem(index); - } - - if (nextTopItem != null) { - if (sameLevel) { - return new CTreeComboViewerRow(nextTopItem); - } - - return new CTreeComboViewerRow(findLastVisibleItem(nextTopItem)); - } - } else { - CTreeComboItem parentItem = item.getParentItem(); - int previousIndex = parentItem.indexOf(item) - 1; - - CTreeComboItem itemBefore; - if (previousIndex >= 0) { - if (sameLevel) { - itemBefore = parentItem.getItem(previousIndex); - } else { - itemBefore = findLastVisibleItem(parentItem.getItem(previousIndex)); - } - } else { - itemBefore = parentItem; - } - - if (itemBefore != null) { - return new CTreeComboViewerRow(itemBefore); - } - } - - return null; - } - - private CTreeComboItem findLastVisibleItem(CTreeComboItem parentItem) { - CTreeComboItem rv = parentItem; - - while (rv.getExpanded() && rv.getItemCount() > 0) { - rv = rv.getItem(rv.getItemCount() - 1); - } - - return rv; - } - - private CTreeComboItem findNextItem(CTreeComboItem item) { - CTreeComboItem rv = null; - CTreeCombo tree = item.getParent(); - CTreeComboItem parentItem = item.getParentItem(); - - int nextIndex; - int totalItems; - - if (parentItem == null) { - nextIndex = tree.indexOf(item) + 1; - totalItems = tree.getItemCount(); - } else { - nextIndex = parentItem.indexOf(item) + 1; - totalItems = parentItem.getItemCount(); - } - - // This is once more the last item in the tree - // Search on - if (nextIndex == totalItems) { - if (item.getParentItem() != null) { - rv = findNextItem(item.getParentItem()); - } - } else { - if (parentItem == null) { - rv = tree.getItem(nextIndex); - } else { - rv = parentItem.getItem(nextIndex); - } - } - - return rv; - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getTreePath() - */ - public TreePath getTreePath() { - CTreeComboItem tItem = item; - LinkedList segments = new LinkedList(); - while (tItem != null) { - Object segment = tItem.getData(); - Assert.isNotNull(segment); - segments.addFirst(segment); - tItem = tItem.getParentItem(); - } - - return new TreePath(segments.toArray()); - } - - void setItem(CTreeComboItem item) { - this.item = item; - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#clone() - */ - public Object clone() { - return new CTreeComboViewerRow(item); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getElement() - */ - public Object getElement() { - return item.getData(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getVisualIndex(int) - */ - public int getVisualIndex(int creationIndex) { - int[] order = item.getParent().getColumnOrder(); - - for (int i = 0; i < order.length; i++) { - if (order[i] == creationIndex) { - return i; - } - } - - return super.getVisualIndex(creationIndex); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getCreationIndex(int) - */ - public int getCreationIndex(int visualIndex) { - if (item != null && !item.isDisposed() && hasColumns() && isValidOrderIndex(visualIndex)) { - return item.getParent().getColumnOrder()[visualIndex]; - } - return super.getCreationIndex(visualIndex); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getTextBounds(int) - */ - public Rectangle getTextBounds(int index) { - return item.getTextBounds(index); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getImageBounds(int) - */ - public Rectangle getImageBounds(int index) { - return item.getImageBounds(index); - } - - private boolean hasColumns() { - return this.item.getParent().getColumnCount() != 0; - } - - private boolean isValidOrderIndex(int currentIndex) { - return currentIndex < this.item.getParent().getColumnOrder().length; - } -} +/******************************************************************************* + * Copyright (c) 2019 Thomas Schindl & Laurent Caron. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Thomas Schindl (tom dot schindl at bestsolution dot at) - initial API + * and implementation + * - Laurent Caron (laurent dot caron at gmail dot com) - Integration to Nebula, + * code cleaning and documentation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ctreecombo.viewer; + +import java.util.LinkedList; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.ViewerRow; +import org.eclipse.nebula.widgets.ctreecombo.CTreeCombo; +import org.eclipse.nebula.widgets.ctreecombo.CTreeComboItem; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Widget; + +/** + * CTreeComboViewerRow represents items in a CTreeCombo widget. + */ +public class CTreeComboViewerRow extends ViewerRow { + private CTreeComboItem item; + + /** + * Create a new instance of the receiver. + * + * @param item + */ + CTreeComboViewerRow(CTreeComboItem item) { + this.item = item; + } + + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getBounds(int) + */ + public Rectangle getBounds(int columnIndex) { + return item.getBounds(columnIndex); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getBounds() + */ + public Rectangle getBounds() { + return item.getBounds(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getColumnCount() + */ + public int getColumnCount() { + return item.getParent().getColumnCount(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getItem() + */ + public Widget getItem() { + return item; + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getBackground(int) + */ + public Color getBackground(int columnIndex) { + return item.getBackground(columnIndex); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getFont(int) + */ + public Font getFont(int columnIndex) { + return item.getFont(columnIndex); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getForeground(int) + */ + public Color getForeground(int columnIndex) { + return item.getForeground(columnIndex); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getImage(int) + */ + public Image getImage(int columnIndex) { + return item.getImage(columnIndex); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getText(int) + */ + public String getText(int columnIndex) { + return item.getText(columnIndex); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setBackground(int, org.eclipse.swt.graphics.Color) + */ + public void setBackground(int columnIndex, Color color) { + item.setBackground(columnIndex, color); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setFont(int, org.eclipse.swt.graphics.Font) + */ + public void setFont(int columnIndex, Font font) { + item.setFont(columnIndex, font); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setForeground(int, org.eclipse.swt.graphics.Color) + */ + public void setForeground(int columnIndex, Color color) { + item.setForeground(columnIndex, color); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setImage(int, org.eclipse.swt.graphics.Image) + */ + public void setImage(int columnIndex, Image image) { + Image oldImage = item.getImage(columnIndex); + if (image != oldImage) { + item.setImage(columnIndex, image); + } + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setText(int, java.lang.String) + */ + public void setText(int columnIndex, String text) { + item.setText(columnIndex, text == null ? "" : text); //$NON-NLS-1$ + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getControl() + */ + public Control getControl() { + return item.getParent(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getNeighbor(int, boolean) + */ + public ViewerRow getNeighbor(int direction, boolean sameLevel) { + if (direction == ViewerRow.ABOVE) { + return getRowAbove(sameLevel); + } else if (direction == ViewerRow.BELOW) { + return getRowBelow(sameLevel); + } else { + throw new IllegalArgumentException("Illegal value of direction argument."); //$NON-NLS-1$ + } + } + + private ViewerRow getRowBelow(boolean sameLevel) { + CTreeCombo tree = item.getParent(); + + // This means we have top-level item + if (item.getParentItem() == null) { + if (sameLevel || !item.getExpanded()) { + int index = tree.indexOf(item) + 1; + + if (index < tree.getItemCount()) { + return new CTreeComboViewerRow(tree.getItem(index)); + } + } else if (item.getExpanded() && item.getItemCount() > 0) { + return new CTreeComboViewerRow(item.getItem(0)); + } + } else { + if (sameLevel || !item.getExpanded()) { + CTreeComboItem parentItem = item.getParentItem(); + + int nextIndex = parentItem.indexOf(item) + 1; + int totalIndex = parentItem.getItemCount(); + + CTreeComboItem itemAfter; + + // This would mean that it was the last item + if (nextIndex == totalIndex) { + itemAfter = findNextItem(parentItem); + } else { + itemAfter = parentItem.getItem(nextIndex); + } + + if (itemAfter != null) { + return new CTreeComboViewerRow(itemAfter); + } + + } else if (item.getExpanded() && item.getItemCount() > 0) { + return new CTreeComboViewerRow(item.getItem(0)); + } + } + + return null; + } + + private ViewerRow getRowAbove(boolean sameLevel) { + CTreeCombo tree = item.getParent(); + + // This means we have top-level item + if (item.getParentItem() == null) { + int index = tree.indexOf(item) - 1; + CTreeComboItem nextTopItem = null; + + if (index >= 0) { + nextTopItem = tree.getItem(index); + } + + if (nextTopItem != null) { + if (sameLevel) { + return new CTreeComboViewerRow(nextTopItem); + } + + return new CTreeComboViewerRow(findLastVisibleItem(nextTopItem)); + } + } else { + CTreeComboItem parentItem = item.getParentItem(); + int previousIndex = parentItem.indexOf(item) - 1; + + CTreeComboItem itemBefore; + if (previousIndex >= 0) { + if (sameLevel) { + itemBefore = parentItem.getItem(previousIndex); + } else { + itemBefore = findLastVisibleItem(parentItem.getItem(previousIndex)); + } + } else { + itemBefore = parentItem; + } + + if (itemBefore != null) { + return new CTreeComboViewerRow(itemBefore); + } + } + + return null; + } + + private CTreeComboItem findLastVisibleItem(CTreeComboItem parentItem) { + CTreeComboItem rv = parentItem; + + while (rv.getExpanded() && rv.getItemCount() > 0) { + rv = rv.getItem(rv.getItemCount() - 1); + } + + return rv; + } + + private CTreeComboItem findNextItem(CTreeComboItem item) { + CTreeComboItem rv = null; + CTreeCombo tree = item.getParent(); + CTreeComboItem parentItem = item.getParentItem(); + + int nextIndex; + int totalItems; + + if (parentItem == null) { + nextIndex = tree.indexOf(item) + 1; + totalItems = tree.getItemCount(); + } else { + nextIndex = parentItem.indexOf(item) + 1; + totalItems = parentItem.getItemCount(); + } + + // This is once more the last item in the tree + // Search on + if (nextIndex == totalItems) { + if (item.getParentItem() != null) { + rv = findNextItem(item.getParentItem()); + } + } else { + if (parentItem == null) { + rv = tree.getItem(nextIndex); + } else { + rv = parentItem.getItem(nextIndex); + } + } + + return rv; + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getTreePath() + */ + public TreePath getTreePath() { + CTreeComboItem tItem = item; + LinkedList segments = new LinkedList(); + while (tItem != null) { + Object segment = tItem.getData(); + Assert.isNotNull(segment); + segments.addFirst(segment); + tItem = tItem.getParentItem(); + } + + return new TreePath(segments.toArray()); + } + + void setItem(CTreeComboItem item) { + this.item = item; + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#clone() + */ + public Object clone() { + return new CTreeComboViewerRow(item); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getElement() + */ + public Object getElement() { + return item.getData(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getVisualIndex(int) + */ + public int getVisualIndex(int creationIndex) { + int[] order = item.getParent().getColumnOrder(); + + for (int i = 0; i < order.length; i++) { + if (order[i] == creationIndex) { + return i; + } + } + + return super.getVisualIndex(creationIndex); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getCreationIndex(int) + */ + public int getCreationIndex(int visualIndex) { + if (item != null && !item.isDisposed() && hasColumns() && isValidOrderIndex(visualIndex)) { + return item.getParent().getColumnOrder()[visualIndex]; + } + return super.getCreationIndex(visualIndex); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getTextBounds(int) + */ + public Rectangle getTextBounds(int index) { + return item.getTextBounds(index); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getImageBounds(int) + */ + public Rectangle getImageBounds(int index) { + return item.getImageBounds(index); + } + + private boolean hasColumns() { + return this.item.getParent().getColumnCount() != 0; + } + + private boolean isValidOrderIndex(int currentIndex) { + return currentIndex < this.item.getParent().getColumnOrder().length; + } +} diff --git a/widgets/ctreecombo/pom.xml b/widgets/ctreecombo/pom.xml index 217324a0b..78a363a2f 100644 --- a/widgets/ctreecombo/pom.xml +++ b/widgets/ctreecombo/pom.xml @@ -1,32 +1,32 @@ - - - - 4.0.0 - - ctreecombo - pom - 1.0.0-SNAPSHOT - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - nebula-parent - ../../releng/org.eclipse.nebula.nebula-parent - - - - org.eclipse.nebula.widgets.ctreecombo - org.eclipse.nebula.widgets.ctreecombo.feature - org.eclipse.nebula.widgets.ctreecombo.snippets - - - - + + + + 4.0.0 + + ctreecombo + pom + 1.0.0-SNAPSHOT + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + nebula-parent + ../../releng/org.eclipse.nebula.nebula-parent + + + + org.eclipse.nebula.widgets.ctreecombo + org.eclipse.nebula.widgets.ctreecombo.feature + org.eclipse.nebula.widgets.ctreecombo.snippets + + + + diff --git a/widgets/cwt/org.eclipse.nebula.cwt.tests/src/org/eclipse/nebula/cwt/svg/VControlTest.java b/widgets/cwt/org.eclipse.nebula.cwt.tests/src/org/eclipse/nebula/cwt/svg/VControlTest.java index 9e8ab4388..7d36b452d 100644 --- a/widgets/cwt/org.eclipse.nebula.cwt.tests/src/org/eclipse/nebula/cwt/svg/VControlTest.java +++ b/widgets/cwt/org.eclipse.nebula.cwt.tests/src/org/eclipse/nebula/cwt/svg/VControlTest.java @@ -1,59 +1,59 @@ -package org.eclipse.nebula.cwt.svg; - -import java.io.IOException; -import java.io.InputStream; - -import org.eclipse.nebula.cwt.v.VCanvas; -import org.eclipse.nebula.cwt.v.VGridLayout; -import org.eclipse.nebula.cwt.v.VLabel; -import org.eclipse.nebula.cwt.v.VPanel; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -public class VControlTest { - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(1, false)); - shell.setText("Test"); - - SvgDocument SVG_BACK = null; - try (final InputStream in = VControlTest.class.getResourceAsStream("caretLeft.svg")) { - SVG_BACK = SvgDocument.load(in); - } - catch (IOException e) { - e.printStackTrace(); - } - if(SVG_BACK == null) { - return; - } - - VCanvas vCanvas = new VCanvas(shell,SWT.NONE); - - VPanel vPanel = vCanvas.getPanel(); - - VGridLayout layout = new VGridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - vPanel.setLayout(layout); - - VLabel vLabel = new VLabel(vPanel, SWT.NONE); - vLabel.setImage(SVG_BACK); - - Point size = vCanvas.computeSize(SWT.DEFAULT, SWT.DEFAULT); - System.out.println(size); - - // display the shell... - shell.open(); - shell.pack(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } -} +package org.eclipse.nebula.cwt.svg; + +import java.io.IOException; +import java.io.InputStream; + +import org.eclipse.nebula.cwt.v.VCanvas; +import org.eclipse.nebula.cwt.v.VGridLayout; +import org.eclipse.nebula.cwt.v.VLabel; +import org.eclipse.nebula.cwt.v.VPanel; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class VControlTest { + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(1, false)); + shell.setText("Test"); + + SvgDocument SVG_BACK = null; + try (final InputStream in = VControlTest.class.getResourceAsStream("caretLeft.svg")) { + SVG_BACK = SvgDocument.load(in); + } + catch (IOException e) { + e.printStackTrace(); + } + if(SVG_BACK == null) { + return; + } + + VCanvas vCanvas = new VCanvas(shell,SWT.NONE); + + VPanel vPanel = vCanvas.getPanel(); + + VGridLayout layout = new VGridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + vPanel.setLayout(layout); + + VLabel vLabel = new VLabel(vPanel, SWT.NONE); + vLabel.setImage(SVG_BACK); + + Point size = vCanvas.computeSize(SWT.DEFAULT, SWT.DEFAULT); + System.out.println(size); + + // display the shell... + shell.open(); + shell.pack(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } +} diff --git a/widgets/cwt/org.eclipse.nebula.cwt/.classpath b/widgets/cwt/org.eclipse.nebula.cwt/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/cwt/org.eclipse.nebula.cwt/.classpath +++ b/widgets/cwt/org.eclipse.nebula.cwt/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/cwt/org.eclipse.nebula.cwt/.settings/org.eclipse.jdt.core.prefs b/widgets/cwt/org.eclipse.nebula.cwt/.settings/org.eclipse.jdt.core.prefs index 7fd9e334f..f646b22e3 100644 --- a/widgets/cwt/org.eclipse.nebula.cwt/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/cwt/org.eclipse.nebula.cwt/.settings/org.eclipse.jdt.core.prefs @@ -1,377 +1,377 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.builder.cleanOutputFolder=clean -org.eclipse.jdt.core.builder.duplicateResourceTask=warning -org.eclipse.jdt.core.builder.invalidClasspath=abort -org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore -org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,*.testsuite,*.deploy,*.location,*.execution,*.datapool,*.artifact,*.html,*.svg -org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes= -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=warning -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning -org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning -org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true -org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true -org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true -org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true -org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true -org.eclipse.jdt.core.incompatibleJDKLevel=ignore -org.eclipse.jdt.core.incompleteClasspath=error +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,*.testsuite,*.deploy,*.location,*.execution,*.datapool,*.artifact,*.html,*.svg +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.codeComplete.argumentPrefixes= +org.eclipse.jdt.core.codeComplete.argumentSuffixes= +org.eclipse.jdt.core.codeComplete.fieldPrefixes= +org.eclipse.jdt.core.codeComplete.fieldSuffixes= +org.eclipse.jdt.core.codeComplete.localPrefixes= +org.eclipse.jdt.core.codeComplete.localSuffixes= +org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= +org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.doc.comment.support=enabled +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning +org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning +org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true +org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true +org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true +org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true +org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error diff --git a/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/base/BaseCombo.java b/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/base/BaseCombo.java index 15772fbf1..9fba1d6fb 100644 --- a/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/base/BaseCombo.java +++ b/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/base/BaseCombo.java @@ -1,1353 +1,1353 @@ -/**************************************************************************** - * Copyright (c) 2005-2009 Jeremy Dowdall - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - SWT's CCombo was relied upon _heavily_ for example and reference - * Jeremy Dowdall - initial API and implementation - *****************************************************************************/ - -package org.eclipse.nebula.cwt.base; - -import org.eclipse.nebula.cwt.animation.AnimationRunner; -import org.eclipse.nebula.cwt.animation.effects.Resize; -import org.eclipse.nebula.cwt.animation.movement.LinearInOut; -import org.eclipse.nebula.cwt.v.VButton; -import org.eclipse.nebula.cwt.v.VButtonPainter; -import org.eclipse.nebula.cwt.v.VControl; -import org.eclipse.nebula.cwt.v.VLayout; -import org.eclipse.nebula.cwt.v.VNative; -import org.eclipse.nebula.cwt.v.VPanel; -import org.eclipse.nebula.cwt.v.VSimpleLayout; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TraverseListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Monitor; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * The AbstractCombo is an abstract class which provides the basic functionality - * for a button with a DROP_DOWN, or "popup", shell component. When the user - * selects the button the shell is set visible and the SWT Components which have - * been placed on the "content" Composite will be shown. - */ -public abstract class BaseCombo extends Canvas { - - /** - * Special layout implementation to position the combo's drop-down Button - * within its Text. - */ - protected class DropComboLayout extends VLayout { - - protected Point computeSize(VPanel panel, int wHint, int hHint, - boolean flushCache) { - Point size = text.computeSize(SWT.DEFAULT, SWT.DEFAULT); - if (button.getVisible()) { - size.x += size.y; - } - - size.y += textMarginHeight; - - if (wHint != SWT.DEFAULT) { - size.x = Math.min(size.x, wHint); - } - if (hHint != SWT.DEFAULT) { - size.y = Math.min(size.y, hHint); - } - return size; - } - - protected void layout(VPanel panel, boolean flushCache) { - Rectangle cRect = panel.getClientArea(); - - Point tSize = text.computeSize(SWT.DEFAULT, SWT.DEFAULT); - tSize.y += textMarginHeight; - - Point bSize = button.getVisible() ? new Point(tSize.y, tSize.y) - : new Point(0, 0); - - if (leftAlign) { - text.setBounds(cRect.x + bSize.x, cRect.y - + (win32 ? getBorderWidth() : 0), - cRect.width - bSize.x, tSize.y); - button.setBounds(cRect.x, cRect.y, bSize.x, bSize.y); - } else { - text.setBounds(cRect.x + (win32 ? 1 : 0), cRect.y - + (win32 ? 1 : 0), cRect.width - bSize.x - - (win32 ? 2 : 0), tSize.y - (win32 ? 2 : 0)); - button.setBounds( - win32 ? (cRect.x + cRect.width - cRect.height + 1) - : (cRect.x + cRect.width - bSize.x), cRect.y, - win32 ? (cRect.height - 1) : bSize.x, - win32 ? cRect.height : bSize.y); - } - } - } - - /** - * true if the platform is carbon, false otherwise - */ - protected static final boolean carbon = "carbon".equals(SWT.getPlatform()); //$NON-NLS-1$ - - /** - * true if the platform is gtk, false otherwise - */ - protected static final boolean gtk = "gtk".equals(SWT.getPlatform()); //$NON-NLS-1$ - - /** - * true if the platform is win32, false otherwise - */ - protected static final boolean win32 = "win32".equals(SWT.getPlatform()); //$NON-NLS-1$ - - /** - * A constant value used to pad the computed height for this widget, so that - * the combo's Button will fit without clipping its top and bottom borders. - */ - protected static final int textMarginHeight = win32 ? 4 : 0; - - /** - * A style constant indicating that this combo will only have a drop down - * button, rather than a button and a text box. - */ - protected static final int BUTTON_ONLY = 0; - - /** - * A constant indicating that the drop down button is always visible. Valid - * only when style is DROP_DOWN. - * - * @see #BUTTON_AUTO - * @see #BUTTON_NEVER - */ - protected static final int BUTTON_ALWAYS = 1; - - /** - * A constant indicating that the drop down button is never visible. Valid - * only when style is DROP_DOWN. - *

- * This setting may be useful if the subclass of this BaseCombo allows - * programmatic opening and closing of the drop down shell via - * {@link #setOpen(boolean)}, or a similar method. - *

- * - * @see #BUTTON_AUTO - * @see #BUTTON_ALWAYS - * @see #setOpen(boolean) - * @see #setOpen(boolean, Runnable) - */ - protected static final int BUTTON_NEVER = 2; - - /** - * A constant indicating that the drop down button is visible when the text - * box has the focus, and is hidden otherwise. Valid only when style is - * DROP_DOWN. - * - * @see #BUTTON_ALWAYS - * @see #BUTTON_NEVER - */ - protected static final int BUTTON_AUTO = 3; - - /** - * boolean to disable button on open state. - */ - boolean buttonActive = true; - - private static int checkStyle(int style) { - int rstyle = SWT.NONE; - if ((style & SWT.BORDER) != 0) { - if (win32 || (style & SWT.SIMPLE) != 0) { - rstyle |= SWT.BORDER; - } - } - if (win32) { - rstyle |= SWT.DOUBLE_BUFFERED; - } - return rstyle; - } - - /** - * A recursive method to find out if a composite is an ancestor of a - * control. - * - * @param control - * @param composite - * @return true if the composite is an ancestor, false otherwise. - */ - protected static boolean containsControl(Control control, - Composite composite) { - if (composite != null && !composite.isDisposed()) { - Control[] children = composite.getChildren(); - for (Control child : children) { - if (!child.isDisposed()) { - if (child == control) { - return true; - } else if (child instanceof Composite) { - return containsControl(control, (Composite) child); - } - } - } - } - return false; - } - - /** - * The VPanel that is the base of this widget. If the style is SIMPLE, this - * panel will be the base of the content area, otherwise, it is the base of - * the text/button area. - */ - protected VPanel panel = null; - - /** - * The Button widget of a DROP_DOWN style combo. This value may be null -- - * protect all references to this field with the checkButton() method. - */ - protected VButton button = null; - - /** - * True if a default image should be used for the button; false otherwise - - * as is the case when an image is set using {@link #setButtonImage(Image)} - * - * @see #setButtonImage(Image) - */ - protected boolean defaultButtonImage = true; - - /** - * The Text widget of a DROP_DOWN style combo. This value may be null -- - * protect all references to this field with the checkText() method. - */ - protected VNative text = null; - - /** - * The popup Shell widget of a DROP_DOWN style combo. This value may be null - * -- protect all references to this field with the checkContentShell() - * method. - */ - protected Shell contentShell = null; - - /** - * The widget contents of the popup Shell in a DROP_DOWN combo or the full - * contents of a SIMPLE combo. This value may be null -- protect all - * references to this field with the checkContent() method. - */ - protected Control content; - - /** - * The style bits requested. NOTE: this may not match the value returned by - * {@link #getStyle()} if invalid bits were requested. - */ - protected int style; - - /** - * Flag to indicate that this is a SIMPLE style combo. - */ - protected boolean simple; - - /** - * Flag to indicate that this combo's BUTTON should be displayed on the left - * side of its Text. - */ - protected boolean leftAlign = false; - - private int buttonVisibility; - - private Listener buttonVisibilityListener; - - private boolean dropDown; - - private boolean open = false; - - private boolean holdOpen = false; - - private VControl positionControl; - - private VControl stretchControl; - - private Listener textListener; - private Listener shellListener; - private Listener comboListener = new Listener() { - public void handleEvent(Event event) { - switch (event.type) { - case SWT.Move: - if (isOpen()) { - setOpen(false); - } - break; - case SWT.Resize: - if (isOpen()) { - setOpen(false); - } - layout(true); - break; - } - } - }; - - private Listener disposeListener = new Listener() { - public void handleEvent(Event event) { - if (!isDisposed()) { - getShell().removeListener(SWT.Deactivate, comboListener); - if (checkContentShell()) { - contentShell.dispose(); - } - } - } - }; - - /** - * Main constructor -- must be called by all subclasses in their own - * constructors. - *

- * SWT.TOGGLE, SWT.PUSH, SWT.ARROW, SWT.FLAT, SWT.TRAIL, SWT.LEAD, - * SWT.BORDER, SWT.SIMPLE, SWT.DROP_DOWN - *

- * - * @param parent - * the visual parent of this widget - * @param style - * the requested SWT style bitmask for this widget - */ - public BaseCombo(Composite parent, int style) { - super(parent, checkStyle(style)); - - panel = new VPanel(this, SWT.NONE); - panel.setWidget(this); - - init(style); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when keys are pressed and released on the system keyboard, by sending - * it one of the messages defined in the KeyListener - * interface. - *

- * When a key listener is added to a control, the control - * will take part in widget traversal. By default, all - * traversal keys (such as the tab key and so on) are - * delivered to the control. In order for a control to take - * part in traversal, it should listen for traversal events. - * Otherwise, the user can traverse into a control but not - * out. Note that native controls such as table and tree - * implement key traversal in the operating system. It is - * not necessary to add traversal listeners for these controls, - * unless you want to override the default traversal. - *

- * @param listener the listener which should be notified - * - * @exception IllegalArgumentException
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see KeyListener - * @see #removeKeyListener - */ - public void addKeyListener (KeyListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (checkText()) { - text.getControl().addKeyListener(listener); - } - } - - /** - * Adds the listener to the collection of listeners who will be notified - * when the receiver's text is modified, by sending it one of the messages - * defined in the ModifyListener interface.
- * Note that this is NOT the correct way to listen for changes in the - * underlying model for the combo. This should be provided by some other - * mechanism, such as a {@link SelectionListener}. - * - * @param listener - * the listener which should be notified - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #removeModifyListener - */ - public void addModifyListener(ModifyListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (checkText()) { - text.getControl().addModifyListener(listener); - } - } - - private void addTextListener() { - text.getControl().addListener(SWT.KeyDown, textListener); - text.getControl().addListener(SWT.Modify, textListener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when traversal events occur, by sending it - * one of the messages defined in the TraverseListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see TraverseListener - * @see #removeTraverseListener - */ - public void addTraverseListener (TraverseListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (checkText()) { - text.getControl().addTraverseListener(listener); - } - } - - - /** - * @return true if the {@link #button} field is in a fit state to be used - */ - protected boolean checkButton() { - return (button != null && !button.isDisposed()); - } - - /** - * @return true if the {@link #content} field is in a fit state to be used - */ - protected boolean checkContent() { - return (content != null && !content.isDisposed()); - } - - /** - * @return true if the {@link #contentShell} field is in a fit state to be - * used - */ - protected boolean checkContentShell() { - return (contentShell != null && !contentShell.isDisposed()); - } - - /** - * @return true if the {@link #text} field is in a fit state to be used - */ - protected boolean checkText() { - return (text != null && !text.isDisposed()); - } - - private void createButton(int style) { - int mask = BUTTON_ONLY | SWT.TOGGLE | SWT.PUSH | SWT.ARROW | SWT.FLAT; - int buttonStyle = style & mask; - - button = new VButton(panel, buttonStyle | SWT.NO_FOCUS); - if ((style & BUTTON_ONLY) == 0) { - button.setMargins(0, 0); - } - button.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - if(buttonActive) { - setOpen(!isOpen()); - } - } - }); - - if (win32) { - button.setPainter(new VButtonPainter() { - @Override - public void paintBackground(VControl control, Event e) { - VButton button = (VButton) control; - if (button.hasState(VControl.STATE_ACTIVE)) { - Rectangle r = button.getBounds(); - e.gc.setBackground(e.display - .getSystemColor(SWT.COLOR_GRAY)); - e.gc.fillRoundRectangle(r.x, r.y, r.width - 1, - r.height - 1, 2, 2); - e.gc.drawRoundRectangle(r.x, r.y, r.width - 1, - r.height - 1, 2, 2); - } - } - }); - } - } - - private void createContentShell() { - contentShell = new Shell(getShell(), SWT.NO_TRIM | SWT.ON_TOP); - contentShell.addListener(SWT.Close, shellListener); - contentShell.addListener(SWT.Deactivate, shellListener); - } - - private void createText(int style) { - textListener = new Listener() { - public void handleEvent(Event event) { - switch (event.type) { - case SWT.KeyDown: - if (event.stateMask == SWT.CTRL && event.keyCode == ' ') { - event.doit = false; - setOpen(true); - } - break; - case SWT.Modify: - Event e = new Event(); - e.time = event.time; - setModifyEventProperties(e); - notifyListeners(SWT.Modify, e); - break; - } - } - }; - - int mask = SWT.TRAIL | SWT.LEAD; - int textStyle = SWT.SINGLE | (style & mask); - if (!win32 && (style & SWT.BORDER) != 0) { - textStyle |= SWT.BORDER; - } - - text = VNative.create(Text.class, panel, textStyle); - addTextListener(); - } - - /** - * @param image - */ - protected final void doSetButtonImage(Image image) { - if (checkButton()) { - button.setImage(image); - } - } - - /** - * @return the Control that was set as this popup shell's content with - * setContent(Control) - */ - protected Control getContent() { - return content; - } - - /** - * @return the content shell - */ - protected Shell getContentShell() { - if (contentShell == null) { - createContentShell(); - } - return contentShell; - } - - /** - * Returns the editable state. - * - * @return whether or not the receiver is editable - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean getEditable() { - return checkText() ? text.getControl().getEditable() : getEnabled(); - } - - /** - * Fixes bug 181442: [CDateTime] Incorrect getEnabled() - */ - public boolean getEnabled() { - return checkText() ? text.getEnabled() : super.getEnabled(); - } - - /** - * @return the state of the holdOpen flag - */ - protected boolean getHoldOpen() { - return holdOpen; - } - - /** - * returns the menu for this combo - */ - public Menu getMenu() { - if (checkText()) { - return text.getMenu(); - } - return super.getMenu(); - } - - /** - * @return the stretch control - */ - protected VControl getStretchControl() { - return stretchControl; - } - - public int getStyle() { - return style; - } - - /** - * Returns the text of this combo - * - * @return the combo's text - */ - public String getText() { - return checkText() ? text.getText() : ""; //$NON-NLS-1$ - } - - private void init(int style) { - this.style = style; - simple = (style & SWT.SIMPLE) != 0; - dropDown = (style & (BUTTON_ONLY | SWT.DROP_DOWN)) != 0; - leftAlign = (style & SWT.LEFT) != 0; - - if (simple) { - panel.setLayout(new VSimpleLayout()); - } else if (dropDown) { - createButton(style); - if ((style & BUTTON_ONLY) == 0) { - createText(style); - if (win32) { - setPositionControl(panel); - } else { - setPositionControl(text); - } - panel.setLayout(new DropComboLayout()); - } else { - setPositionControl(button); - panel.setLayout(new VSimpleLayout()); - } - - shellListener = new Listener() { - public void handleEvent(Event event) { - switch (event.type) { - case SWT.Close: - event.doit = false; - setOpen(false); - break; - case SWT.Deactivate: - if (!checkContent() || content.getMenu() == null - || !content.getMenu().isVisible()) { - setOpen(false); - } - break; - } - } - }; - - addListener(SWT.Move, comboListener); - addListener(SWT.Resize, comboListener); - } else { - panel.setLayout(new VSimpleLayout()); - createText(style); - } - - addListener(SWT.Dispose, disposeListener); - } - - /** - * @return true if style is CDT.DROP_DOWN - */ - protected boolean isDropDown() { - return dropDown; - } - - /** - * @return the state of the popup shell's visibility - */ - public boolean isOpen() { - return open; - } - - /** - * @return if Shell style is SWT.RIGHT_TO_LEFT - */ - protected boolean isRTL() { - return (getShell().getStyle() & SWT.RIGHT_TO_LEFT) == SWT.RIGHT_TO_LEFT; - } - - /** - * @return if style is CDT.SIMPLE - */ - protected boolean isSimple() { - return simple; - } - - /** - * called just after the content shell is set not-visible and has - * "closed" - *

- * override if you want to do something with the shell just after becoming - * not visible - *

- * - * @param popup - * @see #preClose(Shell) - */ - protected void postClose(Shell popup) { - // subclasses to implement if necessary - } - - /** - * called after the content shell is set visible and has "opened" - *

- * override if you want to do something with the shell just after becoming - * visible - *

- * - * @param popup - * @see #preOpen(Shell) - */ - protected void postOpen(Shell popup) { - // subclasses to implement if necessary - } - - /** - * called just before the content shell is set not-visible and - * "closes" - *

- * override if you want to do something with the shell prior to it becoming - * not visible - *

- * - * @param popup - * @see #postClose(Shell) - */ - protected void preClose(Shell popup) { - // subclasses to implement if necessary - } - - /** - * called just before the content shell is set visible and "opens" - *

- * override if you want to do something with the shell prior to it becoming - * visible - *

- * - * @param popup - * @see #postOpen(Shell) - */ - protected void preOpen(Shell popup) { - // subclasses to implement if necessary - } - - - /** - * Removes the listener from the collection of listeners who will - * be notified when keys are pressed and released on the system keyboard. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see KeyListener - * @see #addKeyListener - */ - public void removeKeyListener(KeyListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (checkText()) { - text.getControl().removeKeyListener(listener); - } - } - - /** - * Removes the listener from the collection of listeners who will be - * notified when the receiver's text is modified. - * - * @param listener - * the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #addModifyListener - */ - public void removeModifyListener(ModifyListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (checkText()) { - text.getControl().removeModifyListener(listener); - } - } - - private void removeTextListener() { - text.getControl().removeListener(SWT.KeyDown, textListener); - text.getControl().removeListener(SWT.Modify, textListener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when traversal events occur. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see TraverseListener - * @see #addTraverseListener - */ - public void removeTraverseListener(TraverseListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (checkText()) { - text.getControl().removeTraverseListener(listener); - } - } - - /** - * Set the alignment of the button in relation to the text box. Only valid - * if style is DROP_DOWN. - * - * @param alignment - * can be either SWT.LEFT or SWT.RIGHT. Other values have no - * effect. - */ - protected void setButtonAlignment(int alignment) { - if (SWT.LEFT == alignment) { - leftAlign = true; - } else if (SWT.RIGHT == alignment) { - leftAlign = false; - } - layout(true); - } - - /** - * Set the custom image for the drop down button. Only valid if style is - * DROP_DOWN. Passing null in will set the image to its default value. - * - * @param image - */ - protected void setButtonImage(Image image) { - doSetButtonImage(image); - } - - /** - * Set the text for the drop down button. Only valid if style is DROP_DOWN. - * Passing null will clear the text. - * - * @param text - */ - protected void setButtonText(String text) { - if (checkButton()) { - button.setText(text); - } - } - - /** - * Set the visibility style of the drop button. - *

- * The style will be forced to NEVER if the contents are null - *

- *
- *
Styles:
- *
BUTTON_ALWAYS, BUTTON_AUTO, BUTTON_MANUAL, BUTTON_NEVER
- *
- *
- *
Style BUTTON_ALWAYS:
- *
Button will always be shown - standard SWT.DROP_DOWN behaviour. The - * method setButtonVisible(boolean) has no affect with this style set
- *
Style BUTTON_AUTO:
- *
Button visibility will be handled automatically through focus events, - * popup events, as well as programmatically
- *
Style BUTTON_MANUAL:
- *
Button visibility will only be handled programmatically
- *
Style BUTTON_NEVER:
- *
Button will never be shown - standard SWT.SIMPLE behaviour. The - * method setButtonVisible(boolean) has no affect with this style set
- *
- * - * @param visibility - * the visibility style constant - * @see #setButtonVisible(boolean) - */ - protected void setButtonVisibility(int visibility) { - buttonVisibility = visibility; - setButtonVisible(false); - if (buttonVisibility == BUTTON_AUTO) { - buttonVisibilityListener = new Listener() { - public void handleEvent(Event event) { - switch (event.type) { - case SWT.FocusIn: - setButtonVisible(true); - break; - case SWT.FocusOut: - setButtonVisible(false); - break; - } - } - }; - addListener(SWT.FocusIn, buttonVisibilityListener); - addListener(SWT.FocusOut, buttonVisibilityListener); - } else { - if (buttonVisibilityListener != null) { - removeListener(SWT.FocusIn, buttonVisibilityListener); - removeListener(SWT.FocusOut, buttonVisibilityListener); - buttonVisibilityListener = null; - } - } - } - - /** - * Set the visible state of the button - *

- * Note: This method is only useful when the button's visibility style is - * either AUTO or MANUAL. - *

- * - * @param visible - * @see #setButtonVisibility(int) - */ - protected void setButtonVisible(boolean visible) { - - // bug 352689 - if (!checkButton()) - return; - - if (BUTTON_ALWAYS == buttonVisibility) { - visible = true; - } else if (BUTTON_NEVER == buttonVisibility) { - visible = false; - } - - button.setVisible(visible); - - layout(true); - update(); - } - - /** - * set the content of the popup shell - *

- * Can be a single control, or a Composite consisting of many controls - *

- * - * @param content - */ - protected void setContent(Control content) { - this.content = content; - if (this.content != null) { - if (!simple) { - this.content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, - true, true)); - } - } - } - - /** - * Called when the popup shell has been open, this method provides a - * location for subclasses to set the focus to the content. - * - * @return true if the focus was set, false otherwise - */ - protected abstract boolean setContentFocus(); - - /** - * Sets the editable state. - * - * @param editable - * the new editable state - */ - public void setEditable(boolean editable) { - panel.setStyle(SWT.READ_ONLY, !editable); - if (checkButton()) { - button.setEnabled(editable); - } - if (checkText()) { - if (editable != text.getControl().getEditable()) { - text.getControl().setEditable(editable); - if (editable) { - addTextListener(); - } else { - removeTextListener(); - } - } - } - } - - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - panel.setEnabled(enabled); - } - - public boolean setFocus() { - return panel.setFocus(); - } - - /** - * @see org.eclipse.swt.widgets.Canvas#setFont(org.eclipse.swt.graphics.Font) - */ - public void setFont(Font font) { - super.setFont(font); - if (checkButton()) { - button.setFont(font); - } - if (checkText()) { - text.setFont(font); - } - if (checkContent()) { - if( content != this ){ - content.setFont(font); - } - } - } - - /** - * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) - */ - public void setBackground(Color color) { - super.setBackground(color); - if (checkButton()) { - button.setBackground(color); - } - if (checkText()) { - text.setBackground(color); - } - if (checkContent()) { - if( content != this ){ - content.setBackground(color); - } - } - } - - /** - * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color) - */ - public void setForeground(Color color) { - super.setForeground(color); - if (checkButton()) { - button.setForeground(color); - } - if (checkText()) { - text.setForeground(color); - } - if (checkContent()) { - if( content != this ){ - content.setForeground(color); - } - } - - } - - /** - * if holdOpen is true, the popup shell will not close regardless of events - * and/or calls to popUp(false) until holdOpen is first set false - *

- * merely sets the holdOpen flag, does not change popup visibility state - *

- * - * @param holdOpen - */ - protected void setHoldOpen(boolean holdOpen) { - this.holdOpen = holdOpen; - } - - /** - * Sets the menu for the Text widget of this DropCombo - *

- * Note that setting the menu to null causes the native menu to be used - *

- *

- * If the intent is to disable the menu, then set it to a blank menu - *

- */ - public void setMenu(Menu menu) { - if (checkText()) { - text.getControl().setMenu(menu); - } else { - super.setMenu(menu); - } - } - - /** - * Provides a chance for subclasses to set the properties of the modify - * event called when the text is modified. Not valid if style is SIMPLE. - *

- * For example, CDateTime overrides this method to set the data field to the - * current time:
- * e.data = calendar.getTime(); - *

- * - * @param e - */ - protected void setModifyEventProperties(Event e) { - // subclasses to implement - } - - /** - * Convenience method for BaseCombo:setOpen(boolean, Runnable), omitting optional runnable. - * - * @param open - * true to open the popup (date/time picker) shell, false to close it. - *
- *
- * @see BaseCombo#setOpen(boolean, Runnable) - */ - protected void setOpen(boolean open) { - if (open == this.open) { - return; - } - setOpen(open, null); - } - - /** - * If 'open' is true, then open the popup shell (time/date picker) (set to visible)
- * If 'open' is false, close the popup shell (set to not visible)
- * If content == null or isOpen() == open this - * method simply returns.
- * If contentShell == null then contentShell will be created. - * - * @param open - * true to open the popup (date/time picker) shell, false to close it. - * @param callback - * an optional runnable to be run when the operation completes. - *
- *
- * @see BaseCombo#setOpen(boolean) - */ - protected synchronized void setOpen(boolean open, final Runnable callback) { - buttonActive = false; - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=198240 - // Avoid infinite loop: - // Button starts close - // Close triggers SWT.Deactivate event - // Deactivate listener calls setOpen(false) - if (isOpen() == open) { - return; - } - - if (content == null || content.isDisposed()) { - if (contentShell != null) { - contentShell.dispose(); - contentShell = null; - } - this.open = false; - return; - } - - if (contentShell == null || contentShell.isDisposed()) { - createContentShell(); - } - - if (getShell() != contentShell.getParent()) { - content.setParent(this); - contentShell.dispose(); - contentShell = null; - createContentShell(); - } - - if (content.getParent() != contentShell) { - content.setParent(contentShell); - } - - if (!open) { - if (!holdOpen) { - this.open = false; - - preClose(contentShell); - - // Point location = - // positionControl.getComposite().toDisplay(positionControl.getLocation()); - // Point contentLocation = contentShell.getLocation(); - // if(location.y > contentLocation.y) { - // aStyle |= Animator.UP; - // } - - Point start = contentShell.getSize(); - Point end = new Point(start.x, 0); - Runnable runnable = new Runnable() { - public void run() { - postClose(contentShell); - buttonActive = true; - - if (callback != null) { - callback.run(); - } - } - }; - - AnimationRunner runner = new AnimationRunner(); - runner.runEffect(new Resize(contentShell, start, end, 200, - new LinearInOut(), runnable, runnable)); - - if (checkText()) { - text.setFocus(); - } - } - } else { - this.open = true; - - Point size = content.computeSize(-1, -1); - content.setSize(size); - Point location = positionControl.getComposite().toDisplay( - positionControl.getLocation()); - location.y += (positionControl.getSize().y + 2); - int dHeight = positionControl.getControl().getMonitor().getClientArea().height; - if ((location.y + size.y) > dHeight) { - location.y -= (positionControl.getSize().y + size.y + 4); - // aStyle |= Animator.UP; - } - if ((stretchControl != null) - && (size.x < stretchControl.getSize().x)) { - size.x = stretchControl.getSize().x; - // contentShell.setSize(size); - } - - if (leftAlign || isRTL()) { - location.x -= positionControl.getLocation().x; - // bug 336853 - if (isRTL()) { - location.x -= getBounds().width; - } - - } else { - - location.x += (positionControl.getSize().x - size.x); - - // Edge detection - Monitor monitor = positionControl.getControl().getMonitor(); - Rectangle monitorBounds = monitor.getBounds(); - location.x = Math.max(monitorBounds.x, location.x); - - } - if (win32) { - location.x += 2; - } else if (carbon) { - location.y += 8; - } - - contentShell.setBounds(location.x, location.y, size.x, 0); - - // chance for subclasses to do something before the shell becomes - // visible - preOpen(contentShell); - - Point start = new Point(size.x, 0); - Point end = new Point(size.x, size.y); - Runnable runnable = new Runnable() { - public void run() { - setContentFocus(); - postOpen(contentShell); - if (callback != null) { - callback.run(); - } - } - }; - - contentShell.setVisible(true); - AnimationRunner runner = new AnimationRunner(); - runner.runEffect(new Resize(contentShell, start, end, 200, - new LinearInOut(), runnable, runnable)); - contentShell.setRedraw(true); - } - if (BUTTON_AUTO == buttonVisibility) { - setButtonVisible(!open); - } - } - - /** - * sets the control to which the popup will align itself - *

- * the control does not necessarily need to be "this" or the button, but - * will default to "this" if positionControl == null - *

- * - * @param positionControl - */ - protected void setPositionControl(VControl positionControl) { - if (positionControl == null) { - this.positionControl = panel; - } else { - this.positionControl = positionControl; - } - } - - /** - * If stretch is false, then the width of the popup will be set to its - * preferred width (via computeSize(SWT.DEFAULT, SWT.DEFAULT)) - *

- * However, if stretchControl is true, the width of the popup will be - * stretched to equal the width of this control (if, however, popup's - * preferred width is greater than this control's width popup will not be - * shrunk down) - *

- * - * @param stretch - */ - protected void setStretch(boolean stretch) { - this.stretchControl = stretch ? panel : null; - } - - /** - * Sets the tooltip on the text and button parts of this Composite widget. - * - * @param tooltip - * the new tooltip text - */ - public void setToolTipText(String tooltip) { - text.setToolTipText(tooltip); - button.setToolTipText(tooltip); - super.setToolTipText(tooltip); - } -} +/**************************************************************************** + * Copyright (c) 2005-2009 Jeremy Dowdall + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - SWT's CCombo was relied upon _heavily_ for example and reference + * Jeremy Dowdall - initial API and implementation + *****************************************************************************/ + +package org.eclipse.nebula.cwt.base; + +import org.eclipse.nebula.cwt.animation.AnimationRunner; +import org.eclipse.nebula.cwt.animation.effects.Resize; +import org.eclipse.nebula.cwt.animation.movement.LinearInOut; +import org.eclipse.nebula.cwt.v.VButton; +import org.eclipse.nebula.cwt.v.VButtonPainter; +import org.eclipse.nebula.cwt.v.VControl; +import org.eclipse.nebula.cwt.v.VLayout; +import org.eclipse.nebula.cwt.v.VNative; +import org.eclipse.nebula.cwt.v.VPanel; +import org.eclipse.nebula.cwt.v.VSimpleLayout; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Monitor; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * The AbstractCombo is an abstract class which provides the basic functionality + * for a button with a DROP_DOWN, or "popup", shell component. When the user + * selects the button the shell is set visible and the SWT Components which have + * been placed on the "content" Composite will be shown. + */ +public abstract class BaseCombo extends Canvas { + + /** + * Special layout implementation to position the combo's drop-down Button + * within its Text. + */ + protected class DropComboLayout extends VLayout { + + protected Point computeSize(VPanel panel, int wHint, int hHint, + boolean flushCache) { + Point size = text.computeSize(SWT.DEFAULT, SWT.DEFAULT); + if (button.getVisible()) { + size.x += size.y; + } + + size.y += textMarginHeight; + + if (wHint != SWT.DEFAULT) { + size.x = Math.min(size.x, wHint); + } + if (hHint != SWT.DEFAULT) { + size.y = Math.min(size.y, hHint); + } + return size; + } + + protected void layout(VPanel panel, boolean flushCache) { + Rectangle cRect = panel.getClientArea(); + + Point tSize = text.computeSize(SWT.DEFAULT, SWT.DEFAULT); + tSize.y += textMarginHeight; + + Point bSize = button.getVisible() ? new Point(tSize.y, tSize.y) + : new Point(0, 0); + + if (leftAlign) { + text.setBounds(cRect.x + bSize.x, cRect.y + + (win32 ? getBorderWidth() : 0), + cRect.width - bSize.x, tSize.y); + button.setBounds(cRect.x, cRect.y, bSize.x, bSize.y); + } else { + text.setBounds(cRect.x + (win32 ? 1 : 0), cRect.y + + (win32 ? 1 : 0), cRect.width - bSize.x + - (win32 ? 2 : 0), tSize.y - (win32 ? 2 : 0)); + button.setBounds( + win32 ? (cRect.x + cRect.width - cRect.height + 1) + : (cRect.x + cRect.width - bSize.x), cRect.y, + win32 ? (cRect.height - 1) : bSize.x, + win32 ? cRect.height : bSize.y); + } + } + } + + /** + * true if the platform is carbon, false otherwise + */ + protected static final boolean carbon = "carbon".equals(SWT.getPlatform()); //$NON-NLS-1$ + + /** + * true if the platform is gtk, false otherwise + */ + protected static final boolean gtk = "gtk".equals(SWT.getPlatform()); //$NON-NLS-1$ + + /** + * true if the platform is win32, false otherwise + */ + protected static final boolean win32 = "win32".equals(SWT.getPlatform()); //$NON-NLS-1$ + + /** + * A constant value used to pad the computed height for this widget, so that + * the combo's Button will fit without clipping its top and bottom borders. + */ + protected static final int textMarginHeight = win32 ? 4 : 0; + + /** + * A style constant indicating that this combo will only have a drop down + * button, rather than a button and a text box. + */ + protected static final int BUTTON_ONLY = 0; + + /** + * A constant indicating that the drop down button is always visible. Valid + * only when style is DROP_DOWN. + * + * @see #BUTTON_AUTO + * @see #BUTTON_NEVER + */ + protected static final int BUTTON_ALWAYS = 1; + + /** + * A constant indicating that the drop down button is never visible. Valid + * only when style is DROP_DOWN. + *

+ * This setting may be useful if the subclass of this BaseCombo allows + * programmatic opening and closing of the drop down shell via + * {@link #setOpen(boolean)}, or a similar method. + *

+ * + * @see #BUTTON_AUTO + * @see #BUTTON_ALWAYS + * @see #setOpen(boolean) + * @see #setOpen(boolean, Runnable) + */ + protected static final int BUTTON_NEVER = 2; + + /** + * A constant indicating that the drop down button is visible when the text + * box has the focus, and is hidden otherwise. Valid only when style is + * DROP_DOWN. + * + * @see #BUTTON_ALWAYS + * @see #BUTTON_NEVER + */ + protected static final int BUTTON_AUTO = 3; + + /** + * boolean to disable button on open state. + */ + boolean buttonActive = true; + + private static int checkStyle(int style) { + int rstyle = SWT.NONE; + if ((style & SWT.BORDER) != 0) { + if (win32 || (style & SWT.SIMPLE) != 0) { + rstyle |= SWT.BORDER; + } + } + if (win32) { + rstyle |= SWT.DOUBLE_BUFFERED; + } + return rstyle; + } + + /** + * A recursive method to find out if a composite is an ancestor of a + * control. + * + * @param control + * @param composite + * @return true if the composite is an ancestor, false otherwise. + */ + protected static boolean containsControl(Control control, + Composite composite) { + if (composite != null && !composite.isDisposed()) { + Control[] children = composite.getChildren(); + for (Control child : children) { + if (!child.isDisposed()) { + if (child == control) { + return true; + } else if (child instanceof Composite) { + return containsControl(control, (Composite) child); + } + } + } + } + return false; + } + + /** + * The VPanel that is the base of this widget. If the style is SIMPLE, this + * panel will be the base of the content area, otherwise, it is the base of + * the text/button area. + */ + protected VPanel panel = null; + + /** + * The Button widget of a DROP_DOWN style combo. This value may be null -- + * protect all references to this field with the checkButton() method. + */ + protected VButton button = null; + + /** + * True if a default image should be used for the button; false otherwise - + * as is the case when an image is set using {@link #setButtonImage(Image)} + * + * @see #setButtonImage(Image) + */ + protected boolean defaultButtonImage = true; + + /** + * The Text widget of a DROP_DOWN style combo. This value may be null -- + * protect all references to this field with the checkText() method. + */ + protected VNative text = null; + + /** + * The popup Shell widget of a DROP_DOWN style combo. This value may be null + * -- protect all references to this field with the checkContentShell() + * method. + */ + protected Shell contentShell = null; + + /** + * The widget contents of the popup Shell in a DROP_DOWN combo or the full + * contents of a SIMPLE combo. This value may be null -- protect all + * references to this field with the checkContent() method. + */ + protected Control content; + + /** + * The style bits requested. NOTE: this may not match the value returned by + * {@link #getStyle()} if invalid bits were requested. + */ + protected int style; + + /** + * Flag to indicate that this is a SIMPLE style combo. + */ + protected boolean simple; + + /** + * Flag to indicate that this combo's BUTTON should be displayed on the left + * side of its Text. + */ + protected boolean leftAlign = false; + + private int buttonVisibility; + + private Listener buttonVisibilityListener; + + private boolean dropDown; + + private boolean open = false; + + private boolean holdOpen = false; + + private VControl positionControl; + + private VControl stretchControl; + + private Listener textListener; + private Listener shellListener; + private Listener comboListener = new Listener() { + public void handleEvent(Event event) { + switch (event.type) { + case SWT.Move: + if (isOpen()) { + setOpen(false); + } + break; + case SWT.Resize: + if (isOpen()) { + setOpen(false); + } + layout(true); + break; + } + } + }; + + private Listener disposeListener = new Listener() { + public void handleEvent(Event event) { + if (!isDisposed()) { + getShell().removeListener(SWT.Deactivate, comboListener); + if (checkContentShell()) { + contentShell.dispose(); + } + } + } + }; + + /** + * Main constructor -- must be called by all subclasses in their own + * constructors. + *

+ * SWT.TOGGLE, SWT.PUSH, SWT.ARROW, SWT.FLAT, SWT.TRAIL, SWT.LEAD, + * SWT.BORDER, SWT.SIMPLE, SWT.DROP_DOWN + *

+ * + * @param parent + * the visual parent of this widget + * @param style + * the requested SWT style bitmask for this widget + */ + public BaseCombo(Composite parent, int style) { + super(parent, checkStyle(style)); + + panel = new VPanel(this, SWT.NONE); + panel.setWidget(this); + + init(style); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when keys are pressed and released on the system keyboard, by sending + * it one of the messages defined in the KeyListener + * interface. + *

+ * When a key listener is added to a control, the control + * will take part in widget traversal. By default, all + * traversal keys (such as the tab key and so on) are + * delivered to the control. In order for a control to take + * part in traversal, it should listen for traversal events. + * Otherwise, the user can traverse into a control but not + * out. Note that native controls such as table and tree + * implement key traversal in the operating system. It is + * not necessary to add traversal listeners for these controls, + * unless you want to override the default traversal. + *

+ * @param listener the listener which should be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see KeyListener + * @see #removeKeyListener + */ + public void addKeyListener (KeyListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (checkText()) { + text.getControl().addKeyListener(listener); + } + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the receiver's text is modified, by sending it one of the messages + * defined in the ModifyListener interface.
+ * Note that this is NOT the correct way to listen for changes in the + * underlying model for the combo. This should be provided by some other + * mechanism, such as a {@link SelectionListener}. + * + * @param listener + * the listener which should be notified + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #removeModifyListener + */ + public void addModifyListener(ModifyListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (checkText()) { + text.getControl().addModifyListener(listener); + } + } + + private void addTextListener() { + text.getControl().addListener(SWT.KeyDown, textListener); + text.getControl().addListener(SWT.Modify, textListener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when traversal events occur, by sending it + * one of the messages defined in the TraverseListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see TraverseListener + * @see #removeTraverseListener + */ + public void addTraverseListener (TraverseListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (checkText()) { + text.getControl().addTraverseListener(listener); + } + } + + + /** + * @return true if the {@link #button} field is in a fit state to be used + */ + protected boolean checkButton() { + return (button != null && !button.isDisposed()); + } + + /** + * @return true if the {@link #content} field is in a fit state to be used + */ + protected boolean checkContent() { + return (content != null && !content.isDisposed()); + } + + /** + * @return true if the {@link #contentShell} field is in a fit state to be + * used + */ + protected boolean checkContentShell() { + return (contentShell != null && !contentShell.isDisposed()); + } + + /** + * @return true if the {@link #text} field is in a fit state to be used + */ + protected boolean checkText() { + return (text != null && !text.isDisposed()); + } + + private void createButton(int style) { + int mask = BUTTON_ONLY | SWT.TOGGLE | SWT.PUSH | SWT.ARROW | SWT.FLAT; + int buttonStyle = style & mask; + + button = new VButton(panel, buttonStyle | SWT.NO_FOCUS); + if ((style & BUTTON_ONLY) == 0) { + button.setMargins(0, 0); + } + button.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + if(buttonActive) { + setOpen(!isOpen()); + } + } + }); + + if (win32) { + button.setPainter(new VButtonPainter() { + @Override + public void paintBackground(VControl control, Event e) { + VButton button = (VButton) control; + if (button.hasState(VControl.STATE_ACTIVE)) { + Rectangle r = button.getBounds(); + e.gc.setBackground(e.display + .getSystemColor(SWT.COLOR_GRAY)); + e.gc.fillRoundRectangle(r.x, r.y, r.width - 1, + r.height - 1, 2, 2); + e.gc.drawRoundRectangle(r.x, r.y, r.width - 1, + r.height - 1, 2, 2); + } + } + }); + } + } + + private void createContentShell() { + contentShell = new Shell(getShell(), SWT.NO_TRIM | SWT.ON_TOP); + contentShell.addListener(SWT.Close, shellListener); + contentShell.addListener(SWT.Deactivate, shellListener); + } + + private void createText(int style) { + textListener = new Listener() { + public void handleEvent(Event event) { + switch (event.type) { + case SWT.KeyDown: + if (event.stateMask == SWT.CTRL && event.keyCode == ' ') { + event.doit = false; + setOpen(true); + } + break; + case SWT.Modify: + Event e = new Event(); + e.time = event.time; + setModifyEventProperties(e); + notifyListeners(SWT.Modify, e); + break; + } + } + }; + + int mask = SWT.TRAIL | SWT.LEAD; + int textStyle = SWT.SINGLE | (style & mask); + if (!win32 && (style & SWT.BORDER) != 0) { + textStyle |= SWT.BORDER; + } + + text = VNative.create(Text.class, panel, textStyle); + addTextListener(); + } + + /** + * @param image + */ + protected final void doSetButtonImage(Image image) { + if (checkButton()) { + button.setImage(image); + } + } + + /** + * @return the Control that was set as this popup shell's content with + * setContent(Control) + */ + protected Control getContent() { + return content; + } + + /** + * @return the content shell + */ + protected Shell getContentShell() { + if (contentShell == null) { + createContentShell(); + } + return contentShell; + } + + /** + * Returns the editable state. + * + * @return whether or not the receiver is editable + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean getEditable() { + return checkText() ? text.getControl().getEditable() : getEnabled(); + } + + /** + * Fixes bug 181442: [CDateTime] Incorrect getEnabled() + */ + public boolean getEnabled() { + return checkText() ? text.getEnabled() : super.getEnabled(); + } + + /** + * @return the state of the holdOpen flag + */ + protected boolean getHoldOpen() { + return holdOpen; + } + + /** + * returns the menu for this combo + */ + public Menu getMenu() { + if (checkText()) { + return text.getMenu(); + } + return super.getMenu(); + } + + /** + * @return the stretch control + */ + protected VControl getStretchControl() { + return stretchControl; + } + + public int getStyle() { + return style; + } + + /** + * Returns the text of this combo + * + * @return the combo's text + */ + public String getText() { + return checkText() ? text.getText() : ""; //$NON-NLS-1$ + } + + private void init(int style) { + this.style = style; + simple = (style & SWT.SIMPLE) != 0; + dropDown = (style & (BUTTON_ONLY | SWT.DROP_DOWN)) != 0; + leftAlign = (style & SWT.LEFT) != 0; + + if (simple) { + panel.setLayout(new VSimpleLayout()); + } else if (dropDown) { + createButton(style); + if ((style & BUTTON_ONLY) == 0) { + createText(style); + if (win32) { + setPositionControl(panel); + } else { + setPositionControl(text); + } + panel.setLayout(new DropComboLayout()); + } else { + setPositionControl(button); + panel.setLayout(new VSimpleLayout()); + } + + shellListener = new Listener() { + public void handleEvent(Event event) { + switch (event.type) { + case SWT.Close: + event.doit = false; + setOpen(false); + break; + case SWT.Deactivate: + if (!checkContent() || content.getMenu() == null + || !content.getMenu().isVisible()) { + setOpen(false); + } + break; + } + } + }; + + addListener(SWT.Move, comboListener); + addListener(SWT.Resize, comboListener); + } else { + panel.setLayout(new VSimpleLayout()); + createText(style); + } + + addListener(SWT.Dispose, disposeListener); + } + + /** + * @return true if style is CDT.DROP_DOWN + */ + protected boolean isDropDown() { + return dropDown; + } + + /** + * @return the state of the popup shell's visibility + */ + public boolean isOpen() { + return open; + } + + /** + * @return if Shell style is SWT.RIGHT_TO_LEFT + */ + protected boolean isRTL() { + return (getShell().getStyle() & SWT.RIGHT_TO_LEFT) == SWT.RIGHT_TO_LEFT; + } + + /** + * @return if style is CDT.SIMPLE + */ + protected boolean isSimple() { + return simple; + } + + /** + * called just after the content shell is set not-visible and has + * "closed" + *

+ * override if you want to do something with the shell just after becoming + * not visible + *

+ * + * @param popup + * @see #preClose(Shell) + */ + protected void postClose(Shell popup) { + // subclasses to implement if necessary + } + + /** + * called after the content shell is set visible and has "opened" + *

+ * override if you want to do something with the shell just after becoming + * visible + *

+ * + * @param popup + * @see #preOpen(Shell) + */ + protected void postOpen(Shell popup) { + // subclasses to implement if necessary + } + + /** + * called just before the content shell is set not-visible and + * "closes" + *

+ * override if you want to do something with the shell prior to it becoming + * not visible + *

+ * + * @param popup + * @see #postClose(Shell) + */ + protected void preClose(Shell popup) { + // subclasses to implement if necessary + } + + /** + * called just before the content shell is set visible and "opens" + *

+ * override if you want to do something with the shell prior to it becoming + * visible + *

+ * + * @param popup + * @see #postOpen(Shell) + */ + protected void preOpen(Shell popup) { + // subclasses to implement if necessary + } + + + /** + * Removes the listener from the collection of listeners who will + * be notified when keys are pressed and released on the system keyboard. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see KeyListener + * @see #addKeyListener + */ + public void removeKeyListener(KeyListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (checkText()) { + text.getControl().removeKeyListener(listener); + } + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the receiver's text is modified. + * + * @param listener + * the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #addModifyListener + */ + public void removeModifyListener(ModifyListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (checkText()) { + text.getControl().removeModifyListener(listener); + } + } + + private void removeTextListener() { + text.getControl().removeListener(SWT.KeyDown, textListener); + text.getControl().removeListener(SWT.Modify, textListener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when traversal events occur. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see TraverseListener + * @see #addTraverseListener + */ + public void removeTraverseListener(TraverseListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (checkText()) { + text.getControl().removeTraverseListener(listener); + } + } + + /** + * Set the alignment of the button in relation to the text box. Only valid + * if style is DROP_DOWN. + * + * @param alignment + * can be either SWT.LEFT or SWT.RIGHT. Other values have no + * effect. + */ + protected void setButtonAlignment(int alignment) { + if (SWT.LEFT == alignment) { + leftAlign = true; + } else if (SWT.RIGHT == alignment) { + leftAlign = false; + } + layout(true); + } + + /** + * Set the custom image for the drop down button. Only valid if style is + * DROP_DOWN. Passing null in will set the image to its default value. + * + * @param image + */ + protected void setButtonImage(Image image) { + doSetButtonImage(image); + } + + /** + * Set the text for the drop down button. Only valid if style is DROP_DOWN. + * Passing null will clear the text. + * + * @param text + */ + protected void setButtonText(String text) { + if (checkButton()) { + button.setText(text); + } + } + + /** + * Set the visibility style of the drop button. + *

+ * The style will be forced to NEVER if the contents are null + *

+ *
+ *
Styles:
+ *
BUTTON_ALWAYS, BUTTON_AUTO, BUTTON_MANUAL, BUTTON_NEVER
+ *
+ *
+ *
Style BUTTON_ALWAYS:
+ *
Button will always be shown - standard SWT.DROP_DOWN behaviour. The + * method setButtonVisible(boolean) has no affect with this style set
+ *
Style BUTTON_AUTO:
+ *
Button visibility will be handled automatically through focus events, + * popup events, as well as programmatically
+ *
Style BUTTON_MANUAL:
+ *
Button visibility will only be handled programmatically
+ *
Style BUTTON_NEVER:
+ *
Button will never be shown - standard SWT.SIMPLE behaviour. The + * method setButtonVisible(boolean) has no affect with this style set
+ *
+ * + * @param visibility + * the visibility style constant + * @see #setButtonVisible(boolean) + */ + protected void setButtonVisibility(int visibility) { + buttonVisibility = visibility; + setButtonVisible(false); + if (buttonVisibility == BUTTON_AUTO) { + buttonVisibilityListener = new Listener() { + public void handleEvent(Event event) { + switch (event.type) { + case SWT.FocusIn: + setButtonVisible(true); + break; + case SWT.FocusOut: + setButtonVisible(false); + break; + } + } + }; + addListener(SWT.FocusIn, buttonVisibilityListener); + addListener(SWT.FocusOut, buttonVisibilityListener); + } else { + if (buttonVisibilityListener != null) { + removeListener(SWT.FocusIn, buttonVisibilityListener); + removeListener(SWT.FocusOut, buttonVisibilityListener); + buttonVisibilityListener = null; + } + } + } + + /** + * Set the visible state of the button + *

+ * Note: This method is only useful when the button's visibility style is + * either AUTO or MANUAL. + *

+ * + * @param visible + * @see #setButtonVisibility(int) + */ + protected void setButtonVisible(boolean visible) { + + // bug 352689 + if (!checkButton()) + return; + + if (BUTTON_ALWAYS == buttonVisibility) { + visible = true; + } else if (BUTTON_NEVER == buttonVisibility) { + visible = false; + } + + button.setVisible(visible); + + layout(true); + update(); + } + + /** + * set the content of the popup shell + *

+ * Can be a single control, or a Composite consisting of many controls + *

+ * + * @param content + */ + protected void setContent(Control content) { + this.content = content; + if (this.content != null) { + if (!simple) { + this.content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, + true, true)); + } + } + } + + /** + * Called when the popup shell has been open, this method provides a + * location for subclasses to set the focus to the content. + * + * @return true if the focus was set, false otherwise + */ + protected abstract boolean setContentFocus(); + + /** + * Sets the editable state. + * + * @param editable + * the new editable state + */ + public void setEditable(boolean editable) { + panel.setStyle(SWT.READ_ONLY, !editable); + if (checkButton()) { + button.setEnabled(editable); + } + if (checkText()) { + if (editable != text.getControl().getEditable()) { + text.getControl().setEditable(editable); + if (editable) { + addTextListener(); + } else { + removeTextListener(); + } + } + } + } + + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + panel.setEnabled(enabled); + } + + public boolean setFocus() { + return panel.setFocus(); + } + + /** + * @see org.eclipse.swt.widgets.Canvas#setFont(org.eclipse.swt.graphics.Font) + */ + public void setFont(Font font) { + super.setFont(font); + if (checkButton()) { + button.setFont(font); + } + if (checkText()) { + text.setFont(font); + } + if (checkContent()) { + if( content != this ){ + content.setFont(font); + } + } + } + + /** + * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) + */ + public void setBackground(Color color) { + super.setBackground(color); + if (checkButton()) { + button.setBackground(color); + } + if (checkText()) { + text.setBackground(color); + } + if (checkContent()) { + if( content != this ){ + content.setBackground(color); + } + } + } + + /** + * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color) + */ + public void setForeground(Color color) { + super.setForeground(color); + if (checkButton()) { + button.setForeground(color); + } + if (checkText()) { + text.setForeground(color); + } + if (checkContent()) { + if( content != this ){ + content.setForeground(color); + } + } + + } + + /** + * if holdOpen is true, the popup shell will not close regardless of events + * and/or calls to popUp(false) until holdOpen is first set false + *

+ * merely sets the holdOpen flag, does not change popup visibility state + *

+ * + * @param holdOpen + */ + protected void setHoldOpen(boolean holdOpen) { + this.holdOpen = holdOpen; + } + + /** + * Sets the menu for the Text widget of this DropCombo + *

+ * Note that setting the menu to null causes the native menu to be used + *

+ *

+ * If the intent is to disable the menu, then set it to a blank menu + *

+ */ + public void setMenu(Menu menu) { + if (checkText()) { + text.getControl().setMenu(menu); + } else { + super.setMenu(menu); + } + } + + /** + * Provides a chance for subclasses to set the properties of the modify + * event called when the text is modified. Not valid if style is SIMPLE. + *

+ * For example, CDateTime overrides this method to set the data field to the + * current time:
+ * e.data = calendar.getTime(); + *

+ * + * @param e + */ + protected void setModifyEventProperties(Event e) { + // subclasses to implement + } + + /** + * Convenience method for BaseCombo:setOpen(boolean, Runnable), omitting optional runnable. + * + * @param open + * true to open the popup (date/time picker) shell, false to close it. + *
+ *
+ * @see BaseCombo#setOpen(boolean, Runnable) + */ + protected void setOpen(boolean open) { + if (open == this.open) { + return; + } + setOpen(open, null); + } + + /** + * If 'open' is true, then open the popup shell (time/date picker) (set to visible)
+ * If 'open' is false, close the popup shell (set to not visible)
+ * If content == null or isOpen() == open this + * method simply returns.
+ * If contentShell == null then contentShell will be created. + * + * @param open + * true to open the popup (date/time picker) shell, false to close it. + * @param callback + * an optional runnable to be run when the operation completes. + *
+ *
+ * @see BaseCombo#setOpen(boolean) + */ + protected synchronized void setOpen(boolean open, final Runnable callback) { + buttonActive = false; + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=198240 + // Avoid infinite loop: + // Button starts close + // Close triggers SWT.Deactivate event + // Deactivate listener calls setOpen(false) + if (isOpen() == open) { + return; + } + + if (content == null || content.isDisposed()) { + if (contentShell != null) { + contentShell.dispose(); + contentShell = null; + } + this.open = false; + return; + } + + if (contentShell == null || contentShell.isDisposed()) { + createContentShell(); + } + + if (getShell() != contentShell.getParent()) { + content.setParent(this); + contentShell.dispose(); + contentShell = null; + createContentShell(); + } + + if (content.getParent() != contentShell) { + content.setParent(contentShell); + } + + if (!open) { + if (!holdOpen) { + this.open = false; + + preClose(contentShell); + + // Point location = + // positionControl.getComposite().toDisplay(positionControl.getLocation()); + // Point contentLocation = contentShell.getLocation(); + // if(location.y > contentLocation.y) { + // aStyle |= Animator.UP; + // } + + Point start = contentShell.getSize(); + Point end = new Point(start.x, 0); + Runnable runnable = new Runnable() { + public void run() { + postClose(contentShell); + buttonActive = true; + + if (callback != null) { + callback.run(); + } + } + }; + + AnimationRunner runner = new AnimationRunner(); + runner.runEffect(new Resize(contentShell, start, end, 200, + new LinearInOut(), runnable, runnable)); + + if (checkText()) { + text.setFocus(); + } + } + } else { + this.open = true; + + Point size = content.computeSize(-1, -1); + content.setSize(size); + Point location = positionControl.getComposite().toDisplay( + positionControl.getLocation()); + location.y += (positionControl.getSize().y + 2); + int dHeight = positionControl.getControl().getMonitor().getClientArea().height; + if ((location.y + size.y) > dHeight) { + location.y -= (positionControl.getSize().y + size.y + 4); + // aStyle |= Animator.UP; + } + if ((stretchControl != null) + && (size.x < stretchControl.getSize().x)) { + size.x = stretchControl.getSize().x; + // contentShell.setSize(size); + } + + if (leftAlign || isRTL()) { + location.x -= positionControl.getLocation().x; + // bug 336853 + if (isRTL()) { + location.x -= getBounds().width; + } + + } else { + + location.x += (positionControl.getSize().x - size.x); + + // Edge detection + Monitor monitor = positionControl.getControl().getMonitor(); + Rectangle monitorBounds = monitor.getBounds(); + location.x = Math.max(monitorBounds.x, location.x); + + } + if (win32) { + location.x += 2; + } else if (carbon) { + location.y += 8; + } + + contentShell.setBounds(location.x, location.y, size.x, 0); + + // chance for subclasses to do something before the shell becomes + // visible + preOpen(contentShell); + + Point start = new Point(size.x, 0); + Point end = new Point(size.x, size.y); + Runnable runnable = new Runnable() { + public void run() { + setContentFocus(); + postOpen(contentShell); + if (callback != null) { + callback.run(); + } + } + }; + + contentShell.setVisible(true); + AnimationRunner runner = new AnimationRunner(); + runner.runEffect(new Resize(contentShell, start, end, 200, + new LinearInOut(), runnable, runnable)); + contentShell.setRedraw(true); + } + if (BUTTON_AUTO == buttonVisibility) { + setButtonVisible(!open); + } + } + + /** + * sets the control to which the popup will align itself + *

+ * the control does not necessarily need to be "this" or the button, but + * will default to "this" if positionControl == null + *

+ * + * @param positionControl + */ + protected void setPositionControl(VControl positionControl) { + if (positionControl == null) { + this.positionControl = panel; + } else { + this.positionControl = positionControl; + } + } + + /** + * If stretch is false, then the width of the popup will be set to its + * preferred width (via computeSize(SWT.DEFAULT, SWT.DEFAULT)) + *

+ * However, if stretchControl is true, the width of the popup will be + * stretched to equal the width of this control (if, however, popup's + * preferred width is greater than this control's width popup will not be + * shrunk down) + *

+ * + * @param stretch + */ + protected void setStretch(boolean stretch) { + this.stretchControl = stretch ? panel : null; + } + + /** + * Sets the tooltip on the text and button parts of this Composite widget. + * + * @param tooltip + * the new tooltip text + */ + public void setToolTipText(String tooltip) { + text.setToolTipText(tooltip); + button.setToolTipText(tooltip); + super.setToolTipText(tooltip); + } +} diff --git a/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VControl.java b/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VControl.java index 701b4d01f..dbff90b34 100644 --- a/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VControl.java +++ b/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VControl.java @@ -1,1096 +1,1096 @@ -/**************************************************************************** - * Copyright (c) 2008, 2009 Jeremy Dowdall - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jeremy Dowdall - initial API and implementation - *****************************************************************************/ - -package org.eclipse.nebula.cwt.v; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.nebula.cwt.svg.SvgDocument; -import org.eclipse.nebula.cwt.svg.SvgFragment; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.graphics.Font; -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.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Widget; - -/** - * A VControl is a class wich wraps an SWT Button to create a widget that acts - * as much like a native Button as possible while adding the following features: - *
    - *
  • The appearance of Label when the mouse is not over it and it does not - * have the focus or selection (if style is SWT.TOGGLE).
  • - *
  • Can fit seemlessly into a larger visual piece - simple set the image to - * that of its background and adjust the image's offset if necessary.
  • - *
  • Can draw polygons and ovals.
  • - *
  • Can center or otherwise align its visual display (text, image, polygon - * or oval).
  • - *
- */ -@SuppressWarnings("javadoc") -public abstract class VControl { - - public enum Type { - Button, Custom, Label, - Native, Panel, Text, Spacer - } - - /** - * true if the platform is Carbon, false otherwise - */ - public static final boolean carbon = "carbon".equals(SWT.getPlatform()); //$NON-NLS-1$ - - /** - * true if the platform is GTK, false otherwise - */ - public static final boolean gtk = "gtk".equals(SWT.getPlatform()); //$NON-NLS-1$ - - /** - * true if the platform is Win32, false otherwise - */ - public static final boolean win32 = "win32".equals(SWT.getPlatform()); //$NON-NLS-1$ - - private static final int[] Points_OK = { 2, 6, 5, 9, 10, 3, 9, 2, 5, 7, 3, - 5 }; - private static final int[] Points_Cancel = { 0, 1, 3, 4, 0, 7, 1, 8, 4, 5, - 7, 8, 8, 7, 5, 4, 8, 1, 7, 0, 4, 3, 1, 0 }; - private static final int[] Points_Left = { 9, 0, 4, 5, 9, 10 }; - private static final int[] Points_Right = { 2, 0, 7, 5, 2, 10 }; - private static final int[] Points_Up = { 10, 8, 5, 3, 0, 8 }; - private static final int[] Points_Down = { 10, 2, 5, 7, 0, 2 }; - private static final int[] Points_Add = { 2, 4, 4, 4, 4, 2, 5, 2, 5, 4, 7, - 4, 7, 5, 5, 5, 5, 7, 4, 7, 4, 5, 2, 5 }; - private static final int[] Points_Subtract = { 2, 4, 7, 4, 7, 5, 2, 5 }; - - // public static final int STATE_INACTIVE = 1 << 0; - public static final int STATE_ACTIVE = 1 << 1; - public static final int STATE_SELECTED = 1 << 2; - // public static final int STATE_FOCUS = 1 << 3; - public static final int STATE_ENABLED = 1 << 4; - public static final int STATE_MOUSE_DOWN = 1 << 5; - - protected final static boolean containsControl(Control control, - Composite composite) { - if (composite != null && !composite.isDisposed()) { - Control[] children = composite.getChildren(); - for (Control child : children) { - if (!child.isDisposed()) { - if (child == control) { - return true; - } else if (child instanceof Composite) { - return containsControl(control, (Composite) child); - } - } - } - } - return false; - } - - Composite composite; - VPanel parent; - private int style; - Menu menu; - Image image; - SvgDocument svg; - String text; - String tooltipText; - int[] points; - Color fill; - Color foreground; - Color background; - Font font; - private Cursor activeCursor; - private Cursor inactiveCursor; - - GridData layoutData; - - private int state = STATE_ENABLED; - Rectangle bounds; - int marginTop = 5; - int marginBottom = 5; - int marginLeft = 5; - int marginRight = 5; - int xAlign; - - int yAlign; - - boolean disposed = false; - boolean square = false; - int visibility = 100; - boolean scaleImage = false; - boolean customToolTip = false; - - IControlPainter painter; - Map dataMap; - Map> listeners = new HashMap>(); - private Set eventTypes = new HashSet(); - - private Listener listener = event -> { - if (event.type == SWT.FocusIn) { - if (VControl.this == VTracker.getFocusControl()) { - return; - } - } - VControl.this.handleEvent(event); - }; - - private boolean activatable = true; - - /** - * Javadoc out of date // TODO: update javadoc - * - * @param panel - * @param style - */ - public VControl(VPanel panel, int style) { - setParent(panel); - - this.style = style; - bounds = new Rectangle(0, 0, 0, 0); - - if ((style & SWT.OK) != 0) { - setPolygon(Points_OK); - if (foreground == null) setForeground(Display.getDefault().getSystemColor(SWT.COLOR_DARK_GREEN)); - } else if ((style & SWT.CANCEL) != 0) { - setPolygon(Points_Cancel); - if (foreground == null) setForeground(Display.getDefault().getSystemColor(SWT.COLOR_DARK_RED)); - } else if ((style & SWT.ARROW) != 0) { - if ((style & SWT.DOWN) != 0) { - setPolygon(Points_Down); - } else if ((style & SWT.LEFT) != 0) { - setPolygon(Points_Left); - } else if ((style & SWT.RIGHT) != 0) { - setPolygon(Points_Right); - } else if ((style & SWT.UP) != 0) { - setPolygon(Points_Up); - } - } else if ((style & SWT.UP) != 0) { - setPolygon(Points_Add); - } else if ((style & SWT.DOWN) != 0) { - setPolygon(Points_Subtract); - } - - if (foreground == null) { - setForeground(Display.getDefault() - .getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - } - if (fill == null) { - setFill(getForeground()); - } - } - - void handleEvent(Event event) { - event.data = this; - filterEvent(event); - if (listeners != null && listeners.containsKey(event.type)) { - Listener[] la = listeners.get(event.type) - .toArray(new Listener[listeners.get(event.type).size()]); - for (Listener listener : la) { - listener.handleEvent(event); - } - } - } - - void activate() { - if (activatable && hasState(STATE_ENABLED) - && setState(STATE_ACTIVE, true)) { - setState(STATE_MOUSE_DOWN, VTracker.isMouseDown()); - setCursor(activeCursor); - attachListeners(false); - if (redrawOnActivate()) { - redraw(); - } - notifyListeners(SWT.Activate); - } - } - - void addListener(int eventType) { - eventTypes.add(eventType); - if (hasState(STATE_ACTIVE)) { - composite.addListener(eventType, listener); - } - } - - public void addListener(int eventType, Listener listener) { - if (!listeners.containsKey(eventType)) { - listeners.put(eventType, new ArrayList()); - } - listeners.get(eventType).add(listener); - if (hasState(STATE_ACTIVE)) { - composite.addListener(eventType, listener); - } - } - - void attachListeners(boolean keyListeners) { - Set eventTypes = new HashSet(this.eventTypes); - eventTypes.addAll(listeners.keySet()); - for (Integer eventType : eventTypes) { - if (include(keyListeners, eventType)) { - composite.addListener(eventType, listener); - } - } - } - - void detachListeners(boolean keyListeners) { - Set eventTypes = new HashSet(this.eventTypes); - eventTypes.addAll(listeners.keySet()); - for (Integer eventType : eventTypes) { - if (include(keyListeners, eventType)) { - composite.removeListener(eventType, listener); - } - } - } - - public Point computeSize(int wHint, int hHint) { - return computeSize(wHint, hHint, true); - } - - public Point computeSize(int wHint, int hHint, boolean changed) { - if (wHint != SWT.DEFAULT && wHint < 0) { - wHint = 0; - } - if (hHint != SWT.DEFAULT && hHint < 0) { - hHint = 0; - } - - Point size = new Point(2, 2); - - if (image != null) { - Rectangle r = image.getBounds(); - size.x = r.width; - size.y = r.height; - } else if (points != null) { - if (points.length > 2) { - int minX = points[0]; - int maxX = points[0]; - int minY = points[1]; - int maxY = points[1]; - for (int i = 2; i < (points.length - 1); i++) { - minX = Math.min(minX, points[i]); - maxX = Math.max(maxX, points[i]); - minY = Math.min(minY, points[i + 1]); - maxY = Math.max(maxY, points[i + 1]); - } - size.x += maxX - minX; - size.y += maxY - minY; - } else { - size.x += points[0]; - size.y += points[1]; - } - } else if (svg != null) { - Float width = null, height = null; - for (SvgFragment fragment : svg.getFragments()) { - if (fragment.getWidth() != null) { - width = fragment.getWidth(); - } - if (fragment.getHeight() != null) { - height = fragment.getHeight(); - } - if (fragment.getViewBox() != null && fragment.getViewBox().length>3) { - width = fragment.getViewBox()[2]; - height = fragment.getViewBox()[3]; - } - } - if (width != null) { - size.x=width.intValue(); - } - if (height != null) { - size.y=height.intValue(); - } - } - - if (text != null) { - GC gc = new GC(composite); - if (getFont() != null) { - gc.setFont(getFont()); - } - Point tSize = gc.textExtent(text); - gc.dispose(); - size.x += tSize.x; - size.y += tSize.y; - } - - size.x += (marginLeft + marginRight); - size.y += (marginTop + marginBottom); - - if (square) { - size.x = size.y = Math.max(size.x, size.y); - } - - return size; - } - - public Menu createMenu() { - menu = new Menu(composite); - addListener(SWT.MouseDown, new Listener() { - public void handleEvent(Event event) { - if (SWT.MouseDown == event.type && event.button == 3) { - menu.setVisible(true); - } - } - }); - return menu; - } - - void deactivate() { - if (setState(STATE_ACTIVE, false)) { - setState(STATE_MOUSE_DOWN, false); - setCursor(inactiveCursor); - detachListeners(false); - if (redrawOnDeactivate()) { - redraw(); - } - notifyListeners(SWT.Deactivate); - } - } - - public void dispose() { - if (!disposed) { - disposed = true; - - notifyListeners(SWT.Dispose, new Event()); - - if (this == VTracker.getActiveControl()) { - VTracker.instance().deactivate(this); - } - if (this == VTracker.getFocusControl()) { - VTracker.instance().setFocusControl(null); - } - if (!composite.isDisposed()) { - detachListeners(true); - detachListeners(false); - } - setParent(null); - if (painter != null) { - painter.dispose(); - } - listeners.clear(); - listeners = null; - text = null; - // tooltip = null; - tooltipText = null; - image = null; - points = null; - } - } - - public Color getBackground() { - if (background != null) { - return background; - } - VPanel p = parent; - while (p != null) { - if (p.background != null) - return p.background; - p = p.parent; - } - return composite.getBackground(); - } - - public Rectangle getBounds() { - return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); - } - - public Rectangle getClientArea() { - return new Rectangle(bounds.x + marginLeft, bounds.y + marginTop, - bounds.width - (marginLeft + marginRight), - bounds.height - (marginTop + marginBottom)); - } - - public Point getClientSize() { - return new Point(bounds.width - (marginLeft + marginRight), - bounds.height - (marginTop + marginBottom)); - } - - public Composite getComposite() { - return composite; - } - - public Control getControl() { - return composite; - } - - public Object getData(Enum name) { - return getData(name.name()); - } - - public T getData(Enum name, Class clazz) { - return getData(name.name(), clazz); - } - - public Object getData(String name) { - if (dataMap != null) { - return dataMap.get(name); - } - return null; - } - - public T getData(String name, Class clazz) { - if (dataMap != null) { - return (T) dataMap.get(name); - } - return null; - } - - public Display getDisplay() { - return composite.getDisplay(); - } - - public boolean getEnabled() { - return hasState(STATE_ENABLED); - } - - public Font getFont() { - return font; - } - - public Color getForeground() { - return foreground; - } - - public Image getImage() { - return image; - } - - public GridData getLayoutData() { - return (layoutData != null) ? layoutData : new GridData(); - } - - protected Listener[] getListeners(int eventType) { - List l = listeners.get(eventType); - return l.toArray(new Listener[l.size()]); - } - - public Point getLocation() { - return new Point(bounds.x, bounds.y); - } - - public Rectangle getMargins() { - return new Rectangle(marginLeft, marginRight, marginTop, marginBottom); - } - - public Menu getMenu() { - return menu; - } - - public VPanel getParent() { - return parent; - } - - public Shell getShell() { - return composite.getShell(); - } - - public Point getSize() { - return new Point(bounds.width, bounds.height); - } - - public int getState() { - return state; - } - - public int getStyle() { - return style; - } - - /** - * @return the text string displayed on this VControl - */ - public String getText() { - return text; - } - - public String getToolTipText() { - return (tooltipText != null) ? tooltipText : ""; //$NON-NLS-1$ - } - - public abstract Type getType(); - - public int getVisibility() { - return visibility; - } - - public boolean getVisible() { - return visibility > 0; - } - - public Composite getWidget() { - return getParent().getWidget(); - } - - protected void filterEvent(Event event) { - // subclasses to implement if necessary - } - - public boolean hasState(int state) { - return (this.state & state) != 0; - } - - public boolean hasStyle(int style) { - return (this.style & style) != 0; - } - - private boolean include(boolean key, int type) { - if (type == SWT.Selection) { - return false; - } - if (key && (type == SWT.KeyDown || type == SWT.KeyUp - || type == SWT.Traverse)) { - return true; - } - if (!key && !(type == SWT.KeyDown || type == SWT.KeyUp - || type == SWT.Traverse)) { - return true; - } - return false; - } - - public boolean isActivatable() { - return activatable; - } - - public boolean isDisposed() { - return disposed; - } - - public boolean isEnabled() { - return getEnabled() && ((parent != null) ? parent.isEnabled() - : composite.isEnabled()); - } - - public boolean isSameWidgetAs(VControl control) { - return control != null && getWidget() == control.getWidget(); - } - - public boolean isSameWidgetAs(Widget widget) { - Composite w = getWidget(); - return w == widget || containsControl((Control) widget, w); - } - - /** - * @return true if this VControl is to be sized as a square - */ - public boolean isSquare() { - return square; - } - - public boolean isVisible() { - return getVisible() && composite.isVisible(); - } - - public void moveAbove(VControl control) { - parent.move(this, null); - } - - public void moveBelow(VControl control) { - parent.move(null, this); - } - - public void notifyListeners(int eventType) { - notifyListeners(eventType, null); - } - - public void notifyListeners(int eventType, Event event) { - if (listeners.containsKey(eventType)) { - if (event == null) { - event = new Event(); - } - event.data = this; - event.type = eventType; - if (this instanceof VNative && eventType == SWT.FocusOut) { - System.out.println("wtf"); //$NON-NLS-1$ - } - for (Listener listener : getListeners(eventType)) { - listener.handleEvent(event); - } - } - } - - public final void paintControl(Event e) { - if (painter != null && bounds.intersects(e.x, e.y, e.width, e.height) - && isVisible()) { - int alpha = e.gc.getAlpha(); - int fullX, fullY, fullW, fullH; - fullX = bounds.x - 1; - fullY = bounds.y - 1; - if (parent != null) { - fullW = Math.min( - parent.bounds.x + parent.bounds.width - bounds.x, - bounds.x + bounds.width) + 1; - fullH = Math.min( - parent.bounds.y + parent.bounds.height - bounds.y, - bounds.y + bounds.height) + 1; - } else { - fullW = bounds.width; - fullH = bounds.height; - } - int clientX, clientY, clientW, clientH; - clientX = fullX + marginLeft; - clientY = fullY + marginTop; - clientW = fullW - marginLeft - marginRight; - clientH = fullH - marginTop - marginBottom; - - e.gc.setClipping(fullX, fullY, fullW, fullH); - setAlpha(e.gc); - painter.paintBackground(this, e); - - if (clientW > 0 && clientH > 0) { - e.gc.setClipping(clientX, clientY, clientW, clientH); - setAlpha(e.gc); - painter.paintContent(this, e); - } - - e.gc.setClipping(fullX, fullY, fullW, fullH); - setAlpha(e.gc); - painter.paintBorders(this, e); - - if (!getEnabled()) { - setAlpha(e.gc, 25); - e.gc.setBackground( - e.display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - e.gc.fillRectangle(fullX, fullY, fullW, fullH); - } - - e.gc.setClipping((Rectangle) null); - e.gc.setAlpha(alpha); - - if (listeners.containsKey(SWT.Paint)) { - for (Listener listener : listeners.get(SWT.Paint)) { - listener.handleEvent(e); - } - } - } - } - - public void redraw() { - if (composite != null && !composite.isDisposed()) { - composite.redraw(bounds.x, bounds.y, bounds.width, bounds.height, - false); - } - } - - protected boolean redrawOnActivate() { - return true; - } - - protected boolean redrawOnDeactivate() { - return true; - } - - void removeListener(int eventType) { - eventTypes.remove(eventType); - if (hasState(STATE_ACTIVE)) { - composite.removeListener(eventType, listener); - } - } - - public void removeListener(int eventType, Listener listener) { - if (listeners.containsKey(eventType)) { - listeners.get(eventType).remove(listener); - } - if (hasState(STATE_ACTIVE)) { - composite.removeListener(eventType, listener); - } - } - - public void setActivatable(boolean activatable) { - this.activatable = activatable; - } - - public void setActiveCursor(Cursor cursor) { - activeCursor = cursor; - } - - /** - * @param x - * @param y - */ - public void setAlignment(int x, int y) { - xAlign = x; - yAlign = y; - } - - public void setAlpha(GC gc) { - gc.setAlpha((int) (2.55 * visibility)); - } - - public void setAlpha(GC gc, int alpha) { - gc.setAlpha((int) ((double) alpha * (double) visibility * 0.01)); - } - - public void setBackground(Color color) { - background = color; - } - - public void setBounds(int x, int y, int width, int height) { - boolean moved = (bounds.x != x || bounds.y != y); - boolean resized = (bounds.width != width || bounds.height != height); - - bounds.x = x; - bounds.y = y; - bounds.width = width; - bounds.height = height; - - if (moved) { - notifyListeners(SWT.Move, new Event()); - } - if (resized) { - notifyListeners(SWT.Resize, new Event()); - } - } - - public void setBounds(Rectangle bounds) { - setBounds(bounds.x, bounds.y, bounds.width, bounds.height); - } - - public void setCursor(Cursor cursor) { - getComposite().setCursor(cursor); - } - - public void setData(Enum name, Object value) { - setData(name.name(), value); - } - - public void setData(String name, Object value) { - if (value == null) { - if (dataMap != null) { - dataMap.remove(name); - if (dataMap.isEmpty()) { - dataMap = null; - } - } - } else { - if (dataMap == null) { - dataMap = new HashMap(); - } - dataMap.put(name, value); - } - } - - public void setEnabled(boolean enabled) { - if (setState(STATE_ENABLED, enabled)) { - if (this instanceof VNative) { - Control c = getControl(); - if (c != null) { - c.setEnabled(enabled); - } - } - if (!enabled) { - deactivate(); - } - redraw(); - } - } - - public void setFill(Color color) { - fill = color; - } - - public boolean setFocus() { - return VTracker.instance().setFocusControl(this); - } - - protected boolean setFocus(boolean focus) { - if (!hasStyle(SWT.NO_FOCUS)) { - if (focus) { - attachListeners(true); - notifyListeners(SWT.FocusIn); - } else { - notifyListeners(SWT.FocusOut); - detachListeners(true); - } - return true; - } - return false; - } - - public void setFont(Font font) { - this.font = font; - } - - public void setForeground(Color color) { - foreground = color; - } - - public void setImage(Image image) { - this.image = image; - redraw(); - } - - public void setImage(SvgDocument svg) { - this.svg = svg; - redraw(); - } - - public void setInactiveCursor(Cursor cursor) { - inactiveCursor = cursor; - } - - public void setLayoutData(GridData data) { - layoutData = data; - } - - public void setLocation(Point location) { - if (location != null) { - setLocation(location.x, location.y); - } - } - - public void setLocation(int x, int y) { - setBounds(x, y, bounds.width, bounds.height); - } - - /** - * @param marginWidth - * @param marginHeight - */ - public void setMargins(int marginWidth, int marginHeight) { - setMargins(marginWidth, marginWidth, marginHeight, marginHeight); - } - - /** - * @param left - * @param right - * @param top - * @param bottom - */ - public void setMargins(int left, int right, int top, int bottom) { - if (left >= 0) { - marginLeft = left; - } - if (right >= 0) { - marginRight = right; - } - if (top >= 0) { - marginTop = top; - } - if (bottom >= 0) { - marginBottom = bottom; - } - } - - public void setMargins(Rectangle margins) { - setMargins(margins.x, margins.y, margins.width, margins.height); - } - - public void setOval(int rx, int ry) { - setPolygon(new int[] { rx, ry }); - } - - public void setOval(int rx, int ry, Color fillColor) { - setPolygon(new int[] { rx, ry }, fillColor); - } - - public void setPainter(IControlPainter painter) { - this.painter = painter; - } - - public void setParent(VPanel panel) { - if (this.parent != null) { - this.parent.removeChild(this); - } - this.parent = panel; - if (this.parent != null) { - this.composite = this.parent.composite; - this.parent.addChild(this); - } - } - - public void setPolygon(int[] points) { - setPolygon(points, (fill != null ? fill - : ((background != null) ? background : getForeground()))); - } - - public void setPolygon(int[] points, Color fillColor) { - if (points == null || points.length < 2 || points.length % 2 != 0) { - return; - } - if (points.length == 2 && (points[0] < 1 || points[1] < 1)) { - return; - } - this.points = points; - setFill(fillColor); - redraw(); - } - - public void setScaleImage(boolean scale) { - this.scaleImage = scale; - } - - public void setSize(Point size) { - if (size != null) { - setBounds(bounds.x, bounds.y, size.x, size.y); - } - } - - /** - * if parameter equal is true, the x and y sizes of this VControl will be - * forced equal, thus drawing a square button - * - * @param equal - */ - public void setSquare(boolean equal) { - square = equal; - } - - protected boolean setState(int state, boolean set) { - if (set && !hasState(state)) { - this.state |= state; - return true; - } else if (!set && hasState(state)) { - this.state &= ~state; - return true; - } - return false; - } - - public void setStyle(int style) { - this.style = style; - } - - public boolean setStyle(int style, boolean set) { - if (set && !hasStyle(style)) { - this.style |= style; - return true; - } else if (!set && hasStyle(style)) { - this.style &= ~style; - return true; - } - return false; - } - - /** - * @param text - */ - public void setText(String text) { - this.text = text; - redraw(); - } - - public void setToolTipText(String text) { - tooltipText = text; - } - - void setVisibility(int visibility) { - if (visibility > 100) { - visibility = 100; - } else if (visibility < 0) { - visibility = 0; - } - this.visibility = visibility; - if (!isVisible()) { - if (this == VTracker.getFocusControl()) { - VTracker.instance().setFocusControl(null); - } - VTracker.instance().deactivate(this); - } - redraw(); - } - - public void setVisible(boolean visible) { - setVisibility(visible ? 100 : 0); - } - - public void setVisible(final boolean visible, final int duration) { - setVisible(visible, duration, null); - } - - public void setVisible(final boolean visible, final int duration, - final Runnable callback) { - if (duration <= 0) { - setVisible(visible); - } else { - new Thread() { - @Override - public void run() { - do { - Display.getDefault().syncExec(new Runnable() { - public void run() { - if (!disposed) { - setVisibility( - visibility + (visible ? 10 : -10)); - composite.update(); - } - } - }); - if (!disposed) { - try { - Thread.sleep(5 * duration / 100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } while (!disposed && visibility > 0 && visibility < 100); - if (!disposed && visibility != 0 && visibility != 100) { - Display.getDefault().syncExec(new Runnable() { - public void run() { - if (!disposed) { - setVisible(visible); - composite.update(); - } - } - }); - } - if (callback != null) { - callback.run(); - } - } - }.start(); - } - } - - public Point toControl(Point point) { - return getComposite().toControl(point); - } - - public Point toControl(int x, int y) { - return getComposite().toControl(x, y); - } - - public Point toDisplay(Point point) { - return getComposite().toDisplay(point); - } - - public Point toDisplay(int x, int y) { - return getComposite().toDisplay(x, y); - } - - @Override - public String toString() { - return super.toString() + " {" + text + "}"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - public void update() { - if (composite != null && !composite.isDisposed()) { - composite.update(); - } - } - -} +/**************************************************************************** + * Copyright (c) 2008, 2009 Jeremy Dowdall + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Jeremy Dowdall - initial API and implementation + *****************************************************************************/ + +package org.eclipse.nebula.cwt.v; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.nebula.cwt.svg.SvgDocument; +import org.eclipse.nebula.cwt.svg.SvgFragment; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +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.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Widget; + +/** + * A VControl is a class wich wraps an SWT Button to create a widget that acts + * as much like a native Button as possible while adding the following features: + *
    + *
  • The appearance of Label when the mouse is not over it and it does not + * have the focus or selection (if style is SWT.TOGGLE).
  • + *
  • Can fit seemlessly into a larger visual piece - simple set the image to + * that of its background and adjust the image's offset if necessary.
  • + *
  • Can draw polygons and ovals.
  • + *
  • Can center or otherwise align its visual display (text, image, polygon + * or oval).
  • + *
+ */ +@SuppressWarnings("javadoc") +public abstract class VControl { + + public enum Type { + Button, Custom, Label, + Native, Panel, Text, Spacer + } + + /** + * true if the platform is Carbon, false otherwise + */ + public static final boolean carbon = "carbon".equals(SWT.getPlatform()); //$NON-NLS-1$ + + /** + * true if the platform is GTK, false otherwise + */ + public static final boolean gtk = "gtk".equals(SWT.getPlatform()); //$NON-NLS-1$ + + /** + * true if the platform is Win32, false otherwise + */ + public static final boolean win32 = "win32".equals(SWT.getPlatform()); //$NON-NLS-1$ + + private static final int[] Points_OK = { 2, 6, 5, 9, 10, 3, 9, 2, 5, 7, 3, + 5 }; + private static final int[] Points_Cancel = { 0, 1, 3, 4, 0, 7, 1, 8, 4, 5, + 7, 8, 8, 7, 5, 4, 8, 1, 7, 0, 4, 3, 1, 0 }; + private static final int[] Points_Left = { 9, 0, 4, 5, 9, 10 }; + private static final int[] Points_Right = { 2, 0, 7, 5, 2, 10 }; + private static final int[] Points_Up = { 10, 8, 5, 3, 0, 8 }; + private static final int[] Points_Down = { 10, 2, 5, 7, 0, 2 }; + private static final int[] Points_Add = { 2, 4, 4, 4, 4, 2, 5, 2, 5, 4, 7, + 4, 7, 5, 5, 5, 5, 7, 4, 7, 4, 5, 2, 5 }; + private static final int[] Points_Subtract = { 2, 4, 7, 4, 7, 5, 2, 5 }; + + // public static final int STATE_INACTIVE = 1 << 0; + public static final int STATE_ACTIVE = 1 << 1; + public static final int STATE_SELECTED = 1 << 2; + // public static final int STATE_FOCUS = 1 << 3; + public static final int STATE_ENABLED = 1 << 4; + public static final int STATE_MOUSE_DOWN = 1 << 5; + + protected final static boolean containsControl(Control control, + Composite composite) { + if (composite != null && !composite.isDisposed()) { + Control[] children = composite.getChildren(); + for (Control child : children) { + if (!child.isDisposed()) { + if (child == control) { + return true; + } else if (child instanceof Composite) { + return containsControl(control, (Composite) child); + } + } + } + } + return false; + } + + Composite composite; + VPanel parent; + private int style; + Menu menu; + Image image; + SvgDocument svg; + String text; + String tooltipText; + int[] points; + Color fill; + Color foreground; + Color background; + Font font; + private Cursor activeCursor; + private Cursor inactiveCursor; + + GridData layoutData; + + private int state = STATE_ENABLED; + Rectangle bounds; + int marginTop = 5; + int marginBottom = 5; + int marginLeft = 5; + int marginRight = 5; + int xAlign; + + int yAlign; + + boolean disposed = false; + boolean square = false; + int visibility = 100; + boolean scaleImage = false; + boolean customToolTip = false; + + IControlPainter painter; + Map dataMap; + Map> listeners = new HashMap>(); + private Set eventTypes = new HashSet(); + + private Listener listener = event -> { + if (event.type == SWT.FocusIn) { + if (VControl.this == VTracker.getFocusControl()) { + return; + } + } + VControl.this.handleEvent(event); + }; + + private boolean activatable = true; + + /** + * Javadoc out of date // TODO: update javadoc + * + * @param panel + * @param style + */ + public VControl(VPanel panel, int style) { + setParent(panel); + + this.style = style; + bounds = new Rectangle(0, 0, 0, 0); + + if ((style & SWT.OK) != 0) { + setPolygon(Points_OK); + if (foreground == null) setForeground(Display.getDefault().getSystemColor(SWT.COLOR_DARK_GREEN)); + } else if ((style & SWT.CANCEL) != 0) { + setPolygon(Points_Cancel); + if (foreground == null) setForeground(Display.getDefault().getSystemColor(SWT.COLOR_DARK_RED)); + } else if ((style & SWT.ARROW) != 0) { + if ((style & SWT.DOWN) != 0) { + setPolygon(Points_Down); + } else if ((style & SWT.LEFT) != 0) { + setPolygon(Points_Left); + } else if ((style & SWT.RIGHT) != 0) { + setPolygon(Points_Right); + } else if ((style & SWT.UP) != 0) { + setPolygon(Points_Up); + } + } else if ((style & SWT.UP) != 0) { + setPolygon(Points_Add); + } else if ((style & SWT.DOWN) != 0) { + setPolygon(Points_Subtract); + } + + if (foreground == null) { + setForeground(Display.getDefault() + .getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + } + if (fill == null) { + setFill(getForeground()); + } + } + + void handleEvent(Event event) { + event.data = this; + filterEvent(event); + if (listeners != null && listeners.containsKey(event.type)) { + Listener[] la = listeners.get(event.type) + .toArray(new Listener[listeners.get(event.type).size()]); + for (Listener listener : la) { + listener.handleEvent(event); + } + } + } + + void activate() { + if (activatable && hasState(STATE_ENABLED) + && setState(STATE_ACTIVE, true)) { + setState(STATE_MOUSE_DOWN, VTracker.isMouseDown()); + setCursor(activeCursor); + attachListeners(false); + if (redrawOnActivate()) { + redraw(); + } + notifyListeners(SWT.Activate); + } + } + + void addListener(int eventType) { + eventTypes.add(eventType); + if (hasState(STATE_ACTIVE)) { + composite.addListener(eventType, listener); + } + } + + public void addListener(int eventType, Listener listener) { + if (!listeners.containsKey(eventType)) { + listeners.put(eventType, new ArrayList()); + } + listeners.get(eventType).add(listener); + if (hasState(STATE_ACTIVE)) { + composite.addListener(eventType, listener); + } + } + + void attachListeners(boolean keyListeners) { + Set eventTypes = new HashSet(this.eventTypes); + eventTypes.addAll(listeners.keySet()); + for (Integer eventType : eventTypes) { + if (include(keyListeners, eventType)) { + composite.addListener(eventType, listener); + } + } + } + + void detachListeners(boolean keyListeners) { + Set eventTypes = new HashSet(this.eventTypes); + eventTypes.addAll(listeners.keySet()); + for (Integer eventType : eventTypes) { + if (include(keyListeners, eventType)) { + composite.removeListener(eventType, listener); + } + } + } + + public Point computeSize(int wHint, int hHint) { + return computeSize(wHint, hHint, true); + } + + public Point computeSize(int wHint, int hHint, boolean changed) { + if (wHint != SWT.DEFAULT && wHint < 0) { + wHint = 0; + } + if (hHint != SWT.DEFAULT && hHint < 0) { + hHint = 0; + } + + Point size = new Point(2, 2); + + if (image != null) { + Rectangle r = image.getBounds(); + size.x = r.width; + size.y = r.height; + } else if (points != null) { + if (points.length > 2) { + int minX = points[0]; + int maxX = points[0]; + int minY = points[1]; + int maxY = points[1]; + for (int i = 2; i < (points.length - 1); i++) { + minX = Math.min(minX, points[i]); + maxX = Math.max(maxX, points[i]); + minY = Math.min(minY, points[i + 1]); + maxY = Math.max(maxY, points[i + 1]); + } + size.x += maxX - minX; + size.y += maxY - minY; + } else { + size.x += points[0]; + size.y += points[1]; + } + } else if (svg != null) { + Float width = null, height = null; + for (SvgFragment fragment : svg.getFragments()) { + if (fragment.getWidth() != null) { + width = fragment.getWidth(); + } + if (fragment.getHeight() != null) { + height = fragment.getHeight(); + } + if (fragment.getViewBox() != null && fragment.getViewBox().length>3) { + width = fragment.getViewBox()[2]; + height = fragment.getViewBox()[3]; + } + } + if (width != null) { + size.x=width.intValue(); + } + if (height != null) { + size.y=height.intValue(); + } + } + + if (text != null) { + GC gc = new GC(composite); + if (getFont() != null) { + gc.setFont(getFont()); + } + Point tSize = gc.textExtent(text); + gc.dispose(); + size.x += tSize.x; + size.y += tSize.y; + } + + size.x += (marginLeft + marginRight); + size.y += (marginTop + marginBottom); + + if (square) { + size.x = size.y = Math.max(size.x, size.y); + } + + return size; + } + + public Menu createMenu() { + menu = new Menu(composite); + addListener(SWT.MouseDown, new Listener() { + public void handleEvent(Event event) { + if (SWT.MouseDown == event.type && event.button == 3) { + menu.setVisible(true); + } + } + }); + return menu; + } + + void deactivate() { + if (setState(STATE_ACTIVE, false)) { + setState(STATE_MOUSE_DOWN, false); + setCursor(inactiveCursor); + detachListeners(false); + if (redrawOnDeactivate()) { + redraw(); + } + notifyListeners(SWT.Deactivate); + } + } + + public void dispose() { + if (!disposed) { + disposed = true; + + notifyListeners(SWT.Dispose, new Event()); + + if (this == VTracker.getActiveControl()) { + VTracker.instance().deactivate(this); + } + if (this == VTracker.getFocusControl()) { + VTracker.instance().setFocusControl(null); + } + if (!composite.isDisposed()) { + detachListeners(true); + detachListeners(false); + } + setParent(null); + if (painter != null) { + painter.dispose(); + } + listeners.clear(); + listeners = null; + text = null; + // tooltip = null; + tooltipText = null; + image = null; + points = null; + } + } + + public Color getBackground() { + if (background != null) { + return background; + } + VPanel p = parent; + while (p != null) { + if (p.background != null) + return p.background; + p = p.parent; + } + return composite.getBackground(); + } + + public Rectangle getBounds() { + return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); + } + + public Rectangle getClientArea() { + return new Rectangle(bounds.x + marginLeft, bounds.y + marginTop, + bounds.width - (marginLeft + marginRight), + bounds.height - (marginTop + marginBottom)); + } + + public Point getClientSize() { + return new Point(bounds.width - (marginLeft + marginRight), + bounds.height - (marginTop + marginBottom)); + } + + public Composite getComposite() { + return composite; + } + + public Control getControl() { + return composite; + } + + public Object getData(Enum name) { + return getData(name.name()); + } + + public T getData(Enum name, Class clazz) { + return getData(name.name(), clazz); + } + + public Object getData(String name) { + if (dataMap != null) { + return dataMap.get(name); + } + return null; + } + + public T getData(String name, Class clazz) { + if (dataMap != null) { + return (T) dataMap.get(name); + } + return null; + } + + public Display getDisplay() { + return composite.getDisplay(); + } + + public boolean getEnabled() { + return hasState(STATE_ENABLED); + } + + public Font getFont() { + return font; + } + + public Color getForeground() { + return foreground; + } + + public Image getImage() { + return image; + } + + public GridData getLayoutData() { + return (layoutData != null) ? layoutData : new GridData(); + } + + protected Listener[] getListeners(int eventType) { + List l = listeners.get(eventType); + return l.toArray(new Listener[l.size()]); + } + + public Point getLocation() { + return new Point(bounds.x, bounds.y); + } + + public Rectangle getMargins() { + return new Rectangle(marginLeft, marginRight, marginTop, marginBottom); + } + + public Menu getMenu() { + return menu; + } + + public VPanel getParent() { + return parent; + } + + public Shell getShell() { + return composite.getShell(); + } + + public Point getSize() { + return new Point(bounds.width, bounds.height); + } + + public int getState() { + return state; + } + + public int getStyle() { + return style; + } + + /** + * @return the text string displayed on this VControl + */ + public String getText() { + return text; + } + + public String getToolTipText() { + return (tooltipText != null) ? tooltipText : ""; //$NON-NLS-1$ + } + + public abstract Type getType(); + + public int getVisibility() { + return visibility; + } + + public boolean getVisible() { + return visibility > 0; + } + + public Composite getWidget() { + return getParent().getWidget(); + } + + protected void filterEvent(Event event) { + // subclasses to implement if necessary + } + + public boolean hasState(int state) { + return (this.state & state) != 0; + } + + public boolean hasStyle(int style) { + return (this.style & style) != 0; + } + + private boolean include(boolean key, int type) { + if (type == SWT.Selection) { + return false; + } + if (key && (type == SWT.KeyDown || type == SWT.KeyUp + || type == SWT.Traverse)) { + return true; + } + if (!key && !(type == SWT.KeyDown || type == SWT.KeyUp + || type == SWT.Traverse)) { + return true; + } + return false; + } + + public boolean isActivatable() { + return activatable; + } + + public boolean isDisposed() { + return disposed; + } + + public boolean isEnabled() { + return getEnabled() && ((parent != null) ? parent.isEnabled() + : composite.isEnabled()); + } + + public boolean isSameWidgetAs(VControl control) { + return control != null && getWidget() == control.getWidget(); + } + + public boolean isSameWidgetAs(Widget widget) { + Composite w = getWidget(); + return w == widget || containsControl((Control) widget, w); + } + + /** + * @return true if this VControl is to be sized as a square + */ + public boolean isSquare() { + return square; + } + + public boolean isVisible() { + return getVisible() && composite.isVisible(); + } + + public void moveAbove(VControl control) { + parent.move(this, null); + } + + public void moveBelow(VControl control) { + parent.move(null, this); + } + + public void notifyListeners(int eventType) { + notifyListeners(eventType, null); + } + + public void notifyListeners(int eventType, Event event) { + if (listeners.containsKey(eventType)) { + if (event == null) { + event = new Event(); + } + event.data = this; + event.type = eventType; + if (this instanceof VNative && eventType == SWT.FocusOut) { + System.out.println("wtf"); //$NON-NLS-1$ + } + for (Listener listener : getListeners(eventType)) { + listener.handleEvent(event); + } + } + } + + public final void paintControl(Event e) { + if (painter != null && bounds.intersects(e.x, e.y, e.width, e.height) + && isVisible()) { + int alpha = e.gc.getAlpha(); + int fullX, fullY, fullW, fullH; + fullX = bounds.x - 1; + fullY = bounds.y - 1; + if (parent != null) { + fullW = Math.min( + parent.bounds.x + parent.bounds.width - bounds.x, + bounds.x + bounds.width) + 1; + fullH = Math.min( + parent.bounds.y + parent.bounds.height - bounds.y, + bounds.y + bounds.height) + 1; + } else { + fullW = bounds.width; + fullH = bounds.height; + } + int clientX, clientY, clientW, clientH; + clientX = fullX + marginLeft; + clientY = fullY + marginTop; + clientW = fullW - marginLeft - marginRight; + clientH = fullH - marginTop - marginBottom; + + e.gc.setClipping(fullX, fullY, fullW, fullH); + setAlpha(e.gc); + painter.paintBackground(this, e); + + if (clientW > 0 && clientH > 0) { + e.gc.setClipping(clientX, clientY, clientW, clientH); + setAlpha(e.gc); + painter.paintContent(this, e); + } + + e.gc.setClipping(fullX, fullY, fullW, fullH); + setAlpha(e.gc); + painter.paintBorders(this, e); + + if (!getEnabled()) { + setAlpha(e.gc, 25); + e.gc.setBackground( + e.display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + e.gc.fillRectangle(fullX, fullY, fullW, fullH); + } + + e.gc.setClipping((Rectangle) null); + e.gc.setAlpha(alpha); + + if (listeners.containsKey(SWT.Paint)) { + for (Listener listener : listeners.get(SWT.Paint)) { + listener.handleEvent(e); + } + } + } + } + + public void redraw() { + if (composite != null && !composite.isDisposed()) { + composite.redraw(bounds.x, bounds.y, bounds.width, bounds.height, + false); + } + } + + protected boolean redrawOnActivate() { + return true; + } + + protected boolean redrawOnDeactivate() { + return true; + } + + void removeListener(int eventType) { + eventTypes.remove(eventType); + if (hasState(STATE_ACTIVE)) { + composite.removeListener(eventType, listener); + } + } + + public void removeListener(int eventType, Listener listener) { + if (listeners.containsKey(eventType)) { + listeners.get(eventType).remove(listener); + } + if (hasState(STATE_ACTIVE)) { + composite.removeListener(eventType, listener); + } + } + + public void setActivatable(boolean activatable) { + this.activatable = activatable; + } + + public void setActiveCursor(Cursor cursor) { + activeCursor = cursor; + } + + /** + * @param x + * @param y + */ + public void setAlignment(int x, int y) { + xAlign = x; + yAlign = y; + } + + public void setAlpha(GC gc) { + gc.setAlpha((int) (2.55 * visibility)); + } + + public void setAlpha(GC gc, int alpha) { + gc.setAlpha((int) ((double) alpha * (double) visibility * 0.01)); + } + + public void setBackground(Color color) { + background = color; + } + + public void setBounds(int x, int y, int width, int height) { + boolean moved = (bounds.x != x || bounds.y != y); + boolean resized = (bounds.width != width || bounds.height != height); + + bounds.x = x; + bounds.y = y; + bounds.width = width; + bounds.height = height; + + if (moved) { + notifyListeners(SWT.Move, new Event()); + } + if (resized) { + notifyListeners(SWT.Resize, new Event()); + } + } + + public void setBounds(Rectangle bounds) { + setBounds(bounds.x, bounds.y, bounds.width, bounds.height); + } + + public void setCursor(Cursor cursor) { + getComposite().setCursor(cursor); + } + + public void setData(Enum name, Object value) { + setData(name.name(), value); + } + + public void setData(String name, Object value) { + if (value == null) { + if (dataMap != null) { + dataMap.remove(name); + if (dataMap.isEmpty()) { + dataMap = null; + } + } + } else { + if (dataMap == null) { + dataMap = new HashMap(); + } + dataMap.put(name, value); + } + } + + public void setEnabled(boolean enabled) { + if (setState(STATE_ENABLED, enabled)) { + if (this instanceof VNative) { + Control c = getControl(); + if (c != null) { + c.setEnabled(enabled); + } + } + if (!enabled) { + deactivate(); + } + redraw(); + } + } + + public void setFill(Color color) { + fill = color; + } + + public boolean setFocus() { + return VTracker.instance().setFocusControl(this); + } + + protected boolean setFocus(boolean focus) { + if (!hasStyle(SWT.NO_FOCUS)) { + if (focus) { + attachListeners(true); + notifyListeners(SWT.FocusIn); + } else { + notifyListeners(SWT.FocusOut); + detachListeners(true); + } + return true; + } + return false; + } + + public void setFont(Font font) { + this.font = font; + } + + public void setForeground(Color color) { + foreground = color; + } + + public void setImage(Image image) { + this.image = image; + redraw(); + } + + public void setImage(SvgDocument svg) { + this.svg = svg; + redraw(); + } + + public void setInactiveCursor(Cursor cursor) { + inactiveCursor = cursor; + } + + public void setLayoutData(GridData data) { + layoutData = data; + } + + public void setLocation(Point location) { + if (location != null) { + setLocation(location.x, location.y); + } + } + + public void setLocation(int x, int y) { + setBounds(x, y, bounds.width, bounds.height); + } + + /** + * @param marginWidth + * @param marginHeight + */ + public void setMargins(int marginWidth, int marginHeight) { + setMargins(marginWidth, marginWidth, marginHeight, marginHeight); + } + + /** + * @param left + * @param right + * @param top + * @param bottom + */ + public void setMargins(int left, int right, int top, int bottom) { + if (left >= 0) { + marginLeft = left; + } + if (right >= 0) { + marginRight = right; + } + if (top >= 0) { + marginTop = top; + } + if (bottom >= 0) { + marginBottom = bottom; + } + } + + public void setMargins(Rectangle margins) { + setMargins(margins.x, margins.y, margins.width, margins.height); + } + + public void setOval(int rx, int ry) { + setPolygon(new int[] { rx, ry }); + } + + public void setOval(int rx, int ry, Color fillColor) { + setPolygon(new int[] { rx, ry }, fillColor); + } + + public void setPainter(IControlPainter painter) { + this.painter = painter; + } + + public void setParent(VPanel panel) { + if (this.parent != null) { + this.parent.removeChild(this); + } + this.parent = panel; + if (this.parent != null) { + this.composite = this.parent.composite; + this.parent.addChild(this); + } + } + + public void setPolygon(int[] points) { + setPolygon(points, (fill != null ? fill + : ((background != null) ? background : getForeground()))); + } + + public void setPolygon(int[] points, Color fillColor) { + if (points == null || points.length < 2 || points.length % 2 != 0) { + return; + } + if (points.length == 2 && (points[0] < 1 || points[1] < 1)) { + return; + } + this.points = points; + setFill(fillColor); + redraw(); + } + + public void setScaleImage(boolean scale) { + this.scaleImage = scale; + } + + public void setSize(Point size) { + if (size != null) { + setBounds(bounds.x, bounds.y, size.x, size.y); + } + } + + /** + * if parameter equal is true, the x and y sizes of this VControl will be + * forced equal, thus drawing a square button + * + * @param equal + */ + public void setSquare(boolean equal) { + square = equal; + } + + protected boolean setState(int state, boolean set) { + if (set && !hasState(state)) { + this.state |= state; + return true; + } else if (!set && hasState(state)) { + this.state &= ~state; + return true; + } + return false; + } + + public void setStyle(int style) { + this.style = style; + } + + public boolean setStyle(int style, boolean set) { + if (set && !hasStyle(style)) { + this.style |= style; + return true; + } else if (!set && hasStyle(style)) { + this.style &= ~style; + return true; + } + return false; + } + + /** + * @param text + */ + public void setText(String text) { + this.text = text; + redraw(); + } + + public void setToolTipText(String text) { + tooltipText = text; + } + + void setVisibility(int visibility) { + if (visibility > 100) { + visibility = 100; + } else if (visibility < 0) { + visibility = 0; + } + this.visibility = visibility; + if (!isVisible()) { + if (this == VTracker.getFocusControl()) { + VTracker.instance().setFocusControl(null); + } + VTracker.instance().deactivate(this); + } + redraw(); + } + + public void setVisible(boolean visible) { + setVisibility(visible ? 100 : 0); + } + + public void setVisible(final boolean visible, final int duration) { + setVisible(visible, duration, null); + } + + public void setVisible(final boolean visible, final int duration, + final Runnable callback) { + if (duration <= 0) { + setVisible(visible); + } else { + new Thread() { + @Override + public void run() { + do { + Display.getDefault().syncExec(new Runnable() { + public void run() { + if (!disposed) { + setVisibility( + visibility + (visible ? 10 : -10)); + composite.update(); + } + } + }); + if (!disposed) { + try { + Thread.sleep(5 * duration / 100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } while (!disposed && visibility > 0 && visibility < 100); + if (!disposed && visibility != 0 && visibility != 100) { + Display.getDefault().syncExec(new Runnable() { + public void run() { + if (!disposed) { + setVisible(visible); + composite.update(); + } + } + }); + } + if (callback != null) { + callback.run(); + } + } + }.start(); + } + } + + public Point toControl(Point point) { + return getComposite().toControl(point); + } + + public Point toControl(int x, int y) { + return getComposite().toControl(x, y); + } + + public Point toDisplay(Point point) { + return getComposite().toDisplay(point); + } + + public Point toDisplay(int x, int y) { + return getComposite().toDisplay(x, y); + } + + @Override + public String toString() { + return super.toString() + " {" + text + "}"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public void update() { + if (composite != null && !composite.isDisposed()) { + composite.update(); + } + } + +} diff --git a/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VControlPainter.java b/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VControlPainter.java index e02961d48..fb13f1867 100644 --- a/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VControlPainter.java +++ b/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VControlPainter.java @@ -1,249 +1,249 @@ -/**************************************************************************** - * Copyright (c) 2008, 2009 Jeremy Dowdall - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jeremy Dowdall - initial API and implementation - *****************************************************************************/ - -package org.eclipse.nebula.cwt.v; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Event; - -public class VControlPainter implements IControlPainter { - - private static double getX(VControl control, double width) { - double x; - - if(control.xAlign == SWT.LEFT) { - x = control.marginLeft; - } else if(control.xAlign == SWT.RIGHT) { - x = control.bounds.width - width - control.marginRight; - } else { // CENTERED / Default - x = ((control.bounds.width - width) / 2.0); - } - - x += control.bounds.x; - - return x; - } - - private static double getY(VControl control, double height) { - double y; - - if(control.yAlign == SWT.TOP) { - y = control.marginTop; - } else if(control.yAlign == SWT.BOTTOM) { - y = control.bounds.height - height - control.marginBottom; - } else { // CENTERED / Default - y = ((control.bounds.height - height) / 2.0); - } - - y += control.bounds.y; - - return y; - } - - private static void paintImage(VControl control, Event e) { - Rectangle ibounds = control.image.getBounds(); - if(control.scaleImage) { - Rectangle cbounds = control.getClientArea(); - e.gc.drawImage(control.image, 0, 0, ibounds.width, ibounds.height, cbounds.x, cbounds.y, cbounds.width, cbounds.height); - } else { - e.gc.drawImage(control.image, (int)getX(control, ibounds.width), (int)getY(control, ibounds.height)); - } - } - - private static void paintImageAndText(VControl control, Event e) { - e.gc.setTextAntialias(SWT.ON); - if(control.foreground != null && !control.foreground.isDisposed()) { - e.gc.setForeground(control.foreground); - } - - Rectangle ibounds = control.image.getBounds(); - Point tsize = e.gc.textExtent(control.text); - - int x = (int)getX(control, ibounds.width + tsize.x); - - e.gc.drawImage(control.image, x, (int)getY(control, ibounds.height)); - - x += ibounds.width + 3; - - e.gc.drawText(control.text, x, (int)getY(control, tsize.y), true); - } - - private static void paintOval(VControl control, Event e, int x, int y) { - if(control.fill != null && !control.fill.isDisposed()) { - e.gc.setBackground(control.fill); - e.gc.fillOval(x, y, control.points[0], control.points[1]); - } - - e.gc.drawOval(x, y, control.points[0], control.points[1]); - } - - private static void paintPoly(VControl control, Event e, int x, int y, int minX, int minY) { - int[] data = new int[control.points.length]; - for(int i = 0; i < control.points.length; i += 2) { - data[i] = control.points[i] + x - minX - 1; - } - for(int i = 1; i < data.length; i += 2) { - data[i] = control.points[i] + y - minY; - } - - if(control.fill != null && !control.fill.isDisposed()) { - e.gc.setBackground(control.fill); - e.gc.fillPolygon(data); - } - - e.gc.drawPolygon(data); - } - - private static void paintPolygon(VControl control, Event e) { - e.gc.setAntialias(SWT.ON); - if(control.foreground != null && !control.foreground.isDisposed()) { - e.gc.setForeground(control.foreground); - } - - int minX = (control.points.length > 2) ? control.points[0] : 0; - int maxX = control.points[0]; - int minY = (control.points.length > 2) ? control.points[1] : 0; - int maxY = control.points[1]; - for(int i = 2; i < (control.points.length - 1); i++) { - minX = Math.min(minX, control.points[i]); - maxX = Math.max(maxX, control.points[i]); - minY = Math.min(minY, control.points[i + 1]); - maxY = Math.max(maxY, control.points[i + 1]); - } - - int x = (int)getX(control, maxX-minX); - int y = (int)getY(control, maxY-minY); - - if(control.points.length > 2) { - paintPoly(control, e, x, y, minX, minY); - } else { - paintOval(control, e, x, y); - } - } - - private static void paintPolygonAndText(VControl control, Event e) { - e.gc.setAntialias(SWT.ON); - e.gc.setTextAntialias(SWT.ON); - if(control.foreground != null && !control.foreground.isDisposed()) { - e.gc.setForeground(control.foreground); - } - - int minX = (control.points.length > 2) ? control.points[0] : 0; - int maxX = control.points[0]; - int minY = (control.points.length > 2) ? control.points[1] : 0; - int maxY = control.points[1]; - for(int i = 2; i < (control.points.length - 1); i++) { - minX = Math.min(minX, control.points[i]); - maxX = Math.max(maxX, control.points[i]); - minY = Math.min(minY, control.points[i + 1]); - maxY = Math.max(maxY, control.points[i + 1]); - } - - Point psize = new Point(maxX-minX, maxY-minY); - Point tsize = e.gc.textExtent(control.text); - - int x = (int)getX(control, psize.x+tsize.x); - int y = (int)getY(control, psize.y); - - if(control.points.length > 2) { - paintPoly(control, e, x, y, minX, minY); - } else { - paintOval(control, e, x, y); - } - - x += psize.x + 3; - - e.gc.drawText(control.text, x, (int)getY(control, tsize.y), true); - } - - private static void paintText(VControl control, Event e) { - Font current = e.gc.getFont(); - e.gc.setTextAntialias(SWT.ON); - if (control.foreground != null && !control.foreground.isDisposed()) { - e.gc.setForeground(control.foreground); - } - - if (control.font != null && !control.font.isDisposed() ) { - e.gc.setFont(control.font); - } - - Point size = e.gc.textExtent(control.text); - e.gc.drawText(control.text, (int)getX(control, size.x), (int)getY(control, size.y), true); - e.gc.setFont(current); - } - - public void dispose() { - // nothing to do - } - - public void paintBackground(VControl control, Event e) { - int alpha = e.gc.getAlpha(); - if(!control.isEnabled()) { - control.setAlpha(e.gc, 170); - } - if(control.background != null && !control.background.isDisposed()) { - e.gc.setBackground(control.background); - e.gc.fillRectangle(control.bounds); - } - e.gc.setAlpha(alpha); - } - - public void paintBorders(VControl control, Event e) { - int alpha = e.gc.getAlpha(); - if(!control.isEnabled()) { - control.setAlpha(e.gc, 170); - } - if(control.hasStyle(SWT.BORDER)) { - Rectangle r = control.getBounds(); - e.gc.setForeground(control.getForeground()); - e.gc.drawRectangle(r.x, r.y, r.width - 1, r.height - 1); - } - e.gc.setAlpha(alpha); - } - - public void paintContent(VControl control, Event e) { - int alpha = e.gc.getAlpha(); - Font current = e.gc.getFont(); - if(!control.isEnabled()) { - control.setAlpha(e.gc, 170); - } - if(control.svg != null) { - if(control.text != null) { - paintImageAndText(control, e); - } else { - control.svg.apply(e.gc, control.getClientArea()); - } - } else if(control.image != null && !control.image.getDevice().isDisposed()) { - if(control.text != null) { - paintImageAndText(control, e); - } else { - paintImage(control, e); - } - } else if(control.points != null && control.points.length > 0) { - if(control.text != null) { - paintPolygonAndText(control, e); - } else { - paintPolygon(control, e); - } - } else if(control.text != null) { - paintText(control, e); - } - e.gc.setAlpha(alpha); - e.gc.setFont(current); - } - -} +/**************************************************************************** + * Copyright (c) 2008, 2009 Jeremy Dowdall + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Jeremy Dowdall - initial API and implementation + *****************************************************************************/ + +package org.eclipse.nebula.cwt.v; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Event; + +public class VControlPainter implements IControlPainter { + + private static double getX(VControl control, double width) { + double x; + + if(control.xAlign == SWT.LEFT) { + x = control.marginLeft; + } else if(control.xAlign == SWT.RIGHT) { + x = control.bounds.width - width - control.marginRight; + } else { // CENTERED / Default + x = ((control.bounds.width - width) / 2.0); + } + + x += control.bounds.x; + + return x; + } + + private static double getY(VControl control, double height) { + double y; + + if(control.yAlign == SWT.TOP) { + y = control.marginTop; + } else if(control.yAlign == SWT.BOTTOM) { + y = control.bounds.height - height - control.marginBottom; + } else { // CENTERED / Default + y = ((control.bounds.height - height) / 2.0); + } + + y += control.bounds.y; + + return y; + } + + private static void paintImage(VControl control, Event e) { + Rectangle ibounds = control.image.getBounds(); + if(control.scaleImage) { + Rectangle cbounds = control.getClientArea(); + e.gc.drawImage(control.image, 0, 0, ibounds.width, ibounds.height, cbounds.x, cbounds.y, cbounds.width, cbounds.height); + } else { + e.gc.drawImage(control.image, (int)getX(control, ibounds.width), (int)getY(control, ibounds.height)); + } + } + + private static void paintImageAndText(VControl control, Event e) { + e.gc.setTextAntialias(SWT.ON); + if(control.foreground != null && !control.foreground.isDisposed()) { + e.gc.setForeground(control.foreground); + } + + Rectangle ibounds = control.image.getBounds(); + Point tsize = e.gc.textExtent(control.text); + + int x = (int)getX(control, ibounds.width + tsize.x); + + e.gc.drawImage(control.image, x, (int)getY(control, ibounds.height)); + + x += ibounds.width + 3; + + e.gc.drawText(control.text, x, (int)getY(control, tsize.y), true); + } + + private static void paintOval(VControl control, Event e, int x, int y) { + if(control.fill != null && !control.fill.isDisposed()) { + e.gc.setBackground(control.fill); + e.gc.fillOval(x, y, control.points[0], control.points[1]); + } + + e.gc.drawOval(x, y, control.points[0], control.points[1]); + } + + private static void paintPoly(VControl control, Event e, int x, int y, int minX, int minY) { + int[] data = new int[control.points.length]; + for(int i = 0; i < control.points.length; i += 2) { + data[i] = control.points[i] + x - minX - 1; + } + for(int i = 1; i < data.length; i += 2) { + data[i] = control.points[i] + y - minY; + } + + if(control.fill != null && !control.fill.isDisposed()) { + e.gc.setBackground(control.fill); + e.gc.fillPolygon(data); + } + + e.gc.drawPolygon(data); + } + + private static void paintPolygon(VControl control, Event e) { + e.gc.setAntialias(SWT.ON); + if(control.foreground != null && !control.foreground.isDisposed()) { + e.gc.setForeground(control.foreground); + } + + int minX = (control.points.length > 2) ? control.points[0] : 0; + int maxX = control.points[0]; + int minY = (control.points.length > 2) ? control.points[1] : 0; + int maxY = control.points[1]; + for(int i = 2; i < (control.points.length - 1); i++) { + minX = Math.min(minX, control.points[i]); + maxX = Math.max(maxX, control.points[i]); + minY = Math.min(minY, control.points[i + 1]); + maxY = Math.max(maxY, control.points[i + 1]); + } + + int x = (int)getX(control, maxX-minX); + int y = (int)getY(control, maxY-minY); + + if(control.points.length > 2) { + paintPoly(control, e, x, y, minX, minY); + } else { + paintOval(control, e, x, y); + } + } + + private static void paintPolygonAndText(VControl control, Event e) { + e.gc.setAntialias(SWT.ON); + e.gc.setTextAntialias(SWT.ON); + if(control.foreground != null && !control.foreground.isDisposed()) { + e.gc.setForeground(control.foreground); + } + + int minX = (control.points.length > 2) ? control.points[0] : 0; + int maxX = control.points[0]; + int minY = (control.points.length > 2) ? control.points[1] : 0; + int maxY = control.points[1]; + for(int i = 2; i < (control.points.length - 1); i++) { + minX = Math.min(minX, control.points[i]); + maxX = Math.max(maxX, control.points[i]); + minY = Math.min(minY, control.points[i + 1]); + maxY = Math.max(maxY, control.points[i + 1]); + } + + Point psize = new Point(maxX-minX, maxY-minY); + Point tsize = e.gc.textExtent(control.text); + + int x = (int)getX(control, psize.x+tsize.x); + int y = (int)getY(control, psize.y); + + if(control.points.length > 2) { + paintPoly(control, e, x, y, minX, minY); + } else { + paintOval(control, e, x, y); + } + + x += psize.x + 3; + + e.gc.drawText(control.text, x, (int)getY(control, tsize.y), true); + } + + private static void paintText(VControl control, Event e) { + Font current = e.gc.getFont(); + e.gc.setTextAntialias(SWT.ON); + if (control.foreground != null && !control.foreground.isDisposed()) { + e.gc.setForeground(control.foreground); + } + + if (control.font != null && !control.font.isDisposed() ) { + e.gc.setFont(control.font); + } + + Point size = e.gc.textExtent(control.text); + e.gc.drawText(control.text, (int)getX(control, size.x), (int)getY(control, size.y), true); + e.gc.setFont(current); + } + + public void dispose() { + // nothing to do + } + + public void paintBackground(VControl control, Event e) { + int alpha = e.gc.getAlpha(); + if(!control.isEnabled()) { + control.setAlpha(e.gc, 170); + } + if(control.background != null && !control.background.isDisposed()) { + e.gc.setBackground(control.background); + e.gc.fillRectangle(control.bounds); + } + e.gc.setAlpha(alpha); + } + + public void paintBorders(VControl control, Event e) { + int alpha = e.gc.getAlpha(); + if(!control.isEnabled()) { + control.setAlpha(e.gc, 170); + } + if(control.hasStyle(SWT.BORDER)) { + Rectangle r = control.getBounds(); + e.gc.setForeground(control.getForeground()); + e.gc.drawRectangle(r.x, r.y, r.width - 1, r.height - 1); + } + e.gc.setAlpha(alpha); + } + + public void paintContent(VControl control, Event e) { + int alpha = e.gc.getAlpha(); + Font current = e.gc.getFont(); + if(!control.isEnabled()) { + control.setAlpha(e.gc, 170); + } + if(control.svg != null) { + if(control.text != null) { + paintImageAndText(control, e); + } else { + control.svg.apply(e.gc, control.getClientArea()); + } + } else if(control.image != null && !control.image.getDevice().isDisposed()) { + if(control.text != null) { + paintImageAndText(control, e); + } else { + paintImage(control, e); + } + } else if(control.points != null && control.points.length > 0) { + if(control.text != null) { + paintPolygonAndText(control, e); + } else { + paintPolygon(control, e); + } + } else if(control.text != null) { + paintText(control, e); + } + e.gc.setAlpha(alpha); + e.gc.setFont(current); + } + +} diff --git a/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VTracker.java b/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VTracker.java index ca24b855f..7377e309c 100644 --- a/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VTracker.java +++ b/widgets/cwt/org.eclipse.nebula.cwt/src/org/eclipse/nebula/cwt/v/VTracker.java @@ -1,430 +1,430 @@ -/**************************************************************************** -* Copyright (c) 2008, 2009 Jeremy Dowdall -* - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 -* -* Contributors: -* Jeremy Dowdall - initial API and implementation -* Thorsten Hake - Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=419447 -*****************************************************************************/ - -package org.eclipse.nebula.cwt.v; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Widget; - -public class VTracker implements DisposeListener { - - private static VTracker tracker; - - static void addTopLevelPanel(VPanel panel) { - VTracker tracker = instance(); - if(tracker.panels == null) { - tracker.panels = new HashMap(); - } - tracker.panels.put(panel.composite, panel); - if(!tracker.listening) { - tracker.listening = true; - Display.getDefault().addFilter(SWT.FocusIn, tracker.filter); - Display.getDefault().addFilter(SWT.MouseMove, tracker.filter); - Display.getDefault().addFilter(SWT.MouseDown, tracker.filter); - Display.getDefault().addFilter(SWT.MouseUp, tracker.filter); - Display.getDefault().addFilter(SWT.Traverse, tracker.filter); - } - panel.composite.addDisposeListener(tracker); - } - - public static void deactivate() { - instance().deactivate(getActiveControl()); - } - - public static int getLastTraverse() { - return instance().lastTraverse; - } - - public static int getMouseDownButton() { - return instance().mouseButton; - } - - public static Point getMouseDownLocation() { - return instance().mouseDown; - } - - public static boolean isFocusControl(Control control) { - VControl focusControl = instance().focusControl; - return (focusControl != null) && focusControl.isSameWidgetAs(control); - } - - public static boolean isMouseDown() { - return instance().mouseDown != null; - } - - public static VControl getFocusControl() { - return instance().focusControl; - } - - public static VControl getActiveControl() { - return instance().activeControl; - } - - private static boolean setFocusFromPrev(Control control) { - Control c = null; - Composite parent = control.getParent(); - if(parent == null) { - c = control; - } else { - Control[] ca = parent.getTabList(); - for(int i = 0; i < ca.length; i++) { - if(ca[i] == control) { - if(i == ca.length-1) { - c = ca[0]; - } else { - c = ca[i+1]; - } - break; - } - } - } - if(c != null) { - c.setFocus(); - } - return false; - } - - private static boolean setFocusFromNext(Control control) { - Control c = null; - Composite parent = control.getParent(); - if(parent == null) { - c = control; - } else { - Control[] ca = parent.getTabList(); - for(int i = 0; i < ca.length; i++) { - if(ca[i] == control) { - if(i == 0) { - c = ca[ca.length-1]; - } else { - c = ca[i-1]; - } - break; - } - } - } - if(c != null) { - c.setFocus(); - } - return false; - } - - private static void setFocusToNext(Composite comp) { - if(comp != null) { - Composite parent = comp.getParent(); - Control[] controls = parent.getTabList(); - if(parent instanceof Shell) { - for(int i = 0; i < controls.length; i++) { - if(controls[i] == comp) { - for(int j = 0; j < controls.length; j++) { - i++; - if(i > controls.length-1) { - i = 0; - } - if(controls[i].forceFocus()) { - return; - } - } - } - } - } else { - for(int i = 0; i < controls.length; i++) { - if(controls[i] == comp) { - for( ; i < controls.length-1; i++) { - if(controls[i+1].forceFocus()) { - return; - } - } - setFocusToNext(comp.getParent()); - } - } - } - } - } - - private static void setFocusToPrev(Composite comp) { - if(comp != null) { - Composite parent = comp.getParent(); - Control[] controls = parent.getTabList(); - if(parent instanceof Shell) { - for(int i = 0; i < controls.length; i++) { - if(controls[i] == comp) { - for(int j = 0; j < controls.length; j++) { - i--; - if(i < 0) { - i = controls.length-1; - } - if(controls[i].forceFocus()) { - return; - } - } - } - } - } else { - for(int i = 0; i < controls.length; i++) { - if(controls[i] == comp) { - for(int j=i ; j > 0; j--) { - if(controls[j-1].forceFocus()) { - return; - } - } - setFocusToPrev(comp.getParent()); - } - } - } - } - } - - private static Boolean lock = new Boolean(true); - static VTracker instance() { - if(tracker == null) { - synchronized (lock) { - if(tracker == null) { - tracker = new VTracker(); - } - } - } - return tracker; - } - - private Map panels; - - private VControl activeControl = null; - - private Listener filter = new Listener() { - public void handleEvent(Event event) { - switch (event.type){ - case SWT.Traverse: - lastTraverse = event.detail; - if(SWT.TRAVERSE_TAB_NEXT == event.detail || SWT.TRAVERSE_TAB_PREVIOUS == event.detail) { - if(focusControl != null) { - event.doit = true; - focusControl.handleEvent(event); - if(event.doit) { - Composite comp = focusControl.getWidget(); - if(SWT.TRAVERSE_TAB_NEXT == event.detail) { - setFocusToNext(comp); - } else { - setFocusToPrev(comp); - } - } - } - } - break; - case SWT.FocusIn: - setFocusControl(getVControl(event.widget)); - break; - case SWT.MouseDown: - mouseButton = event.button; - mouseDown = new Point(event.x, event.y); - if(activeControl != null && activeControl.setState(VControl.STATE_MOUSE_DOWN, true)) { - activeControl.redraw(); - } - break; - case SWT.MouseMove: - if(panels.containsKey(event.widget)) { - VControl vcontrol = panels.get(event.widget).getControl(event.x, event.y, true); - if(vcontrol != activeControl && (vcontrol == null || vcontrol.isEnabled())) { - activate(vcontrol); - } - } else if(activeControl != null && event.widget != activeControl.getControl()) { - activeControl.deactivate(); - activeControl = null; - } - break; - case SWT.MouseUp: - mouseButton = -1; - mouseDown = null; - if(activeControl != null && activeControl.setState(VControl.STATE_MOUSE_DOWN, false)) { - activeControl.redraw(); - } - break; - } - } - }; - - public static VControl getVControl(Widget widget) { - if(widget instanceof Shell) { - Control[] ca = ((Shell) widget).getTabList(); - if(ca.length > 0) { - widget = ca[0]; - } - } - Object o = widget.getData("cwt_vcontrol"); - if(o instanceof VControl) { - return (VControl) o; - } - return null; - } - - private VControl focusControl = null; - - private boolean listening = false; - - private int mouseButton = -1; - - private Point mouseDown = null; - - private int lastTraverse = -1; - - private VTracker() { - // singleton - } - - void activate(VControl vcontrol) { - if(activeControl != null && !activeControl.isDisposed()) { - activeControl.deactivate(); - } - activeControl = vcontrol; - if(activeControl != null) { - activeControl.activate(); - } - } - - void deactivate(VControl vcontrol) { - if(vcontrol != null) { - if(!vcontrol.isDisposed()) { - vcontrol.deactivate(); - } - if(activeControl == vcontrol) { - activeControl = null; - } - } - } - - private VControl getNewFocus(VPanel panel) { - for(VControl child : panel.getChildren()) { - if(!child.hasStyle(SWT.NO_FOCUS)) { - if(child instanceof VPanel) { - VControl newFocus = getNewFocus((VPanel) child); - if(newFocus != null) { - return newFocus; - } - } else { - return child; - } - } - } - return null; - } - - boolean setFocusControl(VControl control) { - VControl newFocus = control; - if(newFocus instanceof VPanel) { - newFocus = getNewFocus((VPanel) newFocus); - } else if(control != null && control.hasStyle(SWT.NO_FOCUS)) { - return false; - } - - if(newFocus == focusControl) { - if(newFocus != null && !newFocus.isDisposed()) { - return newFocus.getControl().forceFocus(); - } - return false; - } - - try { - Display.getDefault().removeFilter(SWT.FocusIn, filter); - - VControl oldFocus = focusControl; - if(oldFocus != null && !oldFocus.isDisposed()) { - oldFocus.setFocus(false); - } - if(newFocus != null) { - if(!newFocus.isDisposed() && newFocus.setFocus(true)) { - if (!newFocus.getControl().forceFocus()) { - return false; - } - } else { - return false; - } - } - focusControl = newFocus; - if(newFocus != null) { - newFocus.redraw(); - } - if(oldFocus != null && !oldFocus.isDisposed()) { - oldFocus.redraw(); - } - notifyWidgetFocusListeners(focusControl, oldFocus); - if(newFocus != null) { - return true; - } - return false; - } finally { - Display.getDefault().addFilter(SWT.FocusIn, filter); - } - } - - private void notifyWidgetFocusListeners(VControl newFocus, VControl oldFocus) { - if(newFocus != null && !newFocus.isSameWidgetAs(oldFocus)) { - Widget widget = newFocus.getWidget(); - if(widget.getData("cwt_focus") == null) { //$NON-NLS-1$ - widget.setData("cwt_focus", this); //$NON-NLS-1$ - Event event = new Event(); - event.widget = widget; - event.data = this; - event.type = SWT.FocusIn; - event.widget.notifyListeners(SWT.FocusIn, event); - } - } - if((newFocus == null || !(newFocus instanceof VButton) || ((VButton)newFocus).getParent().getData("PickerPart") == null) //$NON-NLS-1$ - && (oldFocus != null && !oldFocus.isSameWidgetAs(newFocus))) { - Widget widget = oldFocus.getWidget(); - if(widget.getData("cwt_focus") != null) { //$NON-NLS-1$ - widget.setData("cwt_focus", null); //$NON-NLS-1$ - Event event = new Event(); - event.widget = widget; - event.data = this; - event.type = SWT.FocusOut; - event.widget.notifyListeners(SWT.FocusOut, event); - } - } - } - - public void widgetDisposed(DisposeEvent e) { - VTracker tracker = instance(); - if(tracker.panels != null && tracker.panels.containsKey(e.widget)) { - tracker.panels.remove(e.widget); - if(tracker.panels.isEmpty()) { - Display.getDefault().removeFilter(SWT.FocusIn, tracker.filter); - Display.getDefault().removeFilter(SWT.MouseMove, tracker.filter); - Display.getDefault().removeFilter(SWT.MouseDown, tracker.filter); - Display.getDefault().removeFilter(SWT.MouseUp, tracker.filter); - Display.getDefault().removeFilter(SWT.Traverse, tracker.filter); - tracker.listening = false; - if(activeControl != null) { - Control control = activeControl.getControl(); - if(control != null && !control.isDisposed()) { - control.dispose(); - } - } - tracker.panels = null; - } - } - } - -} +/**************************************************************************** +* Copyright (c) 2008, 2009 Jeremy Dowdall +* + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* Jeremy Dowdall - initial API and implementation +* Thorsten Hake - Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=419447 +*****************************************************************************/ + +package org.eclipse.nebula.cwt.v; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Widget; + +public class VTracker implements DisposeListener { + + private static VTracker tracker; + + static void addTopLevelPanel(VPanel panel) { + VTracker tracker = instance(); + if(tracker.panels == null) { + tracker.panels = new HashMap(); + } + tracker.panels.put(panel.composite, panel); + if(!tracker.listening) { + tracker.listening = true; + Display.getDefault().addFilter(SWT.FocusIn, tracker.filter); + Display.getDefault().addFilter(SWT.MouseMove, tracker.filter); + Display.getDefault().addFilter(SWT.MouseDown, tracker.filter); + Display.getDefault().addFilter(SWT.MouseUp, tracker.filter); + Display.getDefault().addFilter(SWT.Traverse, tracker.filter); + } + panel.composite.addDisposeListener(tracker); + } + + public static void deactivate() { + instance().deactivate(getActiveControl()); + } + + public static int getLastTraverse() { + return instance().lastTraverse; + } + + public static int getMouseDownButton() { + return instance().mouseButton; + } + + public static Point getMouseDownLocation() { + return instance().mouseDown; + } + + public static boolean isFocusControl(Control control) { + VControl focusControl = instance().focusControl; + return (focusControl != null) && focusControl.isSameWidgetAs(control); + } + + public static boolean isMouseDown() { + return instance().mouseDown != null; + } + + public static VControl getFocusControl() { + return instance().focusControl; + } + + public static VControl getActiveControl() { + return instance().activeControl; + } + + private static boolean setFocusFromPrev(Control control) { + Control c = null; + Composite parent = control.getParent(); + if(parent == null) { + c = control; + } else { + Control[] ca = parent.getTabList(); + for(int i = 0; i < ca.length; i++) { + if(ca[i] == control) { + if(i == ca.length-1) { + c = ca[0]; + } else { + c = ca[i+1]; + } + break; + } + } + } + if(c != null) { + c.setFocus(); + } + return false; + } + + private static boolean setFocusFromNext(Control control) { + Control c = null; + Composite parent = control.getParent(); + if(parent == null) { + c = control; + } else { + Control[] ca = parent.getTabList(); + for(int i = 0; i < ca.length; i++) { + if(ca[i] == control) { + if(i == 0) { + c = ca[ca.length-1]; + } else { + c = ca[i-1]; + } + break; + } + } + } + if(c != null) { + c.setFocus(); + } + return false; + } + + private static void setFocusToNext(Composite comp) { + if(comp != null) { + Composite parent = comp.getParent(); + Control[] controls = parent.getTabList(); + if(parent instanceof Shell) { + for(int i = 0; i < controls.length; i++) { + if(controls[i] == comp) { + for(int j = 0; j < controls.length; j++) { + i++; + if(i > controls.length-1) { + i = 0; + } + if(controls[i].forceFocus()) { + return; + } + } + } + } + } else { + for(int i = 0; i < controls.length; i++) { + if(controls[i] == comp) { + for( ; i < controls.length-1; i++) { + if(controls[i+1].forceFocus()) { + return; + } + } + setFocusToNext(comp.getParent()); + } + } + } + } + } + + private static void setFocusToPrev(Composite comp) { + if(comp != null) { + Composite parent = comp.getParent(); + Control[] controls = parent.getTabList(); + if(parent instanceof Shell) { + for(int i = 0; i < controls.length; i++) { + if(controls[i] == comp) { + for(int j = 0; j < controls.length; j++) { + i--; + if(i < 0) { + i = controls.length-1; + } + if(controls[i].forceFocus()) { + return; + } + } + } + } + } else { + for(int i = 0; i < controls.length; i++) { + if(controls[i] == comp) { + for(int j=i ; j > 0; j--) { + if(controls[j-1].forceFocus()) { + return; + } + } + setFocusToPrev(comp.getParent()); + } + } + } + } + } + + private static Boolean lock = new Boolean(true); + static VTracker instance() { + if(tracker == null) { + synchronized (lock) { + if(tracker == null) { + tracker = new VTracker(); + } + } + } + return tracker; + } + + private Map panels; + + private VControl activeControl = null; + + private Listener filter = new Listener() { + public void handleEvent(Event event) { + switch (event.type){ + case SWT.Traverse: + lastTraverse = event.detail; + if(SWT.TRAVERSE_TAB_NEXT == event.detail || SWT.TRAVERSE_TAB_PREVIOUS == event.detail) { + if(focusControl != null) { + event.doit = true; + focusControl.handleEvent(event); + if(event.doit) { + Composite comp = focusControl.getWidget(); + if(SWT.TRAVERSE_TAB_NEXT == event.detail) { + setFocusToNext(comp); + } else { + setFocusToPrev(comp); + } + } + } + } + break; + case SWT.FocusIn: + setFocusControl(getVControl(event.widget)); + break; + case SWT.MouseDown: + mouseButton = event.button; + mouseDown = new Point(event.x, event.y); + if(activeControl != null && activeControl.setState(VControl.STATE_MOUSE_DOWN, true)) { + activeControl.redraw(); + } + break; + case SWT.MouseMove: + if(panels.containsKey(event.widget)) { + VControl vcontrol = panels.get(event.widget).getControl(event.x, event.y, true); + if(vcontrol != activeControl && (vcontrol == null || vcontrol.isEnabled())) { + activate(vcontrol); + } + } else if(activeControl != null && event.widget != activeControl.getControl()) { + activeControl.deactivate(); + activeControl = null; + } + break; + case SWT.MouseUp: + mouseButton = -1; + mouseDown = null; + if(activeControl != null && activeControl.setState(VControl.STATE_MOUSE_DOWN, false)) { + activeControl.redraw(); + } + break; + } + } + }; + + public static VControl getVControl(Widget widget) { + if(widget instanceof Shell) { + Control[] ca = ((Shell) widget).getTabList(); + if(ca.length > 0) { + widget = ca[0]; + } + } + Object o = widget.getData("cwt_vcontrol"); + if(o instanceof VControl) { + return (VControl) o; + } + return null; + } + + private VControl focusControl = null; + + private boolean listening = false; + + private int mouseButton = -1; + + private Point mouseDown = null; + + private int lastTraverse = -1; + + private VTracker() { + // singleton + } + + void activate(VControl vcontrol) { + if(activeControl != null && !activeControl.isDisposed()) { + activeControl.deactivate(); + } + activeControl = vcontrol; + if(activeControl != null) { + activeControl.activate(); + } + } + + void deactivate(VControl vcontrol) { + if(vcontrol != null) { + if(!vcontrol.isDisposed()) { + vcontrol.deactivate(); + } + if(activeControl == vcontrol) { + activeControl = null; + } + } + } + + private VControl getNewFocus(VPanel panel) { + for(VControl child : panel.getChildren()) { + if(!child.hasStyle(SWT.NO_FOCUS)) { + if(child instanceof VPanel) { + VControl newFocus = getNewFocus((VPanel) child); + if(newFocus != null) { + return newFocus; + } + } else { + return child; + } + } + } + return null; + } + + boolean setFocusControl(VControl control) { + VControl newFocus = control; + if(newFocus instanceof VPanel) { + newFocus = getNewFocus((VPanel) newFocus); + } else if(control != null && control.hasStyle(SWT.NO_FOCUS)) { + return false; + } + + if(newFocus == focusControl) { + if(newFocus != null && !newFocus.isDisposed()) { + return newFocus.getControl().forceFocus(); + } + return false; + } + + try { + Display.getDefault().removeFilter(SWT.FocusIn, filter); + + VControl oldFocus = focusControl; + if(oldFocus != null && !oldFocus.isDisposed()) { + oldFocus.setFocus(false); + } + if(newFocus != null) { + if(!newFocus.isDisposed() && newFocus.setFocus(true)) { + if (!newFocus.getControl().forceFocus()) { + return false; + } + } else { + return false; + } + } + focusControl = newFocus; + if(newFocus != null) { + newFocus.redraw(); + } + if(oldFocus != null && !oldFocus.isDisposed()) { + oldFocus.redraw(); + } + notifyWidgetFocusListeners(focusControl, oldFocus); + if(newFocus != null) { + return true; + } + return false; + } finally { + Display.getDefault().addFilter(SWT.FocusIn, filter); + } + } + + private void notifyWidgetFocusListeners(VControl newFocus, VControl oldFocus) { + if(newFocus != null && !newFocus.isSameWidgetAs(oldFocus)) { + Widget widget = newFocus.getWidget(); + if(widget.getData("cwt_focus") == null) { //$NON-NLS-1$ + widget.setData("cwt_focus", this); //$NON-NLS-1$ + Event event = new Event(); + event.widget = widget; + event.data = this; + event.type = SWT.FocusIn; + event.widget.notifyListeners(SWT.FocusIn, event); + } + } + if((newFocus == null || !(newFocus instanceof VButton) || ((VButton)newFocus).getParent().getData("PickerPart") == null) //$NON-NLS-1$ + && (oldFocus != null && !oldFocus.isSameWidgetAs(newFocus))) { + Widget widget = oldFocus.getWidget(); + if(widget.getData("cwt_focus") != null) { //$NON-NLS-1$ + widget.setData("cwt_focus", null); //$NON-NLS-1$ + Event event = new Event(); + event.widget = widget; + event.data = this; + event.type = SWT.FocusOut; + event.widget.notifyListeners(SWT.FocusOut, event); + } + } + } + + public void widgetDisposed(DisposeEvent e) { + VTracker tracker = instance(); + if(tracker.panels != null && tracker.panels.containsKey(e.widget)) { + tracker.panels.remove(e.widget); + if(tracker.panels.isEmpty()) { + Display.getDefault().removeFilter(SWT.FocusIn, tracker.filter); + Display.getDefault().removeFilter(SWT.MouseMove, tracker.filter); + Display.getDefault().removeFilter(SWT.MouseDown, tracker.filter); + Display.getDefault().removeFilter(SWT.MouseUp, tracker.filter); + Display.getDefault().removeFilter(SWT.Traverse, tracker.filter); + tracker.listening = false; + if(activeControl != null) { + Control control = activeControl.getControl(); + if(control != null && !control.isDisposed()) { + control.dispose(); + } + } + tracker.panels = null; + } + } + } + +} diff --git a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/.classpath b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/.classpath index 672067f1e..d499d3059 100644 --- a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/.classpath +++ b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/.settings/org.eclipse.jdt.core.prefs b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/.settings/org.eclipse.jdt.core.prefs index a8ab67359..64fef7776 100644 --- a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/.settings/org.eclipse.jdt.core.prefs @@ -1,72 +1,72 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullReference=ignore -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.doc.comment.support=enabled +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error +org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/AbstractCombo.java b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/AbstractCombo.java index d682e050e..e8e32cb9e 100644 --- a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/AbstractCombo.java +++ b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/AbstractCombo.java @@ -1,1206 +1,1206 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - * Eric Wuillai - modification of CCombo into an abstract combo - *******************************************************************************/ -package org.eclipse.nebula.widgets.datechooser; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.TypedListener; - -/** - * Abstract class for combo widgets composed of a Text, a - * Button and a popup associated to the button. - *

- * - * The creation of text, button and popup content is delegated to abstract - * methods. - *

- * - * Note that although this class is a subclass of Composite, - * it does not make sense to add children to it, or set a layout on it. - *

- * - *

- *
Styles: - *
BORDER, READ_ONLY, FLAT
- *
Events: - *
Selection
- *
- */ -public abstract class AbstractCombo extends Composite { - /** GTK platform constant */ - public static final boolean GTK = "gtk".equals(SWT.getPlatform()); - /** WIN32 platform constant */ - public static final boolean WIN32 = "win32".equals(SWT.getPlatform()); - - /** The parent Shell */ - Shell _shell; - /** Text widget for the input */ - protected Text text; - /** Popup shell for the selection */ - protected Shell popup; - /** Button opening the popup */ - protected Button button; - /** Content of the popup */ - protected Control popupContent; - /** Listener for all internal events */ - protected Listener listener; - /** Listener for external events */ - protected Listener filter; - /** Flag indicating if the widget has focus or not */ - protected boolean hasFocus; - /** Flag to show button only if combo has the focus */ - protected boolean showButtonOnFocus = false; - /** Flag indicating that the popup content must be created each time the combo is dropped */ - protected boolean createOnDrop = false; - - /** - * Constructs a new instance of this class given its parent - * and a style value describing its behavior and appearance. - *

- * - * @param parent a widget which will be the parent of the new instance (cannot be null) - * @param style the style of widget to construct - */ - public AbstractCombo(Composite parent, int style) { - super(parent, style = checkStyle(style)); - _shell = super.getShell(); - GridLayout layout = new GridLayout(2, false); - layout.horizontalSpacing = layout.marginWidth = layout.marginHeight = 0; - super.setLayout(layout); - - // Creates the Text widget - int textStyle = SWT.SINGLE; - if ((style & SWT.READ_ONLY) != 0) - textStyle |= SWT.READ_ONLY; - if ((style & SWT.FLAT) != 0) - textStyle |= SWT.FLAT; - text = createTextControl(textStyle); - GridData data = new GridData(GridData.FILL_BOTH); - text.setLayoutData(data); - - int buttonStyle = SWT.ARROW | SWT.DOWN; - if ((style & SWT.FLAT) != 0) - buttonStyle |= SWT.FLAT; - button = createButtonControl(buttonStyle); - button.setLayoutData(new GridData(GridData.FILL_VERTICAL)); - - listener = new Listener() { - public void handleEvent(Event event) { - if (popup == event.widget) { - popupEvent(event); - return; - } - if (text == event.widget) { - textEvent(event); - return; - } - if (popupContent == event.widget) { - contentEvent(event); - return; - } - if (button == event.widget) { - buttonEvent(event); - return; - } - if (AbstractCombo.this == event.widget) { - comboEvent(event); - return; - } - if (getShell() == event.widget) { - getDisplay().asyncExec(new Runnable() { - public void run() { - if (isDisposed()) - return; - handleFocus(SWT.FocusOut); - } - }); - } - } - }; - filter = new Listener() { - public void handleEvent(Event event) { - if (isDisposed()) - return; - Shell shell = ((Control) event.widget).getShell(); - if (shell == AbstractCombo.this.getShell()) { - handleFocus(SWT.FocusOut); - } - } - }; - - // comboEvent - this.addListener(SWT.Dispose, listener); - this.addListener(SWT.FocusIn, listener); - this.addListener(SWT.Move, listener); - // textEvent - text.addListener(SWT.Modify, listener); - text.addListener(SWT.FocusIn, listener); - text.addListener(SWT.KeyDown, listener); - text.addListener(SWT.Traverse, listener); - // buttonEvent - button.addListener(SWT.FocusIn, listener); - button.addListener(SWT.MouseDown, listener); - button.addListener(SWT.MouseUp, listener); - button.addListener(SWT.Selection, listener); - } - - static int checkStyle(int style) { - int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; - return SWT.NO_FOCUS | (style & mask); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the receiver's text is modified, by sending - * it one of the messages defined in the ModifyListener - * interface. - * - * @param listener the listener which should be notified - * @exception IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * @see ModifyListener - * @see #removeModifyListener - */ - public void addModifyListener(ModifyListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener(listener); - addListener(SWT.Modify, typedListener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the receiver's selection changes, by sending - * it one of the messages defined in the SelectionListener - * interface. - *

- * widgetSelected is called when the combo's list selection changes. - * widgetDefaultSelected is typically called when ENTER is pressed the combo's text area. - *

- * - * @param listener the listener which should be notified - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(SelectionListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener(listener); - addListener(SWT.Selection, typedListener); - addListener(SWT.DefaultSelection, typedListener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the receiver's text is verified, by sending - * it one of the messages defined in the VerifyListener - * interface. - * - * @param listener the listener which should be notified - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * @see VerifyListener - * @see #removeVerifyListener - */ - public void addVerifyListener(VerifyListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener(listener); - addListener(SWT.Verify, typedListener); - } - - /** - * Called just before the popup is dropped. Override to execute actions - * before the apparition of the popup. - *

- * - * By default, do nothing. - */ - protected void beforeDrop() { - } - - /** - * Manages button events. - * - * @param event event - */ - protected void buttonEvent(Event event) { - switch (event.type) { - case SWT.FocusIn: - handleFocus(SWT.FocusIn); - break; - case SWT.MouseDown: { - Event mouseEvent = new Event(); - mouseEvent.button = event.button; - mouseEvent.count = event.count; - mouseEvent.stateMask = event.stateMask; - mouseEvent.time = event.time; - mouseEvent.x = event.x; - mouseEvent.y = event.y; - notifyListeners(SWT.MouseDown, mouseEvent); - event.doit = mouseEvent.doit; - break; - } - case SWT.MouseUp: { - Event mouseEvent = new Event(); - mouseEvent.button = event.button; - mouseEvent.count = event.count; - mouseEvent.stateMask = event.stateMask; - mouseEvent.time = event.time; - mouseEvent.x = event.x; - mouseEvent.y = event.y; - notifyListeners(SWT.MouseUp, mouseEvent); - event.doit = mouseEvent.doit; - break; - } - case SWT.Selection: - text.setFocus(); - dropDown(!isDropped()); - break; - } - } - - /** - * Manages global combo events. - * - * @param event event - */ - protected void comboEvent(Event event) { - switch (event.type) { - case SWT.Dispose: { - removeListener(SWT.Dispose, listener); - notifyListeners(SWT.Dispose, event); - event.type = SWT.None; - - if (popup != null && !popup.isDisposed()) { - popupContent.removeListener(SWT.Dispose, listener); - popup.dispose(); - } - getShell().removeListener(SWT.Deactivate, listener); - getDisplay().removeFilter(SWT.FocusIn, filter); - popup = null; - text = null; - popupContent = null; - button = null; - _shell = null; - break; - } - case SWT.FocusIn: { - Control focusControl = getDisplay().getFocusControl(); - if (focusControl == button || focusControl == popupContent) - return; - if (isDropped()) { - popupContent.setFocus(); - } else { - text.setFocus(); - } - break; - } - case SWT.Move: - dropDown(false); - break; - } - } - - /** - * Manages popup content events. SelectionEvent are notified to all - * registered SelectionListeners of the combo. - * - * @param event event - */ - protected void contentEvent(Event event) { - switch (event.type) { - case SWT.FocusIn: - handleFocus(SWT.FocusIn); - break; - case SWT.Selection: { - if (doSelection()) { - dropDown(false); - Event e = new Event(); - e.time = event.time; - e.stateMask = event.stateMask; - e.doit = event.doit; - e.data = event.data; - notifyListeners(SWT.Selection, e); - event.doit = e.doit; - } - break; - } - } - } - - /** - * Copies the selected text. - *

- * The current selection is copied to the clipboard. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void copy() { - checkWidget(); - text.copy(); - } - - /** - * Creates the arrow button widget. Override to change appearance or - * behavior of the button. - * - * @param style button style - * @return The created button - */ - protected Button createButtonControl(int style) { - Button button = new Button(this, style); - return button; - } - - /** - * Creates the popup that will be displayed when the button is selected. - * Popup is a new Shell containing a unique Control. The content is specific - * to each implementation of the Combo and is created overriding the - * createPopupContent method. - */ - protected void createPopup() { - popup = new Shell(getShell(), SWT.TOOL | SWT.ON_TOP); - popupContent = createPopupContent(popup); - popupContent.setFont(text.getFont()); - popupContent.setBackground(text.getBackground()); - popupContent.setForeground(text.getForeground()); - popup.pack(); - - popup.addListener(SWT.Close, listener); - popup.addListener(SWT.Deactivate, listener); - popupContent.addListener(SWT.FocusIn, listener); - popupContent.addListener(SWT.Selection, listener); - } - - /** - * Creates the popup content. The popup is dependent of each implementation. - * Content can be a List, a Table or every other - * control.
- * The popupContent attribute must be set with the created - * control. The parent must be the shell attribute, that is - * initialized by default with a FillLayout. - * - * @param parent The parent Composite that will contain the control - * @return The created Control for the popup content - */ - protected abstract Control createPopupContent(Composite parent); - - /** - * Creates the text widget. Override to change appearance or behavior of - * the default text that is created here. - * - * @param style text style - * @return the created Text control - */ - protected Text createTextControl(int style) { - Text text = new Text(this, style); - return text; - } - - /** - * Cuts the selected text. - *

- * The current selection is first copied to the clipboard and then deleted - * from the widget. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void cut() { - checkWidget(); - text.cut(); - } - - /** - * This method is called when a SWT.Selection is notify in the popup content, - * allowing to update the Text widget content. - * - * @return true if the SWT.Selection event must be propagated, else false - */ - protected abstract boolean doSelection(); - - /** - * Manages drop down of the popup. - * - * @param drop true to drop the popup, false to close - */ - protected void dropDown(boolean drop) { - if (drop == isDropped()) - return; - - if (!drop) { - if (popup != null) { - popup.setVisible(false); - if (createOnDrop) { - popup.dispose(); - popup = null; - popupContent = null; - } - } - if (!isDisposed() && isFocusControl()) { - text.setFocus(); - } - return; - } - if (!isVisible()) - return; - if (popup == null || getShell() != popup.getParent()) { - if (popup != null) { - popup.dispose(); - popup = null; - popupContent = null; - } - createPopup(); - } - setPopupLocation(); - beforeDrop(); - popup.setVisible(true); - if (isFocusControl()) - popupContent.setFocus(); - } - - /** - * Gets the editable state. - * - * @return whether or not the receiver is editable - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public boolean getEditable() { - checkWidget(); - return text.getEditable(); - } - - /** - * Returns true if the receiver's popup is visible, - * and false otherwise. - *

- * If one of the receiver's ancestors is not visible or some - * other condition makes the receiver not visible, this method - * may still indicate that it is considered visible even though - * it may not actually be showing. - *

- * - * @return the receiver's popup's visibility state - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public boolean getPopupVisible() { - checkWidget(); - return isDropped(); - } - - /** - * Returns a Point whose x coordinate is the start of the - * selection in the receiver's text field, and whose y coordinate is the end - * of the selection. The returned values are zero-relative. An "empty" - * selection as indicated by the the x and y coordinates having the same - * value. - * - * @return a point representing the selection start and end - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Point getSelection() { - checkWidget(); - return text.getSelection(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.swt.widgets.Control#getShell() - */ - public Shell getShell() { - checkWidget(); - Shell shell = super.getShell(); - if (shell != _shell) { - if (_shell != null && !_shell.isDisposed()) { - _shell.removeListener(SWT.Deactivate, listener); - } - _shell = shell; - } - return _shell; - } - - /** - * Returns the receiver's style information. - * - * @see org.eclipse.swt.widgets.Widget#getStyle() - */ - public int getStyle() { - int style = super.getStyle(); - style &= ~SWT.READ_ONLY; - if (!text.getEditable()) - style |= SWT.READ_ONLY; - return style; - } - - /** - * Returns a string containing a copy of the contents of the receiver's text - * field. - * - * @return the receiver's text - */ - public String getText() { - checkWidget(); - return text.getText(); - } - - /** - * Returns the height of the receivers's text field. - * - * @return the text height - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getTextHeight() { - checkWidget(); - return text.getLineHeight(); - } - - /** - * Returns the maximum number of characters that the receiver's - * text field is capable of holding. If this has not been changed - * by setTextLimit(), it will be the constant - * Combo.LIMIT. - * - * @return the text limit - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getTextLimit() { - checkWidget(); - return text.getTextLimit(); - } - - /** - * Manages the focus on the combo. - * - * @param type SWT.FocusIn or SWT.FocusOut - */ - protected void handleFocus(int type) { - if (isDisposed()) - return; - switch (type) { - case SWT.FocusIn: { - if (hasFocus) - return; - hasFocus = true; - updateButtonDisplay(); - Shell shell = getShell(); - shell.removeListener(SWT.Deactivate, listener); - shell.addListener(SWT.Deactivate, listener); - Display display = getDisplay(); - display.removeFilter(SWT.FocusIn, filter); - display.addFilter(SWT.FocusIn, filter); - notifyListeners(SWT.FocusIn, new Event()); - break; - } - case SWT.FocusOut: { - if (!hasFocus) - return; - Control focusControl = getDisplay().getFocusControl(); - if (focusControl == button || (popupContent != null && popupContent.isFocusControl()) || focusControl == text) - return; - hasFocus = false; - updateButtonDisplay(); - Shell shell = getShell(); - shell.removeListener(SWT.Deactivate, listener); - getDisplay().removeFilter(SWT.FocusIn, filter); - notifyListeners(SWT.FocusOut, new Event()); - break; - } - } - } - - /** - * Returns true if popup is dropped (visible), else false. - * - * @return boolean indicating if popup is dropped - */ - protected boolean isDropped() { - return popup != null && !popup.isDisposed() && popup.getVisible(); - } - - /** - * Returns true if the receiver has the user-interface focus, - * and false otherwise. - * - * @see org.eclipse.swt.widgets.Control#isFocusControl() - */ - public boolean isFocusControl() { - checkWidget(); - if (text.isFocusControl() || button.isFocusControl() || (popupContent != null && popupContent.isFocusControl()) || (popup != null && popup.isFocusControl())) { - return true; - } - return super.isFocusControl(); - } - - /** - * Returns true if button is displayed only when the combo has - * has focus and false otherwise. - * - * @return boolean indicating if combo must show button only on focus - */ - public boolean isShowButtonOnFocus() { - return showButtonOnFocus; - } - - /** - * Pastes text from clipboard. - *

- * The selected text is deleted from the widget - * and new text inserted from the clipboard. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void paste() { - checkWidget(); - text.paste(); - } - - /** - * Manages popup shell events. - * - * @param event event - */ - protected void popupEvent(Event event) { - switch (event.type) { - case SWT.Close: - event.doit = false; - dropDown(false); - break; - case SWT.Deactivate: - /* - * Bug in GTK. When the arrow button is pressed the popup control receives a - * deactivate event and then the arrow button receives a selection event. If - * we hide the popup in the deactivate event, the selection event will show - * it again. To prevent the popup from showing again, we will let the selection - * event of the arrow button hide the popup. - * In Windows, hiding the popup during the deactivate causes the deactivate - * to be called twice and the selection event to be disappear. - */ - if (!"carbon".equals(SWT.getPlatform())) { - Point point = button.toControl(getDisplay().getCursorLocation()); - Point size = button.getSize(); - Rectangle rect = new Rectangle(0, 0, size.x, size.y); - if (!rect.contains(point)) - dropDown(false); - } else { - dropDown(false); - } - break; - } - } - - /** - * Causes the entire bounds of the receiver to be marked as needing to be - * redrawn. The next time a paint request is processed, the control will be - * completely painted, including the background. - */ - public void redraw() { - super.redraw(); - text.redraw(); - button.redraw(); - if (popup.isVisible()) - popupContent.redraw(); - } - - /** - * Causes the rectangular area of the receiver specified by the arguments to - * be marked as needing to be redrawn. The next time a paint request is - * processed, that area of the receiver will be painted, including the - * background. If the all flag is true, any children of the receiver which - * intersect with the specified area will also paint their intersecting - * areas. If the all flag is false, the children will not be painted. - * - * @param x - * @param y - * @param width - * @param height - * @param all - */ - public void redraw(int x, int y, int width, int height, boolean all) { - super.redraw(x, y, width, height, true); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the receiver's text is modified. - * - * @param listener the listener which should no longer be notified - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * @see ModifyListener - * @see #addModifyListener - */ - public void removeModifyListener(ModifyListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - removeListener(SWT.Modify, listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the receiver's selection changes. - * - * @param listener the listener which should no longer be notified - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(SelectionListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - removeListener(SWT.Selection, listener); - removeListener(SWT.DefaultSelection, listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the control is verified. - * - * @param listener the listener which should no longer be notified - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * @see VerifyListener - * @see #addVerifyListener - */ - public void removeVerifyListener(VerifyListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - removeListener(SWT.Verify, listener); - } - - /** - * Selects all the text in the receiver. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void selectAll() { - checkWidget(); - text.selectAll(); - } - - /** - * Sets the receiver's background color to the color specified by the - * argument, or to the default system color for the control if the argument - * is null. - * - * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) - */ - public void setBackground(Color color) { - super.setBackground(color); - if (text != null) - text.setBackground(color); - if (button != null) - button.setBackground(color); - if (popupContent != null) - popupContent.setBackground(color); - } - - /** - * Sets the flag indicating if the popup content must be created each time - * the combo is dropped. - * It can be necessary to set this flag to true when the popup content use - * to many controls, as the DateChooser. - * - * @param createOnDrop true if popup is recreated at each drop, else false - */ - protected void setCreateOnDrop(boolean createOnDrop) { - this.createOnDrop = createOnDrop; - } - - /** - * Sets the editable state. - * - * @param editable the new editable state - */ - public void setEditable(boolean editable) { - checkWidget(); - text.setEditable(editable); - button.setEnabled(editable); - } - - /** - * Enables the receiver if the argument is true, and disables it - * otherwise. - * - * @see org.eclipse.swt.widgets.Control#setEnabled(boolean) - */ - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - if (isDropped()) - dropDown(false); - if (text != null) - text.setEnabled(enabled); - if (button != null) - button.setEnabled(enabled); - } - - /** - * Causes the receiver to have the keyboard focus, such that all keyboard - * events will be delivered to it. - * - * @see org.eclipse.swt.widgets.Control#setFocus() - */ - public boolean setFocus() { - checkWidget(); - if (!isEnabled() || !isVisible()) - return false; - if (isFocusControl()) - return true; - return text.setFocus(); - } - - /** - * Sets the font that the receiver will use to paint textual information to - * the font specified by the argument, or to the default font for that kind - * of control if the argument is null. - * - * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font) - */ - public void setFont(Font font) { - super.setFont(font); - text.setFont(font); - if (popupContent != null) { - popupContent.setFont(font); - } - pack(); - } - - /** - * Sets the receiver's foreground color to the color specified by the - * argument, or to the default system color for the control if the argument - * is null. - * - * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color) - */ - public void setForeground(Color color) { - super.setForeground(color); - if (text != null) - text.setForeground(color); - if (button != null) - button.setForeground(color); - if (popupContent != null) - popupContent.setForeground(color); - } - - /** - * Sets the layout which is associated with the receiver to be - * the argument which may be null. - *

- * Note : No Layout can be set on this Control because it already - * manages the size and position of its children. - *

- * - * @param layout the receiver's new layout or null - */ - public void setLayout(Layout layout) { - checkWidget(); - return; - } - - /** - * Sets the receiver's pop up menu to the argument. All controls may - * optionally have a pop up menu that is displayed when the user requests - * one for the control. The sequence of key strokes, button presses and/or - * button releases that are used to request a pop up menu is platform - * specific. - * - * Note: Disposing of a control that has a pop up menu will dispose of the - * menu. To avoid this behavior, set the menu to null before the control - * is disposed. - * - * @param menu the new pop up menu - */ - public void setMenu(Menu menu) { - text.setMenu(menu); - } - - /** - * Calculates and returns the location of popup.
- * Called just before than the popup is dropped. - */ - protected void setPopupLocation() { - Display display = Display.getCurrent(); - Rectangle r = getBounds(); - Point p = display.map(this, null, 0, r.height); - Rectangle sb = display.getBounds(); - if (p.y + popup.getSize().y > sb.height) { - p.y -= r.height + popup.getSize().y + getBorderWidth(); - } - int popx = popup.getSize().x; - if (p.x + popx > sb.width) { - p.x -= popx - r.width + getBorderWidth(); - } else if (popx < r.width) { - p.x += r.width - popx; - } - popup.setLocation(p.x, p.y); - } - - /** - * Sets the selection in the receiver's text field to the - * range specified by the argument whose x coordinate is the - * start of the selection and whose y coordinate is the end - * of the selection. - * - * @param selection a point representing the new selection start and end - */ - public void setSelection(Point selection) { - checkWidget(); - if (selection == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - text.setSelection(selection.x, selection.y); - } - - /** - * Sets the flag indicating if the button must be shown only if the combo - * has the focus (true). - * - * @param showButtonOnFocus true if button must be shown on focus only - */ - public void setShowButtonOnFocus(boolean showButtonOnFocus) { - this.showButtonOnFocus = showButtonOnFocus; - updateButtonDisplay(); - } - - /** - * Sets the maximum number of characters that the receiver's - * text field is capable of holding to be the argument. - * - * @param limit new text limit - * @exception IllegalArgumentException - *
    - *
  • ERROR_CANNOT_BE_ZERO - if the limit is zero
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setTextLimit(int limit) { - checkWidget(); - text.setTextLimit(limit); - } - - /** - * Sets the receiver's tool tip text to the argument, which may be null - * indicating that no tool tip text should be shown. - * - * @param string the new tool tip text (or null) - */ - public void setToolTipText(String string) { - checkWidget(); - super.setToolTipText(string); - button.setToolTipText(string); - text.setToolTipText(string); - } - - /** - * Marks the receiver as visible if the argument is true, and - * marks it invisible otherwise. - * - * @see org.eclipse.swt.widgets.Control#setVisible(boolean) - */ - public void setVisible(boolean visible) { - super.setVisible(visible); - if (isDisposed()) - return; - if (popup == null || popup.isDisposed()) - return; - if (!visible) { - popup.setVisible(false); - } - } - - /** - * Manages text widget events. ModifyEvent are notified to all registered - * ModifyListener of the combo. - * - * @param event event - */ - protected void textEvent(Event event) { - switch (event.type) { - case SWT.FocusIn: - handleFocus(SWT.FocusIn); - break; - case SWT.Modify: { - Event e = new Event(); - e.time = event.time; - notifyListeners(SWT.Modify, e); - break; - } - case SWT.KeyDown: { - Event keyEvent = new Event(); - keyEvent.time = event.time; - keyEvent.character = event.character; - keyEvent.keyCode = event.keyCode; - keyEvent.stateMask = event.stateMask; - notifyListeners(SWT.KeyDown, keyEvent); - if ((event.stateMask & SWT.ALT) != 0 && event.keyCode == SWT.ARROW_DOWN) { - event.doit = false; - dropDown(true); - } - break; - } - case SWT.Traverse: { - switch (event.detail) { - case SWT.TRAVERSE_ARROW_PREVIOUS: - case SWT.TRAVERSE_ARROW_NEXT: - // The enter causes default selection and - // the arrow keys are used to manipulate the list contents so - // do not use them for traversal. - event.doit = false; - break; - case SWT.TRAVERSE_TAB_PREVIOUS: - event.doit = traverse(SWT.TRAVERSE_TAB_PREVIOUS); - event.detail = SWT.TRAVERSE_NONE; - return; - } - Event e = new Event(); - e.time = event.time; - e.detail = event.detail; - e.doit = event.doit; - e.character = event.character; - e.keyCode = event.keyCode; - notifyListeners(SWT.Traverse, e); - event.doit = e.doit; - event.detail = e.detail; - break; - } - } - } - - /** - * Updates the visibility of the button in function of the flag and the focus. - */ - protected void updateButtonDisplay() { - if (showButtonOnFocus) { - GridData data = (GridData) button.getLayoutData(); - data.exclude = !hasFocus; - button.setVisible(hasFocus); - super.layout(false); - } - } -} +/******************************************************************************* + * Copyright (c) 2000, 2009 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + * Eric Wuillai - modification of CCombo into an abstract combo + *******************************************************************************/ +package org.eclipse.nebula.widgets.datechooser; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.TypedListener; + +/** + * Abstract class for combo widgets composed of a Text, a + * Button and a popup associated to the button. + *

+ * + * The creation of text, button and popup content is delegated to abstract + * methods. + *

+ * + * Note that although this class is a subclass of Composite, + * it does not make sense to add children to it, or set a layout on it. + *

+ * + *

+ *
Styles: + *
BORDER, READ_ONLY, FLAT
+ *
Events: + *
Selection
+ *
+ */ +public abstract class AbstractCombo extends Composite { + /** GTK platform constant */ + public static final boolean GTK = "gtk".equals(SWT.getPlatform()); + /** WIN32 platform constant */ + public static final boolean WIN32 = "win32".equals(SWT.getPlatform()); + + /** The parent Shell */ + Shell _shell; + /** Text widget for the input */ + protected Text text; + /** Popup shell for the selection */ + protected Shell popup; + /** Button opening the popup */ + protected Button button; + /** Content of the popup */ + protected Control popupContent; + /** Listener for all internal events */ + protected Listener listener; + /** Listener for external events */ + protected Listener filter; + /** Flag indicating if the widget has focus or not */ + protected boolean hasFocus; + /** Flag to show button only if combo has the focus */ + protected boolean showButtonOnFocus = false; + /** Flag indicating that the popup content must be created each time the combo is dropped */ + protected boolean createOnDrop = false; + + /** + * Constructs a new instance of this class given its parent + * and a style value describing its behavior and appearance. + *

+ * + * @param parent a widget which will be the parent of the new instance (cannot be null) + * @param style the style of widget to construct + */ + public AbstractCombo(Composite parent, int style) { + super(parent, style = checkStyle(style)); + _shell = super.getShell(); + GridLayout layout = new GridLayout(2, false); + layout.horizontalSpacing = layout.marginWidth = layout.marginHeight = 0; + super.setLayout(layout); + + // Creates the Text widget + int textStyle = SWT.SINGLE; + if ((style & SWT.READ_ONLY) != 0) + textStyle |= SWT.READ_ONLY; + if ((style & SWT.FLAT) != 0) + textStyle |= SWT.FLAT; + text = createTextControl(textStyle); + GridData data = new GridData(GridData.FILL_BOTH); + text.setLayoutData(data); + + int buttonStyle = SWT.ARROW | SWT.DOWN; + if ((style & SWT.FLAT) != 0) + buttonStyle |= SWT.FLAT; + button = createButtonControl(buttonStyle); + button.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + + listener = new Listener() { + public void handleEvent(Event event) { + if (popup == event.widget) { + popupEvent(event); + return; + } + if (text == event.widget) { + textEvent(event); + return; + } + if (popupContent == event.widget) { + contentEvent(event); + return; + } + if (button == event.widget) { + buttonEvent(event); + return; + } + if (AbstractCombo.this == event.widget) { + comboEvent(event); + return; + } + if (getShell() == event.widget) { + getDisplay().asyncExec(new Runnable() { + public void run() { + if (isDisposed()) + return; + handleFocus(SWT.FocusOut); + } + }); + } + } + }; + filter = new Listener() { + public void handleEvent(Event event) { + if (isDisposed()) + return; + Shell shell = ((Control) event.widget).getShell(); + if (shell == AbstractCombo.this.getShell()) { + handleFocus(SWT.FocusOut); + } + } + }; + + // comboEvent + this.addListener(SWT.Dispose, listener); + this.addListener(SWT.FocusIn, listener); + this.addListener(SWT.Move, listener); + // textEvent + text.addListener(SWT.Modify, listener); + text.addListener(SWT.FocusIn, listener); + text.addListener(SWT.KeyDown, listener); + text.addListener(SWT.Traverse, listener); + // buttonEvent + button.addListener(SWT.FocusIn, listener); + button.addListener(SWT.MouseDown, listener); + button.addListener(SWT.MouseUp, listener); + button.addListener(SWT.Selection, listener); + } + + static int checkStyle(int style) { + int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; + return SWT.NO_FOCUS | (style & mask); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the receiver's text is modified, by sending + * it one of the messages defined in the ModifyListener + * interface. + * + * @param listener the listener which should be notified + * @exception IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * @see ModifyListener + * @see #removeModifyListener + */ + public void addModifyListener(ModifyListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener(listener); + addListener(SWT.Modify, typedListener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the receiver's selection changes, by sending + * it one of the messages defined in the SelectionListener + * interface. + *

+ * widgetSelected is called when the combo's list selection changes. + * widgetDefaultSelected is typically called when ENTER is pressed the combo's text area. + *

+ * + * @param listener the listener which should be notified + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(SelectionListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener(listener); + addListener(SWT.Selection, typedListener); + addListener(SWT.DefaultSelection, typedListener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the receiver's text is verified, by sending + * it one of the messages defined in the VerifyListener + * interface. + * + * @param listener the listener which should be notified + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * @see VerifyListener + * @see #removeVerifyListener + */ + public void addVerifyListener(VerifyListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener(listener); + addListener(SWT.Verify, typedListener); + } + + /** + * Called just before the popup is dropped. Override to execute actions + * before the apparition of the popup. + *

+ * + * By default, do nothing. + */ + protected void beforeDrop() { + } + + /** + * Manages button events. + * + * @param event event + */ + protected void buttonEvent(Event event) { + switch (event.type) { + case SWT.FocusIn: + handleFocus(SWT.FocusIn); + break; + case SWT.MouseDown: { + Event mouseEvent = new Event(); + mouseEvent.button = event.button; + mouseEvent.count = event.count; + mouseEvent.stateMask = event.stateMask; + mouseEvent.time = event.time; + mouseEvent.x = event.x; + mouseEvent.y = event.y; + notifyListeners(SWT.MouseDown, mouseEvent); + event.doit = mouseEvent.doit; + break; + } + case SWT.MouseUp: { + Event mouseEvent = new Event(); + mouseEvent.button = event.button; + mouseEvent.count = event.count; + mouseEvent.stateMask = event.stateMask; + mouseEvent.time = event.time; + mouseEvent.x = event.x; + mouseEvent.y = event.y; + notifyListeners(SWT.MouseUp, mouseEvent); + event.doit = mouseEvent.doit; + break; + } + case SWT.Selection: + text.setFocus(); + dropDown(!isDropped()); + break; + } + } + + /** + * Manages global combo events. + * + * @param event event + */ + protected void comboEvent(Event event) { + switch (event.type) { + case SWT.Dispose: { + removeListener(SWT.Dispose, listener); + notifyListeners(SWT.Dispose, event); + event.type = SWT.None; + + if (popup != null && !popup.isDisposed()) { + popupContent.removeListener(SWT.Dispose, listener); + popup.dispose(); + } + getShell().removeListener(SWT.Deactivate, listener); + getDisplay().removeFilter(SWT.FocusIn, filter); + popup = null; + text = null; + popupContent = null; + button = null; + _shell = null; + break; + } + case SWT.FocusIn: { + Control focusControl = getDisplay().getFocusControl(); + if (focusControl == button || focusControl == popupContent) + return; + if (isDropped()) { + popupContent.setFocus(); + } else { + text.setFocus(); + } + break; + } + case SWT.Move: + dropDown(false); + break; + } + } + + /** + * Manages popup content events. SelectionEvent are notified to all + * registered SelectionListeners of the combo. + * + * @param event event + */ + protected void contentEvent(Event event) { + switch (event.type) { + case SWT.FocusIn: + handleFocus(SWT.FocusIn); + break; + case SWT.Selection: { + if (doSelection()) { + dropDown(false); + Event e = new Event(); + e.time = event.time; + e.stateMask = event.stateMask; + e.doit = event.doit; + e.data = event.data; + notifyListeners(SWT.Selection, e); + event.doit = e.doit; + } + break; + } + } + } + + /** + * Copies the selected text. + *

+ * The current selection is copied to the clipboard. + *

+ * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void copy() { + checkWidget(); + text.copy(); + } + + /** + * Creates the arrow button widget. Override to change appearance or + * behavior of the button. + * + * @param style button style + * @return The created button + */ + protected Button createButtonControl(int style) { + Button button = new Button(this, style); + return button; + } + + /** + * Creates the popup that will be displayed when the button is selected. + * Popup is a new Shell containing a unique Control. The content is specific + * to each implementation of the Combo and is created overriding the + * createPopupContent method. + */ + protected void createPopup() { + popup = new Shell(getShell(), SWT.TOOL | SWT.ON_TOP); + popupContent = createPopupContent(popup); + popupContent.setFont(text.getFont()); + popupContent.setBackground(text.getBackground()); + popupContent.setForeground(text.getForeground()); + popup.pack(); + + popup.addListener(SWT.Close, listener); + popup.addListener(SWT.Deactivate, listener); + popupContent.addListener(SWT.FocusIn, listener); + popupContent.addListener(SWT.Selection, listener); + } + + /** + * Creates the popup content. The popup is dependent of each implementation. + * Content can be a List, a Table or every other + * control.
+ * The popupContent attribute must be set with the created + * control. The parent must be the shell attribute, that is + * initialized by default with a FillLayout. + * + * @param parent The parent Composite that will contain the control + * @return The created Control for the popup content + */ + protected abstract Control createPopupContent(Composite parent); + + /** + * Creates the text widget. Override to change appearance or behavior of + * the default text that is created here. + * + * @param style text style + * @return the created Text control + */ + protected Text createTextControl(int style) { + Text text = new Text(this, style); + return text; + } + + /** + * Cuts the selected text. + *

+ * The current selection is first copied to the clipboard and then deleted + * from the widget. + *

+ * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void cut() { + checkWidget(); + text.cut(); + } + + /** + * This method is called when a SWT.Selection is notify in the popup content, + * allowing to update the Text widget content. + * + * @return true if the SWT.Selection event must be propagated, else false + */ + protected abstract boolean doSelection(); + + /** + * Manages drop down of the popup. + * + * @param drop true to drop the popup, false to close + */ + protected void dropDown(boolean drop) { + if (drop == isDropped()) + return; + + if (!drop) { + if (popup != null) { + popup.setVisible(false); + if (createOnDrop) { + popup.dispose(); + popup = null; + popupContent = null; + } + } + if (!isDisposed() && isFocusControl()) { + text.setFocus(); + } + return; + } + if (!isVisible()) + return; + if (popup == null || getShell() != popup.getParent()) { + if (popup != null) { + popup.dispose(); + popup = null; + popupContent = null; + } + createPopup(); + } + setPopupLocation(); + beforeDrop(); + popup.setVisible(true); + if (isFocusControl()) + popupContent.setFocus(); + } + + /** + * Gets the editable state. + * + * @return whether or not the receiver is editable + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public boolean getEditable() { + checkWidget(); + return text.getEditable(); + } + + /** + * Returns true if the receiver's popup is visible, + * and false otherwise. + *

+ * If one of the receiver's ancestors is not visible or some + * other condition makes the receiver not visible, this method + * may still indicate that it is considered visible even though + * it may not actually be showing. + *

+ * + * @return the receiver's popup's visibility state + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public boolean getPopupVisible() { + checkWidget(); + return isDropped(); + } + + /** + * Returns a Point whose x coordinate is the start of the + * selection in the receiver's text field, and whose y coordinate is the end + * of the selection. The returned values are zero-relative. An "empty" + * selection as indicated by the the x and y coordinates having the same + * value. + * + * @return a point representing the selection start and end + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public Point getSelection() { + checkWidget(); + return text.getSelection(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.widgets.Control#getShell() + */ + public Shell getShell() { + checkWidget(); + Shell shell = super.getShell(); + if (shell != _shell) { + if (_shell != null && !_shell.isDisposed()) { + _shell.removeListener(SWT.Deactivate, listener); + } + _shell = shell; + } + return _shell; + } + + /** + * Returns the receiver's style information. + * + * @see org.eclipse.swt.widgets.Widget#getStyle() + */ + public int getStyle() { + int style = super.getStyle(); + style &= ~SWT.READ_ONLY; + if (!text.getEditable()) + style |= SWT.READ_ONLY; + return style; + } + + /** + * Returns a string containing a copy of the contents of the receiver's text + * field. + * + * @return the receiver's text + */ + public String getText() { + checkWidget(); + return text.getText(); + } + + /** + * Returns the height of the receivers's text field. + * + * @return the text height + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getTextHeight() { + checkWidget(); + return text.getLineHeight(); + } + + /** + * Returns the maximum number of characters that the receiver's + * text field is capable of holding. If this has not been changed + * by setTextLimit(), it will be the constant + * Combo.LIMIT. + * + * @return the text limit + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getTextLimit() { + checkWidget(); + return text.getTextLimit(); + } + + /** + * Manages the focus on the combo. + * + * @param type SWT.FocusIn or SWT.FocusOut + */ + protected void handleFocus(int type) { + if (isDisposed()) + return; + switch (type) { + case SWT.FocusIn: { + if (hasFocus) + return; + hasFocus = true; + updateButtonDisplay(); + Shell shell = getShell(); + shell.removeListener(SWT.Deactivate, listener); + shell.addListener(SWT.Deactivate, listener); + Display display = getDisplay(); + display.removeFilter(SWT.FocusIn, filter); + display.addFilter(SWT.FocusIn, filter); + notifyListeners(SWT.FocusIn, new Event()); + break; + } + case SWT.FocusOut: { + if (!hasFocus) + return; + Control focusControl = getDisplay().getFocusControl(); + if (focusControl == button || (popupContent != null && popupContent.isFocusControl()) || focusControl == text) + return; + hasFocus = false; + updateButtonDisplay(); + Shell shell = getShell(); + shell.removeListener(SWT.Deactivate, listener); + getDisplay().removeFilter(SWT.FocusIn, filter); + notifyListeners(SWT.FocusOut, new Event()); + break; + } + } + } + + /** + * Returns true if popup is dropped (visible), else false. + * + * @return boolean indicating if popup is dropped + */ + protected boolean isDropped() { + return popup != null && !popup.isDisposed() && popup.getVisible(); + } + + /** + * Returns true if the receiver has the user-interface focus, + * and false otherwise. + * + * @see org.eclipse.swt.widgets.Control#isFocusControl() + */ + public boolean isFocusControl() { + checkWidget(); + if (text.isFocusControl() || button.isFocusControl() || (popupContent != null && popupContent.isFocusControl()) || (popup != null && popup.isFocusControl())) { + return true; + } + return super.isFocusControl(); + } + + /** + * Returns true if button is displayed only when the combo has + * has focus and false otherwise. + * + * @return boolean indicating if combo must show button only on focus + */ + public boolean isShowButtonOnFocus() { + return showButtonOnFocus; + } + + /** + * Pastes text from clipboard. + *

+ * The selected text is deleted from the widget + * and new text inserted from the clipboard. + *

+ * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void paste() { + checkWidget(); + text.paste(); + } + + /** + * Manages popup shell events. + * + * @param event event + */ + protected void popupEvent(Event event) { + switch (event.type) { + case SWT.Close: + event.doit = false; + dropDown(false); + break; + case SWT.Deactivate: + /* + * Bug in GTK. When the arrow button is pressed the popup control receives a + * deactivate event and then the arrow button receives a selection event. If + * we hide the popup in the deactivate event, the selection event will show + * it again. To prevent the popup from showing again, we will let the selection + * event of the arrow button hide the popup. + * In Windows, hiding the popup during the deactivate causes the deactivate + * to be called twice and the selection event to be disappear. + */ + if (!"carbon".equals(SWT.getPlatform())) { + Point point = button.toControl(getDisplay().getCursorLocation()); + Point size = button.getSize(); + Rectangle rect = new Rectangle(0, 0, size.x, size.y); + if (!rect.contains(point)) + dropDown(false); + } else { + dropDown(false); + } + break; + } + } + + /** + * Causes the entire bounds of the receiver to be marked as needing to be + * redrawn. The next time a paint request is processed, the control will be + * completely painted, including the background. + */ + public void redraw() { + super.redraw(); + text.redraw(); + button.redraw(); + if (popup.isVisible()) + popupContent.redraw(); + } + + /** + * Causes the rectangular area of the receiver specified by the arguments to + * be marked as needing to be redrawn. The next time a paint request is + * processed, that area of the receiver will be painted, including the + * background. If the all flag is true, any children of the receiver which + * intersect with the specified area will also paint their intersecting + * areas. If the all flag is false, the children will not be painted. + * + * @param x + * @param y + * @param width + * @param height + * @param all + */ + public void redraw(int x, int y, int width, int height, boolean all) { + super.redraw(x, y, width, height, true); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the receiver's text is modified. + * + * @param listener the listener which should no longer be notified + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * @see ModifyListener + * @see #addModifyListener + */ + public void removeModifyListener(ModifyListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + removeListener(SWT.Modify, listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the receiver's selection changes. + * + * @param listener the listener which should no longer be notified + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(SelectionListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + removeListener(SWT.Selection, listener); + removeListener(SWT.DefaultSelection, listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the control is verified. + * + * @param listener the listener which should no longer be notified + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * @see VerifyListener + * @see #addVerifyListener + */ + public void removeVerifyListener(VerifyListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + removeListener(SWT.Verify, listener); + } + + /** + * Selects all the text in the receiver. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void selectAll() { + checkWidget(); + text.selectAll(); + } + + /** + * Sets the receiver's background color to the color specified by the + * argument, or to the default system color for the control if the argument + * is null. + * + * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) + */ + public void setBackground(Color color) { + super.setBackground(color); + if (text != null) + text.setBackground(color); + if (button != null) + button.setBackground(color); + if (popupContent != null) + popupContent.setBackground(color); + } + + /** + * Sets the flag indicating if the popup content must be created each time + * the combo is dropped. + * It can be necessary to set this flag to true when the popup content use + * to many controls, as the DateChooser. + * + * @param createOnDrop true if popup is recreated at each drop, else false + */ + protected void setCreateOnDrop(boolean createOnDrop) { + this.createOnDrop = createOnDrop; + } + + /** + * Sets the editable state. + * + * @param editable the new editable state + */ + public void setEditable(boolean editable) { + checkWidget(); + text.setEditable(editable); + button.setEnabled(editable); + } + + /** + * Enables the receiver if the argument is true, and disables it + * otherwise. + * + * @see org.eclipse.swt.widgets.Control#setEnabled(boolean) + */ + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + if (isDropped()) + dropDown(false); + if (text != null) + text.setEnabled(enabled); + if (button != null) + button.setEnabled(enabled); + } + + /** + * Causes the receiver to have the keyboard focus, such that all keyboard + * events will be delivered to it. + * + * @see org.eclipse.swt.widgets.Control#setFocus() + */ + public boolean setFocus() { + checkWidget(); + if (!isEnabled() || !isVisible()) + return false; + if (isFocusControl()) + return true; + return text.setFocus(); + } + + /** + * Sets the font that the receiver will use to paint textual information to + * the font specified by the argument, or to the default font for that kind + * of control if the argument is null. + * + * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font) + */ + public void setFont(Font font) { + super.setFont(font); + text.setFont(font); + if (popupContent != null) { + popupContent.setFont(font); + } + pack(); + } + + /** + * Sets the receiver's foreground color to the color specified by the + * argument, or to the default system color for the control if the argument + * is null. + * + * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color) + */ + public void setForeground(Color color) { + super.setForeground(color); + if (text != null) + text.setForeground(color); + if (button != null) + button.setForeground(color); + if (popupContent != null) + popupContent.setForeground(color); + } + + /** + * Sets the layout which is associated with the receiver to be + * the argument which may be null. + *

+ * Note : No Layout can be set on this Control because it already + * manages the size and position of its children. + *

+ * + * @param layout the receiver's new layout or null + */ + public void setLayout(Layout layout) { + checkWidget(); + return; + } + + /** + * Sets the receiver's pop up menu to the argument. All controls may + * optionally have a pop up menu that is displayed when the user requests + * one for the control. The sequence of key strokes, button presses and/or + * button releases that are used to request a pop up menu is platform + * specific. + * + * Note: Disposing of a control that has a pop up menu will dispose of the + * menu. To avoid this behavior, set the menu to null before the control + * is disposed. + * + * @param menu the new pop up menu + */ + public void setMenu(Menu menu) { + text.setMenu(menu); + } + + /** + * Calculates and returns the location of popup.
+ * Called just before than the popup is dropped. + */ + protected void setPopupLocation() { + Display display = Display.getCurrent(); + Rectangle r = getBounds(); + Point p = display.map(this, null, 0, r.height); + Rectangle sb = display.getBounds(); + if (p.y + popup.getSize().y > sb.height) { + p.y -= r.height + popup.getSize().y + getBorderWidth(); + } + int popx = popup.getSize().x; + if (p.x + popx > sb.width) { + p.x -= popx - r.width + getBorderWidth(); + } else if (popx < r.width) { + p.x += r.width - popx; + } + popup.setLocation(p.x, p.y); + } + + /** + * Sets the selection in the receiver's text field to the + * range specified by the argument whose x coordinate is the + * start of the selection and whose y coordinate is the end + * of the selection. + * + * @param selection a point representing the new selection start and end + */ + public void setSelection(Point selection) { + checkWidget(); + if (selection == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + text.setSelection(selection.x, selection.y); + } + + /** + * Sets the flag indicating if the button must be shown only if the combo + * has the focus (true). + * + * @param showButtonOnFocus true if button must be shown on focus only + */ + public void setShowButtonOnFocus(boolean showButtonOnFocus) { + this.showButtonOnFocus = showButtonOnFocus; + updateButtonDisplay(); + } + + /** + * Sets the maximum number of characters that the receiver's + * text field is capable of holding to be the argument. + * + * @param limit new text limit + * @exception IllegalArgumentException + *
    + *
  • ERROR_CANNOT_BE_ZERO - if the limit is zero
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setTextLimit(int limit) { + checkWidget(); + text.setTextLimit(limit); + } + + /** + * Sets the receiver's tool tip text to the argument, which may be null + * indicating that no tool tip text should be shown. + * + * @param string the new tool tip text (or null) + */ + public void setToolTipText(String string) { + checkWidget(); + super.setToolTipText(string); + button.setToolTipText(string); + text.setToolTipText(string); + } + + /** + * Marks the receiver as visible if the argument is true, and + * marks it invisible otherwise. + * + * @see org.eclipse.swt.widgets.Control#setVisible(boolean) + */ + public void setVisible(boolean visible) { + super.setVisible(visible); + if (isDisposed()) + return; + if (popup == null || popup.isDisposed()) + return; + if (!visible) { + popup.setVisible(false); + } + } + + /** + * Manages text widget events. ModifyEvent are notified to all registered + * ModifyListener of the combo. + * + * @param event event + */ + protected void textEvent(Event event) { + switch (event.type) { + case SWT.FocusIn: + handleFocus(SWT.FocusIn); + break; + case SWT.Modify: { + Event e = new Event(); + e.time = event.time; + notifyListeners(SWT.Modify, e); + break; + } + case SWT.KeyDown: { + Event keyEvent = new Event(); + keyEvent.time = event.time; + keyEvent.character = event.character; + keyEvent.keyCode = event.keyCode; + keyEvent.stateMask = event.stateMask; + notifyListeners(SWT.KeyDown, keyEvent); + if ((event.stateMask & SWT.ALT) != 0 && event.keyCode == SWT.ARROW_DOWN) { + event.doit = false; + dropDown(true); + } + break; + } + case SWT.Traverse: { + switch (event.detail) { + case SWT.TRAVERSE_ARROW_PREVIOUS: + case SWT.TRAVERSE_ARROW_NEXT: + // The enter causes default selection and + // the arrow keys are used to manipulate the list contents so + // do not use them for traversal. + event.doit = false; + break; + case SWT.TRAVERSE_TAB_PREVIOUS: + event.doit = traverse(SWT.TRAVERSE_TAB_PREVIOUS); + event.detail = SWT.TRAVERSE_NONE; + return; + } + Event e = new Event(); + e.time = event.time; + e.detail = event.detail; + e.doit = event.doit; + e.character = event.character; + e.keyCode = event.keyCode; + notifyListeners(SWT.Traverse, e); + event.doit = e.doit; + event.detail = e.detail; + break; + } + } + } + + /** + * Updates the visibility of the button in function of the flag and the focus. + */ + protected void updateButtonDisplay() { + if (showButtonOnFocus) { + GridData data = (GridData) button.getLayoutData(); + data.exclude = !hasFocus; + button.setVisible(hasFocus); + super.layout(false); + } + } +} diff --git a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/DateChooser.java b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/DateChooser.java index 72407ff05..0ba897950 100644 --- a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/DateChooser.java +++ b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/DateChooser.java @@ -1,1714 +1,1714 @@ -/******************************************************************************* - * Copyright (c) 2005, 2009 Eric Wuillai. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Eric Wuillai (eric@wdev91.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.datechooser; - -import java.text.DateFormat; -import java.text.DateFormatSymbols; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.ResourceBundle; -import java.util.TimeZone; - -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.swt.widgets.TypedListener; - -/** - * Calendar widget. Presents the monthly view of a calendar for date picking. - *

- * - * Calendar is composed of a header and a grid for date selection. The header - * display the current month and year, and the two buttons for navigation - * (previous and next month). An optional footer display the today date. - *

- * - * Features: - *

    - *
  • Month names, weekday names and first day of week depend of the locale - * set on the calendar
  • - *
  • GUI (colors, font...) are customizable through themes (3 provided)
  • - *
  • Shows days from adjacent months
  • - *
  • Optionally shows weeks numbers
  • - *
  • Optional footer showing today date
  • - *
  • Multi selection and interval selection
  • - *
  • Keyboard support.
  • - *
- *

- * - * To know which dates have been selected in the calendar, there is two means : - *

    - *
  • The getSelectedDate() method returns the currently - * selected date (single selection). The getSelectedDates() - * returns a list of all selected dates (multi selection).
  • - *
  • Add a CalendarListener to the calendar. This listener - * will be notified of selection. event.data contain the - * selection if in single selection mode.
  • - *
- *

- * - * Keyboard navigation : - *

    - *
  • Arrows: Change the focus cell.
  • - *
  • Page UP / DOWN: Next / previous month.
  • - *
  • Ctrl-Page UP / DOWN: Next / previous year.
  • - *
  • SPACE: Select the cell having the focus. If in multi selection mode, - * all previous selected dates are cleared.
  • - *
  • Ctrl-SPACE: Add the cell having the focus to the selection (multi - * selection mode).
  • - *
  • Shift-SPACE: Select all dates in the interval between the current - * focus and the last selected date.
  • - *
  • HOME: Set the focus on the today date, and select it if - * autoselectOnFooter is true.
  • - *
- */ -public class DateChooser extends Composite { - /** Bundle name constant */ - public static final String BUNDLE_NAME = "org.eclipse.nebula.widgets.datechooser.resources"; //$NON-NLS-1$ - /** Header spacing constant */ - protected static final int HEADER_SPACING = 3; - /** Value to use when there is none internal widget having the focus */ - protected static final int NOFOCUS = -100; - - public static final int GRID_NONE = 0; - public static final int GRID_LINES = 1; - public static final int GRID_FULL = 2; - - // ----- Selection ----- - /** Multi selection flag */ - protected boolean multi; - /** Selection */ - protected List selection; - /** Begin date of selection interval */ - protected Date beginInterval; - /** End date of selection interval */ - protected Date endInterval; - /** If true, the today date is automatically selected on footer selection event */ - protected boolean autoSelectOnFooter = false; - - // ----- Calendar month header ----- - /** Month header panel */ - protected Composite monthPanel; - /** Navigation button for previous month */ - protected Button prevMonth; - /** Label for the display of current month and year (corresponding to curDate) */ - protected Label currentMonth; - /** Navigation button for next month */ - protected Button nextMonth; - /** Popup menu for month selection */ - protected Menu monthsMenu; - - // Calendar grid ----- - /** Grid panel */ - protected Composite gridPanel; - /** Layout of the grid */ - protected DateChooserLayout gridLayout; - /** Panel for display of weekday names */ - protected Composite headersPanel; - /** Grid headers, displaying weekday names */ - protected Label[] headers; - /** Panel for display of day numbers */ - protected Composite daysPanel; - /** Days numbers cells */ - protected Cell[] days; - /** Panel for display of week numbers */ - protected Composite weeksPanel; - /** Weeks numbers cells */ - protected Cell[] weeks; - /** Index in the grid of the first day of displayed month */ - protected int firstDayIndex; - - // ----- Calendar footer ----- - /** Today label of the footer */ - protected Label todayLabel; - - // ---- Localization ----- - /** Locale used for localized names and formats */ - protected Locale locale; - /** Format for the display of month and year in the header */ - protected SimpleDateFormat df1; - /** Format for the today date in the footer */ - protected DateFormat df2; - /** Index of the first day of week */ - protected int firstDayOfWeek; - /** Minimal number of days in the first week */ - protected int minimalDaysInFirstWeek; - /** Resources bundle */ - protected ResourceBundle resources; - - // ----- Dates ----- - /** Date of 1st day of the currently displayed month */ - protected Calendar currentMonthCal; - /** The today date */ - protected Calendar todayCal; - - // ----- GUI settings ----- - /** Calendar theme */ - protected DateChooserTheme theme; - /** Flag to set grid visible or not */ - protected int gridVisible = GRID_FULL; - /** Flag to set weeks numbers visible or not */ - protected boolean weeksVisible = false; - /** Flag to set footer visible or not */ - protected boolean footerVisible = false; - /** Flag to set navigation enabled or not */ - protected boolean navigationEnabled = true; - /** If true, change the current month if an adjacent day is clicked */ - protected boolean autoChangeOnAdjacent = true; - - // ----- GUI interactions ----- - /** Listener for all internal events */ - protected Listener listener; - /** Listener for external events */ - protected Listener filter; - /** Flag indicating if the calendar has the focus */ - protected boolean hasFocus = false; - /** Index of the focus in the days numbers grid */ - protected int focusIndex = NOFOCUS; - - private int redraw = 0; - - /** - * Defines a grid cell. Each cell displays a day or week number. - */ - protected class Cell { - Label label; - int index; - Calendar cal; - boolean weekend; - int adjacent; - boolean selected; - boolean today; - - Cell(Composite parent, int idx) { - label = new Label(parent, SWT.CENTER); - index = idx; - label.addListener(SWT.MouseDown, listener); - label.setData(this); - } - } - - /** - * Calendar grid specific layout. - */ - protected class DateChooserLayout extends Layout { - private final Point gridPanelSize = new Point(0, 0); - private final Point headersPanelSize = new Point(0, 0); - private final Point weeksPanelSize = new Point(0, 0); - private final Point daysPanelSize = new Point(0, 0); - private final Point todayLabelSize = new Point(0, 0); - private int cellWidth = 0; - private int cellHeight = 0; - - protected void compute() { - final GC gc = new GC(days[0].label); - - int headerWidth = 0; - final String[] months = df1.getDateFormatSymbols().getMonths(); - for (int i = 0; i < months.length; i++) { - headerWidth = Math.max(headerWidth, gc.textExtent(months[i]).x); - } - headerWidth += prevMonth.computeSize(SWT.DEFAULT, SWT.DEFAULT, false).x * 2 + HEADER_SPACING * 4 + gc.textExtent(" 9999").x; //$NON-NLS-1$ - - cellWidth = gc.textExtent("99").x + theme.cellPadding * 2; - cellWidth = Math.max(cellWidth, (headerWidth - 8) / 7 + 1); - cellHeight = days[0].label.computeSize(SWT.DEFAULT, SWT.DEFAULT, false).y; - - weeksPanel.setVisible(weeksVisible); - headers[0].setVisible(weeksVisible); - if (weeksVisible) { - gridPanelSize.x = (cellWidth + 1) * 8 + 1; - weeksPanelSize.x = cellWidth + 1; - weeksPanelSize.y = (cellHeight + 1) * 6 - 1; - } else { - gridPanelSize.x = (cellWidth + 1) * 7 + 1; - headersPanelSize.x += 1; - } - - headersPanelSize.x = gridPanelSize.x; - headersPanelSize.y = cellHeight + 1; - daysPanelSize.x = headersPanelSize.x; - daysPanelSize.y = (cellHeight + 1) * 6 - 1; - gridPanelSize.y = headersPanelSize.y + daysPanelSize.y + 2; - - todayLabel.setVisible(footerVisible); - if (footerVisible) { - todayLabelSize.x = gridPanelSize.x; - todayLabelSize.y = headersPanelSize.y + 1; - gridPanelSize.y += todayLabelSize.y; - } - - gc.dispose(); - } - - @Override - protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { - if (flushCache) { - compute(); - } - return gridPanelSize; - } - - @Override - protected void layout(Composite composite, boolean flushCache) { - if (flushCache) { - compute(); - } - - headersPanel.setBounds(0, 0, headersPanelSize.x, headersPanelSize.y); - - if (weeksVisible) { - for (int i = 0; i < 8; i++) { - headers[i].setBounds((cellWidth + 1) * i + 1, 1, cellWidth, cellHeight); - } - weeksPanel.setBounds(0, headersPanelSize.y + 1, weeksPanelSize.x, weeksPanelSize.y); - for (int i = 0; i < 6; i++) { - weeks[i].label.setBounds(1, (cellHeight + 1) * i, cellWidth, cellHeight); - } - } else { - for (int i = 0; i < 7; i++) { - headers[i + 1].setBounds((cellWidth + 1) * i + 1, 1, cellWidth, cellHeight); - } - } - - final int x = weeksVisible ? 0 : 1; - final int px = weeksVisible ? weeksPanelSize.x + 1 : 0; - - daysPanel.setBounds(px, headersPanelSize.y + 1, daysPanelSize.x, daysPanelSize.y); - for (int r = 0; r < 6; r++) { - for (int c = 0; c < 7; c++) { - days[r * 7 + c].label.setBounds(x + (cellWidth + 1) * c, (cellHeight + 1) * r, cellWidth, cellHeight); - } - } - - todayLabel.setBounds(0, headersPanelSize.y + daysPanelSize.y + 2, todayLabelSize.x, todayLabelSize.y); - } - } - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The calendar is initialized by default with the default Locale, and the - * current date for today and selected date attributes. - * - * @param parent a composite control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - */ - public DateChooser(Composite parent, int style) { - super(parent, style); - multi = (style & SWT.MULTI) > 0; - selection = new ArrayList(); - createContent(); - setLocale(Locale.getDefault()); - setTheme(DateChooserTheme.getDefaultTheme()); - setTodayDate(new Date()); - setCurrentMonth(todayCal.getTime()); - computeSize(SWT.DEFAULT, SWT.DEFAULT, true); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the receiver's selection changes, by sending - * it one of the messages defined in the SelectionListener - * interface. - *

- * widgetSelected is called when the dates selection changes. - *

- * - * @param lsnr the listener which should be notified - * @see SelectionListener - * @see #removeSelectionListener - */ - public void addSelectionListener(SelectionListener lsnr) { - checkWidget(); - if (lsnr == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - final TypedListener typedListener = new TypedListener(lsnr); - addListener(SWT.Selection, typedListener); - } - - /** - * Manages navigation buttons events. - * - * @param event event - */ - protected void buttonsEvent(Event event) { - switch (event.type) { - case SWT.MouseUp: { - final Rectangle r = ((Control) event.widget).getBounds(); - if (event.x < 0 || event.x >= r.width || event.y < 0 || event.y >= r.height) { - return; - } - final boolean ctrl = (event.stateMask & SWT.CTRL) != 0; - if (event.widget == prevMonth) { - changeCurrentMonth(ctrl ? -12 : -1); - } else if (event.widget == nextMonth) { - changeCurrentMonth(ctrl ? 12 : 1); - } - break; - } - - case SWT.FocusIn: - handleFocus(event.type); - break; - } - } - - /** - * Manages event at the calendar level. - * - * @param event event - */ - protected void calendarEvent(Event event) { - switch (event.type) { - case SWT.Traverse: - switch (event.detail) { - case SWT.TRAVERSE_ARROW_NEXT: - case SWT.TRAVERSE_ARROW_PREVIOUS: - case SWT.TRAVERSE_PAGE_NEXT: - case SWT.TRAVERSE_PAGE_PREVIOUS: - event.doit = false; - break; - default: - event.doit = true; - } - break; - - case SWT.FocusIn: - handleFocus(event.type); - break; - - case SWT.KeyDown: { - final boolean ctrl = (event.stateMask & SWT.CTRL) != 0; - switch (event.keyCode) { - case SWT.ARROW_LEFT: - if (event.stateMask != 0) { - return; - } - setFocus(focusIndex - 1); - break; - case SWT.ARROW_RIGHT: - if (event.stateMask != 0) { - return; - } - setFocus(focusIndex + 1); - break; - case SWT.ARROW_UP: - if (event.stateMask != 0) { - return; - } - setFocus(focusIndex - 7); - break; - case SWT.ARROW_DOWN: - if (event.stateMask != 0) { - return; - } - setFocus(focusIndex + 7); - break; - case SWT.PAGE_DOWN: - if (event.stateMask != 0 || !navigationEnabled) { - return; - } - changeCurrentMonth(ctrl ? 12 : 1); - break; - case SWT.PAGE_UP: - if (event.stateMask != 0 || !navigationEnabled) { - return; - } - changeCurrentMonth(ctrl ? -12 : -1); - break; - case ' ': - select(focusIndex, event.stateMask); - break; - case SWT.HOME: - if (event.stateMask != 0) { - return; - } - setFocusOnToday(autoSelectOnFooter); - break; - default: - return; - } - if (hasFocus) { - gridRedraw(); - } - break; - } - - case SWT.Dispose: { - final Display display = getDisplay(); - display.removeFilter(SWT.FocusIn, filter); - display.removeFilter(SWT.KeyDown, filter); - hasFocus = false; - break; - } - } - } - - /** - * Displays a new month in the grid. The new month is specified by delta from - * the currently displayed one. - * - * @param add delta from the current month - */ - protected void changeCurrentMonth(int add) { - if (add == 0) { - return; - } - currentMonthCal.add(Calendar.MONTH, add); - refreshDisplay(); - } - - /** - * Clears the selection. - */ - public void clearSelection() { - clearSelection(true); - } - - /** - * Clears the selection. The refresh flag allows to indicate must be - * refreshed or not. - * - * @param refresh true to refresh display, else false - */ - protected void clearSelection(boolean refresh) { - selection.clear(); - for (int i = 0; i < days.length; i++) { - days[i].selected = false; - } - beginInterval = null; - if (refresh) { - refreshDisplay(); - } - } - - /** - * Constructs and initializes all the GUI of the calendar. - */ - private void createContent() { - final GridLayout layout = new GridLayout(1, false); - layout.horizontalSpacing = 0; - layout.verticalSpacing = 0; - layout.marginWidth = 0; - layout.marginHeight = 0; - super.setLayout(layout); - - listener = new Listener() { - @Override - public void handleEvent(Event event) { - if (event.type == SWT.MouseDown && !hasFocus) { - setFocus(); - return; - } - if (DateChooser.this == event.widget && event.type != SWT.KeyDown) { - calendarEvent(event); - } else if (prevMonth == event.widget || nextMonth == event.widget) { - buttonsEvent(event); - } else if (todayLabel == event.widget) { - footerEvent(event); - } else if (daysPanel == event.widget || gridPanel == event.widget || event.widget instanceof Label) { - gridEvent(event); - } else if (monthsMenu == event.widget || event.widget instanceof MenuItem) { - menuEvent(event); - } - } - }; - filter = new Listener() { - @Override - public void handleEvent(Event event) { - switch (event.type) { - case SWT.FocusIn: - handleFocus(SWT.FocusOut); - break; - case SWT.KeyDown: - calendarEvent(event); - break; - } - } - }; - - createHeader(); - createGrid(); - - addListener(SWT.Dispose, listener); - addListener(SWT.Traverse, listener); - addListener(SWT.KeyDown, listener); - addListener(SWT.FocusIn, listener); - } - - /** - * Creates the grid of labels displaying the days numbers. The grid is composed - * of a header row, displaying days initials, and 6 row for the days numbers. - * All labels are empty (no text displayed), the content depending of both the - * locale (for first day of week) and the current displayed month. - */ - private void createGrid() { - // Master grid panel - gridPanel = new Composite(this, SWT.NONE); - gridLayout = new DateChooserLayout(); - gridPanel.setLayout(gridLayout); - gridPanel.addListener(SWT.Paint, listener); - - // Weeks numbers panel - weeksPanel = new Composite(gridPanel, SWT.NONE); - weeks = new Cell[6]; - for (int i = 0; i < 6; i++) { - weeks[i] = new Cell(weeksPanel, i); - } - - // Grid header panel - headersPanel = new Composite(gridPanel, SWT.NONE); - headers = new Label[8]; - for (int i = 0; i < 8; i++) { - headers[i] = new Label(headersPanel, SWT.CENTER); - headers[i].addListener(SWT.MouseDown, listener); - } - - // Grid panel - daysPanel = new Composite(gridPanel, SWT.NONE); - days = new Cell[42]; - for (int i = 0; i < 42; i++) { - days[i] = new Cell(daysPanel, i); - days[i].label.addListener(SWT.MouseUp, listener); - } - daysPanel.addListener(SWT.Paint, listener); - - // Footer panel - todayLabel = new Label(gridPanel, SWT.CENTER); - todayLabel.addListener(SWT.MouseDoubleClick, listener); - todayLabel.addListener(SWT.MouseDown, listener); - } - - /** - * Creates the header of the calendar. The header contains the label - * displaying the current month and year, and the two buttons for navigation : - * previous and next month. - */ - private void createHeader() { - monthPanel = new Composite(this, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(3).spacing(HEADER_SPACING, 0).margins(HEADER_SPACING, 2).applyTo(monthPanel); - GridDataFactory.fillDefaults().applyTo(monthPanel); - monthPanel.addListener(SWT.MouseDown, listener); - - prevMonth = new Button(monthPanel, SWT.ARROW | SWT.LEFT | SWT.FLAT); - prevMonth.addListener(SWT.MouseUp, listener); - prevMonth.addListener(SWT.FocusIn, listener); - - currentMonth = new Label(monthPanel, SWT.CENTER); - currentMonth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - currentMonth.addListener(SWT.MouseDown, listener); - - nextMonth = new Button(monthPanel, SWT.ARROW | SWT.RIGHT | SWT.FLAT); - nextMonth.addListener(SWT.MouseUp, listener); - nextMonth.addListener(SWT.FocusIn, listener); - - monthsMenu = new Menu(getShell(), SWT.POP_UP); - currentMonth.setMenu(monthsMenu); - for (int i = 0; i < 12; i++) { - final MenuItem item = new MenuItem(monthsMenu, SWT.PUSH); - item.addListener(SWT.Selection, listener); - item.setData(new Integer(i)); - } - monthsMenu.addListener(SWT.Show, listener); - } - - /** - * Disposes of the operating system resources associated with the receiver - * and all its descendants. - * - * @see org.eclipse.swt.widgets.Widget#dispose() - */ - @Override - public void dispose() { - getDisplay().removeFilter(SWT.KeyDown, filter); - getDisplay().removeFilter(SWT.FocusIn, filter); - super.dispose(); - } - - /** - * Manages events on the footer label. - * - * @param event event - */ - protected void footerEvent(Event event) { - switch (event.type) { - case SWT.MouseDoubleClick: - setFocusOnToday(autoSelectOnFooter); - break; - } - } - - /** - * Forces the receiver to have the keyboard focus, causing all keyboard events - * to be delivered to it. - * - * @return true if the control got focus, and false if it was unable to. - */ - @Override - public boolean forceFocus() { - checkWidget(); - if (super.forceFocus()) { - handleFocus(SWT.FocusIn); - return true; - } - return false; - } - - /** - * Returns the cell index corresponding to the given label. - * - * @param label label - * @return cell index - */ - private int getCellIndex(Label label) { - for (int i = 0; i < days.length; i++) { - if (days[i].label == label) { - return i; - } - } - return -1; - } - - /** - * Returns the current displayed month. - * - * @return Date representing current month. - */ - public Date getCurrentMonth() { - checkWidget(); - return currentMonthCal.getTime(); - } - - /** - * Gets what the first day of the week is. - * - * @return the first day of the week. - */ - public int getFirstDayOfWeek() { - return firstDayOfWeek; - } - - /** - * Returns the grid visibility status. - * - * @return Returns the grid visible status. - */ - public int getGridVisible() { - checkWidget(); - return gridVisible; - } - - /** - * Gets what the minimal days required in the first week of the year are. - * - * @return the minimal days required in the first week of the year. - */ - public int getMinimalDaysInFirstWeek() { - return minimalDaysInFirstWeek; - } - - /** - * Returns the selected date. If calendar is in multi selection mode, the - * first item of selection list is returned, with no guaranty of the selection - * order by the user. - * If no selection, return null. - * - * @return selected date - */ - public Date getSelectedDate() { - checkWidget(); - return selection.isEmpty() ? null : (Date) selection.get(0); - } - - /** - * Returns all the selected dates. The collection returned is a copy of the - * internal selection list. - *

- * - * If the calendar is in single selection mode, it is preferable to use - * getSelectedDate that returns a Date value. - * - * @return Collection of selected dates - */ - public Collection getSelectedDates() { - checkWidget(); - final List returnSelection = new ArrayList(selection.size()); - for (final Iterator it = selection.iterator(); it.hasNext();) { - final Date d = it.next(); - if (!returnSelection.contains(d)) { - returnSelection.add(d); - } - } - return returnSelection; - } - - /** - * Returns the today date. - * - * @return today date - */ - public Date getTodayDate() { - checkWidget(); - return todayCal.getTime(); - } - - /** - * Manages events at the grid level. - * - * @param event event - */ - protected void gridEvent(Event event) { - switch (event.type) { - case SWT.MouseUp: { - final Rectangle r = ((Control) event.widget).getBounds(); - if (event.x < 0 || event.x >= r.width || event.y < 0 || event.y >= r.height) { - return; - } - setFocus(getCellIndex((Label) event.widget)); - select(focusIndex, event.stateMask); - break; - } - - case SWT.Paint: { - if (!hasFocus) { - return; - } - if (focusIndex < 0) { - setFocus(-1); - } - - // Draw the focus rectangle on the grid - final Rectangle r = days[focusIndex].label.getBounds(); - if (daysPanel == event.widget) { - event.gc.setLineWidth(1); - event.gc.setForeground(theme.focusColor); - event.gc.drawRectangle(r.x - 1, r.y - 1, r.width + 1, r.height + 1); - } else if (gridPanel == event.widget) { - final int line = focusIndex / 7; - final int col = focusIndex % 7; - if (line == 0 || line == 5 || col == 0 && weeksVisible) { - final Rectangle rg = daysPanel.getBounds(); - event.gc.setForeground(theme.focusColor); - if (line == 0) { - event.gc.drawLine(rg.x + r.x - 1, rg.y - 1, rg.x + r.x + r.width, rg.y - 1); - } else if (line == 5) { - event.gc.drawLine(rg.x + r.x - 1, rg.y + rg.height, rg.x + r.x + r.width, rg.y + rg.height); - } - if (col == 0 && weeksVisible) { - event.gc.drawLine(rg.x + r.x - 1, rg.y + r.y - 1, rg.x + r.x - 1, rg.y + r.y + r.height); - } - } - } - break; - } - } - } - - /** - * Redraw the grid panel and all its children (day panel and labels). - */ - private void gridRedraw() { - final Rectangle r = gridPanel.getBounds(); - gridPanel.redraw(0, 0, r.width, r.height, true); - } - - /** - * Handles the focus. - * - * @param mode SWT.FocusIn or SWT.FocusOut - */ - private void handleFocus(int mode) { - switch (mode) { - case SWT.FocusIn: { - if (hasFocus) { - return; - } - hasFocus = true; - final Display display = getDisplay(); - display.removeFilter(SWT.KeyDown, filter); - display.removeFilter(SWT.FocusIn, filter); - if (focusIndex < 0) { - setFocus(NOFOCUS); - } - notifyListeners(SWT.FocusIn, new Event()); - display.addFilter(SWT.FocusIn, filter); - display.addFilter(SWT.KeyDown, filter); - break; - } - - case SWT.FocusOut: { - if (!hasFocus) { - return; - } - final Control focusControl = getDisplay().getFocusControl(); - if (focusControl == DateChooser.this || focusControl == nextMonth || focusControl == prevMonth) { - return; - } - hasFocus = false; - getDisplay().removeFilter(SWT.KeyDown, filter); - getDisplay().removeFilter(SWT.FocusIn, filter); - notifyListeners(SWT.FocusOut, new Event()); - break; - } - } - gridRedraw(); - } - - /** - * Returns the autoChangeOnAdjacent mode. - * - * @return true / false - */ - public boolean isAutoChangeOnAdjacent() { - return autoChangeOnAdjacent; - } - - /** - * Returns the autoSelectOnFooter mode. - * - * @return true / false - */ - public boolean isAutoSelectOnFooter() { - checkWidget(); - return autoSelectOnFooter; - } - - /** - * Returns true if the given date is selected, else returns - * false. - * - * @param date - * @return true if selected, else false. - */ - public boolean isDateSelected(Date date) { - checkWidget(); - for (final Iterator it = selection.iterator(); it.hasNext();) { - if (it.next().equals(date)) { - return true; - } - } - return false; - } - - /** - * Returns true if the receiver has the user-interface focus, - * and false otherwise. - * - * @return the receiver's focus state - * @see org.eclipse.swt.widgets.Control#isFocusControl() - */ - @Override - public boolean isFocusControl() { - return hasFocus; - } - - /** - * Returns true if footer is visible. - * - * @return true if footer visible, else false - */ - public boolean isFooterVisible() { - checkWidget(); - return footerVisible; - } - - /** - * Returns true if grid is visible in the calendar popup. - * - * @return Returns the grid visible status. - * @deprecated - */ - @Deprecated - public boolean isGridVisible() { - checkWidget(); - return gridVisible == GRID_FULL; - } - - /** - * Returns true if navigation is enabled. If false, buttons are not visible. - * - * @return Returns the navigation status. - */ - public boolean isNavigationEnabled() { - checkWidget(); - return navigationEnabled; - } - - /** - * Returns true if weeks numbers are visible. - * - * @return Returns the weeks numbers visible status. - */ - public boolean isWeeksVisible() { - checkWidget(); - return weeksVisible; - } - - /** - * Manages all events of the contextual menu on the month label of the header. - * - * @param event event - */ - protected void menuEvent(Event event) { - switch (event.type) { - case SWT.Show: - monthsMenu.setDefaultItem(monthsMenu.getItems()[currentMonthCal.get(Calendar.MONTH)]); - break; - - case SWT.Selection: - currentMonthCal.set(Calendar.MONTH, ((Integer) event.widget.getData()).intValue()); - refreshDisplay(); - break; - } - } - - /** - * Sends selection event to the listeners. - */ - protected void notifySelection() { - final Event event = new Event(); - if (!multi) { - event.data = getSelectedDate(); - } - notifyListeners(SWT.Selection, event); - } - - private void redrawDec() { - redraw--; - if (redraw == 0) { - setRedraw(true); - } - } - - private void redrawInc() { - if (redraw == 0) { - setRedraw(false); - } - redraw++; - } - - /** - * Refreshes the display of the grid and header. This can be needed because - * of a month display, a locale or color model change. - */ - private void refreshDisplay() { - if (currentMonthCal == null || theme == null) { - return; - } - redrawInc(); - currentMonth.setText(df1.format(currentMonthCal.getTime())); - - final int maxDay = currentMonthCal.getActualMaximum(Calendar.DAY_OF_MONTH); - final Calendar cal = (Calendar) currentMonthCal.clone(); - int delta = -((cal.get(Calendar.DAY_OF_WEEK) - firstDayOfWeek + 7) % 7); - cal.add(Calendar.DAY_OF_MONTH, delta); - for (int i = 0; i < 42; i++) { - if (i % 7 == 0) { - final int w = cal.get(Calendar.WEEK_OF_YEAR); - weeks[i / 7].label.setText(w < 10 ? "0" + w : "" + w); - } - if (delta == 0) { - firstDayIndex = i; - } - final int weekDay = cal.get(Calendar.DAY_OF_WEEK); - days[i].weekend = weekDay == 1 || weekDay == 7; - days[i].adjacent = delta < 0 ? -1 : delta >= maxDay ? 1 : 0; - days[i].today = cal.equals(todayCal); - if (days[i].cal == null) { - days[i].cal = (Calendar) cal.clone(); - } else { - days[i].cal.setTimeInMillis(cal.getTimeInMillis()); - } - days[i].label.setText("" + days[i].cal.get(Calendar.DAY_OF_MONTH)); //$NON-NLS-1$ - days[i].selected = isDateSelected(cal.getTime()); - setCellColors(days[i]); - - cal.add(Calendar.DAY_OF_MONTH, 1); - delta++; - } - redrawDec(); - } - - /** - * Removes the given date from the selection. - * - * @param d date to remove - */ - public void removeSelectedDate(Date d) { - checkWidget(); - removeSelectedDate(d, true); - } - - /** - * Removes the given date from the selection. The refresh flag allows to - * indicate must be refreshed or not. - * - * @param d date to remove - * @param refresh true to refresh display, else false - */ - private void removeSelectedDate(Date d, boolean refresh) { - for (final Iterator it = selection.iterator(); it.hasNext();) { - final Date itDate = it.next(); - if (itDate.equals(d)) { - selection.remove(itDate); - break; - } - } - if (refresh) { - refreshDisplay(); - } - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the receiver's selection changes. - * - * @param lsnr the listener which should no longer be notified - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(SelectionListener lsnr) { - checkWidget(); - if (lsnr == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - removeListener(SWT.Selection, lsnr); - } - - /** - * Manages the selection based on the current selected cell, specified by - * index, and the keyboard mask. - * - * @param index index of selected cell - * @param stateMask keyboard state - */ - private void select(int index, int stateMask) { - final Cell cell = days[index]; - if (!navigationEnabled && cell.adjacent != 0) { - return; - } - - // check if the cell is enabled - if (!theme.getCustomState(cell.cal.getTime())) { - refreshDisplay(); - return; - } - - boolean ctrl = (stateMask & SWT.CTRL) != 0; - boolean shift = (stateMask & SWT.SHIFT) != 0; - if (shift && beginInterval == null) { - ctrl = true; - shift = false; - } - if (!multi || !ctrl && !shift) { - clearSelection(false); - } - final Date selectedDate = cell.cal.getTime(); - if (multi && ctrl && cell.selected) { - // Remove the selection on a single cell - removeSelectedDate(selectedDate, false); - beginInterval = null; - endInterval = null; - } else { - if (multi && shift) { - // Interval selection - final Calendar c = (Calendar) cell.cal.clone(); - Date d; - int delta; - // Clear the previous interval - if (endInterval != null) { - delta = endInterval.after(beginInterval) ? -1 : 1; - c.setTime(endInterval); - d = c.getTime(); - while (d.compareTo(beginInterval) != 0) { - removeSelectedDate(d, false); - c.add(Calendar.DAY_OF_MONTH, delta); - d = c.getTime(); - } - } - // Select the new interval - endInterval = selectedDate; - delta = endInterval.after(beginInterval) ? -1 : 1; - c.setTime(endInterval); - d = c.getTime(); - while (d.compareTo(beginInterval) != 0) { - selection.add(d); - c.add(Calendar.DAY_OF_MONTH, delta); - d = c.getTime(); - } - } else { - // Single selection - selection.add(selectedDate); - beginInterval = cell.cal.getTime(); - endInterval = null; - } - } - // Changes the displayed month if an adjacent day has been selected - if (cell.adjacent != 0 && autoChangeOnAdjacent) { - changeCurrentMonth(cell.adjacent); - } else { - refreshDisplay(); - } - notifySelection(); - } - - /** - * Sets to true to enable the automatic change of current month - * when an adjacent day is clicked in the grid. - *

- * This mode is true by default. - * - * @param autoChangeOnAdjacent true / false - */ - public void setAutoChangeOnAdjacent(boolean autoChangeOnAdjacent) { - this.autoChangeOnAdjacent = autoChangeOnAdjacent; - } - - /** - * Set the autoSelectOnFooter mode. If true, the today date is automatically - * selected on the footer selection event. - * This mode is false by default. - * - * @param autoselectOnFooter true /false - */ - public void setAutoSelectOnFooter(boolean autoselectOnFooter) { - checkWidget(); - autoSelectOnFooter = autoselectOnFooter; - } - - /** - * Sets the colors of a grid cell in function of its current state. - * - * @param cell grid cell - */ - private void setCellColors(Cell cell) { - if (cell.selected) { - cell.label.setBackground(theme.selectedBackground); - cell.label.setForeground(theme.selectedForeground); - } else if (cell.today) { - cell.label.setBackground(theme.todayBackground); - cell.label.setForeground(theme.todayForeground); - } else { - cell.label.setBackground(theme.dayCellBackground); - cell.label.setForeground(cell.adjacent != 0 ? theme.extraMonthForeground : cell.weekend ? theme.weekendForeground : theme.dayCellForeground); - } - - // Now check for customs colors - final Date cellDate = cell.cal.getTime(); - final Color custom = theme.getCustomColor(cellDate); - if (custom != null && !cell.selected) { - cell.label.setBackground(custom); - } - // set tooltip - cell.label.setToolTipText(theme.getCustomTootlip(cellDate)); - } - - /** - * Sets a new month to display. - * - * @param month New month - */ - public void setCurrentMonth(Date month) { - checkWidget(); - if (month == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (currentMonthCal == null) { - currentMonthCal = Calendar.getInstance(locale); - currentMonthCal.setFirstDayOfWeek(firstDayOfWeek); - currentMonthCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); - } - currentMonthCal.setTime(month); - trunc(currentMonthCal); - currentMonthCal.set(Calendar.DAY_OF_MONTH, 1); - refreshDisplay(); - } - - /** - * Sets what the first day of the week is. - *

- * This method allows to change the default first day of the week set - * from the locale. It must be called after setLocale(). - * - * @param firstDayOfWeek the given first day of the week. - */ - public void setFirstDayOfWeek(int firstDayOfWeek) { - this.firstDayOfWeek = firstDayOfWeek; - currentMonthCal.setFirstDayOfWeek(firstDayOfWeek); - todayCal.setFirstDayOfWeek(firstDayOfWeek); - } - - /** - * Causes the receiver to have the keyboard focus, - * such that all keyboard events will be delivered to it. - * - * @return true if the control got focus, and false if it was unable to. - */ - @Override - public boolean setFocus() { - checkWidget(); - if (super.setFocus()) { - handleFocus(SWT.FocusIn); - return true; - } - return false; - } - - /** - * Sets the focus on the given cell, specified by index. - * - * @param index index of cell taking the focus - */ - private void setFocus(int index) { - if (index == NOFOCUS) { - if (todayCal.get(Calendar.MONTH) == currentMonthCal.get(Calendar.MONTH) && todayCal.get(Calendar.YEAR) == currentMonthCal.get(Calendar.YEAR)) { - for (int i = 0; i < days.length; i++) { - if (days[i].today) { - focusIndex = i; - return; - } - } - } - for (int i = 0; i < days.length; i++) { - if (days[i].cal.get(Calendar.DAY_OF_MONTH) == 1) { - focusIndex = i; - return; - } - } - } - if (index < 0) { - if (!navigationEnabled) { - return; - } - changeCurrentMonth(-1); - focusIndex = index + 42; - } else if (index >= 42) { - if (!navigationEnabled) { - return; - } - changeCurrentMonth(1); - focusIndex = index - 42; - } else { - focusIndex = index; - } - } - - /** - * Sets the focus on the given date. The current displayed month is changed - * if necessary. - * - * @param date date to set the focus on - */ - public void setFocusOnDate(Date date) { - final Calendar dateCal = (Calendar) currentMonthCal.clone(); - dateCal.setTime(date); - if (dateCal.get(Calendar.MONTH) != currentMonthCal.get(Calendar.MONTH) || dateCal.get(Calendar.YEAR) != currentMonthCal.get(Calendar.YEAR)) { - setCurrentMonth(date); - } - focusIndex = firstDayIndex + dateCal.get(Calendar.DAY_OF_MONTH) - 1; - } - - /** - * Sets the focus on the today date. If autoselect is true, the today date - * is selected. - * - * @param autoselect true to select automatically the today date, else false - */ - public void setFocusOnToday(boolean autoselect) { - checkWidget(); - redrawInc(); - if (currentMonthCal.get(Calendar.MONTH) != todayCal.get(Calendar.MONTH) || currentMonthCal.get(Calendar.YEAR) != todayCal.get(Calendar.YEAR)) { - setCurrentMonth(todayCal.getTime()); - } - setFocus(NOFOCUS); - if (autoselect) { - select(focusIndex, 0); - } - if (isDisposed()) { - return; - } - refreshDisplay(); - redrawDec(); - } - - /** - * Sets the font that the receiver will use to paint textual information to - * the font specified by the argument, or to the default font for that kind - * of control if the argument is null. - *

- * - * The new font is applied to all elements (labels) composing the calendar. - * The width of cells is adjusted. - * - * @param font the new font (or null) - */ - @Override - public void setFont(Font font) { - checkWidget(); - redrawInc(); - super.setFont(font); - currentMonth.setFont(font); - for (int i = 0; i < headers.length; i++) { - headers[i].setFont(font); - } - for (int i = 0; i < days.length; i++) { - days[i].label.setFont(font); - } - for (int i = 0; i < weeks.length; i++) { - weeks[i].label.setFont(font); - } - todayLabel.setFont(font); - redrawDec(); - } - - /** - * Sets the footer visible or not. The footer displays the today date. It is - * not visible by default. - * - * @param footerVisible true to set footer visible, else false - */ - public void setFooterVisible(boolean footerVisible) { - checkWidget(); - if (footerVisible != this.footerVisible) { - this.footerVisible = footerVisible; - layout(true); - } - } - - /** - * Sets the grid visible or not in the calendar popup. By default, the grid - * is visible. - * - * @param gridVisible true to set grid visible, else false - * @deprecated - */ - @Deprecated - public void setGridVisible(boolean gridVisible) { - setGridVisible(gridVisible ? GRID_FULL : GRID_NONE); - } - - /** - * Sets the grid visible or not. By default, the grid is visible. The - * possible values are GRID_FULL, GRID_LINES and GRID_NONE. - * - * @param gridVisible grid visibility flag - */ - public void setGridVisible(int gridVisible) { - checkWidget(); - this.gridVisible = gridVisible; - switch (this.gridVisible) { - case GRID_FULL: - gridPanel.setBackground(theme.gridLinesColor); - headersPanel.setBackground(theme.gridLinesColor); - daysPanel.setBackground(theme.gridLinesColor); - weeksPanel.setBackground(theme.gridLinesColor); - break; - - case GRID_LINES: - gridPanel.setBackground(theme.gridLinesColor); - headersPanel.setBackground(theme.gridHeaderBackground); - daysPanel.setBackground(theme.dayCellBackground); - weeksPanel.setBackground(theme.gridHeaderBackground); - break; - - case GRID_NONE: - gridPanel.setBackground(theme.gridHeaderBackground); - headersPanel.setBackground(theme.gridHeaderBackground); - daysPanel.setBackground(theme.dayCellBackground); - weeksPanel.setBackground(theme.gridHeaderBackground); - break; - } - } - - /** - * Sets the layout which is associated with the receiver to be - * the argument which may be null. - *

- * Note : No Layout can be set on this Control because it already - * manages the size and position of its children. - *

- * - * @param layout the receiver's new layout or null - */ - @Override - public void setLayout(Layout layout) { - checkWidget(); - return; - } - - /** - * Sets a new locale to use for calendar. Locale will define the names of - * months and days, and the first day of week. - * - * @param locale new locale (must not be null) - */ - public void setLocale(Locale locale) { - checkWidget(); - if (locale == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - this.locale = locale; - - // Loads the resources - resources = ResourceBundle.getBundle(BUNDLE_NAME, locale); - prevMonth.setToolTipText(resources.getString("DateChooser.previousButton")); //$NON-NLS-1$ - nextMonth.setToolTipText(resources.getString("DateChooser.nextButton")); //$NON-NLS-1$ - - // Defines formats - df1 = new SimpleDateFormat("MMMM yyyy", locale); //$NON-NLS-1$ - df2 = DateFormat.getDateInstance(DateFormat.SHORT, locale); - final Calendar c = Calendar.getInstance(TimeZone.getDefault(), locale); - firstDayOfWeek = c.getFirstDayOfWeek(); - minimalDaysInFirstWeek = Integer.parseInt(resources.getString("minimalDaysInFirstWeek")); - if (currentMonthCal != null) { - currentMonthCal.setFirstDayOfWeek(firstDayOfWeek); - currentMonthCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); - } - if (todayCal != null) { - todayCal.setFirstDayOfWeek(firstDayOfWeek); - todayCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); - } - - // Sets the header menu items - final String[] months = df1.getDateFormatSymbols().getMonths(); - final MenuItem[] items = monthsMenu.getItems(); - for (int i = 0; i < 12; i++) { - items[i].setText(months[i]); - } - - // Sets the grid header initials - redrawInc(); - final DateFormatSymbols symboles = df1.getDateFormatSymbols(); - final String[] sn = symboles.getShortWeekdays(); - final String[] ln = symboles.getWeekdays(); - int f = firstDayOfWeek; - for (int i = 1; i < headers.length; i++) { - headers[i].setText(sn[f].substring(0, 1).toUpperCase()); - headers[i].setToolTipText(ln[f]); - f = f % 7 + 1; - } - - // Updates the footer - updateTodayLabel(); - - refreshDisplay(); - redrawDec(); - } - - /** - * Sets what the minimal days required in the first week of the year are; For - * example, if the first week is defined as one that contains the first day - * of the first month of a year, call this method with value 1. If it must be - * a full week, use value 7. - *

- * This method allows to change the default value set from the locale. - * It must be called after setLocale(). - * - * @param minimalDaysInFirstWeek the given minimal days required in the first week of the year. - */ - public void setMinimalDaysInFirstWeek(int minimalDaysInFirstWeek) { - this.minimalDaysInFirstWeek = minimalDaysInFirstWeek; - currentMonthCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); - todayCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); - } - - /** - * Sets the header's navigation buttons visible or not. - * - * @param navigationEnabled true if enabled, false else - */ - public void setNavigationEnabled(boolean navigationEnabled) { - checkWidget(); - if (navigationEnabled != this.navigationEnabled) { - this.navigationEnabled = navigationEnabled; - prevMonth.setVisible(navigationEnabled); - nextMonth.setVisible(navigationEnabled); - if (navigationEnabled) { - currentMonth.setMenu(monthsMenu); - } else { - currentMonth.setMenu(null); - } - } - } - - /** - * Sets the selected date. The grid is refreshed to display the corresponding - * month. - * - * @param date new selected date (must not be null) - */ - public void setSelectedDate(Date date) { - checkWidget(); - if (date == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - final Calendar c = (Calendar) currentMonthCal.clone(); - c.setTime(date); - trunc(c); - final Date d = c.getTime(); - if (!selection.contains(d)) { - if (!multi) { - clearSelection(false); - } - selection.add(d); - } - setCurrentMonth(d); - } - - /** - * Sets the theme to apply to the calendar. - * - * @param theme new theme (must not be null) - */ - public void setTheme(DateChooserTheme theme) { - checkWidget(); - if (theme == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - this.theme = theme; - redrawInc(); - - // Border - setBackground(theme.borderBackground); - final GridLayout layout = (GridLayout) getLayout(); - layout.marginWidth = theme.borderSize; - layout.marginHeight = theme.borderSize; - - setGridVisible(theme.gridVisible); - - // Month header settings - monthPanel.setBackground(theme.headerBackground); - currentMonth.setBackground(theme.headerBackground); - currentMonth.setForeground(theme.headerForeground); - - // Today footer settings - todayLabel.setBackground(theme.gridHeaderBackground); - todayLabel.setForeground(theme.gridHeaderForeground); - - // Days headers settings - for (int i = 0; i < headers.length; i++) { - headers[i].setBackground(theme.gridHeaderBackground); - headers[i].setForeground(theme.gridHeaderForeground); - } - - // Grid days cells settings - for (int i = 0; i < days.length; i++) { - days[i].label.setBackground(theme.dayCellBackground); - } - - // Weeks cells settings - for (int i = 0; i < weeks.length; i++) { - weeks[i].label.setBackground(theme.gridHeaderBackground); - weeks[i].label.setForeground(theme.gridHeaderForeground); - } - - // Font - setFont(theme.font); - - pack(true); - layout(true); - refreshDisplay(); - redrawDec(); - } - - /** - * Sets the today date. - *

- * - * By default the today date is initialized to the current system date. But it - * can be needed to adjust it for specifics needs. - * - * @param today today date (must not be null) - */ - public void setTodayDate(Date today) { - checkWidget(); - if (today == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (todayCal == null) { - todayCal = Calendar.getInstance(locale); - todayCal.setFirstDayOfWeek(firstDayOfWeek); - todayCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); - } - todayCal.setTime(today); - trunc(todayCal); - updateTodayLabel(); - refreshDisplay(); - } - - /** - * Sets the weeks numbers visible or not. By default, the weeks are NOT - * visible. - * - * @param weeksVisible true to set weeks visible, else false - */ - public void setWeeksVisible(boolean weeksVisible) { - checkWidget(); - if (weeksVisible != this.weeksVisible) { - this.weeksVisible = weeksVisible; - layout(true); - } - } - - /** - * Truncate a given Calendar. The time fields are all set to 0. - * - * @param cal Calendar - */ - private void trunc(Calendar cal) { - cal.set(Calendar.HOUR_OF_DAY, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - } - - /** - * Updates the today label in the footer. Called when the today date or the - * locale is changed. - */ - private void updateTodayLabel() { - if (todayCal != null) { - todayLabel.setText(resources.getString("DateChooser.today") + " " + df2.format(todayCal.getTime())); - } - } -} +/******************************************************************************* + * Copyright (c) 2005, 2009 Eric Wuillai. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eric Wuillai (eric@wdev91.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.datechooser; + +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.ResourceBundle; +import java.util.TimeZone; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.TypedListener; + +/** + * Calendar widget. Presents the monthly view of a calendar for date picking. + *

+ * + * Calendar is composed of a header and a grid for date selection. The header + * display the current month and year, and the two buttons for navigation + * (previous and next month). An optional footer display the today date. + *

+ * + * Features: + *

    + *
  • Month names, weekday names and first day of week depend of the locale + * set on the calendar
  • + *
  • GUI (colors, font...) are customizable through themes (3 provided)
  • + *
  • Shows days from adjacent months
  • + *
  • Optionally shows weeks numbers
  • + *
  • Optional footer showing today date
  • + *
  • Multi selection and interval selection
  • + *
  • Keyboard support.
  • + *
+ *

+ * + * To know which dates have been selected in the calendar, there is two means : + *

    + *
  • The getSelectedDate() method returns the currently + * selected date (single selection). The getSelectedDates() + * returns a list of all selected dates (multi selection).
  • + *
  • Add a CalendarListener to the calendar. This listener + * will be notified of selection. event.data contain the + * selection if in single selection mode.
  • + *
+ *

+ * + * Keyboard navigation : + *

    + *
  • Arrows: Change the focus cell.
  • + *
  • Page UP / DOWN: Next / previous month.
  • + *
  • Ctrl-Page UP / DOWN: Next / previous year.
  • + *
  • SPACE: Select the cell having the focus. If in multi selection mode, + * all previous selected dates are cleared.
  • + *
  • Ctrl-SPACE: Add the cell having the focus to the selection (multi + * selection mode).
  • + *
  • Shift-SPACE: Select all dates in the interval between the current + * focus and the last selected date.
  • + *
  • HOME: Set the focus on the today date, and select it if + * autoselectOnFooter is true.
  • + *
+ */ +public class DateChooser extends Composite { + /** Bundle name constant */ + public static final String BUNDLE_NAME = "org.eclipse.nebula.widgets.datechooser.resources"; //$NON-NLS-1$ + /** Header spacing constant */ + protected static final int HEADER_SPACING = 3; + /** Value to use when there is none internal widget having the focus */ + protected static final int NOFOCUS = -100; + + public static final int GRID_NONE = 0; + public static final int GRID_LINES = 1; + public static final int GRID_FULL = 2; + + // ----- Selection ----- + /** Multi selection flag */ + protected boolean multi; + /** Selection */ + protected List selection; + /** Begin date of selection interval */ + protected Date beginInterval; + /** End date of selection interval */ + protected Date endInterval; + /** If true, the today date is automatically selected on footer selection event */ + protected boolean autoSelectOnFooter = false; + + // ----- Calendar month header ----- + /** Month header panel */ + protected Composite monthPanel; + /** Navigation button for previous month */ + protected Button prevMonth; + /** Label for the display of current month and year (corresponding to curDate) */ + protected Label currentMonth; + /** Navigation button for next month */ + protected Button nextMonth; + /** Popup menu for month selection */ + protected Menu monthsMenu; + + // Calendar grid ----- + /** Grid panel */ + protected Composite gridPanel; + /** Layout of the grid */ + protected DateChooserLayout gridLayout; + /** Panel for display of weekday names */ + protected Composite headersPanel; + /** Grid headers, displaying weekday names */ + protected Label[] headers; + /** Panel for display of day numbers */ + protected Composite daysPanel; + /** Days numbers cells */ + protected Cell[] days; + /** Panel for display of week numbers */ + protected Composite weeksPanel; + /** Weeks numbers cells */ + protected Cell[] weeks; + /** Index in the grid of the first day of displayed month */ + protected int firstDayIndex; + + // ----- Calendar footer ----- + /** Today label of the footer */ + protected Label todayLabel; + + // ---- Localization ----- + /** Locale used for localized names and formats */ + protected Locale locale; + /** Format for the display of month and year in the header */ + protected SimpleDateFormat df1; + /** Format for the today date in the footer */ + protected DateFormat df2; + /** Index of the first day of week */ + protected int firstDayOfWeek; + /** Minimal number of days in the first week */ + protected int minimalDaysInFirstWeek; + /** Resources bundle */ + protected ResourceBundle resources; + + // ----- Dates ----- + /** Date of 1st day of the currently displayed month */ + protected Calendar currentMonthCal; + /** The today date */ + protected Calendar todayCal; + + // ----- GUI settings ----- + /** Calendar theme */ + protected DateChooserTheme theme; + /** Flag to set grid visible or not */ + protected int gridVisible = GRID_FULL; + /** Flag to set weeks numbers visible or not */ + protected boolean weeksVisible = false; + /** Flag to set footer visible or not */ + protected boolean footerVisible = false; + /** Flag to set navigation enabled or not */ + protected boolean navigationEnabled = true; + /** If true, change the current month if an adjacent day is clicked */ + protected boolean autoChangeOnAdjacent = true; + + // ----- GUI interactions ----- + /** Listener for all internal events */ + protected Listener listener; + /** Listener for external events */ + protected Listener filter; + /** Flag indicating if the calendar has the focus */ + protected boolean hasFocus = false; + /** Index of the focus in the days numbers grid */ + protected int focusIndex = NOFOCUS; + + private int redraw = 0; + + /** + * Defines a grid cell. Each cell displays a day or week number. + */ + protected class Cell { + Label label; + int index; + Calendar cal; + boolean weekend; + int adjacent; + boolean selected; + boolean today; + + Cell(Composite parent, int idx) { + label = new Label(parent, SWT.CENTER); + index = idx; + label.addListener(SWT.MouseDown, listener); + label.setData(this); + } + } + + /** + * Calendar grid specific layout. + */ + protected class DateChooserLayout extends Layout { + private final Point gridPanelSize = new Point(0, 0); + private final Point headersPanelSize = new Point(0, 0); + private final Point weeksPanelSize = new Point(0, 0); + private final Point daysPanelSize = new Point(0, 0); + private final Point todayLabelSize = new Point(0, 0); + private int cellWidth = 0; + private int cellHeight = 0; + + protected void compute() { + final GC gc = new GC(days[0].label); + + int headerWidth = 0; + final String[] months = df1.getDateFormatSymbols().getMonths(); + for (int i = 0; i < months.length; i++) { + headerWidth = Math.max(headerWidth, gc.textExtent(months[i]).x); + } + headerWidth += prevMonth.computeSize(SWT.DEFAULT, SWT.DEFAULT, false).x * 2 + HEADER_SPACING * 4 + gc.textExtent(" 9999").x; //$NON-NLS-1$ + + cellWidth = gc.textExtent("99").x + theme.cellPadding * 2; + cellWidth = Math.max(cellWidth, (headerWidth - 8) / 7 + 1); + cellHeight = days[0].label.computeSize(SWT.DEFAULT, SWT.DEFAULT, false).y; + + weeksPanel.setVisible(weeksVisible); + headers[0].setVisible(weeksVisible); + if (weeksVisible) { + gridPanelSize.x = (cellWidth + 1) * 8 + 1; + weeksPanelSize.x = cellWidth + 1; + weeksPanelSize.y = (cellHeight + 1) * 6 - 1; + } else { + gridPanelSize.x = (cellWidth + 1) * 7 + 1; + headersPanelSize.x += 1; + } + + headersPanelSize.x = gridPanelSize.x; + headersPanelSize.y = cellHeight + 1; + daysPanelSize.x = headersPanelSize.x; + daysPanelSize.y = (cellHeight + 1) * 6 - 1; + gridPanelSize.y = headersPanelSize.y + daysPanelSize.y + 2; + + todayLabel.setVisible(footerVisible); + if (footerVisible) { + todayLabelSize.x = gridPanelSize.x; + todayLabelSize.y = headersPanelSize.y + 1; + gridPanelSize.y += todayLabelSize.y; + } + + gc.dispose(); + } + + @Override + protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { + if (flushCache) { + compute(); + } + return gridPanelSize; + } + + @Override + protected void layout(Composite composite, boolean flushCache) { + if (flushCache) { + compute(); + } + + headersPanel.setBounds(0, 0, headersPanelSize.x, headersPanelSize.y); + + if (weeksVisible) { + for (int i = 0; i < 8; i++) { + headers[i].setBounds((cellWidth + 1) * i + 1, 1, cellWidth, cellHeight); + } + weeksPanel.setBounds(0, headersPanelSize.y + 1, weeksPanelSize.x, weeksPanelSize.y); + for (int i = 0; i < 6; i++) { + weeks[i].label.setBounds(1, (cellHeight + 1) * i, cellWidth, cellHeight); + } + } else { + for (int i = 0; i < 7; i++) { + headers[i + 1].setBounds((cellWidth + 1) * i + 1, 1, cellWidth, cellHeight); + } + } + + final int x = weeksVisible ? 0 : 1; + final int px = weeksVisible ? weeksPanelSize.x + 1 : 0; + + daysPanel.setBounds(px, headersPanelSize.y + 1, daysPanelSize.x, daysPanelSize.y); + for (int r = 0; r < 6; r++) { + for (int c = 0; c < 7; c++) { + days[r * 7 + c].label.setBounds(x + (cellWidth + 1) * c, (cellHeight + 1) * r, cellWidth, cellHeight); + } + } + + todayLabel.setBounds(0, headersPanelSize.y + daysPanelSize.y + 2, todayLabelSize.x, todayLabelSize.y); + } + } + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The calendar is initialized by default with the default Locale, and the + * current date for today and selected date attributes. + * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + */ + public DateChooser(Composite parent, int style) { + super(parent, style); + multi = (style & SWT.MULTI) > 0; + selection = new ArrayList(); + createContent(); + setLocale(Locale.getDefault()); + setTheme(DateChooserTheme.getDefaultTheme()); + setTodayDate(new Date()); + setCurrentMonth(todayCal.getTime()); + computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the receiver's selection changes, by sending + * it one of the messages defined in the SelectionListener + * interface. + *

+ * widgetSelected is called when the dates selection changes. + *

+ * + * @param lsnr the listener which should be notified + * @see SelectionListener + * @see #removeSelectionListener + */ + public void addSelectionListener(SelectionListener lsnr) { + checkWidget(); + if (lsnr == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + final TypedListener typedListener = new TypedListener(lsnr); + addListener(SWT.Selection, typedListener); + } + + /** + * Manages navigation buttons events. + * + * @param event event + */ + protected void buttonsEvent(Event event) { + switch (event.type) { + case SWT.MouseUp: { + final Rectangle r = ((Control) event.widget).getBounds(); + if (event.x < 0 || event.x >= r.width || event.y < 0 || event.y >= r.height) { + return; + } + final boolean ctrl = (event.stateMask & SWT.CTRL) != 0; + if (event.widget == prevMonth) { + changeCurrentMonth(ctrl ? -12 : -1); + } else if (event.widget == nextMonth) { + changeCurrentMonth(ctrl ? 12 : 1); + } + break; + } + + case SWT.FocusIn: + handleFocus(event.type); + break; + } + } + + /** + * Manages event at the calendar level. + * + * @param event event + */ + protected void calendarEvent(Event event) { + switch (event.type) { + case SWT.Traverse: + switch (event.detail) { + case SWT.TRAVERSE_ARROW_NEXT: + case SWT.TRAVERSE_ARROW_PREVIOUS: + case SWT.TRAVERSE_PAGE_NEXT: + case SWT.TRAVERSE_PAGE_PREVIOUS: + event.doit = false; + break; + default: + event.doit = true; + } + break; + + case SWT.FocusIn: + handleFocus(event.type); + break; + + case SWT.KeyDown: { + final boolean ctrl = (event.stateMask & SWT.CTRL) != 0; + switch (event.keyCode) { + case SWT.ARROW_LEFT: + if (event.stateMask != 0) { + return; + } + setFocus(focusIndex - 1); + break; + case SWT.ARROW_RIGHT: + if (event.stateMask != 0) { + return; + } + setFocus(focusIndex + 1); + break; + case SWT.ARROW_UP: + if (event.stateMask != 0) { + return; + } + setFocus(focusIndex - 7); + break; + case SWT.ARROW_DOWN: + if (event.stateMask != 0) { + return; + } + setFocus(focusIndex + 7); + break; + case SWT.PAGE_DOWN: + if (event.stateMask != 0 || !navigationEnabled) { + return; + } + changeCurrentMonth(ctrl ? 12 : 1); + break; + case SWT.PAGE_UP: + if (event.stateMask != 0 || !navigationEnabled) { + return; + } + changeCurrentMonth(ctrl ? -12 : -1); + break; + case ' ': + select(focusIndex, event.stateMask); + break; + case SWT.HOME: + if (event.stateMask != 0) { + return; + } + setFocusOnToday(autoSelectOnFooter); + break; + default: + return; + } + if (hasFocus) { + gridRedraw(); + } + break; + } + + case SWT.Dispose: { + final Display display = getDisplay(); + display.removeFilter(SWT.FocusIn, filter); + display.removeFilter(SWT.KeyDown, filter); + hasFocus = false; + break; + } + } + } + + /** + * Displays a new month in the grid. The new month is specified by delta from + * the currently displayed one. + * + * @param add delta from the current month + */ + protected void changeCurrentMonth(int add) { + if (add == 0) { + return; + } + currentMonthCal.add(Calendar.MONTH, add); + refreshDisplay(); + } + + /** + * Clears the selection. + */ + public void clearSelection() { + clearSelection(true); + } + + /** + * Clears the selection. The refresh flag allows to indicate must be + * refreshed or not. + * + * @param refresh true to refresh display, else false + */ + protected void clearSelection(boolean refresh) { + selection.clear(); + for (int i = 0; i < days.length; i++) { + days[i].selected = false; + } + beginInterval = null; + if (refresh) { + refreshDisplay(); + } + } + + /** + * Constructs and initializes all the GUI of the calendar. + */ + private void createContent() { + final GridLayout layout = new GridLayout(1, false); + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + layout.marginWidth = 0; + layout.marginHeight = 0; + super.setLayout(layout); + + listener = new Listener() { + @Override + public void handleEvent(Event event) { + if (event.type == SWT.MouseDown && !hasFocus) { + setFocus(); + return; + } + if (DateChooser.this == event.widget && event.type != SWT.KeyDown) { + calendarEvent(event); + } else if (prevMonth == event.widget || nextMonth == event.widget) { + buttonsEvent(event); + } else if (todayLabel == event.widget) { + footerEvent(event); + } else if (daysPanel == event.widget || gridPanel == event.widget || event.widget instanceof Label) { + gridEvent(event); + } else if (monthsMenu == event.widget || event.widget instanceof MenuItem) { + menuEvent(event); + } + } + }; + filter = new Listener() { + @Override + public void handleEvent(Event event) { + switch (event.type) { + case SWT.FocusIn: + handleFocus(SWT.FocusOut); + break; + case SWT.KeyDown: + calendarEvent(event); + break; + } + } + }; + + createHeader(); + createGrid(); + + addListener(SWT.Dispose, listener); + addListener(SWT.Traverse, listener); + addListener(SWT.KeyDown, listener); + addListener(SWT.FocusIn, listener); + } + + /** + * Creates the grid of labels displaying the days numbers. The grid is composed + * of a header row, displaying days initials, and 6 row for the days numbers. + * All labels are empty (no text displayed), the content depending of both the + * locale (for first day of week) and the current displayed month. + */ + private void createGrid() { + // Master grid panel + gridPanel = new Composite(this, SWT.NONE); + gridLayout = new DateChooserLayout(); + gridPanel.setLayout(gridLayout); + gridPanel.addListener(SWT.Paint, listener); + + // Weeks numbers panel + weeksPanel = new Composite(gridPanel, SWT.NONE); + weeks = new Cell[6]; + for (int i = 0; i < 6; i++) { + weeks[i] = new Cell(weeksPanel, i); + } + + // Grid header panel + headersPanel = new Composite(gridPanel, SWT.NONE); + headers = new Label[8]; + for (int i = 0; i < 8; i++) { + headers[i] = new Label(headersPanel, SWT.CENTER); + headers[i].addListener(SWT.MouseDown, listener); + } + + // Grid panel + daysPanel = new Composite(gridPanel, SWT.NONE); + days = new Cell[42]; + for (int i = 0; i < 42; i++) { + days[i] = new Cell(daysPanel, i); + days[i].label.addListener(SWT.MouseUp, listener); + } + daysPanel.addListener(SWT.Paint, listener); + + // Footer panel + todayLabel = new Label(gridPanel, SWT.CENTER); + todayLabel.addListener(SWT.MouseDoubleClick, listener); + todayLabel.addListener(SWT.MouseDown, listener); + } + + /** + * Creates the header of the calendar. The header contains the label + * displaying the current month and year, and the two buttons for navigation : + * previous and next month. + */ + private void createHeader() { + monthPanel = new Composite(this, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(3).spacing(HEADER_SPACING, 0).margins(HEADER_SPACING, 2).applyTo(monthPanel); + GridDataFactory.fillDefaults().applyTo(monthPanel); + monthPanel.addListener(SWT.MouseDown, listener); + + prevMonth = new Button(monthPanel, SWT.ARROW | SWT.LEFT | SWT.FLAT); + prevMonth.addListener(SWT.MouseUp, listener); + prevMonth.addListener(SWT.FocusIn, listener); + + currentMonth = new Label(monthPanel, SWT.CENTER); + currentMonth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + currentMonth.addListener(SWT.MouseDown, listener); + + nextMonth = new Button(monthPanel, SWT.ARROW | SWT.RIGHT | SWT.FLAT); + nextMonth.addListener(SWT.MouseUp, listener); + nextMonth.addListener(SWT.FocusIn, listener); + + monthsMenu = new Menu(getShell(), SWT.POP_UP); + currentMonth.setMenu(monthsMenu); + for (int i = 0; i < 12; i++) { + final MenuItem item = new MenuItem(monthsMenu, SWT.PUSH); + item.addListener(SWT.Selection, listener); + item.setData(new Integer(i)); + } + monthsMenu.addListener(SWT.Show, listener); + } + + /** + * Disposes of the operating system resources associated with the receiver + * and all its descendants. + * + * @see org.eclipse.swt.widgets.Widget#dispose() + */ + @Override + public void dispose() { + getDisplay().removeFilter(SWT.KeyDown, filter); + getDisplay().removeFilter(SWT.FocusIn, filter); + super.dispose(); + } + + /** + * Manages events on the footer label. + * + * @param event event + */ + protected void footerEvent(Event event) { + switch (event.type) { + case SWT.MouseDoubleClick: + setFocusOnToday(autoSelectOnFooter); + break; + } + } + + /** + * Forces the receiver to have the keyboard focus, causing all keyboard events + * to be delivered to it. + * + * @return true if the control got focus, and false if it was unable to. + */ + @Override + public boolean forceFocus() { + checkWidget(); + if (super.forceFocus()) { + handleFocus(SWT.FocusIn); + return true; + } + return false; + } + + /** + * Returns the cell index corresponding to the given label. + * + * @param label label + * @return cell index + */ + private int getCellIndex(Label label) { + for (int i = 0; i < days.length; i++) { + if (days[i].label == label) { + return i; + } + } + return -1; + } + + /** + * Returns the current displayed month. + * + * @return Date representing current month. + */ + public Date getCurrentMonth() { + checkWidget(); + return currentMonthCal.getTime(); + } + + /** + * Gets what the first day of the week is. + * + * @return the first day of the week. + */ + public int getFirstDayOfWeek() { + return firstDayOfWeek; + } + + /** + * Returns the grid visibility status. + * + * @return Returns the grid visible status. + */ + public int getGridVisible() { + checkWidget(); + return gridVisible; + } + + /** + * Gets what the minimal days required in the first week of the year are. + * + * @return the minimal days required in the first week of the year. + */ + public int getMinimalDaysInFirstWeek() { + return minimalDaysInFirstWeek; + } + + /** + * Returns the selected date. If calendar is in multi selection mode, the + * first item of selection list is returned, with no guaranty of the selection + * order by the user. + * If no selection, return null. + * + * @return selected date + */ + public Date getSelectedDate() { + checkWidget(); + return selection.isEmpty() ? null : (Date) selection.get(0); + } + + /** + * Returns all the selected dates. The collection returned is a copy of the + * internal selection list. + *

+ * + * If the calendar is in single selection mode, it is preferable to use + * getSelectedDate that returns a Date value. + * + * @return Collection of selected dates + */ + public Collection getSelectedDates() { + checkWidget(); + final List returnSelection = new ArrayList(selection.size()); + for (final Iterator it = selection.iterator(); it.hasNext();) { + final Date d = it.next(); + if (!returnSelection.contains(d)) { + returnSelection.add(d); + } + } + return returnSelection; + } + + /** + * Returns the today date. + * + * @return today date + */ + public Date getTodayDate() { + checkWidget(); + return todayCal.getTime(); + } + + /** + * Manages events at the grid level. + * + * @param event event + */ + protected void gridEvent(Event event) { + switch (event.type) { + case SWT.MouseUp: { + final Rectangle r = ((Control) event.widget).getBounds(); + if (event.x < 0 || event.x >= r.width || event.y < 0 || event.y >= r.height) { + return; + } + setFocus(getCellIndex((Label) event.widget)); + select(focusIndex, event.stateMask); + break; + } + + case SWT.Paint: { + if (!hasFocus) { + return; + } + if (focusIndex < 0) { + setFocus(-1); + } + + // Draw the focus rectangle on the grid + final Rectangle r = days[focusIndex].label.getBounds(); + if (daysPanel == event.widget) { + event.gc.setLineWidth(1); + event.gc.setForeground(theme.focusColor); + event.gc.drawRectangle(r.x - 1, r.y - 1, r.width + 1, r.height + 1); + } else if (gridPanel == event.widget) { + final int line = focusIndex / 7; + final int col = focusIndex % 7; + if (line == 0 || line == 5 || col == 0 && weeksVisible) { + final Rectangle rg = daysPanel.getBounds(); + event.gc.setForeground(theme.focusColor); + if (line == 0) { + event.gc.drawLine(rg.x + r.x - 1, rg.y - 1, rg.x + r.x + r.width, rg.y - 1); + } else if (line == 5) { + event.gc.drawLine(rg.x + r.x - 1, rg.y + rg.height, rg.x + r.x + r.width, rg.y + rg.height); + } + if (col == 0 && weeksVisible) { + event.gc.drawLine(rg.x + r.x - 1, rg.y + r.y - 1, rg.x + r.x - 1, rg.y + r.y + r.height); + } + } + } + break; + } + } + } + + /** + * Redraw the grid panel and all its children (day panel and labels). + */ + private void gridRedraw() { + final Rectangle r = gridPanel.getBounds(); + gridPanel.redraw(0, 0, r.width, r.height, true); + } + + /** + * Handles the focus. + * + * @param mode SWT.FocusIn or SWT.FocusOut + */ + private void handleFocus(int mode) { + switch (mode) { + case SWT.FocusIn: { + if (hasFocus) { + return; + } + hasFocus = true; + final Display display = getDisplay(); + display.removeFilter(SWT.KeyDown, filter); + display.removeFilter(SWT.FocusIn, filter); + if (focusIndex < 0) { + setFocus(NOFOCUS); + } + notifyListeners(SWT.FocusIn, new Event()); + display.addFilter(SWT.FocusIn, filter); + display.addFilter(SWT.KeyDown, filter); + break; + } + + case SWT.FocusOut: { + if (!hasFocus) { + return; + } + final Control focusControl = getDisplay().getFocusControl(); + if (focusControl == DateChooser.this || focusControl == nextMonth || focusControl == prevMonth) { + return; + } + hasFocus = false; + getDisplay().removeFilter(SWT.KeyDown, filter); + getDisplay().removeFilter(SWT.FocusIn, filter); + notifyListeners(SWT.FocusOut, new Event()); + break; + } + } + gridRedraw(); + } + + /** + * Returns the autoChangeOnAdjacent mode. + * + * @return true / false + */ + public boolean isAutoChangeOnAdjacent() { + return autoChangeOnAdjacent; + } + + /** + * Returns the autoSelectOnFooter mode. + * + * @return true / false + */ + public boolean isAutoSelectOnFooter() { + checkWidget(); + return autoSelectOnFooter; + } + + /** + * Returns true if the given date is selected, else returns + * false. + * + * @param date + * @return true if selected, else false. + */ + public boolean isDateSelected(Date date) { + checkWidget(); + for (final Iterator it = selection.iterator(); it.hasNext();) { + if (it.next().equals(date)) { + return true; + } + } + return false; + } + + /** + * Returns true if the receiver has the user-interface focus, + * and false otherwise. + * + * @return the receiver's focus state + * @see org.eclipse.swt.widgets.Control#isFocusControl() + */ + @Override + public boolean isFocusControl() { + return hasFocus; + } + + /** + * Returns true if footer is visible. + * + * @return true if footer visible, else false + */ + public boolean isFooterVisible() { + checkWidget(); + return footerVisible; + } + + /** + * Returns true if grid is visible in the calendar popup. + * + * @return Returns the grid visible status. + * @deprecated + */ + @Deprecated + public boolean isGridVisible() { + checkWidget(); + return gridVisible == GRID_FULL; + } + + /** + * Returns true if navigation is enabled. If false, buttons are not visible. + * + * @return Returns the navigation status. + */ + public boolean isNavigationEnabled() { + checkWidget(); + return navigationEnabled; + } + + /** + * Returns true if weeks numbers are visible. + * + * @return Returns the weeks numbers visible status. + */ + public boolean isWeeksVisible() { + checkWidget(); + return weeksVisible; + } + + /** + * Manages all events of the contextual menu on the month label of the header. + * + * @param event event + */ + protected void menuEvent(Event event) { + switch (event.type) { + case SWT.Show: + monthsMenu.setDefaultItem(monthsMenu.getItems()[currentMonthCal.get(Calendar.MONTH)]); + break; + + case SWT.Selection: + currentMonthCal.set(Calendar.MONTH, ((Integer) event.widget.getData()).intValue()); + refreshDisplay(); + break; + } + } + + /** + * Sends selection event to the listeners. + */ + protected void notifySelection() { + final Event event = new Event(); + if (!multi) { + event.data = getSelectedDate(); + } + notifyListeners(SWT.Selection, event); + } + + private void redrawDec() { + redraw--; + if (redraw == 0) { + setRedraw(true); + } + } + + private void redrawInc() { + if (redraw == 0) { + setRedraw(false); + } + redraw++; + } + + /** + * Refreshes the display of the grid and header. This can be needed because + * of a month display, a locale or color model change. + */ + private void refreshDisplay() { + if (currentMonthCal == null || theme == null) { + return; + } + redrawInc(); + currentMonth.setText(df1.format(currentMonthCal.getTime())); + + final int maxDay = currentMonthCal.getActualMaximum(Calendar.DAY_OF_MONTH); + final Calendar cal = (Calendar) currentMonthCal.clone(); + int delta = -((cal.get(Calendar.DAY_OF_WEEK) - firstDayOfWeek + 7) % 7); + cal.add(Calendar.DAY_OF_MONTH, delta); + for (int i = 0; i < 42; i++) { + if (i % 7 == 0) { + final int w = cal.get(Calendar.WEEK_OF_YEAR); + weeks[i / 7].label.setText(w < 10 ? "0" + w : "" + w); + } + if (delta == 0) { + firstDayIndex = i; + } + final int weekDay = cal.get(Calendar.DAY_OF_WEEK); + days[i].weekend = weekDay == 1 || weekDay == 7; + days[i].adjacent = delta < 0 ? -1 : delta >= maxDay ? 1 : 0; + days[i].today = cal.equals(todayCal); + if (days[i].cal == null) { + days[i].cal = (Calendar) cal.clone(); + } else { + days[i].cal.setTimeInMillis(cal.getTimeInMillis()); + } + days[i].label.setText("" + days[i].cal.get(Calendar.DAY_OF_MONTH)); //$NON-NLS-1$ + days[i].selected = isDateSelected(cal.getTime()); + setCellColors(days[i]); + + cal.add(Calendar.DAY_OF_MONTH, 1); + delta++; + } + redrawDec(); + } + + /** + * Removes the given date from the selection. + * + * @param d date to remove + */ + public void removeSelectedDate(Date d) { + checkWidget(); + removeSelectedDate(d, true); + } + + /** + * Removes the given date from the selection. The refresh flag allows to + * indicate must be refreshed or not. + * + * @param d date to remove + * @param refresh true to refresh display, else false + */ + private void removeSelectedDate(Date d, boolean refresh) { + for (final Iterator it = selection.iterator(); it.hasNext();) { + final Date itDate = it.next(); + if (itDate.equals(d)) { + selection.remove(itDate); + break; + } + } + if (refresh) { + refreshDisplay(); + } + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the receiver's selection changes. + * + * @param lsnr the listener which should no longer be notified + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(SelectionListener lsnr) { + checkWidget(); + if (lsnr == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + removeListener(SWT.Selection, lsnr); + } + + /** + * Manages the selection based on the current selected cell, specified by + * index, and the keyboard mask. + * + * @param index index of selected cell + * @param stateMask keyboard state + */ + private void select(int index, int stateMask) { + final Cell cell = days[index]; + if (!navigationEnabled && cell.adjacent != 0) { + return; + } + + // check if the cell is enabled + if (!theme.getCustomState(cell.cal.getTime())) { + refreshDisplay(); + return; + } + + boolean ctrl = (stateMask & SWT.CTRL) != 0; + boolean shift = (stateMask & SWT.SHIFT) != 0; + if (shift && beginInterval == null) { + ctrl = true; + shift = false; + } + if (!multi || !ctrl && !shift) { + clearSelection(false); + } + final Date selectedDate = cell.cal.getTime(); + if (multi && ctrl && cell.selected) { + // Remove the selection on a single cell + removeSelectedDate(selectedDate, false); + beginInterval = null; + endInterval = null; + } else { + if (multi && shift) { + // Interval selection + final Calendar c = (Calendar) cell.cal.clone(); + Date d; + int delta; + // Clear the previous interval + if (endInterval != null) { + delta = endInterval.after(beginInterval) ? -1 : 1; + c.setTime(endInterval); + d = c.getTime(); + while (d.compareTo(beginInterval) != 0) { + removeSelectedDate(d, false); + c.add(Calendar.DAY_OF_MONTH, delta); + d = c.getTime(); + } + } + // Select the new interval + endInterval = selectedDate; + delta = endInterval.after(beginInterval) ? -1 : 1; + c.setTime(endInterval); + d = c.getTime(); + while (d.compareTo(beginInterval) != 0) { + selection.add(d); + c.add(Calendar.DAY_OF_MONTH, delta); + d = c.getTime(); + } + } else { + // Single selection + selection.add(selectedDate); + beginInterval = cell.cal.getTime(); + endInterval = null; + } + } + // Changes the displayed month if an adjacent day has been selected + if (cell.adjacent != 0 && autoChangeOnAdjacent) { + changeCurrentMonth(cell.adjacent); + } else { + refreshDisplay(); + } + notifySelection(); + } + + /** + * Sets to true to enable the automatic change of current month + * when an adjacent day is clicked in the grid. + *

+ * This mode is true by default. + * + * @param autoChangeOnAdjacent true / false + */ + public void setAutoChangeOnAdjacent(boolean autoChangeOnAdjacent) { + this.autoChangeOnAdjacent = autoChangeOnAdjacent; + } + + /** + * Set the autoSelectOnFooter mode. If true, the today date is automatically + * selected on the footer selection event. + * This mode is false by default. + * + * @param autoselectOnFooter true /false + */ + public void setAutoSelectOnFooter(boolean autoselectOnFooter) { + checkWidget(); + autoSelectOnFooter = autoselectOnFooter; + } + + /** + * Sets the colors of a grid cell in function of its current state. + * + * @param cell grid cell + */ + private void setCellColors(Cell cell) { + if (cell.selected) { + cell.label.setBackground(theme.selectedBackground); + cell.label.setForeground(theme.selectedForeground); + } else if (cell.today) { + cell.label.setBackground(theme.todayBackground); + cell.label.setForeground(theme.todayForeground); + } else { + cell.label.setBackground(theme.dayCellBackground); + cell.label.setForeground(cell.adjacent != 0 ? theme.extraMonthForeground : cell.weekend ? theme.weekendForeground : theme.dayCellForeground); + } + + // Now check for customs colors + final Date cellDate = cell.cal.getTime(); + final Color custom = theme.getCustomColor(cellDate); + if (custom != null && !cell.selected) { + cell.label.setBackground(custom); + } + // set tooltip + cell.label.setToolTipText(theme.getCustomTootlip(cellDate)); + } + + /** + * Sets a new month to display. + * + * @param month New month + */ + public void setCurrentMonth(Date month) { + checkWidget(); + if (month == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (currentMonthCal == null) { + currentMonthCal = Calendar.getInstance(locale); + currentMonthCal.setFirstDayOfWeek(firstDayOfWeek); + currentMonthCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); + } + currentMonthCal.setTime(month); + trunc(currentMonthCal); + currentMonthCal.set(Calendar.DAY_OF_MONTH, 1); + refreshDisplay(); + } + + /** + * Sets what the first day of the week is. + *

+ * This method allows to change the default first day of the week set + * from the locale. It must be called after setLocale(). + * + * @param firstDayOfWeek the given first day of the week. + */ + public void setFirstDayOfWeek(int firstDayOfWeek) { + this.firstDayOfWeek = firstDayOfWeek; + currentMonthCal.setFirstDayOfWeek(firstDayOfWeek); + todayCal.setFirstDayOfWeek(firstDayOfWeek); + } + + /** + * Causes the receiver to have the keyboard focus, + * such that all keyboard events will be delivered to it. + * + * @return true if the control got focus, and false if it was unable to. + */ + @Override + public boolean setFocus() { + checkWidget(); + if (super.setFocus()) { + handleFocus(SWT.FocusIn); + return true; + } + return false; + } + + /** + * Sets the focus on the given cell, specified by index. + * + * @param index index of cell taking the focus + */ + private void setFocus(int index) { + if (index == NOFOCUS) { + if (todayCal.get(Calendar.MONTH) == currentMonthCal.get(Calendar.MONTH) && todayCal.get(Calendar.YEAR) == currentMonthCal.get(Calendar.YEAR)) { + for (int i = 0; i < days.length; i++) { + if (days[i].today) { + focusIndex = i; + return; + } + } + } + for (int i = 0; i < days.length; i++) { + if (days[i].cal.get(Calendar.DAY_OF_MONTH) == 1) { + focusIndex = i; + return; + } + } + } + if (index < 0) { + if (!navigationEnabled) { + return; + } + changeCurrentMonth(-1); + focusIndex = index + 42; + } else if (index >= 42) { + if (!navigationEnabled) { + return; + } + changeCurrentMonth(1); + focusIndex = index - 42; + } else { + focusIndex = index; + } + } + + /** + * Sets the focus on the given date. The current displayed month is changed + * if necessary. + * + * @param date date to set the focus on + */ + public void setFocusOnDate(Date date) { + final Calendar dateCal = (Calendar) currentMonthCal.clone(); + dateCal.setTime(date); + if (dateCal.get(Calendar.MONTH) != currentMonthCal.get(Calendar.MONTH) || dateCal.get(Calendar.YEAR) != currentMonthCal.get(Calendar.YEAR)) { + setCurrentMonth(date); + } + focusIndex = firstDayIndex + dateCal.get(Calendar.DAY_OF_MONTH) - 1; + } + + /** + * Sets the focus on the today date. If autoselect is true, the today date + * is selected. + * + * @param autoselect true to select automatically the today date, else false + */ + public void setFocusOnToday(boolean autoselect) { + checkWidget(); + redrawInc(); + if (currentMonthCal.get(Calendar.MONTH) != todayCal.get(Calendar.MONTH) || currentMonthCal.get(Calendar.YEAR) != todayCal.get(Calendar.YEAR)) { + setCurrentMonth(todayCal.getTime()); + } + setFocus(NOFOCUS); + if (autoselect) { + select(focusIndex, 0); + } + if (isDisposed()) { + return; + } + refreshDisplay(); + redrawDec(); + } + + /** + * Sets the font that the receiver will use to paint textual information to + * the font specified by the argument, or to the default font for that kind + * of control if the argument is null. + *

+ * + * The new font is applied to all elements (labels) composing the calendar. + * The width of cells is adjusted. + * + * @param font the new font (or null) + */ + @Override + public void setFont(Font font) { + checkWidget(); + redrawInc(); + super.setFont(font); + currentMonth.setFont(font); + for (int i = 0; i < headers.length; i++) { + headers[i].setFont(font); + } + for (int i = 0; i < days.length; i++) { + days[i].label.setFont(font); + } + for (int i = 0; i < weeks.length; i++) { + weeks[i].label.setFont(font); + } + todayLabel.setFont(font); + redrawDec(); + } + + /** + * Sets the footer visible or not. The footer displays the today date. It is + * not visible by default. + * + * @param footerVisible true to set footer visible, else false + */ + public void setFooterVisible(boolean footerVisible) { + checkWidget(); + if (footerVisible != this.footerVisible) { + this.footerVisible = footerVisible; + layout(true); + } + } + + /** + * Sets the grid visible or not in the calendar popup. By default, the grid + * is visible. + * + * @param gridVisible true to set grid visible, else false + * @deprecated + */ + @Deprecated + public void setGridVisible(boolean gridVisible) { + setGridVisible(gridVisible ? GRID_FULL : GRID_NONE); + } + + /** + * Sets the grid visible or not. By default, the grid is visible. The + * possible values are GRID_FULL, GRID_LINES and GRID_NONE. + * + * @param gridVisible grid visibility flag + */ + public void setGridVisible(int gridVisible) { + checkWidget(); + this.gridVisible = gridVisible; + switch (this.gridVisible) { + case GRID_FULL: + gridPanel.setBackground(theme.gridLinesColor); + headersPanel.setBackground(theme.gridLinesColor); + daysPanel.setBackground(theme.gridLinesColor); + weeksPanel.setBackground(theme.gridLinesColor); + break; + + case GRID_LINES: + gridPanel.setBackground(theme.gridLinesColor); + headersPanel.setBackground(theme.gridHeaderBackground); + daysPanel.setBackground(theme.dayCellBackground); + weeksPanel.setBackground(theme.gridHeaderBackground); + break; + + case GRID_NONE: + gridPanel.setBackground(theme.gridHeaderBackground); + headersPanel.setBackground(theme.gridHeaderBackground); + daysPanel.setBackground(theme.dayCellBackground); + weeksPanel.setBackground(theme.gridHeaderBackground); + break; + } + } + + /** + * Sets the layout which is associated with the receiver to be + * the argument which may be null. + *

+ * Note : No Layout can be set on this Control because it already + * manages the size and position of its children. + *

+ * + * @param layout the receiver's new layout or null + */ + @Override + public void setLayout(Layout layout) { + checkWidget(); + return; + } + + /** + * Sets a new locale to use for calendar. Locale will define the names of + * months and days, and the first day of week. + * + * @param locale new locale (must not be null) + */ + public void setLocale(Locale locale) { + checkWidget(); + if (locale == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + this.locale = locale; + + // Loads the resources + resources = ResourceBundle.getBundle(BUNDLE_NAME, locale); + prevMonth.setToolTipText(resources.getString("DateChooser.previousButton")); //$NON-NLS-1$ + nextMonth.setToolTipText(resources.getString("DateChooser.nextButton")); //$NON-NLS-1$ + + // Defines formats + df1 = new SimpleDateFormat("MMMM yyyy", locale); //$NON-NLS-1$ + df2 = DateFormat.getDateInstance(DateFormat.SHORT, locale); + final Calendar c = Calendar.getInstance(TimeZone.getDefault(), locale); + firstDayOfWeek = c.getFirstDayOfWeek(); + minimalDaysInFirstWeek = Integer.parseInt(resources.getString("minimalDaysInFirstWeek")); + if (currentMonthCal != null) { + currentMonthCal.setFirstDayOfWeek(firstDayOfWeek); + currentMonthCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); + } + if (todayCal != null) { + todayCal.setFirstDayOfWeek(firstDayOfWeek); + todayCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); + } + + // Sets the header menu items + final String[] months = df1.getDateFormatSymbols().getMonths(); + final MenuItem[] items = monthsMenu.getItems(); + for (int i = 0; i < 12; i++) { + items[i].setText(months[i]); + } + + // Sets the grid header initials + redrawInc(); + final DateFormatSymbols symboles = df1.getDateFormatSymbols(); + final String[] sn = symboles.getShortWeekdays(); + final String[] ln = symboles.getWeekdays(); + int f = firstDayOfWeek; + for (int i = 1; i < headers.length; i++) { + headers[i].setText(sn[f].substring(0, 1).toUpperCase()); + headers[i].setToolTipText(ln[f]); + f = f % 7 + 1; + } + + // Updates the footer + updateTodayLabel(); + + refreshDisplay(); + redrawDec(); + } + + /** + * Sets what the minimal days required in the first week of the year are; For + * example, if the first week is defined as one that contains the first day + * of the first month of a year, call this method with value 1. If it must be + * a full week, use value 7. + *

+ * This method allows to change the default value set from the locale. + * It must be called after setLocale(). + * + * @param minimalDaysInFirstWeek the given minimal days required in the first week of the year. + */ + public void setMinimalDaysInFirstWeek(int minimalDaysInFirstWeek) { + this.minimalDaysInFirstWeek = minimalDaysInFirstWeek; + currentMonthCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); + todayCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); + } + + /** + * Sets the header's navigation buttons visible or not. + * + * @param navigationEnabled true if enabled, false else + */ + public void setNavigationEnabled(boolean navigationEnabled) { + checkWidget(); + if (navigationEnabled != this.navigationEnabled) { + this.navigationEnabled = navigationEnabled; + prevMonth.setVisible(navigationEnabled); + nextMonth.setVisible(navigationEnabled); + if (navigationEnabled) { + currentMonth.setMenu(monthsMenu); + } else { + currentMonth.setMenu(null); + } + } + } + + /** + * Sets the selected date. The grid is refreshed to display the corresponding + * month. + * + * @param date new selected date (must not be null) + */ + public void setSelectedDate(Date date) { + checkWidget(); + if (date == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final Calendar c = (Calendar) currentMonthCal.clone(); + c.setTime(date); + trunc(c); + final Date d = c.getTime(); + if (!selection.contains(d)) { + if (!multi) { + clearSelection(false); + } + selection.add(d); + } + setCurrentMonth(d); + } + + /** + * Sets the theme to apply to the calendar. + * + * @param theme new theme (must not be null) + */ + public void setTheme(DateChooserTheme theme) { + checkWidget(); + if (theme == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + this.theme = theme; + redrawInc(); + + // Border + setBackground(theme.borderBackground); + final GridLayout layout = (GridLayout) getLayout(); + layout.marginWidth = theme.borderSize; + layout.marginHeight = theme.borderSize; + + setGridVisible(theme.gridVisible); + + // Month header settings + monthPanel.setBackground(theme.headerBackground); + currentMonth.setBackground(theme.headerBackground); + currentMonth.setForeground(theme.headerForeground); + + // Today footer settings + todayLabel.setBackground(theme.gridHeaderBackground); + todayLabel.setForeground(theme.gridHeaderForeground); + + // Days headers settings + for (int i = 0; i < headers.length; i++) { + headers[i].setBackground(theme.gridHeaderBackground); + headers[i].setForeground(theme.gridHeaderForeground); + } + + // Grid days cells settings + for (int i = 0; i < days.length; i++) { + days[i].label.setBackground(theme.dayCellBackground); + } + + // Weeks cells settings + for (int i = 0; i < weeks.length; i++) { + weeks[i].label.setBackground(theme.gridHeaderBackground); + weeks[i].label.setForeground(theme.gridHeaderForeground); + } + + // Font + setFont(theme.font); + + pack(true); + layout(true); + refreshDisplay(); + redrawDec(); + } + + /** + * Sets the today date. + *

+ * + * By default the today date is initialized to the current system date. But it + * can be needed to adjust it for specifics needs. + * + * @param today today date (must not be null) + */ + public void setTodayDate(Date today) { + checkWidget(); + if (today == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (todayCal == null) { + todayCal = Calendar.getInstance(locale); + todayCal.setFirstDayOfWeek(firstDayOfWeek); + todayCal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); + } + todayCal.setTime(today); + trunc(todayCal); + updateTodayLabel(); + refreshDisplay(); + } + + /** + * Sets the weeks numbers visible or not. By default, the weeks are NOT + * visible. + * + * @param weeksVisible true to set weeks visible, else false + */ + public void setWeeksVisible(boolean weeksVisible) { + checkWidget(); + if (weeksVisible != this.weeksVisible) { + this.weeksVisible = weeksVisible; + layout(true); + } + } + + /** + * Truncate a given Calendar. The time fields are all set to 0. + * + * @param cal Calendar + */ + private void trunc(Calendar cal) { + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + } + + /** + * Updates the today label in the footer. Called when the today date or the + * locale is changed. + */ + private void updateTodayLabel() { + if (todayCal != null) { + todayLabel.setText(resources.getString("DateChooser.today") + " " + df2.format(todayCal.getTime())); + } + } +} diff --git a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/DateChooserCombo.java b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/DateChooserCombo.java index f67bee2a1..6dce1caab 100644 --- a/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/DateChooserCombo.java +++ b/widgets/datechooser/org.eclipse.nebula.widgets.datechooser/src/org/eclipse/nebula/widgets/datechooser/DateChooserCombo.java @@ -1,410 +1,410 @@ -/******************************************************************************* - * Copyright (c) 2005, 2009 Eric Wuillai. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Eric Wuillai (eric@wdev91.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.datechooser; - -import java.util.Date; -import java.util.Locale; - -import org.eclipse.nebula.widgets.formattedtext.DateFormatter; -import org.eclipse.nebula.widgets.formattedtext.DefaultFormatterFactory; -import org.eclipse.nebula.widgets.formattedtext.FormattedText; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Text; - -/** - * DateChooserCombo widget. This class represents a date field editor that combines - * a text field and a calendar. Implementation is based on FormattedText - * and DateChooser. - *

- * - * Issues notification when the text content is modified or when a date is - * selected in the calendar. - *

- * - *

- *
Styles: - *
BORDER, READ_ONLY, FLAT
- *
Events: - *
Modify
- *
Selection
- *
- */ -public class DateChooserCombo extends AbstractCombo { - /** Default image filename */ - protected static final String IMAGE = "/org/eclipse/nebula/widgets/datechooser/DateChooserCombo.png"; - - /** Default image for the button */ - protected static Image buttonImage; - - /** FormattedText widget for edition of the date */ - protected FormattedText formattedText; - /** Flag to set footer visible or not in the popup */ - protected boolean footerVisible = false; - /** Flag to set grid visible or not in the popup */ - protected int gridVisible = DateChooser.GRID_FULL; - /** Flag to set weeks numbers visible or not */ - protected boolean weeksVisible = false; - /** Calendar theme */ - protected DateChooserTheme theme; - /** Locale used for localized names and formats */ - protected Locale locale; - - static { - buttonImage = new Image(Display.getCurrent(), DateChooserCombo.class.getResourceAsStream(IMAGE)); - } - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * - * The widget is initialized with a default image for the button, and a - * default DateFormatter. - * - * @param parent a composite control which will be the parent of the new instance (cannot be null) - * @param style the style of control to construct - */ - public DateChooserCombo(Composite parent, int style) { - super(parent, style); - setTheme(DateChooserTheme.getDefaultTheme()); - setImage(buttonImage); - setCreateOnDrop(true); - pack(); - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * keys are pressed and released on the system keyboard, by sending it one of - * the messages defined in the KeyListener interface. - * The listener is set on the Text widget, as there is no sense to have it - * on the Composite. - * - * @param listener the listener which should be notified - */ - public void addKeyListener(KeyListener listener) { - checkWidget(); - text.addKeyListener(listener); - } - - /** - * Called just before the popup is dropped. The selected date of the - * calendar is set to the current date present in the formatted text. - * - * @see org.eclipse.nebula.widgets.datechooser.AbstractCombo#beforeDrop() - */ - protected void beforeDrop() { - Date d = (Date) formattedText.getValue(); - DateChooser cal = (DateChooser) popupContent; - if (d != null) { - cal.setSelectedDate(d); - cal.setFocusOnDate(d); - } else { - cal.clearSelection(); - cal.setFocusOnToday(false); - } - } - - /** - * Returns the preferred size of the receiver.
- * If wHint == SWT.DEFAULT, the preferred size is computed to adjust the width - * to display a date in the MM/dd/yyyy format. If a DateFormatter with more - * larger edit or display patterns is used, the width of the combo must be - * set programmatically. - * - * @param wHint the width hint (can be SWT.DEFAULT) - * @param hHint the height hint (can be SWT.DEFAULT) - * @param changed true if the control's contents have changed, and false otherwise - * @return the preferred size of the control. - */ - public Point computeSize(int wHint, int hHint, boolean changed) { - checkWidget(); - Point size = new Point(wHint, hHint); - Point textSize = text.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); - Point buttonSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); - int borderWidth = getBorderWidth(); - - if (wHint == SWT.DEFAULT) { - GC gc = new GC(formattedText.getControl()); - int width = gc.textExtent("01/01/2000 ").x; - gc.dispose(); - size.x = width + buttonSize.x + 2 * borderWidth; - } - if (hHint == SWT.DEFAULT) { - if (WIN32) { - buttonSize.y = ((GridData) button.getLayoutData()).heightHint; - } - size.y = Math.max(textSize.y, buttonSize.y) + 2 * borderWidth; - } - - return size; - } - - /** - * Creates the button widget. The default appearance with an arrow is - * replaced by a button with an image. - * - * @param style button style - * @return the created Button control - * @see org.eclipse.nebula.widgets.datechooser.AbstractCombo#createButtonControl(int) - */ - protected Button createButtonControl(int style) { - style &= ~(SWT.ARROW | SWT.DOWN); - return new Button(this, style | SWT.PUSH); - } - - /** - * Creates the popup content. The content is a DateChooser. - * - * @param parent The parent Composite that will contain the control - * @return The created Control for the popup content - */ - protected Control createPopupContent(Composite parent) { - DateChooser cal = new DateChooser(parent, SWT.NONE); - cal.setTheme(theme); - if (locale != null) { - cal.setLocale(locale); - } - cal.setGridVisible(gridVisible); - cal.setFooterVisible(footerVisible); - cal.setWeeksVisible(weeksVisible); - cal.setAutoSelectOnFooter(true); - cal.pack(); - return cal; - } - - /** - * Creates the text widget. Overrides the default implementation to create a - * FormattedText with the default formatter for Date - * values. - * The formatter is provided by DefaultFormatterFactory. By default - * a DateFormatter is returned. This can be changed by - * registering a new formatter for Date class. - * - * @param style text style - * @return the created Text control - * @see org.eclipse.nebula.widgets.datechooser.AbstractCombo#createTextControl(int) - */ - protected Text createTextControl(int style) { - formattedText = new FormattedText(this, SWT.NONE); - formattedText.setFormatter(DefaultFormatterFactory.createFormatter(Date.class)); - return formattedText.getControl(); - } - - /** - * This method is called when a SWT.Selection is notify in the popup content, - * allowing to update the Text widget content. - * - * @return true if the SWT.Selection event must be propagated, else false - */ - protected boolean doSelection() { - formattedText.setValue(((DateChooser) popupContent).getSelectedDate()); - return true; - } - - /** - * @see org.eclipse.nebula.widgets.datechooser.AbstractCombo#dropDown(boolean) - */ - protected void dropDown(boolean drop) { - super.dropDown(drop); - if (drop && GTK) { - /* - * Bug GTK. When the popup is displayed, the calendar does not gain the - * focus until the user click into it with the mouse. Then the keyboard - * is unusable. - */ - popupContent.traverse(SWT.TRAVERSE_TAB_NEXT); - } - } - - /** - * Returns the grid visibility status. - * - * @return Returns the grid visible status. - */ - public int getGridVisible() { - checkWidget(); - return gridVisible; - } - - /** - * Returns the current Date value of the widget. - *

- * - * @return Current value - */ - public Date getValue() { - checkWidget(); - return (Date) formattedText.getValue(); - } - - /** - * Returns true if footer is visible in the popup calendar. - * - * @return true if footer visible, else false - */ - public boolean isFooterVisible() { - checkWidget(); - return footerVisible; - } - - /** - * Returns true if grid is visible in the calendar popup. - * - * @return Returns the grid visible status. - * @deprecated - */ - public boolean isGridVisible() { - checkWidget(); - return gridVisible == DateChooser.GRID_FULL; - } - - /** - * Returns true if weeks numbers are visible. - * - * @return Returns the weeks numbers visible status. - */ - public boolean isWeeksVisible() { - checkWidget(); - return weeksVisible; - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when keys are pressed and released on the system keyboard. - * - * @param listener the listener which should no longer be notified - */ - public void removeKeyListener(KeyListener listener) { - checkWidget(); - formattedText.getControl().removeKeyListener(listener); - } - - /** - * Sets the footer of popup calendar visible or not. The footer displays the - * today date. It is not visible by default. - * - * @param footerVisible true to set footer visible, else false - */ - public void setFooterVisible(boolean footerVisible) { - checkWidget(); - this.footerVisible = footerVisible; - } - - /** - * Associates a new DateFormatter to the text widget, replacing - * the default one. - * - * @param formatter date formatter - */ - public void setFormatter(DateFormatter formatter) { - checkWidget(); - formattedText.setFormatter(formatter); - this.locale = formatter.getLocale(); - } - - /** - * Sets the grid visible or not in the calendar popup. By default, the grid - * is visible. - * - * @param gridVisible true to set grid visible, else false - * @deprecated - */ - public void setGridVisible(boolean gridVisible) { - setGridVisible(gridVisible ? DateChooser.GRID_FULL : DateChooser.GRID_NONE); - } - - /** - * Sets the grid visible or not. By default, the grid is visible. The - * possible values are GRID_FULL, GRID_LINES and GRID_NONE. - * - * @param gridVisible grid visibility flag - */ - public void setGridVisible(int gridVisible) { - this.gridVisible = gridVisible; - } - - /** - * Sets a new image to display on the button, replacing the default one. - * - * @param image new image - */ - public void setImage(Image image) { - checkWidget(); - if (image == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - GridData buttonLayout = (GridData) button.getLayoutData(); - if (WIN32) { - ImageData id = image.getImageData(); - buttonLayout.widthHint = id.width + 4; - buttonLayout.heightHint = id.height + 6; - } - button.setImage(image); - pack(); - } - - /** - * Sets the locale used both by the input mask and the calendar. - * - * @param locale locale - */ - public void setLocale(Locale locale) { - checkWidget(); - this.locale = locale; - ((DateFormatter) formattedText.getFormatter()).setLocale(locale); - } - - /** - * Sets the theme to apply to the calendar popup. - * - * @param theme new theme (must not be null) - */ - public void setTheme(DateChooserTheme theme) { - checkWidget(); - if (theme == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - this.theme = theme; - this.gridVisible = theme.gridVisible; - } - - /** - * Sets a new Date value. - * - * @param value new date value - */ - public void setValue(Date value) { - checkWidget(); - formattedText.setValue(value); - } - - /** - * Sets the weeks numbers visible or not. By default, the weeks are NOT - * visible. - * - * @param weeksVisible true to set weeks visible, else false - */ - public void setWeeksVisible(boolean weeksVisible) { - checkWidget(); - this.weeksVisible = weeksVisible; - } -} +/******************************************************************************* + * Copyright (c) 2005, 2009 Eric Wuillai. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eric Wuillai (eric@wdev91.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.datechooser; + +import java.util.Date; +import java.util.Locale; + +import org.eclipse.nebula.widgets.formattedtext.DateFormatter; +import org.eclipse.nebula.widgets.formattedtext.DefaultFormatterFactory; +import org.eclipse.nebula.widgets.formattedtext.FormattedText; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Text; + +/** + * DateChooserCombo widget. This class represents a date field editor that combines + * a text field and a calendar. Implementation is based on FormattedText + * and DateChooser. + *

+ * + * Issues notification when the text content is modified or when a date is + * selected in the calendar. + *

+ * + *

+ *
Styles: + *
BORDER, READ_ONLY, FLAT
+ *
Events: + *
Modify
+ *
Selection
+ *
+ */ +public class DateChooserCombo extends AbstractCombo { + /** Default image filename */ + protected static final String IMAGE = "/org/eclipse/nebula/widgets/datechooser/DateChooserCombo.png"; + + /** Default image for the button */ + protected static Image buttonImage; + + /** FormattedText widget for edition of the date */ + protected FormattedText formattedText; + /** Flag to set footer visible or not in the popup */ + protected boolean footerVisible = false; + /** Flag to set grid visible or not in the popup */ + protected int gridVisible = DateChooser.GRID_FULL; + /** Flag to set weeks numbers visible or not */ + protected boolean weeksVisible = false; + /** Calendar theme */ + protected DateChooserTheme theme; + /** Locale used for localized names and formats */ + protected Locale locale; + + static { + buttonImage = new Image(Display.getCurrent(), DateChooserCombo.class.getResourceAsStream(IMAGE)); + } + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * + * The widget is initialized with a default image for the button, and a + * default DateFormatter. + * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + */ + public DateChooserCombo(Composite parent, int style) { + super(parent, style); + setTheme(DateChooserTheme.getDefaultTheme()); + setImage(buttonImage); + setCreateOnDrop(true); + pack(); + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * keys are pressed and released on the system keyboard, by sending it one of + * the messages defined in the KeyListener interface. + * The listener is set on the Text widget, as there is no sense to have it + * on the Composite. + * + * @param listener the listener which should be notified + */ + public void addKeyListener(KeyListener listener) { + checkWidget(); + text.addKeyListener(listener); + } + + /** + * Called just before the popup is dropped. The selected date of the + * calendar is set to the current date present in the formatted text. + * + * @see org.eclipse.nebula.widgets.datechooser.AbstractCombo#beforeDrop() + */ + protected void beforeDrop() { + Date d = (Date) formattedText.getValue(); + DateChooser cal = (DateChooser) popupContent; + if (d != null) { + cal.setSelectedDate(d); + cal.setFocusOnDate(d); + } else { + cal.clearSelection(); + cal.setFocusOnToday(false); + } + } + + /** + * Returns the preferred size of the receiver.
+ * If wHint == SWT.DEFAULT, the preferred size is computed to adjust the width + * to display a date in the MM/dd/yyyy format. If a DateFormatter with more + * larger edit or display patterns is used, the width of the combo must be + * set programmatically. + * + * @param wHint the width hint (can be SWT.DEFAULT) + * @param hHint the height hint (can be SWT.DEFAULT) + * @param changed true if the control's contents have changed, and false otherwise + * @return the preferred size of the control. + */ + public Point computeSize(int wHint, int hHint, boolean changed) { + checkWidget(); + Point size = new Point(wHint, hHint); + Point textSize = text.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); + Point buttonSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); + int borderWidth = getBorderWidth(); + + if (wHint == SWT.DEFAULT) { + GC gc = new GC(formattedText.getControl()); + int width = gc.textExtent("01/01/2000 ").x; + gc.dispose(); + size.x = width + buttonSize.x + 2 * borderWidth; + } + if (hHint == SWT.DEFAULT) { + if (WIN32) { + buttonSize.y = ((GridData) button.getLayoutData()).heightHint; + } + size.y = Math.max(textSize.y, buttonSize.y) + 2 * borderWidth; + } + + return size; + } + + /** + * Creates the button widget. The default appearance with an arrow is + * replaced by a button with an image. + * + * @param style button style + * @return the created Button control + * @see org.eclipse.nebula.widgets.datechooser.AbstractCombo#createButtonControl(int) + */ + protected Button createButtonControl(int style) { + style &= ~(SWT.ARROW | SWT.DOWN); + return new Button(this, style | SWT.PUSH); + } + + /** + * Creates the popup content. The content is a DateChooser. + * + * @param parent The parent Composite that will contain the control + * @return The created Control for the popup content + */ + protected Control createPopupContent(Composite parent) { + DateChooser cal = new DateChooser(parent, SWT.NONE); + cal.setTheme(theme); + if (locale != null) { + cal.setLocale(locale); + } + cal.setGridVisible(gridVisible); + cal.setFooterVisible(footerVisible); + cal.setWeeksVisible(weeksVisible); + cal.setAutoSelectOnFooter(true); + cal.pack(); + return cal; + } + + /** + * Creates the text widget. Overrides the default implementation to create a + * FormattedText with the default formatter for Date + * values. + * The formatter is provided by DefaultFormatterFactory. By default + * a DateFormatter is returned. This can be changed by + * registering a new formatter for Date class. + * + * @param style text style + * @return the created Text control + * @see org.eclipse.nebula.widgets.datechooser.AbstractCombo#createTextControl(int) + */ + protected Text createTextControl(int style) { + formattedText = new FormattedText(this, SWT.NONE); + formattedText.setFormatter(DefaultFormatterFactory.createFormatter(Date.class)); + return formattedText.getControl(); + } + + /** + * This method is called when a SWT.Selection is notify in the popup content, + * allowing to update the Text widget content. + * + * @return true if the SWT.Selection event must be propagated, else false + */ + protected boolean doSelection() { + formattedText.setValue(((DateChooser) popupContent).getSelectedDate()); + return true; + } + + /** + * @see org.eclipse.nebula.widgets.datechooser.AbstractCombo#dropDown(boolean) + */ + protected void dropDown(boolean drop) { + super.dropDown(drop); + if (drop && GTK) { + /* + * Bug GTK. When the popup is displayed, the calendar does not gain the + * focus until the user click into it with the mouse. Then the keyboard + * is unusable. + */ + popupContent.traverse(SWT.TRAVERSE_TAB_NEXT); + } + } + + /** + * Returns the grid visibility status. + * + * @return Returns the grid visible status. + */ + public int getGridVisible() { + checkWidget(); + return gridVisible; + } + + /** + * Returns the current Date value of the widget. + *

+ * + * @return Current value + */ + public Date getValue() { + checkWidget(); + return (Date) formattedText.getValue(); + } + + /** + * Returns true if footer is visible in the popup calendar. + * + * @return true if footer visible, else false + */ + public boolean isFooterVisible() { + checkWidget(); + return footerVisible; + } + + /** + * Returns true if grid is visible in the calendar popup. + * + * @return Returns the grid visible status. + * @deprecated + */ + public boolean isGridVisible() { + checkWidget(); + return gridVisible == DateChooser.GRID_FULL; + } + + /** + * Returns true if weeks numbers are visible. + * + * @return Returns the weeks numbers visible status. + */ + public boolean isWeeksVisible() { + checkWidget(); + return weeksVisible; + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when keys are pressed and released on the system keyboard. + * + * @param listener the listener which should no longer be notified + */ + public void removeKeyListener(KeyListener listener) { + checkWidget(); + formattedText.getControl().removeKeyListener(listener); + } + + /** + * Sets the footer of popup calendar visible or not. The footer displays the + * today date. It is not visible by default. + * + * @param footerVisible true to set footer visible, else false + */ + public void setFooterVisible(boolean footerVisible) { + checkWidget(); + this.footerVisible = footerVisible; + } + + /** + * Associates a new DateFormatter to the text widget, replacing + * the default one. + * + * @param formatter date formatter + */ + public void setFormatter(DateFormatter formatter) { + checkWidget(); + formattedText.setFormatter(formatter); + this.locale = formatter.getLocale(); + } + + /** + * Sets the grid visible or not in the calendar popup. By default, the grid + * is visible. + * + * @param gridVisible true to set grid visible, else false + * @deprecated + */ + public void setGridVisible(boolean gridVisible) { + setGridVisible(gridVisible ? DateChooser.GRID_FULL : DateChooser.GRID_NONE); + } + + /** + * Sets the grid visible or not. By default, the grid is visible. The + * possible values are GRID_FULL, GRID_LINES and GRID_NONE. + * + * @param gridVisible grid visibility flag + */ + public void setGridVisible(int gridVisible) { + this.gridVisible = gridVisible; + } + + /** + * Sets a new image to display on the button, replacing the default one. + * + * @param image new image + */ + public void setImage(Image image) { + checkWidget(); + if (image == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + GridData buttonLayout = (GridData) button.getLayoutData(); + if (WIN32) { + ImageData id = image.getImageData(); + buttonLayout.widthHint = id.width + 4; + buttonLayout.heightHint = id.height + 6; + } + button.setImage(image); + pack(); + } + + /** + * Sets the locale used both by the input mask and the calendar. + * + * @param locale locale + */ + public void setLocale(Locale locale) { + checkWidget(); + this.locale = locale; + ((DateFormatter) formattedText.getFormatter()).setLocale(locale); + } + + /** + * Sets the theme to apply to the calendar popup. + * + * @param theme new theme (must not be null) + */ + public void setTheme(DateChooserTheme theme) { + checkWidget(); + if (theme == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + this.theme = theme; + this.gridVisible = theme.gridVisible; + } + + /** + * Sets a new Date value. + * + * @param value new date value + */ + public void setValue(Date value) { + checkWidget(); + formattedText.setValue(value); + } + + /** + * Sets the weeks numbers visible or not. By default, the weeks are NOT + * visible. + * + * @param weeksVisible true to set weeks visible, else false + */ + public void setWeeksVisible(boolean weeksVisible) { + checkWidget(); + this.weeksVisible = weeksVisible; + } +} diff --git a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.feature/.classpath b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.feature/.classpath index dd93d7d83..bc3587db4 100644 --- a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.feature/.classpath +++ b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.feature/.classpath @@ -1,6 +1,6 @@ - - - - - - + + + + + + diff --git a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.feature/.settings/org.eclipse.jdt.core.prefs b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.feature/.settings/org.eclipse.jdt.core.prefs index 27656b34c..9d6b57d79 100644 --- a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.feature/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.feature/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.8 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.snippets/.classpath b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.snippets/.classpath +++ b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext/.classpath b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext/.classpath +++ b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext/.settings/org.eclipse.jdt.core.prefs b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/floatingtext/org.eclipse.nebula.widgets.floatingtext/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/.project b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/.project index 5cb306753..d5dafb694 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/.project +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.fontawesome.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.fontawesome.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/build.properties b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/build.properties +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/feature.properties b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/feature.properties +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/feature.xml b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/feature.xml index 86e60ac52..887e79a94 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/feature.xml +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/feature.xml @@ -1,24 +1,24 @@ - - - - - Font Awesome Widget - - - - %license - - - - - - - + + + + + Font Awesome Widget + + + + %license + + + + + + + diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/pom.xml b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/pom.xml index d7a8b6d89..ec9d5902b 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/pom.xml +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - fontawesome - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.fontawesome.feature - eclipse-feature - 1.0.0-SNAPSHOT - - Nebula FontAwesome Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + fontawesome + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.fontawesome.feature + eclipse-feature + 1.0.0-SNAPSHOT + + Nebula FontAwesome Feature + + diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.classpath b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.classpath index 1f4b7f255..b22f6d6da 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.classpath +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.classpath @@ -1,8 +1,8 @@ - - - - - - - - + + + + + + + + diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.project b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.project index acf7dfba9..581569776 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.project +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.fontawesome.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.fontawesome.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/META-INF/MANIFEST.MF b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/META-INF/MANIFEST.MF index 3a3359d7c..124996d88 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/META-INF/MANIFEST.MF +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Font Awesome Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.fontawesome.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.fontawesome;bundle-version="1.0.0" -Bundle-ClassPath: ., - swing2swt.jar -Automatic-Module-Name: org.eclipse.nebula.widgets.fontawesome.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Font Awesome Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.fontawesome.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.fontawesome;bundle-version="1.0.0" +Bundle-ClassPath: ., + swing2swt.jar +Automatic-Module-Name: org.eclipse.nebula.widgets.fontawesome.snippets diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/build.properties b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/build.properties +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/pom.xml b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/pom.xml index e35e0dbd9..19354c697 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/pom.xml +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - fontawesome - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.fontawesome.snippets - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + fontawesome + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.fontawesome.snippets + eclipse-plugin + + diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/src/org/eclipse/nebula/widgets/fontawesome/FontAwesomeSnippet.java b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/src/org/eclipse/nebula/widgets/fontawesome/FontAwesomeSnippet.java index 1c2116871..b38133271 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/src/org/eclipse/nebula/widgets/fontawesome/FontAwesomeSnippet.java +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/src/org/eclipse/nebula/widgets/fontawesome/FontAwesomeSnippet.java @@ -1,64 +1,64 @@ -/******************************************************************************* - * Copyright (c) 2020 Patrik Dufresne (http://www.patrikdufresne.com/). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Patrik Dufresne (info at patrikdufresne dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.fontawesome; - -import java.lang.reflect.Field; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * Snippet for the FontAwesome widget - */ -public class FontAwesomeSnippet { - - public static void main(final String[] args) throws IllegalArgumentException, IllegalAccessException { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setText("FontAwesome Snippet"); - shell.setSize(600, 600); - shell.setLayout(new GridLayout(24, false)); - - // Loop on each COLOR constants. - Field[] fields = FontAwesome.class.getDeclaredFields(); - for (Field field : fields) { - field.setAccessible(true); - if (!field.getType().equals(String.class)) { - continue; - } - String value = (String) field.get(null); - if (value.length() != 1) { - continue; - } - Label text = new Label(shell, SWT.NONE); - text.setFont(FontAwesome.getFont(22)); - text.setText(value); - text.setToolTipText(field.getName()); - } - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - - } - +/******************************************************************************* + * Copyright (c) 2020 Patrik Dufresne (http://www.patrikdufresne.com/). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Patrik Dufresne (info at patrikdufresne dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.fontawesome; + +import java.lang.reflect.Field; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * Snippet for the FontAwesome widget + */ +public class FontAwesomeSnippet { + + public static void main(final String[] args) throws IllegalArgumentException, IllegalAccessException { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setText("FontAwesome Snippet"); + shell.setSize(600, 600); + shell.setLayout(new GridLayout(24, false)); + + // Loop on each COLOR constants. + Field[] fields = FontAwesome.class.getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + if (!field.getType().equals(String.class)) { + continue; + } + String value = (String) field.get(null); + if (value.length() != 1) { + continue; + } + Label text = new Label(shell, SWT.NONE); + text.setFont(FontAwesome.getFont(22)); + text.setText(value); + text.setToolTipText(field.getName()); + } + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + + } + } \ No newline at end of file diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/src/org/eclipse/nebula/widgets/fontawesome/FontAwesomeSnippet2.java b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/src/org/eclipse/nebula/widgets/fontawesome/FontAwesomeSnippet2.java index 95a2542e5..4ae49fe3c 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/src/org/eclipse/nebula/widgets/fontawesome/FontAwesomeSnippet2.java +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome.snippets/src/org/eclipse/nebula/widgets/fontawesome/FontAwesomeSnippet2.java @@ -1,80 +1,80 @@ -/******************************************************************************* - * Copyright (c) 2020 Patrik Dufresne (http://www.patrikdufresne.com/). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Patrik Dufresne (info at patrikdufresne dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.fontawesome; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; - -public class FontAwesomeSnippet2 { - - public static void main(final String[] args) throws IllegalArgumentException, IllegalAccessException { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setText("FontAwesome Snippet"); - shell.setSize(600, 600); - shell.setLayout(new GridLayout(1, false)); - - // Label - new Label(shell, SWT.NONE).setText("In Label"); - Label text = new Label(shell, SWT.NONE); - text.setFont(FontAwesome.getFont(22)); - text.setText(FontAwesome.code); - - // Button - new Label(shell, SWT.NONE).setText("In Button"); - Composite comp1 = new Composite(shell, SWT.NONE); - comp1.setLayout(new RowLayout()); - Button button1 = new Button(comp1, SWT.NONE); - button1.setFont(FontAwesome.getFont(10)); - button1.setText(FontAwesome.plus + " plus"); - Button button2 = new Button(comp1, SWT.NONE); - button2.setFont(FontAwesome.getFont(10)); - button2.setText(FontAwesome.minus + " minus"); - - // Toolbar - new Label(shell, SWT.NONE).setText("In ToolBar"); - ToolBar toolbar = new ToolBar(shell, SWT.NONE); - toolbar.setFont(FontAwesome.getFont(15)); - ToolItem item1 = new ToolItem(toolbar, SWT.NONE); - item1.setText(FontAwesome.align_left); - ToolItem item2 = new ToolItem(toolbar, SWT.NONE); - item2.setText(FontAwesome.align_center); - ToolItem item3 = new ToolItem(toolbar, SWT.NONE); - item3.setText(FontAwesome.align_right); - new ToolItem(toolbar, SWT.SEPARATOR); - ToolItem item4 = new ToolItem(toolbar, SWT.NONE); - item4.setText(FontAwesome.quote_left); - new ToolItem(toolbar, SWT.SEPARATOR); - ToolItem item5 = new ToolItem(toolbar, SWT.NONE); - item5.setText(FontAwesome.question); - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - - } +/******************************************************************************* + * Copyright (c) 2020 Patrik Dufresne (http://www.patrikdufresne.com/). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Patrik Dufresne (info at patrikdufresne dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.fontawesome; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +public class FontAwesomeSnippet2 { + + public static void main(final String[] args) throws IllegalArgumentException, IllegalAccessException { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setText("FontAwesome Snippet"); + shell.setSize(600, 600); + shell.setLayout(new GridLayout(1, false)); + + // Label + new Label(shell, SWT.NONE).setText("In Label"); + Label text = new Label(shell, SWT.NONE); + text.setFont(FontAwesome.getFont(22)); + text.setText(FontAwesome.code); + + // Button + new Label(shell, SWT.NONE).setText("In Button"); + Composite comp1 = new Composite(shell, SWT.NONE); + comp1.setLayout(new RowLayout()); + Button button1 = new Button(comp1, SWT.NONE); + button1.setFont(FontAwesome.getFont(10)); + button1.setText(FontAwesome.plus + " plus"); + Button button2 = new Button(comp1, SWT.NONE); + button2.setFont(FontAwesome.getFont(10)); + button2.setText(FontAwesome.minus + " minus"); + + // Toolbar + new Label(shell, SWT.NONE).setText("In ToolBar"); + ToolBar toolbar = new ToolBar(shell, SWT.NONE); + toolbar.setFont(FontAwesome.getFont(15)); + ToolItem item1 = new ToolItem(toolbar, SWT.NONE); + item1.setText(FontAwesome.align_left); + ToolItem item2 = new ToolItem(toolbar, SWT.NONE); + item2.setText(FontAwesome.align_center); + ToolItem item3 = new ToolItem(toolbar, SWT.NONE); + item3.setText(FontAwesome.align_right); + new ToolItem(toolbar, SWT.SEPARATOR); + ToolItem item4 = new ToolItem(toolbar, SWT.NONE); + item4.setText(FontAwesome.quote_left); + new ToolItem(toolbar, SWT.SEPARATOR); + ToolItem item5 = new ToolItem(toolbar, SWT.NONE); + item5.setText(FontAwesome.question); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + + } } \ No newline at end of file diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.classpath b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.classpath +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.project b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.project index 9983bea46..30799b246 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.project +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.fontawesome - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.fontawesome + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.settings/org.eclipse.jdt.core.prefs b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.settings/org.eclipse.jdt.core.prefs index 230c1b474..a58ebdcad 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/.settings/org.eclipse.jdt.core.prefs @@ -1,15 +1,15 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/META-INF/MANIFEST.MF b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/META-INF/MANIFEST.MF index d10773f11..6b56e9e74 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/META-INF/MANIFEST.MF +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Font Awesome Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.fontawesome -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Export-Package: org.eclipse.nebula.widgets.fontawesome -Require-Bundle: org.eclipse.swt;visibility:=reexport -Automatic-Module-Name: org.eclipse.nebula.widgets.fontawesome +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Font Awesome Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.fontawesome +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Export-Package: org.eclipse.nebula.widgets.fontawesome +Require-Bundle: org.eclipse.swt;visibility:=reexport +Automatic-Module-Name: org.eclipse.nebula.widgets.fontawesome diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/build.properties b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/build.properties +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/pom.xml b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/pom.xml index 1d433b4f5..7fdd2c841 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/pom.xml +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - fontawesome - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.fontawesome - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + fontawesome + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.fontawesome + eclipse-plugin + + diff --git a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/src/org/eclipse/nebula/widgets/fontawesome/FontAwesome.java b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/src/org/eclipse/nebula/widgets/fontawesome/FontAwesome.java index 4dc6e3807..77492da47 100644 --- a/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/src/org/eclipse/nebula/widgets/fontawesome/FontAwesome.java +++ b/widgets/fontawesome/org.eclipse.nebula.widgets.fontawesome/src/org/eclipse/nebula/widgets/fontawesome/FontAwesome.java @@ -1,742 +1,742 @@ -/******************************************************************************* - * Copyright (c) 2020 Patrik Dufresne (http://www.patrikdufresne.com/). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Patrik Dufresne (info at patrikdufresne dot com) - initial API and implementation - * Laurent Caron (laurent dot caron at gmail dot com) - migration to the Nebula Project - * - *******************************************************************************/ -package org.eclipse.nebula.widgets.fontawesome; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.widgets.Display; - -/** - * Utility class used to load the Font Awesome font. - */ -public class FontAwesome { - - public static final String adjust = "\uf042"; - public static final String adn = "\uf170"; - public static final String align_center = "\uf037"; - public static final String align_justify = "\uf039"; - public static final String align_left = "\uf036"; - public static final String align_right = "\uf038"; - public static final String ambulance = "\uf0f9"; - public static final String anchor = "\uf13d"; - public static final String android = "\uf17b"; - public static final String angellist = "\uf209"; - public static final String angle_double_down = "\uf103"; - public static final String angle_double_left = "\uf100"; - public static final String angle_double_right = "\uf101"; - public static final String angle_double_up = "\uf102"; - public static final String angle_down = "\uf107"; - public static final String angle_left = "\uf104"; - public static final String angle_right = "\uf105"; - public static final String angle_up = "\uf106"; - public static final String apple = "\uf179"; - public static final String archive = "\uf187"; - public static final String area_chart = "\uf1fe"; - public static final String arrow_circle_down = "\uf0ab"; - public static final String arrow_circle_left = "\uf0a8"; - public static final String arrow_circle_o_down = "\uf01a"; - public static final String arrow_circle_o_left = "\uf190"; - public static final String arrow_circle_o_right = "\uf18e"; - public static final String arrow_circle_o_up = "\uf01b"; - public static final String arrow_circle_right = "\uf0a9"; - public static final String arrow_circle_up = "\uf0aa"; - public static final String arrow_down = "\uf063"; - public static final String arrow_left = "\uf060"; - public static final String arrow_right = "\uf061"; - public static final String arrow_up = "\uf062"; - public static final String arrows = "\uf047"; - public static final String arrows_alt = "\uf0b2"; - public static final String arrows_h = "\uf07e"; - public static final String arrows_v = "\uf07d"; - public static final String asterisk = "\uf069"; - public static final String at = "\uf1fa"; - public static final String automobile = "\uf1b9"; - public static final String backward = "\uf04a"; - public static final String ban = "\uf05e"; - public static final String bank = "\uf19c"; - public static final String bar_chart = "\uf080"; - public static final String bar_chart_o = "\uf080"; - public static final String barcode = "\uf02a"; - public static final String bars = "\uf0c9"; - public static final String bed = "\uf236"; - public static final String beer = "\uf0fc"; - public static final String behance = "\uf1b4"; - public static final String behance_square = "\uf1b5"; - public static final String bell = "\uf0f3"; - public static final String bell_o = "\uf0a2"; - public static final String bell_slash = "\uf1f6"; - public static final String bell_slash_o = "\uf1f7"; - public static final String bicycle = "\uf206"; - public static final String binoculars = "\uf1e5"; - public static final String birthday_cake = "\uf1fd"; - public static final String bitbucket = "\uf171"; - public static final String bitbucket_square = "\uf172"; - public static final String bitcoin = "\uf15a"; - public static final String bold = "\uf032"; - public static final String bolt = "\uf0e7"; - public static final String bomb = "\uf1e2"; - public static final String book = "\uf02d"; - public static final String bookmark = "\uf02e"; - public static final String bookmark_o = "\uf097"; - public static final String briefcase = "\uf0b1"; - public static final String btc = "\uf15a"; - public static final String bug = "\uf188"; - public static final String building = "\uf1ad"; - public static final String building_o = "\uf0f7"; - public static final String bullhorn = "\uf0a1"; - public static final String bullseye = "\uf140"; - public static final String bus = "\uf207"; - public static final String buysellads = "\uf20d"; - public static final String cab = "\uf1ba"; - public static final String calculator = "\uf1ec"; - public static final String calendar = "\uf073"; - public static final String calendar_o = "\uf133"; - public static final String camera = "\uf030"; - public static final String camera_retro = "\uf083"; - public static final String car = "\uf1b9"; - public static final String caret_down = "\uf0d7"; - public static final String caret_left = "\uf0d9"; - public static final String caret_right = "\uf0da"; - public static final String caret_square_o_down = "\uf150"; - public static final String caret_square_o_left = "\uf191"; - public static final String caret_square_o_right = "\uf152"; - public static final String caret_square_o_up = "\uf151"; - public static final String caret_up = "\uf0d8"; - public static final String cart_arrow_down = "\uf218"; - public static final String cart_plus = "\uf217"; - public static final String cc = "\uf20a"; - public static final String cc_amex = "\uf1f3"; - public static final String cc_discover = "\uf1f2"; - public static final String cc_mastercard = "\uf1f1"; - public static final String cc_paypal = "\uf1f4"; - public static final String cc_stripe = "\uf1f5"; - public static final String cc_visa = "\uf1f0"; - public static final String certificate = "\uf0a3"; - public static final String chain = "\uf0c1"; - public static final String chain_broken = "\uf127"; - public static final String check = "\uf00c"; - public static final String check_circle = "\uf058"; - public static final String check_circle_o = "\uf05d"; - public static final String check_square = "\uf14a"; - public static final String check_square_o = "\uf046"; - public static final String chevron_circle_down = "\uf13a"; - public static final String chevron_circle_left = "\uf137"; - public static final String chevron_circle_right = "\uf138"; - public static final String chevron_circle_up = "\uf139"; - public static final String chevron_down = "\uf078"; - public static final String chevron_left = "\uf053"; - public static final String chevron_right = "\uf054"; - public static final String chevron_up = "\uf077"; - public static final String child = "\uf1ae"; - public static final String circle = "\uf111"; - public static final String circle_o = "\uf10c"; - public static final String circle_o_notch = "\uf1ce"; - public static final String circle_thin = "\uf1db"; - public static final String clipboard = "\uf0ea"; - public static final String clock_o = "\uf017"; - public static final String close = "\uf00d"; - public static final String cloud = "\uf0c2"; - public static final String cloud_download = "\uf0ed"; - public static final String cloud_upload = "\uf0ee"; - public static final String cny = "\uf157"; - public static final String code = "\uf121"; - public static final String code_fork = "\uf126"; - public static final String codepen = "\uf1cb"; - public static final String coffee = "\uf0f4"; - public static final String cog = "\uf013"; - public static final String cogs = "\uf085"; - public static final String columns = "\uf0db"; - public static final String comment = "\uf075"; - public static final String comment_o = "\uf0e5"; - public static final String comments = "\uf086"; - public static final String comments_o = "\uf0e6"; - public static final String compass = "\uf14e"; - public static final String compress = "\uf066"; - public static final String connectdevelop = "\uf20e"; - public static final String copy = "\uf0c5"; - public static final String copyright = "\uf1f9"; - public static final String credit_card = "\uf09d"; - public static final String crop = "\uf125"; - public static final String crosshairs = "\uf05b"; - public static final String css3 = "\uf13c"; - public static final String cube = "\uf1b2"; - public static final String cubes = "\uf1b3"; - public static final String cut = "\uf0c4"; - public static final String cutlery = "\uf0f5"; - public static final String dashboard = "\uf0e4"; - public static final String dashcube = "\uf210"; - public static final String database = "\uf1c0"; - public static final String dedent = "\uf03b"; - private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; - private static final int DEFAULT_FONT_SIZE = 14; - public static final String delicious = "\uf1a5"; - public static final String desktop = "\uf108"; - public static final String deviantart = "\uf1bd"; - public static final String diamond = "\uf219"; - public static final String digg = "\uf1a6"; - public static final String dollar = "\uf155"; - public static final String dot_circle_o = "\uf192"; - public static final String download = "\uf019"; - public static final String dribbble = "\uf17d"; - public static final String dropbox = "\uf16b"; - public static final String drupal = "\uf1a9"; - public static final String edit = "\uf044"; - public static final String eject = "\uf052"; - public static final String ellipsis_h = "\uf141"; - public static final String ellipsis_v = "\uf142"; - public static final String empire = "\uf1d1"; - public static final String envelope = "\uf0e0"; - public static final String envelope_o = "\uf003"; - public static final String envelope_square = "\uf199"; - private static final int EOF = -1; - public static final String eraser = "\uf12d"; - public static final String eur = "\uf153"; - public static final String euro = "\uf153"; - public static final String exchange = "\uf0ec"; - public static final String exclamation = "\uf12a"; - public static final String exclamation_circle = "\uf06a"; - public static final String exclamation_triangle = "\uf071"; - public static final String expand = "\uf065"; - public static final String external_link = "\uf08e"; - public static final String external_link_square = "\uf14c"; - public static final String eye = "\uf06e"; - public static final String eye_slash = "\uf070"; - public static final String eyedropper = "\uf1fb"; - public static final String facebook = "\uf09a"; - public static final String facebook_f = "\uf09a"; - public static final String facebook_official = "\uf230"; - public static final String facebook_square = "\uf082"; - public static final String fast_backward = "\uf049"; - public static final String fast_forward = "\uf050"; - public static final String fax = "\uf1ac"; - public static final String female = "\uf182"; - public static final String fighter_jet = "\uf0fb"; - public static final String file = "\uf15b"; - public static final String file_archive_o = "\uf1c6"; - public static final String file_audio_o = "\uf1c7"; - public static final String file_code_o = "\uf1c9"; - public static final String file_excel_o = "\uf1c3"; - public static final String file_image_o = "\uf1c5"; - public static final String file_movie_o = "\uf1c8"; - public static final String file_o = "\uf016"; - public static final String file_pdf_o = "\uf1c1"; - public static final String file_photo_o = "\uf1c5"; - public static final String file_picture_o = "\uf1c5"; - public static final String file_powerpoint_o = "\uf1c4"; - public static final String file_sound_o = "\uf1c7"; - public static final String file_text = "\uf15c"; - public static final String file_text_o = "\uf0f6"; - public static final String file_video_o = "\uf1c8"; - public static final String file_word_o = "\uf1c2"; - public static final String file_zip_o = "\uf1c6"; - public static final String files_o = "\uf0c5"; - public static final String film = "\uf008"; - public static final String filter = "\uf0b0"; - public static final String fire = "\uf06d"; - public static final String fire_extinguisher = "\uf134"; - public static final String flag = "\uf024"; - public static final String flag_checkered = "\uf11e"; - public static final String flag_o = "\uf11d"; - public static final String flash = "\uf0e7"; - public static final String flask = "\uf0c3"; - public static final String flickr = "\uf16e"; - public static final String floppy_o = "\uf0c7"; - public static final String folder = "\uf07b"; - public static final String folder_o = "\uf114"; - public static final String folder_open = "\uf07c"; - public static final String folder_open_o = "\uf115"; - public static final String font = "\uf031"; - /** - * Symbolic name used to store the font awesome. - */ - public static final String forumbee = "\uf211"; - public static final String forward = "\uf04e"; - public static final String foursquare = "\uf180"; - public static final String frown_o = "\uf119"; - public static final String futbol_o = "\uf1e3"; - public static final String gamepad = "\uf11b"; - public static final String gavel = "\uf0e3"; - public static final String gbp = "\uf154"; - public static final String ge = "\uf1d1"; - public static final String gear = "\uf013"; - public static final String gears = "\uf085"; - public static final String genderless = "\uf1db"; - public static final String gift = "\uf06b"; - public static final String git = "\uf1d3"; - public static final String git_square = "\uf1d2"; - public static final String github = "\uf09b"; - public static final String github_alt = "\uf113"; - public static final String github_square = "\uf092"; - public static final String gittip = "\uf184"; - public static final String glass = "\uf000"; - public static final String globe = "\uf0ac"; - public static final String google = "\uf1a0"; - public static final String google_plus = "\uf0d5"; - public static final String google_plus_square = "\uf0d4"; - public static final String google_wallet = "\uf1ee"; - public static final String graduation_cap = "\uf19d"; - public static final String gratipay = "\uf184"; - public static final String group = "\uf0c0"; - public static final String h_square = "\uf0fd"; - public static final String hacker_news = "\uf1d4"; - public static final String hand_o_down = "\uf0a7"; - public static final String hand_o_left = "\uf0a5"; - public static final String hand_o_right = "\uf0a4"; - public static final String hand_o_up = "\uf0a6"; - public static final String hdd_o = "\uf0a0"; - public static final String header = "\uf1dc"; - public static final String headphones = "\uf025"; - public static final String heart = "\uf004"; - public static final String heart_o = "\uf08a"; - public static final String heartbeat = "\uf21e"; - public static final String history = "\uf1da"; - public static final String home = "\uf015"; - public static final String hospital_o = "\uf0f8"; - public static final String hotel = "\uf236"; - public static final String html5 = "\uf13b"; - public static final String ils = "\uf20b"; - public static final String image = "\uf03e"; - public static final String inbox = "\uf01c"; - public static final String indent = "\uf03c"; - public static final String info = "\uf129"; - public static final String info_circle = "\uf05a"; - public static final String inr = "\uf156"; - public static final String instagram = "\uf16d"; - public static final String institution = "\uf19c"; - public static final String ioxhost = "\uf208"; - public static final String italic = "\uf033"; - public static final String joomla = "\uf1aa"; - public static final String jpy = "\uf157"; - public static final String jsfiddle = "\uf1cc"; - public static final String key = "\uf084"; - public static final String keyboard_o = "\uf11c"; - public static final String krw = "\uf159"; - public static final String language = "\uf1ab"; - public static final String laptop = "\uf109"; - public static final String lastfm = "\uf202"; - public static final String lastfm_square = "\uf203"; - public static final String leaf = "\uf06c"; - public static final String leanpub = "\uf212"; - public static final String legal = "\uf0e3"; - public static final String lemon_o = "\uf094"; - public static final String level_down = "\uf149"; - public static final String level_up = "\uf148"; - public static final String life_bouy = "\uf1cd"; - public static final String life_buoy = "\uf1cd"; - public static final String life_ring = "\uf1cd"; - public static final String life_saver = "\uf1cd"; - public static final String lightbulb_o = "\uf0eb"; - public static final String line_chart = "\uf201"; - public static final String link = "\uf0c1"; - public static final String linkedin = "\uf0e1"; - public static final String linkedin_square = "\uf08c"; - public static final String linux = "\uf17c"; - public static final String list = "\uf03a"; - public static final String list_alt = "\uf022"; - public static final String list_ol = "\uf0cb"; - public static final String list_ul = "\uf0ca"; - public static final String location_arrow = "\uf124"; - public static final String lock = "\uf023"; - public static final String long_arrow_down = "\uf175"; - public static final String long_arrow_left = "\uf177"; - public static final String long_arrow_right = "\uf178"; - public static final String long_arrow_up = "\uf176"; - public static final String magic = "\uf0d0"; - public static final String magnet = "\uf076"; - public static final String mail_forward = "\uf064"; - public static final String mail_reply = "\uf112"; - public static final String mail_reply_all = "\uf122"; - public static final String male = "\uf183"; - public static final String map_marker = "\uf041"; - public static final String mars = "\uf222"; - public static final String mars_double = "\uf227"; - public static final String mars_stroke = "\uf229"; - public static final String mars_stroke_h = "\uf22b"; - public static final String mars_stroke_v = "\uf22a"; - public static final String maxcdn = "\uf136"; - public static final String meanpath = "\uf20c"; - public static final String medium = "\uf23a"; - public static final String medkit = "\uf0fa"; - public static final String meh_o = "\uf11a"; - public static final String mercury = "\uf223"; - public static final String microphone = "\uf130"; - public static final String microphone_slash = "\uf131"; - public static final String minus = "\uf068"; - public static final String minus_circle = "\uf056"; - public static final String minus_square = "\uf146"; - public static final String minus_square_o = "\uf147"; - public static final String mobile = "\uf10b"; - public static final String mobile_phone = "\uf10b"; - public static final String money = "\uf0d6"; - public static final String moon_o = "\uf186"; - public static final String mortar_board = "\uf19d"; - public static final String motorcycle = "\uf21c"; - public static final String music = "\uf001"; - public static final String navicon = "\uf0c9"; - public static final String neuter = "\uf22c"; - public static final String newspaper_o = "\uf1ea"; - public static final String openid = "\uf19b"; - public static final String outdent = "\uf03b"; - public static final String pagelines = "\uf18c"; - public static final String paint_brush = "\uf1fc"; - public static final String paper_plane = "\uf1d8"; - public static final String paper_plane_o = "\uf1d9"; - public static final String paperclip = "\uf0c6"; - public static final String paragraph = "\uf1dd"; - public static final String paste = "\uf0ea"; - public static final String pause = "\uf04c"; - public static final String paw = "\uf1b0"; - public static final String paypal = "\uf1ed"; - public static final String pencil = "\uf040"; - public static final String pencil_square = "\uf14b"; - public static final String pencil_square_o = "\uf044"; - public static final String phone = "\uf095"; - public static final String phone_square = "\uf098"; - public static final String photo = "\uf03e"; - public static final String picture_o = "\uf03e"; - public static final String pie_chart = "\uf200"; - public static final String pied_piper = "\uf1a7"; - public static final String pied_piper_alt = "\uf1a8"; - public static final String pinterest = "\uf0d2"; - public static final String pinterest_p = "\uf231"; - public static final String pinterest_square = "\uf0d3"; - public static final String plane = "\uf072"; - public static final String play = "\uf04b"; - public static final String play_circle = "\uf144"; - public static final String play_circle_o = "\uf01d"; - public static final String plug = "\uf1e6"; - public static final String plus = "\uf067"; - public static final String plus_circle = "\uf055"; - public static final String plus_square = "\uf0fe"; - public static final String plus_square_o = "\uf196"; - public static final String power_off = "\uf011"; - public static final String print = "\uf02f"; - public static final String puzzle_piece = "\uf12e"; - public static final String qq = "\uf1d6"; - public static final String qrcode = "\uf029"; - public static final String question = "\uf128"; - public static final String question_circle = "\uf059"; - public static final String quote_left = "\uf10d"; - public static final String quote_right = "\uf10e"; - public static final String ra = "\uf1d0"; - public static final String random = "\uf074"; - public static final String rebel = "\uf1d0"; - public static final String recycle = "\uf1b8"; - public static final String reddit = "\uf1a1"; - public static final String reddit_square = "\uf1a2"; - public static final String refresh = "\uf021"; - public static final String remove = "\uf00d"; - public static final String renren = "\uf18b"; - public static final String reorder = "\uf0c9"; - public static final String repeat = "\uf01e"; - public static final String reply = "\uf112"; - public static final String reply_all = "\uf122"; - public static final String retweet = "\uf079"; - public static final String rmb = "\uf157"; - public static final String road = "\uf018"; - public static final String rocket = "\uf135"; - public static final String rotate_left = "\uf0e2"; - public static final String rotate_right = "\uf01e"; - public static final String rouble = "\uf158"; - public static final String rss = "\uf09e"; - public static final String rss_square = "\uf143"; - public static final String rub = "\uf158"; - public static final String ruble = "\uf158"; - public static final String rupee = "\uf156"; - public static final String save = "\uf0c7"; - public static final String scissors = "\uf0c4"; - public static final String search = "\uf002"; - public static final String search_minus = "\uf010"; - public static final String search_plus = "\uf00e"; - public static final String sellsy = "\uf213"; - public static final String send = "\uf1d8"; - public static final String send_o = "\uf1d9"; - public static final String server = "\uf233"; - public static final String share = "\uf064"; - public static final String share_alt = "\uf1e0"; - public static final String share_alt_square = "\uf1e1"; - public static final String share_square = "\uf14d"; - public static final String share_square_o = "\uf045"; - public static final String shekel = "\uf20b"; - public static final String sheqel = "\uf20b"; - public static final String shield = "\uf132"; - public static final String ship = "\uf21a"; - public static final String shirtsinbulk = "\uf214"; - public static final String shopping_cart = "\uf07a"; - public static final String sign_in = "\uf090"; - public static final String sign_out = "\uf08b"; - public static final String signal = "\uf012"; - public static final String simplybuilt = "\uf215"; - public static final String sitemap = "\uf0e8"; - public static final String skyatlas = "\uf216"; - public static final String skype = "\uf17e"; - public static final String slack = "\uf198"; - public static final String sliders = "\uf1de"; - public static final String slideshare = "\uf1e7"; - public static final String smile_o = "\uf118"; - public static final String soccer_ball_o = "\uf1e3"; - public static final String sort = "\uf0dc"; - public static final String sort_alpha_asc = "\uf15d"; - public static final String sort_alpha_desc = "\uf15e"; - public static final String sort_amount_asc = "\uf160"; - public static final String sort_amount_desc = "\uf161"; - public static final String sort_asc = "\uf0de"; - public static final String sort_desc = "\uf0dd"; - public static final String sort_down = "\uf0dd"; - public static final String sort_numeric_asc = "\uf162"; - public static final String sort_numeric_desc = "\uf163"; - public static final String sort_up = "\uf0de"; - public static final String soundcloud = "\uf1be"; - public static final String space_shuttle = "\uf197"; - public static final String spinner = "\uf110"; - public static final String spoon = "\uf1b1"; - public static final String spotify = "\uf1bc"; - public static final String square = "\uf0c8"; - public static final String square_o = "\uf096"; - public static final String stack_exchange = "\uf18d"; - public static final String stack_overflow = "\uf16c"; - public static final String star = "\uf005"; - public static final String star_half = "\uf089"; - public static final String star_half_empty = "\uf123"; - public static final String star_half_full = "\uf123"; - public static final String star_half_o = "\uf123"; - public static final String star_o = "\uf006"; - public static final String steam = "\uf1b6"; - public static final String steam_square = "\uf1b7"; - public static final String step_backward = "\uf048"; - public static final String step_forward = "\uf051"; - public static final String stethoscope = "\uf0f1"; - public static final String stop = "\uf04d"; - public static final String street_view = "\uf21d"; - public static final String strikethrough = "\uf0cc"; - public static final String stumbleupon = "\uf1a4"; - public static final String stumbleupon_circle = "\uf1a3"; - public static final String subscript = "\uf12c"; - public static final String subway = "\uf239"; - public static final String suitcase = "\uf0f2"; - public static final String sun_o = "\uf185"; - public static final String superscript = "\uf12b"; - public static final String support = "\uf1cd"; - public static final String table = "\uf0ce"; - public static final String tablet = "\uf10a"; - public static final String tachometer = "\uf0e4"; - public static final String tag = "\uf02b"; - public static final String tags = "\uf02c"; - public static final String tasks = "\uf0ae"; - public static final String taxi = "\uf1ba"; - public static final String tencent_weibo = "\uf1d5"; - public static final String terminal = "\uf120"; - public static final String text_height = "\uf034"; - public static final String text_width = "\uf035"; - public static final String th = "\uf00a"; - public static final String th_large = "\uf009"; - public static final String th_list = "\uf00b"; - public static final String thumb_tack = "\uf08d"; - public static final String thumbs_down = "\uf165"; - public static final String thumbs_o_down = "\uf088"; - public static final String thumbs_o_up = "\uf087"; - public static final String thumbs_up = "\uf164"; - public static final String ticket = "\uf145"; - public static final String times = "\uf00d"; - public static final String times_circle = "\uf057"; - public static final String times_circle_o = "\uf05c"; - public static final String tint = "\uf043"; - public static final String toggle_down = "\uf150"; - public static final String toggle_left = "\uf191"; - public static final String toggle_off = "\uf204"; - public static final String toggle_on = "\uf205"; - public static final String toggle_right = "\uf152"; - public static final String toggle_up = "\uf151"; - public static final String train = "\uf238"; - public static final String transgender = "\uf224"; - public static final String transgender_alt = "\uf225"; - public static final String trash = "\uf1f8"; - public static final String trash_o = "\uf014"; - public static final String tree = "\uf1bb"; - public static final String trello = "\uf181"; - public static final String trophy = "\uf091"; - public static final String truck = "\uf0d1"; - public static final String TRY = "\uf195"; - public static final String tty = "\uf1e4"; - public static final String tumblr = "\uf173"; - public static final String tumblr_square = "\uf174"; - public static final String turkish_lira = "\uf195"; - public static final String twitch = "\uf1e8"; - public static final String twitter = "\uf099"; - public static final String twitter_square = "\uf081"; - public static final String umbrella = "\uf0e9"; - public static final String underline = "\uf0cd"; - public static final String undo = "\uf0e2"; - public static final String university = "\uf19c"; - public static final String unlink = "\uf127"; - public static final String unlock = "\uf09c"; - public static final String unlock_alt = "\uf13e"; - public static final String unsorted = "\uf0dc"; - public static final String upload = "\uf093"; - public static final String usd = "\uf155"; - public static final String user = "\uf007"; - public static final String user_md = "\uf0f0"; - public static final String user_plus = "\uf234"; - public static final String user_secret = "\uf21b"; - public static final String user_times = "\uf235"; - public static final String users = "\uf0c0"; - public static final String venus = "\uf221"; - public static final String venus_double = "\uf226"; - public static final String venus_mars = "\uf228"; - /** - * Version used when developing. - */ - private static final String VERSION_DEV = "DEV"; - public static final String viacoin = "\uf237"; - public static final String video_camera = "\uf03d"; - public static final String vimeo_square = "\uf194"; - public static final String vine = "\uf1ca"; - public static final String vk = "\uf189"; - public static final String volume_down = "\uf027"; - public static final String volume_off = "\uf026"; - public static final String volume_up = "\uf028"; - public static final String warning = "\uf071"; - public static final String wechat = "\uf1d7"; - public static final String weibo = "\uf18a"; - public static final String weixin = "\uf1d7"; - public static final String whatsapp = "\uf232"; - public static final String wheelchair = "\uf193"; - public static final String wifi = "\uf1eb"; - public static final String windows = "\uf17a"; - public static final String won = "\uf159"; - public static final String wordpress = "\uf19a"; - public static final String wrench = "\uf0ad"; - public static final String xing = "\uf168"; - public static final String xing_square = "\uf169"; - public static final String yahoo = "\uf19e"; - public static final String yelp = "\uf1e9"; - public static final String yen = "\uf157"; - public static final String youtube = "\uf167"; - public static final String youtube_play = "\uf16a"; - public static final String youtube_square = "\uf166"; - - private static Map fonts = new HashMap<>(); - - private static long copy(InputStream input, OutputStream output, byte[] buffer) throws IOException { - long count = 0; - int n = 0; - while (EOF != (n = input.read(buffer))) { - output.write(buffer, 0, n); - count += n; - } - return count; - } - - /** - * Return the current version. - * - * @return - */ - private static String getCurrentVersion() { - // Get the version from the package manifest - String version = FontAwesome.class.getPackage().getImplementationVersion(); - if (version == null) { - return VERSION_DEV; - } - return version; - } - - /** - * Return a FontAwesome font for SWT. - * - * @return the font or null. - */ - public static Font getFont() { - if (fonts.containsKey(DEFAULT_FONT_SIZE)) { - return fonts.get(DEFAULT_FONT_SIZE); - } - if (!loadFont()) { - return null; - } - FontData[] data = new FontData[] { new FontData("fontawesome", DEFAULT_FONT_SIZE, SWT.NORMAL) }; - fonts.put(DEFAULT_FONT_SIZE, new Font(Display.getDefault(), data)); - return fonts.get(DEFAULT_FONT_SIZE); - } - - /** - * Return a FontAwesome font for SWT. - * - * @param size - * @return - */ - public static Font getFont(int size) { - if (!fonts.containsKey(size)) { - // GetFont() may return null, so handle this case. - Font font = getFont(); - if (font == null) { - return null; - } - FontData[] data = font.getFontData(); - for (FontData d : data) { - d.setHeight(size); - } - fonts.put(size, new Font(Display.getDefault(), data)); - } - return fonts.get(size); - } - - /** - * Load the font from resources. - * - * @return - */ - private static boolean loadFont() { - // Get file from classpath. - - // Add dispose listener - Display.getDefault().addListener(SWT.Dispose, e -> { - for (Font font : fonts.values()) { - if (!font.isDisposed()) - font.dispose(); - } - }); - - try { - // Copy file to temp diretory. - String temp = System.getProperty("java.io.tmpdir"); - final File tempfile = new File(temp, - System.getProperty("user.name") + "-fontawesome-webfont-" + getCurrentVersion() + ".ttf"); - tempfile.deleteOnExit(); - try (FileOutputStream out = new FileOutputStream(tempfile); - InputStream in = FontAwesome.class.getResourceAsStream("resources/fontawesome-webfont.ttf");) { - if (in == null) { - return false; - } - copy(in, out, new byte[DEFAULT_BUFFER_SIZE]); - } - // Load the font. - return Display.getDefault().loadFont(tempfile.getAbsolutePath()); - } catch (IOException e) { - // This should rarely happen, but clearly, when this happen we need - // to print something to a log file. Otherwise there is no way to debug this. - e.printStackTrace(); - return false; - } - } +/******************************************************************************* + * Copyright (c) 2020 Patrik Dufresne (http://www.patrikdufresne.com/). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Patrik Dufresne (info at patrikdufresne dot com) - initial API and implementation + * Laurent Caron (laurent dot caron at gmail dot com) - migration to the Nebula Project + * + *******************************************************************************/ +package org.eclipse.nebula.widgets.fontawesome; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Display; + +/** + * Utility class used to load the Font Awesome font. + */ +public class FontAwesome { + + public static final String adjust = "\uf042"; + public static final String adn = "\uf170"; + public static final String align_center = "\uf037"; + public static final String align_justify = "\uf039"; + public static final String align_left = "\uf036"; + public static final String align_right = "\uf038"; + public static final String ambulance = "\uf0f9"; + public static final String anchor = "\uf13d"; + public static final String android = "\uf17b"; + public static final String angellist = "\uf209"; + public static final String angle_double_down = "\uf103"; + public static final String angle_double_left = "\uf100"; + public static final String angle_double_right = "\uf101"; + public static final String angle_double_up = "\uf102"; + public static final String angle_down = "\uf107"; + public static final String angle_left = "\uf104"; + public static final String angle_right = "\uf105"; + public static final String angle_up = "\uf106"; + public static final String apple = "\uf179"; + public static final String archive = "\uf187"; + public static final String area_chart = "\uf1fe"; + public static final String arrow_circle_down = "\uf0ab"; + public static final String arrow_circle_left = "\uf0a8"; + public static final String arrow_circle_o_down = "\uf01a"; + public static final String arrow_circle_o_left = "\uf190"; + public static final String arrow_circle_o_right = "\uf18e"; + public static final String arrow_circle_o_up = "\uf01b"; + public static final String arrow_circle_right = "\uf0a9"; + public static final String arrow_circle_up = "\uf0aa"; + public static final String arrow_down = "\uf063"; + public static final String arrow_left = "\uf060"; + public static final String arrow_right = "\uf061"; + public static final String arrow_up = "\uf062"; + public static final String arrows = "\uf047"; + public static final String arrows_alt = "\uf0b2"; + public static final String arrows_h = "\uf07e"; + public static final String arrows_v = "\uf07d"; + public static final String asterisk = "\uf069"; + public static final String at = "\uf1fa"; + public static final String automobile = "\uf1b9"; + public static final String backward = "\uf04a"; + public static final String ban = "\uf05e"; + public static final String bank = "\uf19c"; + public static final String bar_chart = "\uf080"; + public static final String bar_chart_o = "\uf080"; + public static final String barcode = "\uf02a"; + public static final String bars = "\uf0c9"; + public static final String bed = "\uf236"; + public static final String beer = "\uf0fc"; + public static final String behance = "\uf1b4"; + public static final String behance_square = "\uf1b5"; + public static final String bell = "\uf0f3"; + public static final String bell_o = "\uf0a2"; + public static final String bell_slash = "\uf1f6"; + public static final String bell_slash_o = "\uf1f7"; + public static final String bicycle = "\uf206"; + public static final String binoculars = "\uf1e5"; + public static final String birthday_cake = "\uf1fd"; + public static final String bitbucket = "\uf171"; + public static final String bitbucket_square = "\uf172"; + public static final String bitcoin = "\uf15a"; + public static final String bold = "\uf032"; + public static final String bolt = "\uf0e7"; + public static final String bomb = "\uf1e2"; + public static final String book = "\uf02d"; + public static final String bookmark = "\uf02e"; + public static final String bookmark_o = "\uf097"; + public static final String briefcase = "\uf0b1"; + public static final String btc = "\uf15a"; + public static final String bug = "\uf188"; + public static final String building = "\uf1ad"; + public static final String building_o = "\uf0f7"; + public static final String bullhorn = "\uf0a1"; + public static final String bullseye = "\uf140"; + public static final String bus = "\uf207"; + public static final String buysellads = "\uf20d"; + public static final String cab = "\uf1ba"; + public static final String calculator = "\uf1ec"; + public static final String calendar = "\uf073"; + public static final String calendar_o = "\uf133"; + public static final String camera = "\uf030"; + public static final String camera_retro = "\uf083"; + public static final String car = "\uf1b9"; + public static final String caret_down = "\uf0d7"; + public static final String caret_left = "\uf0d9"; + public static final String caret_right = "\uf0da"; + public static final String caret_square_o_down = "\uf150"; + public static final String caret_square_o_left = "\uf191"; + public static final String caret_square_o_right = "\uf152"; + public static final String caret_square_o_up = "\uf151"; + public static final String caret_up = "\uf0d8"; + public static final String cart_arrow_down = "\uf218"; + public static final String cart_plus = "\uf217"; + public static final String cc = "\uf20a"; + public static final String cc_amex = "\uf1f3"; + public static final String cc_discover = "\uf1f2"; + public static final String cc_mastercard = "\uf1f1"; + public static final String cc_paypal = "\uf1f4"; + public static final String cc_stripe = "\uf1f5"; + public static final String cc_visa = "\uf1f0"; + public static final String certificate = "\uf0a3"; + public static final String chain = "\uf0c1"; + public static final String chain_broken = "\uf127"; + public static final String check = "\uf00c"; + public static final String check_circle = "\uf058"; + public static final String check_circle_o = "\uf05d"; + public static final String check_square = "\uf14a"; + public static final String check_square_o = "\uf046"; + public static final String chevron_circle_down = "\uf13a"; + public static final String chevron_circle_left = "\uf137"; + public static final String chevron_circle_right = "\uf138"; + public static final String chevron_circle_up = "\uf139"; + public static final String chevron_down = "\uf078"; + public static final String chevron_left = "\uf053"; + public static final String chevron_right = "\uf054"; + public static final String chevron_up = "\uf077"; + public static final String child = "\uf1ae"; + public static final String circle = "\uf111"; + public static final String circle_o = "\uf10c"; + public static final String circle_o_notch = "\uf1ce"; + public static final String circle_thin = "\uf1db"; + public static final String clipboard = "\uf0ea"; + public static final String clock_o = "\uf017"; + public static final String close = "\uf00d"; + public static final String cloud = "\uf0c2"; + public static final String cloud_download = "\uf0ed"; + public static final String cloud_upload = "\uf0ee"; + public static final String cny = "\uf157"; + public static final String code = "\uf121"; + public static final String code_fork = "\uf126"; + public static final String codepen = "\uf1cb"; + public static final String coffee = "\uf0f4"; + public static final String cog = "\uf013"; + public static final String cogs = "\uf085"; + public static final String columns = "\uf0db"; + public static final String comment = "\uf075"; + public static final String comment_o = "\uf0e5"; + public static final String comments = "\uf086"; + public static final String comments_o = "\uf0e6"; + public static final String compass = "\uf14e"; + public static final String compress = "\uf066"; + public static final String connectdevelop = "\uf20e"; + public static final String copy = "\uf0c5"; + public static final String copyright = "\uf1f9"; + public static final String credit_card = "\uf09d"; + public static final String crop = "\uf125"; + public static final String crosshairs = "\uf05b"; + public static final String css3 = "\uf13c"; + public static final String cube = "\uf1b2"; + public static final String cubes = "\uf1b3"; + public static final String cut = "\uf0c4"; + public static final String cutlery = "\uf0f5"; + public static final String dashboard = "\uf0e4"; + public static final String dashcube = "\uf210"; + public static final String database = "\uf1c0"; + public static final String dedent = "\uf03b"; + private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; + private static final int DEFAULT_FONT_SIZE = 14; + public static final String delicious = "\uf1a5"; + public static final String desktop = "\uf108"; + public static final String deviantart = "\uf1bd"; + public static final String diamond = "\uf219"; + public static final String digg = "\uf1a6"; + public static final String dollar = "\uf155"; + public static final String dot_circle_o = "\uf192"; + public static final String download = "\uf019"; + public static final String dribbble = "\uf17d"; + public static final String dropbox = "\uf16b"; + public static final String drupal = "\uf1a9"; + public static final String edit = "\uf044"; + public static final String eject = "\uf052"; + public static final String ellipsis_h = "\uf141"; + public static final String ellipsis_v = "\uf142"; + public static final String empire = "\uf1d1"; + public static final String envelope = "\uf0e0"; + public static final String envelope_o = "\uf003"; + public static final String envelope_square = "\uf199"; + private static final int EOF = -1; + public static final String eraser = "\uf12d"; + public static final String eur = "\uf153"; + public static final String euro = "\uf153"; + public static final String exchange = "\uf0ec"; + public static final String exclamation = "\uf12a"; + public static final String exclamation_circle = "\uf06a"; + public static final String exclamation_triangle = "\uf071"; + public static final String expand = "\uf065"; + public static final String external_link = "\uf08e"; + public static final String external_link_square = "\uf14c"; + public static final String eye = "\uf06e"; + public static final String eye_slash = "\uf070"; + public static final String eyedropper = "\uf1fb"; + public static final String facebook = "\uf09a"; + public static final String facebook_f = "\uf09a"; + public static final String facebook_official = "\uf230"; + public static final String facebook_square = "\uf082"; + public static final String fast_backward = "\uf049"; + public static final String fast_forward = "\uf050"; + public static final String fax = "\uf1ac"; + public static final String female = "\uf182"; + public static final String fighter_jet = "\uf0fb"; + public static final String file = "\uf15b"; + public static final String file_archive_o = "\uf1c6"; + public static final String file_audio_o = "\uf1c7"; + public static final String file_code_o = "\uf1c9"; + public static final String file_excel_o = "\uf1c3"; + public static final String file_image_o = "\uf1c5"; + public static final String file_movie_o = "\uf1c8"; + public static final String file_o = "\uf016"; + public static final String file_pdf_o = "\uf1c1"; + public static final String file_photo_o = "\uf1c5"; + public static final String file_picture_o = "\uf1c5"; + public static final String file_powerpoint_o = "\uf1c4"; + public static final String file_sound_o = "\uf1c7"; + public static final String file_text = "\uf15c"; + public static final String file_text_o = "\uf0f6"; + public static final String file_video_o = "\uf1c8"; + public static final String file_word_o = "\uf1c2"; + public static final String file_zip_o = "\uf1c6"; + public static final String files_o = "\uf0c5"; + public static final String film = "\uf008"; + public static final String filter = "\uf0b0"; + public static final String fire = "\uf06d"; + public static final String fire_extinguisher = "\uf134"; + public static final String flag = "\uf024"; + public static final String flag_checkered = "\uf11e"; + public static final String flag_o = "\uf11d"; + public static final String flash = "\uf0e7"; + public static final String flask = "\uf0c3"; + public static final String flickr = "\uf16e"; + public static final String floppy_o = "\uf0c7"; + public static final String folder = "\uf07b"; + public static final String folder_o = "\uf114"; + public static final String folder_open = "\uf07c"; + public static final String folder_open_o = "\uf115"; + public static final String font = "\uf031"; + /** + * Symbolic name used to store the font awesome. + */ + public static final String forumbee = "\uf211"; + public static final String forward = "\uf04e"; + public static final String foursquare = "\uf180"; + public static final String frown_o = "\uf119"; + public static final String futbol_o = "\uf1e3"; + public static final String gamepad = "\uf11b"; + public static final String gavel = "\uf0e3"; + public static final String gbp = "\uf154"; + public static final String ge = "\uf1d1"; + public static final String gear = "\uf013"; + public static final String gears = "\uf085"; + public static final String genderless = "\uf1db"; + public static final String gift = "\uf06b"; + public static final String git = "\uf1d3"; + public static final String git_square = "\uf1d2"; + public static final String github = "\uf09b"; + public static final String github_alt = "\uf113"; + public static final String github_square = "\uf092"; + public static final String gittip = "\uf184"; + public static final String glass = "\uf000"; + public static final String globe = "\uf0ac"; + public static final String google = "\uf1a0"; + public static final String google_plus = "\uf0d5"; + public static final String google_plus_square = "\uf0d4"; + public static final String google_wallet = "\uf1ee"; + public static final String graduation_cap = "\uf19d"; + public static final String gratipay = "\uf184"; + public static final String group = "\uf0c0"; + public static final String h_square = "\uf0fd"; + public static final String hacker_news = "\uf1d4"; + public static final String hand_o_down = "\uf0a7"; + public static final String hand_o_left = "\uf0a5"; + public static final String hand_o_right = "\uf0a4"; + public static final String hand_o_up = "\uf0a6"; + public static final String hdd_o = "\uf0a0"; + public static final String header = "\uf1dc"; + public static final String headphones = "\uf025"; + public static final String heart = "\uf004"; + public static final String heart_o = "\uf08a"; + public static final String heartbeat = "\uf21e"; + public static final String history = "\uf1da"; + public static final String home = "\uf015"; + public static final String hospital_o = "\uf0f8"; + public static final String hotel = "\uf236"; + public static final String html5 = "\uf13b"; + public static final String ils = "\uf20b"; + public static final String image = "\uf03e"; + public static final String inbox = "\uf01c"; + public static final String indent = "\uf03c"; + public static final String info = "\uf129"; + public static final String info_circle = "\uf05a"; + public static final String inr = "\uf156"; + public static final String instagram = "\uf16d"; + public static final String institution = "\uf19c"; + public static final String ioxhost = "\uf208"; + public static final String italic = "\uf033"; + public static final String joomla = "\uf1aa"; + public static final String jpy = "\uf157"; + public static final String jsfiddle = "\uf1cc"; + public static final String key = "\uf084"; + public static final String keyboard_o = "\uf11c"; + public static final String krw = "\uf159"; + public static final String language = "\uf1ab"; + public static final String laptop = "\uf109"; + public static final String lastfm = "\uf202"; + public static final String lastfm_square = "\uf203"; + public static final String leaf = "\uf06c"; + public static final String leanpub = "\uf212"; + public static final String legal = "\uf0e3"; + public static final String lemon_o = "\uf094"; + public static final String level_down = "\uf149"; + public static final String level_up = "\uf148"; + public static final String life_bouy = "\uf1cd"; + public static final String life_buoy = "\uf1cd"; + public static final String life_ring = "\uf1cd"; + public static final String life_saver = "\uf1cd"; + public static final String lightbulb_o = "\uf0eb"; + public static final String line_chart = "\uf201"; + public static final String link = "\uf0c1"; + public static final String linkedin = "\uf0e1"; + public static final String linkedin_square = "\uf08c"; + public static final String linux = "\uf17c"; + public static final String list = "\uf03a"; + public static final String list_alt = "\uf022"; + public static final String list_ol = "\uf0cb"; + public static final String list_ul = "\uf0ca"; + public static final String location_arrow = "\uf124"; + public static final String lock = "\uf023"; + public static final String long_arrow_down = "\uf175"; + public static final String long_arrow_left = "\uf177"; + public static final String long_arrow_right = "\uf178"; + public static final String long_arrow_up = "\uf176"; + public static final String magic = "\uf0d0"; + public static final String magnet = "\uf076"; + public static final String mail_forward = "\uf064"; + public static final String mail_reply = "\uf112"; + public static final String mail_reply_all = "\uf122"; + public static final String male = "\uf183"; + public static final String map_marker = "\uf041"; + public static final String mars = "\uf222"; + public static final String mars_double = "\uf227"; + public static final String mars_stroke = "\uf229"; + public static final String mars_stroke_h = "\uf22b"; + public static final String mars_stroke_v = "\uf22a"; + public static final String maxcdn = "\uf136"; + public static final String meanpath = "\uf20c"; + public static final String medium = "\uf23a"; + public static final String medkit = "\uf0fa"; + public static final String meh_o = "\uf11a"; + public static final String mercury = "\uf223"; + public static final String microphone = "\uf130"; + public static final String microphone_slash = "\uf131"; + public static final String minus = "\uf068"; + public static final String minus_circle = "\uf056"; + public static final String minus_square = "\uf146"; + public static final String minus_square_o = "\uf147"; + public static final String mobile = "\uf10b"; + public static final String mobile_phone = "\uf10b"; + public static final String money = "\uf0d6"; + public static final String moon_o = "\uf186"; + public static final String mortar_board = "\uf19d"; + public static final String motorcycle = "\uf21c"; + public static final String music = "\uf001"; + public static final String navicon = "\uf0c9"; + public static final String neuter = "\uf22c"; + public static final String newspaper_o = "\uf1ea"; + public static final String openid = "\uf19b"; + public static final String outdent = "\uf03b"; + public static final String pagelines = "\uf18c"; + public static final String paint_brush = "\uf1fc"; + public static final String paper_plane = "\uf1d8"; + public static final String paper_plane_o = "\uf1d9"; + public static final String paperclip = "\uf0c6"; + public static final String paragraph = "\uf1dd"; + public static final String paste = "\uf0ea"; + public static final String pause = "\uf04c"; + public static final String paw = "\uf1b0"; + public static final String paypal = "\uf1ed"; + public static final String pencil = "\uf040"; + public static final String pencil_square = "\uf14b"; + public static final String pencil_square_o = "\uf044"; + public static final String phone = "\uf095"; + public static final String phone_square = "\uf098"; + public static final String photo = "\uf03e"; + public static final String picture_o = "\uf03e"; + public static final String pie_chart = "\uf200"; + public static final String pied_piper = "\uf1a7"; + public static final String pied_piper_alt = "\uf1a8"; + public static final String pinterest = "\uf0d2"; + public static final String pinterest_p = "\uf231"; + public static final String pinterest_square = "\uf0d3"; + public static final String plane = "\uf072"; + public static final String play = "\uf04b"; + public static final String play_circle = "\uf144"; + public static final String play_circle_o = "\uf01d"; + public static final String plug = "\uf1e6"; + public static final String plus = "\uf067"; + public static final String plus_circle = "\uf055"; + public static final String plus_square = "\uf0fe"; + public static final String plus_square_o = "\uf196"; + public static final String power_off = "\uf011"; + public static final String print = "\uf02f"; + public static final String puzzle_piece = "\uf12e"; + public static final String qq = "\uf1d6"; + public static final String qrcode = "\uf029"; + public static final String question = "\uf128"; + public static final String question_circle = "\uf059"; + public static final String quote_left = "\uf10d"; + public static final String quote_right = "\uf10e"; + public static final String ra = "\uf1d0"; + public static final String random = "\uf074"; + public static final String rebel = "\uf1d0"; + public static final String recycle = "\uf1b8"; + public static final String reddit = "\uf1a1"; + public static final String reddit_square = "\uf1a2"; + public static final String refresh = "\uf021"; + public static final String remove = "\uf00d"; + public static final String renren = "\uf18b"; + public static final String reorder = "\uf0c9"; + public static final String repeat = "\uf01e"; + public static final String reply = "\uf112"; + public static final String reply_all = "\uf122"; + public static final String retweet = "\uf079"; + public static final String rmb = "\uf157"; + public static final String road = "\uf018"; + public static final String rocket = "\uf135"; + public static final String rotate_left = "\uf0e2"; + public static final String rotate_right = "\uf01e"; + public static final String rouble = "\uf158"; + public static final String rss = "\uf09e"; + public static final String rss_square = "\uf143"; + public static final String rub = "\uf158"; + public static final String ruble = "\uf158"; + public static final String rupee = "\uf156"; + public static final String save = "\uf0c7"; + public static final String scissors = "\uf0c4"; + public static final String search = "\uf002"; + public static final String search_minus = "\uf010"; + public static final String search_plus = "\uf00e"; + public static final String sellsy = "\uf213"; + public static final String send = "\uf1d8"; + public static final String send_o = "\uf1d9"; + public static final String server = "\uf233"; + public static final String share = "\uf064"; + public static final String share_alt = "\uf1e0"; + public static final String share_alt_square = "\uf1e1"; + public static final String share_square = "\uf14d"; + public static final String share_square_o = "\uf045"; + public static final String shekel = "\uf20b"; + public static final String sheqel = "\uf20b"; + public static final String shield = "\uf132"; + public static final String ship = "\uf21a"; + public static final String shirtsinbulk = "\uf214"; + public static final String shopping_cart = "\uf07a"; + public static final String sign_in = "\uf090"; + public static final String sign_out = "\uf08b"; + public static final String signal = "\uf012"; + public static final String simplybuilt = "\uf215"; + public static final String sitemap = "\uf0e8"; + public static final String skyatlas = "\uf216"; + public static final String skype = "\uf17e"; + public static final String slack = "\uf198"; + public static final String sliders = "\uf1de"; + public static final String slideshare = "\uf1e7"; + public static final String smile_o = "\uf118"; + public static final String soccer_ball_o = "\uf1e3"; + public static final String sort = "\uf0dc"; + public static final String sort_alpha_asc = "\uf15d"; + public static final String sort_alpha_desc = "\uf15e"; + public static final String sort_amount_asc = "\uf160"; + public static final String sort_amount_desc = "\uf161"; + public static final String sort_asc = "\uf0de"; + public static final String sort_desc = "\uf0dd"; + public static final String sort_down = "\uf0dd"; + public static final String sort_numeric_asc = "\uf162"; + public static final String sort_numeric_desc = "\uf163"; + public static final String sort_up = "\uf0de"; + public static final String soundcloud = "\uf1be"; + public static final String space_shuttle = "\uf197"; + public static final String spinner = "\uf110"; + public static final String spoon = "\uf1b1"; + public static final String spotify = "\uf1bc"; + public static final String square = "\uf0c8"; + public static final String square_o = "\uf096"; + public static final String stack_exchange = "\uf18d"; + public static final String stack_overflow = "\uf16c"; + public static final String star = "\uf005"; + public static final String star_half = "\uf089"; + public static final String star_half_empty = "\uf123"; + public static final String star_half_full = "\uf123"; + public static final String star_half_o = "\uf123"; + public static final String star_o = "\uf006"; + public static final String steam = "\uf1b6"; + public static final String steam_square = "\uf1b7"; + public static final String step_backward = "\uf048"; + public static final String step_forward = "\uf051"; + public static final String stethoscope = "\uf0f1"; + public static final String stop = "\uf04d"; + public static final String street_view = "\uf21d"; + public static final String strikethrough = "\uf0cc"; + public static final String stumbleupon = "\uf1a4"; + public static final String stumbleupon_circle = "\uf1a3"; + public static final String subscript = "\uf12c"; + public static final String subway = "\uf239"; + public static final String suitcase = "\uf0f2"; + public static final String sun_o = "\uf185"; + public static final String superscript = "\uf12b"; + public static final String support = "\uf1cd"; + public static final String table = "\uf0ce"; + public static final String tablet = "\uf10a"; + public static final String tachometer = "\uf0e4"; + public static final String tag = "\uf02b"; + public static final String tags = "\uf02c"; + public static final String tasks = "\uf0ae"; + public static final String taxi = "\uf1ba"; + public static final String tencent_weibo = "\uf1d5"; + public static final String terminal = "\uf120"; + public static final String text_height = "\uf034"; + public static final String text_width = "\uf035"; + public static final String th = "\uf00a"; + public static final String th_large = "\uf009"; + public static final String th_list = "\uf00b"; + public static final String thumb_tack = "\uf08d"; + public static final String thumbs_down = "\uf165"; + public static final String thumbs_o_down = "\uf088"; + public static final String thumbs_o_up = "\uf087"; + public static final String thumbs_up = "\uf164"; + public static final String ticket = "\uf145"; + public static final String times = "\uf00d"; + public static final String times_circle = "\uf057"; + public static final String times_circle_o = "\uf05c"; + public static final String tint = "\uf043"; + public static final String toggle_down = "\uf150"; + public static final String toggle_left = "\uf191"; + public static final String toggle_off = "\uf204"; + public static final String toggle_on = "\uf205"; + public static final String toggle_right = "\uf152"; + public static final String toggle_up = "\uf151"; + public static final String train = "\uf238"; + public static final String transgender = "\uf224"; + public static final String transgender_alt = "\uf225"; + public static final String trash = "\uf1f8"; + public static final String trash_o = "\uf014"; + public static final String tree = "\uf1bb"; + public static final String trello = "\uf181"; + public static final String trophy = "\uf091"; + public static final String truck = "\uf0d1"; + public static final String TRY = "\uf195"; + public static final String tty = "\uf1e4"; + public static final String tumblr = "\uf173"; + public static final String tumblr_square = "\uf174"; + public static final String turkish_lira = "\uf195"; + public static final String twitch = "\uf1e8"; + public static final String twitter = "\uf099"; + public static final String twitter_square = "\uf081"; + public static final String umbrella = "\uf0e9"; + public static final String underline = "\uf0cd"; + public static final String undo = "\uf0e2"; + public static final String university = "\uf19c"; + public static final String unlink = "\uf127"; + public static final String unlock = "\uf09c"; + public static final String unlock_alt = "\uf13e"; + public static final String unsorted = "\uf0dc"; + public static final String upload = "\uf093"; + public static final String usd = "\uf155"; + public static final String user = "\uf007"; + public static final String user_md = "\uf0f0"; + public static final String user_plus = "\uf234"; + public static final String user_secret = "\uf21b"; + public static final String user_times = "\uf235"; + public static final String users = "\uf0c0"; + public static final String venus = "\uf221"; + public static final String venus_double = "\uf226"; + public static final String venus_mars = "\uf228"; + /** + * Version used when developing. + */ + private static final String VERSION_DEV = "DEV"; + public static final String viacoin = "\uf237"; + public static final String video_camera = "\uf03d"; + public static final String vimeo_square = "\uf194"; + public static final String vine = "\uf1ca"; + public static final String vk = "\uf189"; + public static final String volume_down = "\uf027"; + public static final String volume_off = "\uf026"; + public static final String volume_up = "\uf028"; + public static final String warning = "\uf071"; + public static final String wechat = "\uf1d7"; + public static final String weibo = "\uf18a"; + public static final String weixin = "\uf1d7"; + public static final String whatsapp = "\uf232"; + public static final String wheelchair = "\uf193"; + public static final String wifi = "\uf1eb"; + public static final String windows = "\uf17a"; + public static final String won = "\uf159"; + public static final String wordpress = "\uf19a"; + public static final String wrench = "\uf0ad"; + public static final String xing = "\uf168"; + public static final String xing_square = "\uf169"; + public static final String yahoo = "\uf19e"; + public static final String yelp = "\uf1e9"; + public static final String yen = "\uf157"; + public static final String youtube = "\uf167"; + public static final String youtube_play = "\uf16a"; + public static final String youtube_square = "\uf166"; + + private static Map fonts = new HashMap<>(); + + private static long copy(InputStream input, OutputStream output, byte[] buffer) throws IOException { + long count = 0; + int n = 0; + while (EOF != (n = input.read(buffer))) { + output.write(buffer, 0, n); + count += n; + } + return count; + } + + /** + * Return the current version. + * + * @return + */ + private static String getCurrentVersion() { + // Get the version from the package manifest + String version = FontAwesome.class.getPackage().getImplementationVersion(); + if (version == null) { + return VERSION_DEV; + } + return version; + } + + /** + * Return a FontAwesome font for SWT. + * + * @return the font or null. + */ + public static Font getFont() { + if (fonts.containsKey(DEFAULT_FONT_SIZE)) { + return fonts.get(DEFAULT_FONT_SIZE); + } + if (!loadFont()) { + return null; + } + FontData[] data = new FontData[] { new FontData("fontawesome", DEFAULT_FONT_SIZE, SWT.NORMAL) }; + fonts.put(DEFAULT_FONT_SIZE, new Font(Display.getDefault(), data)); + return fonts.get(DEFAULT_FONT_SIZE); + } + + /** + * Return a FontAwesome font for SWT. + * + * @param size + * @return + */ + public static Font getFont(int size) { + if (!fonts.containsKey(size)) { + // GetFont() may return null, so handle this case. + Font font = getFont(); + if (font == null) { + return null; + } + FontData[] data = font.getFontData(); + for (FontData d : data) { + d.setHeight(size); + } + fonts.put(size, new Font(Display.getDefault(), data)); + } + return fonts.get(size); + } + + /** + * Load the font from resources. + * + * @return + */ + private static boolean loadFont() { + // Get file from classpath. + + // Add dispose listener + Display.getDefault().addListener(SWT.Dispose, e -> { + for (Font font : fonts.values()) { + if (!font.isDisposed()) + font.dispose(); + } + }); + + try { + // Copy file to temp diretory. + String temp = System.getProperty("java.io.tmpdir"); + final File tempfile = new File(temp, + System.getProperty("user.name") + "-fontawesome-webfont-" + getCurrentVersion() + ".ttf"); + tempfile.deleteOnExit(); + try (FileOutputStream out = new FileOutputStream(tempfile); + InputStream in = FontAwesome.class.getResourceAsStream("resources/fontawesome-webfont.ttf");) { + if (in == null) { + return false; + } + copy(in, out, new byte[DEFAULT_BUFFER_SIZE]); + } + // Load the font. + return Display.getDefault().loadFont(tempfile.getAbsolutePath()); + } catch (IOException e) { + // This should rarely happen, but clearly, when this happen we need + // to print something to a log file. Otherwise there is no way to debug this. + e.printStackTrace(); + return false; + } + } } \ No newline at end of file diff --git a/widgets/fontawesome/pom.xml b/widgets/fontawesome/pom.xml index 2dcf2cbfb..9eafde7c1 100644 --- a/widgets/fontawesome/pom.xml +++ b/widgets/fontawesome/pom.xml @@ -1,24 +1,24 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - nebula-parent - ../../releng/org.eclipse.nebula.nebula-parent - - - fontawesome - pom - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.fontawesome - org.eclipse.nebula.widgets.fontawesome.feature - org.eclipse.nebula.widgets.fontawesome.snippets - - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + nebula-parent + ../../releng/org.eclipse.nebula.nebula-parent + + + fontawesome + pom + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.fontawesome + org.eclipse.nebula.widgets.fontawesome.feature + org.eclipse.nebula.widgets.fontawesome.snippets + + + + diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/.classpath b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/.classpath index e00865a3c..2026e10c7 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/.classpath +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/.classpath @@ -1,11 +1,11 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/META-INF/MANIFEST.MF b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/META-INF/MANIFEST.MF index 3ce403a9a..d7e7d6e93 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/META-INF/MANIFEST.MF +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/META-INF/MANIFEST.MF @@ -1,12 +1,12 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Formatted Text Tests -Bundle-SymbolicName: org.eclipse.nebula.widgets.formattedtext.tests -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Fragment-Host: org.eclipse.nebula.widgets.formattedtext;bundle-version="1.0.0" -Require-Bundle: org.eclipse.swt, - org.junit -Export-Package: org.eclipse.nebula.widgets.formattedtext -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Automatic-Module-Name: org.eclipse.nebula.widgets.formattedtext.tests +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Formatted Text Tests +Bundle-SymbolicName: org.eclipse.nebula.widgets.formattedtext.tests +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Fragment-Host: org.eclipse.nebula.widgets.formattedtext;bundle-version="1.0.0" +Require-Bundle: org.eclipse.swt, + org.junit +Export-Package: org.eclipse.nebula.widgets.formattedtext +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Automatic-Module-Name: org.eclipse.nebula.widgets.formattedtext.tests diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/src/org/eclipse/nebula/widgets/formattedtext/IPAddressFormatterSnippet.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/src/org/eclipse/nebula/widgets/formattedtext/IPAddressFormatterSnippet.java index 9756f8fde..c87df2314 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/src/org/eclipse/nebula/widgets/formattedtext/IPAddressFormatterSnippet.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext.tests/src/org/eclipse/nebula/widgets/formattedtext/IPAddressFormatterSnippet.java @@ -1,42 +1,42 @@ -package org.eclipse.nebula.widgets.formattedtext; - -import org.eclipse.nebula.widgets.formattedtext.FormattedText; -import org.eclipse.nebula.widgets.formattedtext.IPAddressFormatter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; - -public class IPAddressFormatterSnippet { - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display); - shell.setLayout(new GridLayout()); - - final FormattedText text = new FormattedText(shell, SWT.BORDER); - text.setFormatter(new IPAddressFormatter()); - text.setValue("192.192.92.192"); - GridData data = new GridData(); - data.widthHint = 100; - text.getControl().setLayoutData(data); - - Button btn = new Button(shell, SWT.PUSH); - btn.setText("ok"); - btn.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event e) { - System.out.println(text.getValue()); - } - }); - - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - display.dispose(); - } -} +package org.eclipse.nebula.widgets.formattedtext; + +import org.eclipse.nebula.widgets.formattedtext.FormattedText; +import org.eclipse.nebula.widgets.formattedtext.IPAddressFormatter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; + +public class IPAddressFormatterSnippet { + public static void main(String[] args) { + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new GridLayout()); + + final FormattedText text = new FormattedText(shell, SWT.BORDER); + text.setFormatter(new IPAddressFormatter()); + text.setValue("192.192.92.192"); + GridData data = new GridData(); + data.widthHint = 100; + text.getControl().setLayoutData(data); + + Button btn = new Button(shell, SWT.PUSH); + btn.setText("ok"); + btn.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event e) { + System.out.println(text.getValue()); + } + }); + + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/.classpath b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/.classpath index 92e333a4b..c3ba59e4c 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/.classpath +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/META-INF/MANIFEST.MF b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/META-INF/MANIFEST.MF index dc7d94537..3c9fc9aba 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/META-INF/MANIFEST.MF +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/META-INF/MANIFEST.MF @@ -1,13 +1,13 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Formatted Text -Bundle-SymbolicName: org.eclipse.nebula.widgets.formattedtext -Bundle-Version: 1.0.0.qualifier -Export-Package: org.eclipse.nebula.widgets.formattedtext -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-Vendor: Eclipse Nebula -Require-Bundle: org.eclipse.jface, - org.eclipse.core.databinding, - org.eclipse.jface.databinding, - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.formattedtext +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Formatted Text +Bundle-SymbolicName: org.eclipse.nebula.widgets.formattedtext +Bundle-Version: 1.0.0.qualifier +Export-Package: org.eclipse.nebula.widgets.formattedtext +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: Eclipse Nebula +Require-Bundle: org.eclipse.jface, + org.eclipse.core.databinding, + org.eclipse.jface.databinding, + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.formattedtext diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/BigDecimalFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/BigDecimalFormatter.java index 8b3484a2d..20b794a9d 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/BigDecimalFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/BigDecimalFormatter.java @@ -1,138 +1,138 @@ -/******************************************************************************* - * Copyright (c) 2014 Mario Hofmann. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Mario Hofmann (eclispe@hofmann-coswig.de) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import java.math.BigDecimal; -import java.util.Locale; - -/** - * This class provides formatting of {@link BigDecimal} values in a {@link FormattedText}. - *

- * BigDecimalFormatter returns different numeric types based on the current - * value in the Text field. BigDecimalFormatter is an override of NumberFormatter - * allowing to guaranty to always return {@link BigDecimal} values ({@link Number#toString()}). - *

- */ -public class BigDecimalFormatter extends NumberFormatter { - - /** - * Constructs a new instance with all defaults. - * - * @see NumberFormatter#NumberFormatter() - */ - public BigDecimalFormatter() { - super(); - } - - /** - * Constructs a new instance with default edit and display masks for the given - * locale. - * - * @param loc the {@link Locale locale} - */ - public BigDecimalFormatter(Locale loc) { - super(loc); - } - - /** - * Constructs a new instance with the given edit mask and locale. Display mask - * is identical to the edit mask. - * - * @param editPattern the edit mask - * @param loc the {@link Locale locale} - */ - public BigDecimalFormatter(String editPattern, Locale loc) { - super(editPattern, loc); - } - - /** - * Constructs a new instance with the given masks and locale. - * - * @param editPattern the edit mask - * @param displayPattern the display mask - * @param loc the {@link Locale locale} - */ - public BigDecimalFormatter(String editPattern, String displayPattern, Locale loc) { - super(editPattern, displayPattern, loc); - } - - /** - * Constructs a new instance with the given edit and display masks. Uses the - * default locale. - * - * @param editPattern the edit mask - * @param displayPattern the display mask - */ - public BigDecimalFormatter(String editPattern, String displayPattern) { - super(editPattern, displayPattern); - } - - /** - * Constructs a new instance with the given edit mask. Display mask is - * identical to the edit mask, and locale is the default one. - * - * @param editPattern the edit mask - */ - public BigDecimalFormatter(String editPattern) { - super(editPattern); - } - - /** - * Returns the current value of the text control if it is a valid {@code BigDecimal}. - * If the buffer is flagged as modified, the value is recalculated by parsing - * with the {@code nfEdit} initialized with the edit pattern. If the - * number is not valid, returns {@code null}. - * - * @return current {@link BigDecimal} value if valid, else {@code null} - * @see ITextFormatter#getValue() - */ - public Object getValue() { - Object value = super.getValue(); - if (value instanceof BigDecimal) { - return (BigDecimal) value; - } else if (value instanceof Number) { - return new BigDecimal(((Number) value).toString()); - } else { - return null; - } - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * A BigDecimalFormatter always returns an BigDecimal value. - * - * @return The value type. - */ - public Class getValueType() { - return BigDecimal.class; - } - - /** - * Sets the patterns and initializes the technical attributes used to manage - * the operations.

- * Override the NumberFormatter implementation to handle large numbers. - * - * @param edit edit pattern - * @param display display pattern - * @param loc Locale to use - * @throws IllegalArgumentException if a pattern is invalid - * @see com.wdev91.comp4swt.core.NumberFormatter#setPatterns(java.lang.String, java.lang.String, java.util.Locale) - */ - protected void setPatterns(String edit, String display, Locale loc) { - super.setPatterns(edit, display, loc); - nfEdit.setParseBigDecimal(true); - nfDisplay.setParseBigDecimal(true); - } -} +/******************************************************************************* + * Copyright (c) 2014 Mario Hofmann. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Mario Hofmann (eclispe@hofmann-coswig.de) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import java.math.BigDecimal; +import java.util.Locale; + +/** + * This class provides formatting of {@link BigDecimal} values in a {@link FormattedText}. + *

+ * BigDecimalFormatter returns different numeric types based on the current + * value in the Text field. BigDecimalFormatter is an override of NumberFormatter + * allowing to guaranty to always return {@link BigDecimal} values ({@link Number#toString()}). + *

+ */ +public class BigDecimalFormatter extends NumberFormatter { + + /** + * Constructs a new instance with all defaults. + * + * @see NumberFormatter#NumberFormatter() + */ + public BigDecimalFormatter() { + super(); + } + + /** + * Constructs a new instance with default edit and display masks for the given + * locale. + * + * @param loc the {@link Locale locale} + */ + public BigDecimalFormatter(Locale loc) { + super(loc); + } + + /** + * Constructs a new instance with the given edit mask and locale. Display mask + * is identical to the edit mask. + * + * @param editPattern the edit mask + * @param loc the {@link Locale locale} + */ + public BigDecimalFormatter(String editPattern, Locale loc) { + super(editPattern, loc); + } + + /** + * Constructs a new instance with the given masks and locale. + * + * @param editPattern the edit mask + * @param displayPattern the display mask + * @param loc the {@link Locale locale} + */ + public BigDecimalFormatter(String editPattern, String displayPattern, Locale loc) { + super(editPattern, displayPattern, loc); + } + + /** + * Constructs a new instance with the given edit and display masks. Uses the + * default locale. + * + * @param editPattern the edit mask + * @param displayPattern the display mask + */ + public BigDecimalFormatter(String editPattern, String displayPattern) { + super(editPattern, displayPattern); + } + + /** + * Constructs a new instance with the given edit mask. Display mask is + * identical to the edit mask, and locale is the default one. + * + * @param editPattern the edit mask + */ + public BigDecimalFormatter(String editPattern) { + super(editPattern); + } + + /** + * Returns the current value of the text control if it is a valid {@code BigDecimal}. + * If the buffer is flagged as modified, the value is recalculated by parsing + * with the {@code nfEdit} initialized with the edit pattern. If the + * number is not valid, returns {@code null}. + * + * @return current {@link BigDecimal} value if valid, else {@code null} + * @see ITextFormatter#getValue() + */ + public Object getValue() { + Object value = super.getValue(); + if (value instanceof BigDecimal) { + return (BigDecimal) value; + } else if (value instanceof Number) { + return new BigDecimal(((Number) value).toString()); + } else { + return null; + } + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * A BigDecimalFormatter always returns an BigDecimal value. + * + * @return The value type. + */ + public Class getValueType() { + return BigDecimal.class; + } + + /** + * Sets the patterns and initializes the technical attributes used to manage + * the operations.

+ * Override the NumberFormatter implementation to handle large numbers. + * + * @param edit edit pattern + * @param display display pattern + * @param loc Locale to use + * @throws IllegalArgumentException if a pattern is invalid + * @see com.wdev91.comp4swt.core.NumberFormatter#setPatterns(java.lang.String, java.lang.String, java.util.Locale) + */ + protected void setPatterns(String edit, String display, Locale loc) { + super.setPatterns(edit, display, loc); + nfEdit.setParseBigDecimal(true); + nfDisplay.setParseBigDecimal(true); + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/BigIntegerFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/BigIntegerFormatter.java index ef120014e..559067ab3 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/BigIntegerFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/BigIntegerFormatter.java @@ -1,120 +1,120 @@ -/******************************************************************************* - * Copyright (c) 2014 Mario Hofmann. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Mario Hofmann (eclispe@hofmann-coswig.de) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import java.math.BigInteger; -import java.util.Locale; - -/** - * This class provides formatting of {@link BigInteger} values in a {@link FormattedText}. - *

- * BigIntegerFormatter returns different numeric types based on the current - * value in the Text field. BigIntegerFormatter is an override of NumberFormatter - * allowing to guaranty to always return {@link BigInteger} values ({@link Number#longValue()}). - *

- */ -public class BigIntegerFormatter extends NumberFormatter { - /** - * Constructs a new instance with all defaults. - * - * @see NumberFormatter#NumberFormatter() - */ - public BigIntegerFormatter() { - super(); - } - - /** - * Constructs a new instance with default edit and display masks for the given - * locale. - * - * @param loc the {@link Locale locale} - */ - public BigIntegerFormatter(Locale loc) { - super(loc); - } - - /** - * Constructs a new instance with the given edit mask and locale. Display mask - * is identical to the edit mask. - * - * @param editPattern the edit mask - * @param loc the {@link Locale locale} - */ - public BigIntegerFormatter(String editPattern, Locale loc) { - super(editPattern, loc); - } - - /** - * Constructs a new instance with the given masks and locale. - * - * @param editPattern the edit mask - * @param displayPattern the display mask - * @param loc the {@link Locale locale} - */ - public BigIntegerFormatter(String editPattern, String displayPattern, Locale loc) { - super(editPattern, displayPattern, loc); - } - - /** - * Constructs a new instance with the given edit and display masks. Uses the - * default locale. - * - * @param editPattern the edit mask - * @param displayPattern the display mask - */ - public BigIntegerFormatter(String editPattern, String displayPattern) { - super(editPattern, displayPattern); - } - - /** - * Constructs a new instance with the given edit mask. Display mask is - * identical to the edit mask, and locale is the default one. - * - * @param editPattern the edit mask - */ - public BigIntegerFormatter(String editPattern) { - super(editPattern); - } - - /** - * Returns the current value of the text control if it is a valid {@code BigInteger}. - * If the buffer is flagged as modified, the value is recalculated by parsing - * with the {@code nfEdit} initialized with the edit pattern. If the - * number is not valid, returns {@code null}. - * - * @return current {@link BigInteger} value if valid, else {@code null} - * @see ITextFormatter#getValue() - */ - public Object getValue() { - Object value = super.getValue(); - if (value instanceof BigInteger) { - return value; - } else if (value instanceof Number) { - return new BigInteger(((Number) value).toString()); - } else { - return null; - } - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * An BigIntegerFormatter always returns an BigInteger value. - * - * @return The value type. - */ - public Class getValueType() { - return BigInteger.class; - } -} +/******************************************************************************* + * Copyright (c) 2014 Mario Hofmann. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Mario Hofmann (eclispe@hofmann-coswig.de) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import java.math.BigInteger; +import java.util.Locale; + +/** + * This class provides formatting of {@link BigInteger} values in a {@link FormattedText}. + *

+ * BigIntegerFormatter returns different numeric types based on the current + * value in the Text field. BigIntegerFormatter is an override of NumberFormatter + * allowing to guaranty to always return {@link BigInteger} values ({@link Number#longValue()}). + *

+ */ +public class BigIntegerFormatter extends NumberFormatter { + /** + * Constructs a new instance with all defaults. + * + * @see NumberFormatter#NumberFormatter() + */ + public BigIntegerFormatter() { + super(); + } + + /** + * Constructs a new instance with default edit and display masks for the given + * locale. + * + * @param loc the {@link Locale locale} + */ + public BigIntegerFormatter(Locale loc) { + super(loc); + } + + /** + * Constructs a new instance with the given edit mask and locale. Display mask + * is identical to the edit mask. + * + * @param editPattern the edit mask + * @param loc the {@link Locale locale} + */ + public BigIntegerFormatter(String editPattern, Locale loc) { + super(editPattern, loc); + } + + /** + * Constructs a new instance with the given masks and locale. + * + * @param editPattern the edit mask + * @param displayPattern the display mask + * @param loc the {@link Locale locale} + */ + public BigIntegerFormatter(String editPattern, String displayPattern, Locale loc) { + super(editPattern, displayPattern, loc); + } + + /** + * Constructs a new instance with the given edit and display masks. Uses the + * default locale. + * + * @param editPattern the edit mask + * @param displayPattern the display mask + */ + public BigIntegerFormatter(String editPattern, String displayPattern) { + super(editPattern, displayPattern); + } + + /** + * Constructs a new instance with the given edit mask. Display mask is + * identical to the edit mask, and locale is the default one. + * + * @param editPattern the edit mask + */ + public BigIntegerFormatter(String editPattern) { + super(editPattern); + } + + /** + * Returns the current value of the text control if it is a valid {@code BigInteger}. + * If the buffer is flagged as modified, the value is recalculated by parsing + * with the {@code nfEdit} initialized with the edit pattern. If the + * number is not valid, returns {@code null}. + * + * @return current {@link BigInteger} value if valid, else {@code null} + * @see ITextFormatter#getValue() + */ + public Object getValue() { + Object value = super.getValue(); + if (value instanceof BigInteger) { + return value; + } else if (value instanceof Number) { + return new BigInteger(((Number) value).toString()); + } else { + return null; + } + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * An BigIntegerFormatter always returns an BigInteger value. + * + * @return The value type. + */ + public Class getValueType() { + return BigInteger.class; + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DateTimeFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DateTimeFormatter.java index f801f45f6..f5730c4ad 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DateTimeFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DateTimeFormatter.java @@ -1,1066 +1,1066 @@ -/******************************************************************************* - * Copyright (c) 2005, 2009 Eric Wuillai. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Eric Wuillai (eric@wdev91.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import java.text.DateFormat; -import java.text.DateFormatSymbols; -import java.text.NumberFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Hashtable; -import java.util.Locale; -import java.util.TimeZone; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; - -/** - * This class provides formatting of Date values in a - * FormattedText. Supports a subset of date and time patterns - * defined in SimpleDateFormat for input.

- * - *

Edit Patterns

- * Edit patterns are composed of letters defining the parts of the mask, and - * characters defining the separators.

- * The following pattern letters are defined: - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
LetterDate or Time PartExamples
yYear2006; 06
MMonth in year07
dDay in month10
HHour in day (0-23)0
hHour in am/pm (1-12)12
mMinute in hour30
sSecond in minute55
SMillisecond978
aAm/pm markerPM
- *
- * Edit patterns are limited to numeric formats (except am/pm marker). Variable - * length fields and separators composed of more than one character are - * supported for input. - * - *

Display Patterns

- * Display patterns are associated to a SimpleDateFormat object. - * So they have to be compatible with it. - * - *

Examples

- *
    - *
  • new DateTimeFormatter("MM/dd/yyyy") - 8 jul 2006 will edit - * and display as "07/08/2006".
  • - *
  • new DateTimeFormatter("d/M/yyyy H:m, "dd MMM yyyy HH:mm")- - * 8 jul 2006, 15:05 will edit as "8/7/2006 15:5" and display as - * "08 Jul 2006 15:05".
  • - *
- */ -public class DateTimeFormatter extends AbstractFormatter { - /** Cache of patterns by locale ISO3 codes */ - protected static Hashtable cachedPatterns = new Hashtable<>(); - /** Numbers formatter */ - private static NumberFormat nf; - - /** Calendar containing the current value */ - protected Calendar calendar; - /** Date formatter for display */ - protected SimpleDateFormat sdfDisplay; - /** Input mask */ - protected StringBuffer inputMask; - /** Current edited value */ - protected StringBuffer inputCache; - /** Fields descriptions */ - protected FieldDesc[] fields; - /** Number of fields in edit pattern */ - protected int fieldCount; - /** Year limit for 2 digits year field */ - protected int yearStart; - /** Key listener on the Text widget */ - protected KeyListener klistener; - /** Focus listener on the Text widget */ - protected FocusListener flistener; - /** Filter for modify events */ - protected Listener modifyFilter; - /** The Locale used by this formatter */ - protected Locale locale; - - private class FieldDesc { - /** Time field in Calendar */ - int field; - /** Minimum length of the field in chars */ - int minLen; - /** Maximum length of the field in chars */ - int maxLen; - /** true if the field is empty, else false */ - boolean empty; - /** true if the field contains a valid value, else false */ - boolean valid; - char index; - - int pos; - int curLen; - } - - static { - nf = NumberFormat.getIntegerInstance(); - nf.setGroupingUsed(false); - } - - /** - * Constructs a new instance with all defaults : - *
    - *
  • edit mask in SHORT format for both date and time parts for the default locale
  • - *
  • display mask identical to the edit mask
  • - *
  • default locale
  • - *
- */ - public DateTimeFormatter() { - this(null, null, Locale.getDefault()); - } - - /** - * Constructs a new instance with default edit and display masks for the given - * locale. - * - * @param loc locale - */ - public DateTimeFormatter(Locale loc) { - this(null, null, loc); - } - - /** - * Constructs a new instance with the given edit mask. Display mask is - * identical to the edit mask, and locale is the default one. - * - * @param editPattern edit mask - */ - public DateTimeFormatter(String editPattern) { - this(editPattern, null, Locale.getDefault()); - } - - /** - * Constructs a new instance with the given edit mask and locale. Display mask - * is identical to the edit mask. - * - * @param editPattern edit mask - * @param loc locale - */ - public DateTimeFormatter(String editPattern, Locale loc) { - this(editPattern, null, loc); - } - - /** - * Constructs a new instance with the given edit and display masks. Uses the - * default locale. - * - * @param editPattern edit mask - * @param displayPattern display mask - */ - public DateTimeFormatter(String editPattern, String displayPattern) { - this(editPattern, displayPattern, Locale.getDefault()); - } - - /** - * Constructs a new instance with the given masks and locale. - * - * @param editPattern edit mask - * @param displayPattern display mask - * @param loc locale - */ - public DateTimeFormatter(String editPattern, String displayPattern, Locale loc) { - // Set the default value - calendar = Calendar.getInstance(loc); - calendar.set(Calendar.HOUR_OF_DAY, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - - // Creates the formatter for the edit value - if ( editPattern == null ) { - editPattern = getDefaultEditPattern(loc); - } - compile(editPattern); - - // Creates the formatter for the display value - if ( displayPattern == null ) { - displayPattern = editPattern; - } - sdfDisplay = new SimpleDateFormat(displayPattern, loc); - if ( yearStart == -1 ) { - calendar.setTime(sdfDisplay.get2DigitYearStart()); - yearStart = calendar.get(Calendar.YEAR) % 100; - } - locale = loc; - - // Instantiate the key listener - klistener = new KeyListener() { - public void keyPressed(KeyEvent e) { - if ( e.stateMask != 0 ) return; - switch ( e.keyCode ) { - case SWT.ARROW_UP : - arrow(1); - break; - case SWT.ARROW_DOWN : - arrow(-1); - break; - default : - return; - } - e.doit = false; - } - - public void keyReleased(KeyEvent e) { - } - }; - - // Instantiate the focus listener - flistener = new FocusListener() { - String lastInput; - public void focusGained(FocusEvent e) { - int p = text.getCaretPosition(); - setInputCache(); - String t = inputCache.toString(); - if ( ! t.equals(lastInput ) ) { - Display display = text.getDisplay(); - try { - display.addFilter(SWT.Modify, modifyFilter); - updateText(inputCache.toString(), p); - } finally { - display.removeFilter(SWT.Modify, modifyFilter); - } - } - } - - public void focusLost(FocusEvent e) { - if ( text != null ) { - lastInput = text.getText(); - } - } - }; - - modifyFilter = new Listener() { - public void handleEvent(Event event) { - event.type = SWT.None; - } - }; - } - - /** - * Adjust a field length in the mask to a given length. - * - * @param b begin position (inclusive) - * @param e end position (exclusive) - * @param l new length - * @return new end position - */ - private int ajustMask(int b, int e, int l) { - char c = inputMask.charAt(b); - while ( e - b + 1 < l ) { - inputMask.insert(e++, c); - } - while ( e - b + 1 > l ) { - inputMask.deleteCharAt(e--); - } - return e; - } - - /** - * Executes the increment or decrement of the date value when an arrow UP or - * DOWN is pressed.
- * The calendar field at the position of cursor is incremented / decremented. - * If the field value exceeds its range, the next larger field is incremented - * or decremented and the field value is adjusted back into its range.

- * - * If the calendar is empty, it is initialized with the current date. In these - * case, the arrow is ignored. - * - * @param inc +1 for increment, -1 for decrement - */ - private void arrow(int inc) { - int p = text.getCaretPosition(); - int l = inputMask.length(); - if ( p == l ) return; - char m = inputMask.charAt(p); - if ( m == '*' ) return; - FieldDesc f = getField(p, 0); - int b = f.pos; - if ( countValid() == 0 ) { - setValue(new Date()); - } else if ( f.field == Calendar.YEAR && f.maxLen <= 2 ) { - int year = calendar.get(Calendar.YEAR) % 100 + inc; - year += year >= yearStart ? 1900 : 2000; - calendar.set(f.field, year); - } else { - calendar.add(f.field, inc); - } - setInputCache(); - locateField(f, 0); - ignore = true; - updateText(inputCache.toString(), - Math.min(f.pos + p - b, f.pos + f.curLen - 1)); - ignore = false; - } - - /** - * Clear a part of the input cache.
- * Characters are replaced by spaces in the fields, but separators are - * preserved. - * - * @param b beginning index (inclusive) - * @param e end index (exclusive) - */ - private void clear(int b, int e) { - char m; - int i = b, from = 0; - FieldDesc field; - - while ( i < e ) { - m = inputMask.charAt(i); - if ( m == '*' ) { - from = ++i; - continue; - } - field = getField(i, from); - final int numCharsLeftOfRangeToClear= i-field.pos; - while ( i < e && field.curLen - numCharsLeftOfRangeToClear > 0 ) { - inputCache.deleteCharAt(i); - inputMask.deleteCharAt(i); - e--; - field.curLen--; - } - while ( field.curLen < field.minLen ) { - inputCache.insert(field.pos + field.curLen, SPACE); - inputMask.insert(field.pos + field.curLen, field.index); - i++; - e++; - field.curLen++; - } - updateFieldValue(field, false); - } - } - - /** - * Compiles a given edit pattern, initializing inputMask and - * inputCache. The content of the edit pattern is analyzed char - * by char and the array of field descriptors is initialized. - * Pattern chars allowed are : y, M, d, H, h, s, S, a. - * The presence of other pattern chars defined in SimpleDateFormat - * will raised an IllegalArgumentException. - * - * @param editPattern edit pattern - * @throws IllegalArgumentException pattern is invalid - */ - private void compile(String editPattern) { - inputMask = new StringBuffer(); - inputCache = new StringBuffer(); - fields = new FieldDesc[10]; - int fi = 0; - int length = editPattern.length(); - for (int i = 0; i < length; i++) { - char c = editPattern.charAt(i); - int l = 1; - while ( i < length - 1 && editPattern.charAt(i + 1) == c ) { - i++; - l++; - } - isValidCharPattern(c); - switch ( c ) { - case 'y' : // Year - fields[fi] = new FieldDesc(); - fields[fi].field = Calendar.YEAR; - fields[fi].minLen = fields[fi].maxLen = l <= 2 ? 2 : 4; - if ( fields[fi].maxLen == 2 ) { - yearStart = -1; - } - break; - case 'M' : // Month - fields[fi] = new FieldDesc(); - fields[fi].field = Calendar.MONTH; - fields[fi].minLen = Math.min(l, 2); - fields[fi].maxLen = 2; - break; - case 'd' : // Day in month - fields[fi] = new FieldDesc(); - fields[fi].field = Calendar.DAY_OF_MONTH; - fields[fi].minLen = Math.min(l, 2); - fields[fi].maxLen = 2; - break; - case 'H' : // Hour (0-23) - fields[fi] = new FieldDesc(); - fields[fi].field = Calendar.HOUR_OF_DAY; - fields[fi].minLen = Math.min(l, 2); - fields[fi].maxLen = 2; - break; - case 'h' : // Hour (1-12 AM-PM) - fields[fi] = new FieldDesc(); - fields[fi].field = Calendar.HOUR; - fields[fi].minLen = Math.min(l, 2); - fields[fi].maxLen = 2; - break; - case 'm' : // Minutes - fields[fi] = new FieldDesc(); - fields[fi].field = Calendar.MINUTE; - fields[fi].minLen = Math.min(l, 2); - fields[fi].maxLen = 2; - break; - case 's' : // Seconds - fields[fi] = new FieldDesc(); - fields[fi].field = Calendar.SECOND; - fields[fi].minLen = Math.min(l, 2); - fields[fi].maxLen = 2; - break; - case 'S' : // Milliseconds - fields[fi] = new FieldDesc(); - fields[fi].field = Calendar.MILLISECOND; - fields[fi].minLen = Math.min(l, 3); - fields[fi].maxLen = 3; - break; - case 'a' : // AM-PM marker - fields[fi] = new FieldDesc(); - fields[fi].field = Calendar.AM_PM; - fields[fi].minLen = fields[fi].maxLen = 2; - break; - default : - for (int j = 0; j < l; j++) { - inputMask.append('*'); - inputCache.append(c); - } - continue; - } - fields[fi].empty = true; - fields[fi].valid = false; - calendar.clear(fields[fi].field); - char k = (char) ('0' + fi); - for (int j = 0; j < fields[fi].minLen; j++) { - inputMask.append(k); - inputCache.append(SPACE); - } - fields[fi].index = k; - fi++; - } - fieldCount = fi; - } - - /** - * Returns the count of valid fields. Value returned is between 0 and - * fieldcount. - * - * @return Count of valid fields - */ - private int countValid() { - int count = 0; - for (int i = 0; i < fieldCount; i++) { - if ( fields[i].valid ) count++; - } - return count; - } - - /** - * Called when the formatter is replaced by an other one in the FormattedText - * control. Allow to release resources like additional listeners.

- * - * Removes the KeyListener on the text widget. - * - * @see ITextFormatter#detach() - */ - public void detach() { - text.removeKeyListener(klistener); - text.removeFocusListener(flistener); - } - - /** - * Returns the default edit pattern for the given Locale.

- * - * A DateFormat object is instantiated with SHORT format for - * both date and time parts for the given locale. The corresponding pattern - * string is then retrieved by calling the toPattern.

- * - * Default patterns are stored in a cache with ISO3 language and country codes - * as key. So they are computed only once by locale. - * - * @param loc locale - * @return edit pattern for the locale - */ - public String getDefaultEditPattern(Locale loc) { - if ( loc == null ) { - loc = Locale.getDefault(); - } - String key = "DT" + loc.toString(); - String pattern = cachedPatterns.get(key); - if ( pattern == null ) { - DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, loc); - if ( ! (df instanceof SimpleDateFormat) ) { - throw new IllegalArgumentException("No default pattern for locale " + loc.getDisplayName()); - } - StringBuffer buffer = new StringBuffer(); - buffer.append(((SimpleDateFormat) df).toPattern()); - int i; - if ( buffer.indexOf("yyy") < 0 && (i = buffer.indexOf("yy")) >= 0 ) { - buffer.insert(i, "yy"); - } - pattern = buffer.toString(); - cachedPatterns.put(key, pattern); - } - return pattern; - } - - /** - * Returns the current value formatted for display. - * This method is called by FormattedText when the Text - * widget looses focus. - * The displayed value is the result of formatting on the calendar - * with a SimpleDateFormat for the display pattern passed in - * constructor. In case the input is invalid (eg. blanks fields), the edit - * string is returned in place of the display string. - * - * @return display string if valid, edit string else - * @see ITextFormatter#getDisplayString() - */ - public String getDisplayString() { - return isValid() ? sdfDisplay.format(calendar.getTime()) : getEditString(); - } - - /** - * Returns the current value formatted for input. - * This method is called by FormattedText when the Text - * widget gains focus. - * The value returned is the content of the StringBuilder used as cache. - * - * @return edit string - * @see ITextFormatter#getEditString() - */ - public String getEditString() { - return inputCache.toString(); - } - - /** - * Returns the field descriptor corresponding to a given position in the - * inputMask. The current starting position and length of the - * field are set in the descriptor. - * - * @param p position in mask of the field - * @param from starting position in mask to search for the beginning of the field - * @return Field descriptor - */ - private FieldDesc getField(int p, int from) { - FieldDesc f; - - if ( p >= inputMask.length() ) { - p = inputMask.length() - 1; - } - char c = inputMask.charAt(p); - while ( c == '*' ) { - p--; - if ( p < 0 ) { - return null; - } - c = inputMask.charAt(p); - } - f = fields[c - '0']; - locateField(f, from); - - return f; - } - - /** - * Returns a string representing the current value of a given field based on - * the content of the calendar. - * - * @param f field descriptor - * @return formatted value of field - */ - private String getFormattedValue(FieldDesc f) { - StringBuffer value = new StringBuffer(); - if ( f.valid ) { - int v = calendar.get(f.field); - switch ( f.field ) { - case Calendar.MONTH : - v++; - break; - case Calendar.HOUR : - if ( v == 0 ) v = 12; - break; - case Calendar.AM_PM : - return sdfDisplay.getDateFormatSymbols().getAmPmStrings()[v]; - default: - break; - } - value.append(v); - if ( value.length() > f.maxLen ) { - value.delete(0, value.length() - f.maxLen); - } else while ( value.length() < f.minLen ) { - value.insert(0, '0'); - } - } else { - while ( value.length() < f.minLen ) { - value.append(SPACE); - } - } - return value.toString(); - } - - /** - * Returns the current Locale used by this formatter. - * - * @return Current Locale used - */ - public Locale getLocale() { - return locale; - } - - /** - * Returns the current value of the text control if it is a valid - * Date.
- * The date is valid if all the input fields are set. If invalid, returns - * null. - * - * @return current date value if valid, null else - * @see ITextFormatter#getValue() - */ - public Object getValue() { - return isValid() ? calendar.getTime() : null; - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * A DateTimeFormatter always returns a Date value. - * - * @return The value type. - */ - public Class getValueType() { - return Date.class; - } - - /** - * Inserts a sequence of characters in the input buffer. The current content - * of the buffer is override. The new position of the cursor is computed and - * returned. - * - * @param txt String of characters to insert - * @param p Starting position of insertion - * @return New position of the cursor - */ - private int insert(String txt, int p) { - FieldDesc fd = null; - int i = 0, from = 0, t; - char c, m, o; - while ( i < txt.length() ) { - c = txt.charAt(i); - if ( p < inputMask.length() ) { - m = inputMask.charAt(p); - if ( m == '*' && inputCache.charAt(p) == c ) { - from = p; - i++; - p++; - fd = null; - continue; - } - } else { - m = inputMask.charAt(inputMask.length() - 1); - } - if ( fd == null ) { - fd = getField(p, from); - for (int j = fd.pos; j < p; j++) { - if ( inputCache.charAt(j) == SPACE ) { - inputCache.setCharAt(j, '0'); - } - } - } - t = Character.getType(c); - if ( t == Character.DECIMAL_DIGIT_NUMBER && fd.field != Calendar.AM_PM ) { - o = '#'; - if ( m != '*' && p < inputMask.length() ) { - o = inputCache.charAt(p); - inputCache.setCharAt(p, c); - } else if ( fd.curLen < fd.maxLen ) { - inputCache.insert(p, c); - inputMask.insert(p, inputMask.charAt(fd.pos)); - fd.curLen++; - } else { - beep(); - return p; - } - if ( ! updateFieldValue(fd, true) ) { - if ( o != '#' ) { - inputCache.setCharAt(p, o); - } else { - inputCache.deleteCharAt(p); - inputMask.deleteCharAt(p); - fd.curLen--; - } - beep(); - return p; - } - i++; - p++; - } else if ( fd.field == Calendar.AM_PM - && (t == Character.UPPERCASE_LETTER - || t == Character.LOWERCASE_LETTER) ) { - String[] ampm = sdfDisplay.getDateFormatSymbols().getAmPmStrings(); - if ( Character.toLowerCase(c) == Character.toLowerCase(ampm[0].charAt(0)) ) { - t = 0; - } else if ( Character.toLowerCase(c) == Character.toLowerCase(ampm[1].charAt(0)) ) { - t = 1; - } else { - beep(); - return p; - } - inputCache.replace(fd.pos, fd.pos + fd.curLen, ampm[t]); - while ( fd.curLen < ampm[t].length() ) { - inputMask.insert(p, m); - fd.curLen++; - } - while ( fd.curLen > ampm[t].length() ) { - inputMask.deleteCharAt(p); - fd.curLen--; - } - updateFieldValue(fd, false); - i++; - p = fd.pos + fd.curLen; - } else { - t = fd.pos + fd.curLen; - if ( t < inputCache.length() && c == inputCache.charAt(t) && i == txt.length() - 1 ) { - p = getNextFieldPos(fd); - } else { - beep(); - } - return p; - } - } - if ( fd != null && p == fd.pos + fd.curLen && fd.curLen == fd.maxLen ) { - p = getNextFieldPos(fd); - } - return p; - } - - /** - * Returns true if current edited value is empty, else returns - * false.
- * For a datetime, the value is considered empty if each field composing the - * datetime pattern contains an empty string. - * - * @return true if empty, else false - */ - public boolean isEmpty() { - for (int i = 0; i < fieldCount; i++) { - if ( ! fields[i].empty ) return false; - } - return true; - } - - /** - * Returns true if current edited value is valid, else returns - * false. An empty value is considered as invalid. - * - * @return true if valid, else false - * @see ITextFormatter#isValid() - */ - public boolean isValid() { - return countValid() == fieldCount; - } - - /** - * Checks if a given char is valid for the edit pattern. This method must be - * override to restrict the edit pattern in subclasses. - * - * @param c pattern char - * @throws IllegalArgumentException if not valid - */ - protected void isValidCharPattern(char c) { - switch (c) { - case 'D' : - case 'G' : - case 'w' : - case 'W' : - case 'F' : - case 'E' : - case 'k' : - case 'K' : - case 'z' : - case 'Z' : - throw new IllegalArgumentException("Invalid datetime pattern"); - } - } - - /** - * Searches the current start position and length of a given field, starting - * search to the given index. - * - * @param f field descriptor - * @param from index to begin to search - */ - private void locateField(FieldDesc f, int from) { - while ( inputMask.charAt(from) != f.index ) { - from++; - } - f.pos = from; - - int l = from + 1; - while ( l < inputMask.length() && inputMask.charAt(l) == f.index ) { - l++; - } - f.curLen = l - from; - } - - /** - * Returns the start position in cache of the next field of a given field. - * - * @param f field descriptor - * @return start position of next field - */ - private int getNextFieldPos(FieldDesc f) { - int p = f.pos + f.curLen; - while ( p < inputMask.length() && inputMask.charAt(p) == '*' ) { - p++; - } - return p; - } - - /** - * Resets the full content of the input cache, based on input mask, fields - * descriptors and current value of the calendar. - */ - private void setInputCache() { - int l = inputCache.length(); - for (int i = 0; i < l; i++) { - char c = inputMask.charAt(i); - if ( c == '*' ) { - continue; - } - int j = i; - while ( j < l - 1 && inputMask.charAt(j + 1) == c ) { - j++; - } - FieldDesc f = fields[c - '0']; - String value = getFormattedValue(f); - inputCache.replace(i, j + 1, value); - i = ajustMask(i, j, value.length()); - l = inputCache.length(); - } - } - - /** - * Sets a new Locale on this formatter. - * - * @param loc locale - */ - public void setLocale(Locale loc) { - sdfDisplay.setDateFormatSymbols(new DateFormatSymbols(loc)); - Calendar newCal = Calendar.getInstance(calendar.getTimeZone(), loc); - newCal.setTimeInMillis(0); - for (int i = 0; i < fieldCount; i++) { - if ( fields[i].valid ) { - newCal.set(fields[i].field, calendar.get(fields[i].field)); - } else { - newCal.clear(fields[i].field); - } - } - calendar = newCal; - locale = loc; - } - - /** - * Sets the Text widget that will be managed by this formatter.

- * - * The ancestor is override to add a key listener on the text widget. - * - * @param text Text widget - * @see ITextFormatter#setText(Text) - */ - public void setText(Text text) { - super.setText(text); - text.addKeyListener(klistener); - text.addFocusListener(flistener); - } - - /** - * Sets the time zone with the given time zone value. The time zone is applied - * to both the Calendar used as value cache, and the - * SimpleDateFormat used for display mask. - * - * @param zone Time zone - */ - public void setTimeZone(TimeZone zone) { - if ( zone == null ) SWT.error(SWT.ERROR_NULL_ARGUMENT); - sdfDisplay.setTimeZone(zone); - calendar.setTimeZone(zone); - } - - /** - * Sets the value to edit. The value provided must be a Date. - * - * @param value date value - * @throws IllegalArgumentException if not a date - * @see ITextFormatter#setValue(java.lang.Object) - */ - public void setValue(Object value) { - if ( value instanceof Date ) { - if ( value != null ) { - calendar.setTime((Date) value); - } - for (int i = 0; i < fieldCount; i++) { - fields[i].valid = (value != null); - fields[i].empty = ! fields[i].valid; - } - setInputCache(); - } else if ( value == null ) { - clear(0, inputCache.length()); - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - - /** - * Update a calendar field with the current value string of the given field - * in the input cache. The string value is converted according to the field - * type. If the conversion is invalid, or if the value is out of the field - * limits, it is rejected. Else the corresponding field is updated in the - * calendar. - * - * If the checkLimits flag is set to true, we try to replace the last digit - * of the field by 0 (if over max) or a 1 (if under min). If the resulting - * value is valid, then the input cache is updated. - * - * @param f field descriptor - * @param checkLimits true to check limits, else false - * @return true if calendar has been updated, false if value is rejected - */ - private boolean updateFieldValue(FieldDesc f, boolean checkLimits) { - String s = inputCache.substring(f.pos, f.pos + f.curLen).trim(); - f.empty = false; - if ( s.length() == 0 || s.indexOf(SPACE) >= 0 ) { - calendar.clear(f.field); - f.empty = true; - f.valid = false; - } else if ( f.field == Calendar.AM_PM ) { - calendar.set(f.field, sdfDisplay.getDateFormatSymbols().// - getAmPmStrings()[0].equals(s) ? 0 : 1); - f.valid = true; - } else { - int v = 0; - try { - v = nf.parse(s).intValue(); - } catch (ParseException e) { - e.printStackTrace(System.err); - } - if ( v == 0 && f.field <= Calendar.DAY_OF_MONTH && s.length() < f.maxLen) { - calendar.clear(f.field); - f.valid = false; - } else { - if ( f.field == Calendar.YEAR && f.maxLen <= 2 ) { - v += v >= yearStart ? 1900 : 2000; - } else if ( f.field == Calendar.HOUR && v == 12 ) { - v = 0; - } - - int min = calendar.getActualMinimum(f.field); - int max = calendar.getActualMaximum(f.field); - if ( f.field == Calendar.MONTH ) { - min++; - max++; - } - if ( v < min || v > max ) { - if ( ! checkLimits ) { - return false; - } - if ( v > max ) { - v = (v / 10) * 10; - if ( v > max ) { - return false; - } - inputCache.setCharAt(f.pos + f.curLen - 1, '0'); - } else if ( f.curLen == f.maxLen ) { - v = (v / 10) * 10 + 1; - if ( v < min ) { - return false; - } - inputCache.setCharAt(f.pos + f.curLen - 1, '1'); - } - } - calendar.set(f.field, f.field == Calendar.MONTH ? v - 1 : v); - f.valid = true; - } - } - return true; - } - - /** - * Handles a VerifyEvent sent when the text is about to be modified. - * This method is the entry point of all operations of formatting. - * - * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) - */ - public void verifyText(VerifyEvent e) { - if (ignore) { - return; - } - e.doit = false; - if (e.keyCode == SWT.BS || e.keyCode == SWT.DEL) { - clear(e.start, e.end); - } else { - e.start = insert(e.text, e.start); - } - updateText(inputCache.toString(), e.start); - } -} +/******************************************************************************* + * Copyright (c) 2005, 2009 Eric Wuillai. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eric Wuillai (eric@wdev91.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.NumberFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Hashtable; +import java.util.Locale; +import java.util.TimeZone; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; + +/** + * This class provides formatting of Date values in a + * FormattedText. Supports a subset of date and time patterns + * defined in SimpleDateFormat for input.

+ * + *

Edit Patterns

+ * Edit patterns are composed of letters defining the parts of the mask, and + * characters defining the separators.

+ * The following pattern letters are defined: + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
LetterDate or Time PartExamples
yYear2006; 06
MMonth in year07
dDay in month10
HHour in day (0-23)0
hHour in am/pm (1-12)12
mMinute in hour30
sSecond in minute55
SMillisecond978
aAm/pm markerPM
+ *
+ * Edit patterns are limited to numeric formats (except am/pm marker). Variable + * length fields and separators composed of more than one character are + * supported for input. + * + *

Display Patterns

+ * Display patterns are associated to a SimpleDateFormat object. + * So they have to be compatible with it. + * + *

Examples

+ *
    + *
  • new DateTimeFormatter("MM/dd/yyyy") - 8 jul 2006 will edit + * and display as "07/08/2006".
  • + *
  • new DateTimeFormatter("d/M/yyyy H:m, "dd MMM yyyy HH:mm")- + * 8 jul 2006, 15:05 will edit as "8/7/2006 15:5" and display as + * "08 Jul 2006 15:05".
  • + *
+ */ +public class DateTimeFormatter extends AbstractFormatter { + /** Cache of patterns by locale ISO3 codes */ + protected static Hashtable cachedPatterns = new Hashtable<>(); + /** Numbers formatter */ + private static NumberFormat nf; + + /** Calendar containing the current value */ + protected Calendar calendar; + /** Date formatter for display */ + protected SimpleDateFormat sdfDisplay; + /** Input mask */ + protected StringBuffer inputMask; + /** Current edited value */ + protected StringBuffer inputCache; + /** Fields descriptions */ + protected FieldDesc[] fields; + /** Number of fields in edit pattern */ + protected int fieldCount; + /** Year limit for 2 digits year field */ + protected int yearStart; + /** Key listener on the Text widget */ + protected KeyListener klistener; + /** Focus listener on the Text widget */ + protected FocusListener flistener; + /** Filter for modify events */ + protected Listener modifyFilter; + /** The Locale used by this formatter */ + protected Locale locale; + + private class FieldDesc { + /** Time field in Calendar */ + int field; + /** Minimum length of the field in chars */ + int minLen; + /** Maximum length of the field in chars */ + int maxLen; + /** true if the field is empty, else false */ + boolean empty; + /** true if the field contains a valid value, else false */ + boolean valid; + char index; + + int pos; + int curLen; + } + + static { + nf = NumberFormat.getIntegerInstance(); + nf.setGroupingUsed(false); + } + + /** + * Constructs a new instance with all defaults : + *
    + *
  • edit mask in SHORT format for both date and time parts for the default locale
  • + *
  • display mask identical to the edit mask
  • + *
  • default locale
  • + *
+ */ + public DateTimeFormatter() { + this(null, null, Locale.getDefault()); + } + + /** + * Constructs a new instance with default edit and display masks for the given + * locale. + * + * @param loc locale + */ + public DateTimeFormatter(Locale loc) { + this(null, null, loc); + } + + /** + * Constructs a new instance with the given edit mask. Display mask is + * identical to the edit mask, and locale is the default one. + * + * @param editPattern edit mask + */ + public DateTimeFormatter(String editPattern) { + this(editPattern, null, Locale.getDefault()); + } + + /** + * Constructs a new instance with the given edit mask and locale. Display mask + * is identical to the edit mask. + * + * @param editPattern edit mask + * @param loc locale + */ + public DateTimeFormatter(String editPattern, Locale loc) { + this(editPattern, null, loc); + } + + /** + * Constructs a new instance with the given edit and display masks. Uses the + * default locale. + * + * @param editPattern edit mask + * @param displayPattern display mask + */ + public DateTimeFormatter(String editPattern, String displayPattern) { + this(editPattern, displayPattern, Locale.getDefault()); + } + + /** + * Constructs a new instance with the given masks and locale. + * + * @param editPattern edit mask + * @param displayPattern display mask + * @param loc locale + */ + public DateTimeFormatter(String editPattern, String displayPattern, Locale loc) { + // Set the default value + calendar = Calendar.getInstance(loc); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + // Creates the formatter for the edit value + if ( editPattern == null ) { + editPattern = getDefaultEditPattern(loc); + } + compile(editPattern); + + // Creates the formatter for the display value + if ( displayPattern == null ) { + displayPattern = editPattern; + } + sdfDisplay = new SimpleDateFormat(displayPattern, loc); + if ( yearStart == -1 ) { + calendar.setTime(sdfDisplay.get2DigitYearStart()); + yearStart = calendar.get(Calendar.YEAR) % 100; + } + locale = loc; + + // Instantiate the key listener + klistener = new KeyListener() { + public void keyPressed(KeyEvent e) { + if ( e.stateMask != 0 ) return; + switch ( e.keyCode ) { + case SWT.ARROW_UP : + arrow(1); + break; + case SWT.ARROW_DOWN : + arrow(-1); + break; + default : + return; + } + e.doit = false; + } + + public void keyReleased(KeyEvent e) { + } + }; + + // Instantiate the focus listener + flistener = new FocusListener() { + String lastInput; + public void focusGained(FocusEvent e) { + int p = text.getCaretPosition(); + setInputCache(); + String t = inputCache.toString(); + if ( ! t.equals(lastInput ) ) { + Display display = text.getDisplay(); + try { + display.addFilter(SWT.Modify, modifyFilter); + updateText(inputCache.toString(), p); + } finally { + display.removeFilter(SWT.Modify, modifyFilter); + } + } + } + + public void focusLost(FocusEvent e) { + if ( text != null ) { + lastInput = text.getText(); + } + } + }; + + modifyFilter = new Listener() { + public void handleEvent(Event event) { + event.type = SWT.None; + } + }; + } + + /** + * Adjust a field length in the mask to a given length. + * + * @param b begin position (inclusive) + * @param e end position (exclusive) + * @param l new length + * @return new end position + */ + private int ajustMask(int b, int e, int l) { + char c = inputMask.charAt(b); + while ( e - b + 1 < l ) { + inputMask.insert(e++, c); + } + while ( e - b + 1 > l ) { + inputMask.deleteCharAt(e--); + } + return e; + } + + /** + * Executes the increment or decrement of the date value when an arrow UP or + * DOWN is pressed.
+ * The calendar field at the position of cursor is incremented / decremented. + * If the field value exceeds its range, the next larger field is incremented + * or decremented and the field value is adjusted back into its range.

+ * + * If the calendar is empty, it is initialized with the current date. In these + * case, the arrow is ignored. + * + * @param inc +1 for increment, -1 for decrement + */ + private void arrow(int inc) { + int p = text.getCaretPosition(); + int l = inputMask.length(); + if ( p == l ) return; + char m = inputMask.charAt(p); + if ( m == '*' ) return; + FieldDesc f = getField(p, 0); + int b = f.pos; + if ( countValid() == 0 ) { + setValue(new Date()); + } else if ( f.field == Calendar.YEAR && f.maxLen <= 2 ) { + int year = calendar.get(Calendar.YEAR) % 100 + inc; + year += year >= yearStart ? 1900 : 2000; + calendar.set(f.field, year); + } else { + calendar.add(f.field, inc); + } + setInputCache(); + locateField(f, 0); + ignore = true; + updateText(inputCache.toString(), + Math.min(f.pos + p - b, f.pos + f.curLen - 1)); + ignore = false; + } + + /** + * Clear a part of the input cache.
+ * Characters are replaced by spaces in the fields, but separators are + * preserved. + * + * @param b beginning index (inclusive) + * @param e end index (exclusive) + */ + private void clear(int b, int e) { + char m; + int i = b, from = 0; + FieldDesc field; + + while ( i < e ) { + m = inputMask.charAt(i); + if ( m == '*' ) { + from = ++i; + continue; + } + field = getField(i, from); + final int numCharsLeftOfRangeToClear= i-field.pos; + while ( i < e && field.curLen - numCharsLeftOfRangeToClear > 0 ) { + inputCache.deleteCharAt(i); + inputMask.deleteCharAt(i); + e--; + field.curLen--; + } + while ( field.curLen < field.minLen ) { + inputCache.insert(field.pos + field.curLen, SPACE); + inputMask.insert(field.pos + field.curLen, field.index); + i++; + e++; + field.curLen++; + } + updateFieldValue(field, false); + } + } + + /** + * Compiles a given edit pattern, initializing inputMask and + * inputCache. The content of the edit pattern is analyzed char + * by char and the array of field descriptors is initialized. + * Pattern chars allowed are : y, M, d, H, h, s, S, a. + * The presence of other pattern chars defined in SimpleDateFormat + * will raised an IllegalArgumentException. + * + * @param editPattern edit pattern + * @throws IllegalArgumentException pattern is invalid + */ + private void compile(String editPattern) { + inputMask = new StringBuffer(); + inputCache = new StringBuffer(); + fields = new FieldDesc[10]; + int fi = 0; + int length = editPattern.length(); + for (int i = 0; i < length; i++) { + char c = editPattern.charAt(i); + int l = 1; + while ( i < length - 1 && editPattern.charAt(i + 1) == c ) { + i++; + l++; + } + isValidCharPattern(c); + switch ( c ) { + case 'y' : // Year + fields[fi] = new FieldDesc(); + fields[fi].field = Calendar.YEAR; + fields[fi].minLen = fields[fi].maxLen = l <= 2 ? 2 : 4; + if ( fields[fi].maxLen == 2 ) { + yearStart = -1; + } + break; + case 'M' : // Month + fields[fi] = new FieldDesc(); + fields[fi].field = Calendar.MONTH; + fields[fi].minLen = Math.min(l, 2); + fields[fi].maxLen = 2; + break; + case 'd' : // Day in month + fields[fi] = new FieldDesc(); + fields[fi].field = Calendar.DAY_OF_MONTH; + fields[fi].minLen = Math.min(l, 2); + fields[fi].maxLen = 2; + break; + case 'H' : // Hour (0-23) + fields[fi] = new FieldDesc(); + fields[fi].field = Calendar.HOUR_OF_DAY; + fields[fi].minLen = Math.min(l, 2); + fields[fi].maxLen = 2; + break; + case 'h' : // Hour (1-12 AM-PM) + fields[fi] = new FieldDesc(); + fields[fi].field = Calendar.HOUR; + fields[fi].minLen = Math.min(l, 2); + fields[fi].maxLen = 2; + break; + case 'm' : // Minutes + fields[fi] = new FieldDesc(); + fields[fi].field = Calendar.MINUTE; + fields[fi].minLen = Math.min(l, 2); + fields[fi].maxLen = 2; + break; + case 's' : // Seconds + fields[fi] = new FieldDesc(); + fields[fi].field = Calendar.SECOND; + fields[fi].minLen = Math.min(l, 2); + fields[fi].maxLen = 2; + break; + case 'S' : // Milliseconds + fields[fi] = new FieldDesc(); + fields[fi].field = Calendar.MILLISECOND; + fields[fi].minLen = Math.min(l, 3); + fields[fi].maxLen = 3; + break; + case 'a' : // AM-PM marker + fields[fi] = new FieldDesc(); + fields[fi].field = Calendar.AM_PM; + fields[fi].minLen = fields[fi].maxLen = 2; + break; + default : + for (int j = 0; j < l; j++) { + inputMask.append('*'); + inputCache.append(c); + } + continue; + } + fields[fi].empty = true; + fields[fi].valid = false; + calendar.clear(fields[fi].field); + char k = (char) ('0' + fi); + for (int j = 0; j < fields[fi].minLen; j++) { + inputMask.append(k); + inputCache.append(SPACE); + } + fields[fi].index = k; + fi++; + } + fieldCount = fi; + } + + /** + * Returns the count of valid fields. Value returned is between 0 and + * fieldcount. + * + * @return Count of valid fields + */ + private int countValid() { + int count = 0; + for (int i = 0; i < fieldCount; i++) { + if ( fields[i].valid ) count++; + } + return count; + } + + /** + * Called when the formatter is replaced by an other one in the FormattedText + * control. Allow to release resources like additional listeners.

+ * + * Removes the KeyListener on the text widget. + * + * @see ITextFormatter#detach() + */ + public void detach() { + text.removeKeyListener(klistener); + text.removeFocusListener(flistener); + } + + /** + * Returns the default edit pattern for the given Locale.

+ * + * A DateFormat object is instantiated with SHORT format for + * both date and time parts for the given locale. The corresponding pattern + * string is then retrieved by calling the toPattern.

+ * + * Default patterns are stored in a cache with ISO3 language and country codes + * as key. So they are computed only once by locale. + * + * @param loc locale + * @return edit pattern for the locale + */ + public String getDefaultEditPattern(Locale loc) { + if ( loc == null ) { + loc = Locale.getDefault(); + } + String key = "DT" + loc.toString(); + String pattern = cachedPatterns.get(key); + if ( pattern == null ) { + DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, loc); + if ( ! (df instanceof SimpleDateFormat) ) { + throw new IllegalArgumentException("No default pattern for locale " + loc.getDisplayName()); + } + StringBuffer buffer = new StringBuffer(); + buffer.append(((SimpleDateFormat) df).toPattern()); + int i; + if ( buffer.indexOf("yyy") < 0 && (i = buffer.indexOf("yy")) >= 0 ) { + buffer.insert(i, "yy"); + } + pattern = buffer.toString(); + cachedPatterns.put(key, pattern); + } + return pattern; + } + + /** + * Returns the current value formatted for display. + * This method is called by FormattedText when the Text + * widget looses focus. + * The displayed value is the result of formatting on the calendar + * with a SimpleDateFormat for the display pattern passed in + * constructor. In case the input is invalid (eg. blanks fields), the edit + * string is returned in place of the display string. + * + * @return display string if valid, edit string else + * @see ITextFormatter#getDisplayString() + */ + public String getDisplayString() { + return isValid() ? sdfDisplay.format(calendar.getTime()) : getEditString(); + } + + /** + * Returns the current value formatted for input. + * This method is called by FormattedText when the Text + * widget gains focus. + * The value returned is the content of the StringBuilder used as cache. + * + * @return edit string + * @see ITextFormatter#getEditString() + */ + public String getEditString() { + return inputCache.toString(); + } + + /** + * Returns the field descriptor corresponding to a given position in the + * inputMask. The current starting position and length of the + * field are set in the descriptor. + * + * @param p position in mask of the field + * @param from starting position in mask to search for the beginning of the field + * @return Field descriptor + */ + private FieldDesc getField(int p, int from) { + FieldDesc f; + + if ( p >= inputMask.length() ) { + p = inputMask.length() - 1; + } + char c = inputMask.charAt(p); + while ( c == '*' ) { + p--; + if ( p < 0 ) { + return null; + } + c = inputMask.charAt(p); + } + f = fields[c - '0']; + locateField(f, from); + + return f; + } + + /** + * Returns a string representing the current value of a given field based on + * the content of the calendar. + * + * @param f field descriptor + * @return formatted value of field + */ + private String getFormattedValue(FieldDesc f) { + StringBuffer value = new StringBuffer(); + if ( f.valid ) { + int v = calendar.get(f.field); + switch ( f.field ) { + case Calendar.MONTH : + v++; + break; + case Calendar.HOUR : + if ( v == 0 ) v = 12; + break; + case Calendar.AM_PM : + return sdfDisplay.getDateFormatSymbols().getAmPmStrings()[v]; + default: + break; + } + value.append(v); + if ( value.length() > f.maxLen ) { + value.delete(0, value.length() - f.maxLen); + } else while ( value.length() < f.minLen ) { + value.insert(0, '0'); + } + } else { + while ( value.length() < f.minLen ) { + value.append(SPACE); + } + } + return value.toString(); + } + + /** + * Returns the current Locale used by this formatter. + * + * @return Current Locale used + */ + public Locale getLocale() { + return locale; + } + + /** + * Returns the current value of the text control if it is a valid + * Date.
+ * The date is valid if all the input fields are set. If invalid, returns + * null. + * + * @return current date value if valid, null else + * @see ITextFormatter#getValue() + */ + public Object getValue() { + return isValid() ? calendar.getTime() : null; + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * A DateTimeFormatter always returns a Date value. + * + * @return The value type. + */ + public Class getValueType() { + return Date.class; + } + + /** + * Inserts a sequence of characters in the input buffer. The current content + * of the buffer is override. The new position of the cursor is computed and + * returned. + * + * @param txt String of characters to insert + * @param p Starting position of insertion + * @return New position of the cursor + */ + private int insert(String txt, int p) { + FieldDesc fd = null; + int i = 0, from = 0, t; + char c, m, o; + while ( i < txt.length() ) { + c = txt.charAt(i); + if ( p < inputMask.length() ) { + m = inputMask.charAt(p); + if ( m == '*' && inputCache.charAt(p) == c ) { + from = p; + i++; + p++; + fd = null; + continue; + } + } else { + m = inputMask.charAt(inputMask.length() - 1); + } + if ( fd == null ) { + fd = getField(p, from); + for (int j = fd.pos; j < p; j++) { + if ( inputCache.charAt(j) == SPACE ) { + inputCache.setCharAt(j, '0'); + } + } + } + t = Character.getType(c); + if ( t == Character.DECIMAL_DIGIT_NUMBER && fd.field != Calendar.AM_PM ) { + o = '#'; + if ( m != '*' && p < inputMask.length() ) { + o = inputCache.charAt(p); + inputCache.setCharAt(p, c); + } else if ( fd.curLen < fd.maxLen ) { + inputCache.insert(p, c); + inputMask.insert(p, inputMask.charAt(fd.pos)); + fd.curLen++; + } else { + beep(); + return p; + } + if ( ! updateFieldValue(fd, true) ) { + if ( o != '#' ) { + inputCache.setCharAt(p, o); + } else { + inputCache.deleteCharAt(p); + inputMask.deleteCharAt(p); + fd.curLen--; + } + beep(); + return p; + } + i++; + p++; + } else if ( fd.field == Calendar.AM_PM + && (t == Character.UPPERCASE_LETTER + || t == Character.LOWERCASE_LETTER) ) { + String[] ampm = sdfDisplay.getDateFormatSymbols().getAmPmStrings(); + if ( Character.toLowerCase(c) == Character.toLowerCase(ampm[0].charAt(0)) ) { + t = 0; + } else if ( Character.toLowerCase(c) == Character.toLowerCase(ampm[1].charAt(0)) ) { + t = 1; + } else { + beep(); + return p; + } + inputCache.replace(fd.pos, fd.pos + fd.curLen, ampm[t]); + while ( fd.curLen < ampm[t].length() ) { + inputMask.insert(p, m); + fd.curLen++; + } + while ( fd.curLen > ampm[t].length() ) { + inputMask.deleteCharAt(p); + fd.curLen--; + } + updateFieldValue(fd, false); + i++; + p = fd.pos + fd.curLen; + } else { + t = fd.pos + fd.curLen; + if ( t < inputCache.length() && c == inputCache.charAt(t) && i == txt.length() - 1 ) { + p = getNextFieldPos(fd); + } else { + beep(); + } + return p; + } + } + if ( fd != null && p == fd.pos + fd.curLen && fd.curLen == fd.maxLen ) { + p = getNextFieldPos(fd); + } + return p; + } + + /** + * Returns true if current edited value is empty, else returns + * false.
+ * For a datetime, the value is considered empty if each field composing the + * datetime pattern contains an empty string. + * + * @return true if empty, else false + */ + public boolean isEmpty() { + for (int i = 0; i < fieldCount; i++) { + if ( ! fields[i].empty ) return false; + } + return true; + } + + /** + * Returns true if current edited value is valid, else returns + * false. An empty value is considered as invalid. + * + * @return true if valid, else false + * @see ITextFormatter#isValid() + */ + public boolean isValid() { + return countValid() == fieldCount; + } + + /** + * Checks if a given char is valid for the edit pattern. This method must be + * override to restrict the edit pattern in subclasses. + * + * @param c pattern char + * @throws IllegalArgumentException if not valid + */ + protected void isValidCharPattern(char c) { + switch (c) { + case 'D' : + case 'G' : + case 'w' : + case 'W' : + case 'F' : + case 'E' : + case 'k' : + case 'K' : + case 'z' : + case 'Z' : + throw new IllegalArgumentException("Invalid datetime pattern"); + } + } + + /** + * Searches the current start position and length of a given field, starting + * search to the given index. + * + * @param f field descriptor + * @param from index to begin to search + */ + private void locateField(FieldDesc f, int from) { + while ( inputMask.charAt(from) != f.index ) { + from++; + } + f.pos = from; + + int l = from + 1; + while ( l < inputMask.length() && inputMask.charAt(l) == f.index ) { + l++; + } + f.curLen = l - from; + } + + /** + * Returns the start position in cache of the next field of a given field. + * + * @param f field descriptor + * @return start position of next field + */ + private int getNextFieldPos(FieldDesc f) { + int p = f.pos + f.curLen; + while ( p < inputMask.length() && inputMask.charAt(p) == '*' ) { + p++; + } + return p; + } + + /** + * Resets the full content of the input cache, based on input mask, fields + * descriptors and current value of the calendar. + */ + private void setInputCache() { + int l = inputCache.length(); + for (int i = 0; i < l; i++) { + char c = inputMask.charAt(i); + if ( c == '*' ) { + continue; + } + int j = i; + while ( j < l - 1 && inputMask.charAt(j + 1) == c ) { + j++; + } + FieldDesc f = fields[c - '0']; + String value = getFormattedValue(f); + inputCache.replace(i, j + 1, value); + i = ajustMask(i, j, value.length()); + l = inputCache.length(); + } + } + + /** + * Sets a new Locale on this formatter. + * + * @param loc locale + */ + public void setLocale(Locale loc) { + sdfDisplay.setDateFormatSymbols(new DateFormatSymbols(loc)); + Calendar newCal = Calendar.getInstance(calendar.getTimeZone(), loc); + newCal.setTimeInMillis(0); + for (int i = 0; i < fieldCount; i++) { + if ( fields[i].valid ) { + newCal.set(fields[i].field, calendar.get(fields[i].field)); + } else { + newCal.clear(fields[i].field); + } + } + calendar = newCal; + locale = loc; + } + + /** + * Sets the Text widget that will be managed by this formatter.

+ * + * The ancestor is override to add a key listener on the text widget. + * + * @param text Text widget + * @see ITextFormatter#setText(Text) + */ + public void setText(Text text) { + super.setText(text); + text.addKeyListener(klistener); + text.addFocusListener(flistener); + } + + /** + * Sets the time zone with the given time zone value. The time zone is applied + * to both the Calendar used as value cache, and the + * SimpleDateFormat used for display mask. + * + * @param zone Time zone + */ + public void setTimeZone(TimeZone zone) { + if ( zone == null ) SWT.error(SWT.ERROR_NULL_ARGUMENT); + sdfDisplay.setTimeZone(zone); + calendar.setTimeZone(zone); + } + + /** + * Sets the value to edit. The value provided must be a Date. + * + * @param value date value + * @throws IllegalArgumentException if not a date + * @see ITextFormatter#setValue(java.lang.Object) + */ + public void setValue(Object value) { + if ( value instanceof Date ) { + if ( value != null ) { + calendar.setTime((Date) value); + } + for (int i = 0; i < fieldCount; i++) { + fields[i].valid = (value != null); + fields[i].empty = ! fields[i].valid; + } + setInputCache(); + } else if ( value == null ) { + clear(0, inputCache.length()); + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + + /** + * Update a calendar field with the current value string of the given field + * in the input cache. The string value is converted according to the field + * type. If the conversion is invalid, or if the value is out of the field + * limits, it is rejected. Else the corresponding field is updated in the + * calendar. + * + * If the checkLimits flag is set to true, we try to replace the last digit + * of the field by 0 (if over max) or a 1 (if under min). If the resulting + * value is valid, then the input cache is updated. + * + * @param f field descriptor + * @param checkLimits true to check limits, else false + * @return true if calendar has been updated, false if value is rejected + */ + private boolean updateFieldValue(FieldDesc f, boolean checkLimits) { + String s = inputCache.substring(f.pos, f.pos + f.curLen).trim(); + f.empty = false; + if ( s.length() == 0 || s.indexOf(SPACE) >= 0 ) { + calendar.clear(f.field); + f.empty = true; + f.valid = false; + } else if ( f.field == Calendar.AM_PM ) { + calendar.set(f.field, sdfDisplay.getDateFormatSymbols().// + getAmPmStrings()[0].equals(s) ? 0 : 1); + f.valid = true; + } else { + int v = 0; + try { + v = nf.parse(s).intValue(); + } catch (ParseException e) { + e.printStackTrace(System.err); + } + if ( v == 0 && f.field <= Calendar.DAY_OF_MONTH && s.length() < f.maxLen) { + calendar.clear(f.field); + f.valid = false; + } else { + if ( f.field == Calendar.YEAR && f.maxLen <= 2 ) { + v += v >= yearStart ? 1900 : 2000; + } else if ( f.field == Calendar.HOUR && v == 12 ) { + v = 0; + } + + int min = calendar.getActualMinimum(f.field); + int max = calendar.getActualMaximum(f.field); + if ( f.field == Calendar.MONTH ) { + min++; + max++; + } + if ( v < min || v > max ) { + if ( ! checkLimits ) { + return false; + } + if ( v > max ) { + v = (v / 10) * 10; + if ( v > max ) { + return false; + } + inputCache.setCharAt(f.pos + f.curLen - 1, '0'); + } else if ( f.curLen == f.maxLen ) { + v = (v / 10) * 10 + 1; + if ( v < min ) { + return false; + } + inputCache.setCharAt(f.pos + f.curLen - 1, '1'); + } + } + calendar.set(f.field, f.field == Calendar.MONTH ? v - 1 : v); + f.valid = true; + } + } + return true; + } + + /** + * Handles a VerifyEvent sent when the text is about to be modified. + * This method is the entry point of all operations of formatting. + * + * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) + */ + public void verifyText(VerifyEvent e) { + if (ignore) { + return; + } + e.doit = false; + if (e.keyCode == SWT.BS || e.keyCode == SWT.DEL) { + clear(e.start, e.end); + } else { + e.start = insert(e.text, e.start); + } + updateText(inputCache.toString(), e.start); + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DefaultFormatterFactory.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DefaultFormatterFactory.java index f131b781d..f8bf5e7fb 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DefaultFormatterFactory.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DefaultFormatterFactory.java @@ -1,114 +1,114 @@ -/******************************************************************************* - * Copyright (c) 2005, 2009 Eric Wuillai. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Eric Wuillai (eric@wdev91.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; - -import org.eclipse.swt.SWT; - -/** - * Factory for the default formatters.

- * - * This factory is called by FormattedText when a value is setted - * and no formatter has been provided by constructor or setFormatter(). - * The default formatter is based on the class of the value. The cache is - * searched first for the exact value's class. If no formatter is found, then - * it is searched for any class that is an ancestor of the value's class. - * The cache is a HashMap and the order of search cannot be - * garanteed. The first valid ancestor found is returned.

- * - * Default formatters provided by the factory are: - *

    - *
  • DateFormatter for Date values
  • - *
  • NumberFormatter for Number values
  • - *
- * - * Other formatters can be added with the register() method. Each - * formatter class must implement ITextFormatter and must have a - * default constructor.

- * - * This class is not intended to be instanciated. - */ -public abstract class DefaultFormatterFactory { - /** Cache of default formatter classes */ - private static HashMap, Class> formatters; - - static { - formatters = new HashMap<>(); - formatters.put(String.class, StringFormatter.class); - formatters.put(Date.class, DateFormatter.class); - formatters.put(Number.class, NumberFormatter.class); - } - - private DefaultFormatterFactory() { - } - - /** - * Creates a new default formatter for the given value. The formatter is based - * on the value's class. - * - * @param value Value for which to create a formatter - * @return New formatter corresponding to the value's class, or null if the - * class is unknown. - */ - public static ITextFormatter createFormatter(Object value) { - return createFormatter(value.getClass()); - } - - /** - * Creates a new default formatter for the given class. - * - * @param c Class for which to create a formatter - * @return New formatter corresponding to the class, or null if the class is unknown. - */ - public static ITextFormatter createFormatter(Class c) { - ITextFormatter f = null; - Class fc = formatters.get(c); - if ( fc == null ) { - for (Iterator> it = formatters.keySet().iterator(); it.hasNext(); ) { - Class k = it.next(); - if ( k.isAssignableFrom(c) - && (fc == null || fc.isAssignableFrom(k)) ) { - fc = formatters.get(k); - } - } - } - - if ( fc != null ) { - try { - f = (ITextFormatter) fc.newInstance(); - } catch (Exception e) { - e.printStackTrace(); - } - } - return f; - } - - /** - * Registers a new formatter class for a given class of values. The formatter - * class must implement the ITextFormatter interface. - * - * @param c Class of values - * @param f Class of the formatter - */ - public static void register(Class c, Class f) { - if ( c == null ) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if ( ! ITextFormatter.class.isAssignableFrom(f) ) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, "Must be an ITextFormatter"); //$NON-NLS-1$ - } - formatters.put(c, f); - } -} +/******************************************************************************* + * Copyright (c) 2005, 2009 Eric Wuillai. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eric Wuillai (eric@wdev91.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.swt.SWT; + +/** + * Factory for the default formatters.

+ * + * This factory is called by FormattedText when a value is setted + * and no formatter has been provided by constructor or setFormatter(). + * The default formatter is based on the class of the value. The cache is + * searched first for the exact value's class. If no formatter is found, then + * it is searched for any class that is an ancestor of the value's class. + * The cache is a HashMap and the order of search cannot be + * garanteed. The first valid ancestor found is returned.

+ * + * Default formatters provided by the factory are: + *

    + *
  • DateFormatter for Date values
  • + *
  • NumberFormatter for Number values
  • + *
+ * + * Other formatters can be added with the register() method. Each + * formatter class must implement ITextFormatter and must have a + * default constructor.

+ * + * This class is not intended to be instanciated. + */ +public abstract class DefaultFormatterFactory { + /** Cache of default formatter classes */ + private static HashMap, Class> formatters; + + static { + formatters = new HashMap<>(); + formatters.put(String.class, StringFormatter.class); + formatters.put(Date.class, DateFormatter.class); + formatters.put(Number.class, NumberFormatter.class); + } + + private DefaultFormatterFactory() { + } + + /** + * Creates a new default formatter for the given value. The formatter is based + * on the value's class. + * + * @param value Value for which to create a formatter + * @return New formatter corresponding to the value's class, or null if the + * class is unknown. + */ + public static ITextFormatter createFormatter(Object value) { + return createFormatter(value.getClass()); + } + + /** + * Creates a new default formatter for the given class. + * + * @param c Class for which to create a formatter + * @return New formatter corresponding to the class, or null if the class is unknown. + */ + public static ITextFormatter createFormatter(Class c) { + ITextFormatter f = null; + Class fc = formatters.get(c); + if ( fc == null ) { + for (Iterator> it = formatters.keySet().iterator(); it.hasNext(); ) { + Class k = it.next(); + if ( k.isAssignableFrom(c) + && (fc == null || fc.isAssignableFrom(k)) ) { + fc = formatters.get(k); + } + } + } + + if ( fc != null ) { + try { + f = (ITextFormatter) fc.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return f; + } + + /** + * Registers a new formatter class for a given class of values. The formatter + * class must implement the ITextFormatter interface. + * + * @param c Class of values + * @param f Class of the formatter + */ + public static void register(Class c, Class f) { + if ( c == null ) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if ( ! ITextFormatter.class.isAssignableFrom(f) ) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, "Must be an ITextFormatter"); //$NON-NLS-1$ + } + formatters.put(c, f); + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DoubleFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DoubleFormatter.java index f0df9e6f8..7ec7feb48 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DoubleFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/DoubleFormatter.java @@ -1,65 +1,65 @@ -package org.eclipse.nebula.widgets.formattedtext; - -import java.util.Locale; - -/** - * This class provides formatting of Double values in a - * FormattedText.

- * - * NumberFormatter returns different numeric types based on the current - * value in the Text field. DoubleFormatter is an override of NumberFormatter - * allowing to guaranty to always return Double values (Number.doubleValue()). - */ -public class DoubleFormatter extends NumberFormatter { - public DoubleFormatter() { - super(); - } - - public DoubleFormatter(Locale loc) { - super(loc); - } - - public DoubleFormatter(String editPattern, Locale loc) { - super(editPattern, loc); - } - - public DoubleFormatter(String editPattern, String displayPattern, Locale loc) { - super(editPattern, displayPattern, loc); - } - - public DoubleFormatter(String editPattern, String displayPattern) { - super(editPattern, displayPattern); - } - - public DoubleFormatter(String editPattern) { - super(editPattern); - } - - /** - * Returns the current value of the text control if it is a valid Double. - * If the buffer is flagged as modified, the value is recalculated by parsing - * with the nfEdit initialized with the edit pattern. If the - * number is not valid, returns null. - * - * @return current number value if valid, null else - * @see ITextFormatter#getValue() - */ - public Object getValue() { - Object value = super.getValue(); - if ( value instanceof Number ) { - return new Double(((Number) value).doubleValue()); - } - return super.getValue(); - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * A DoubleFormatter always returns a Double value. - * - * @return The value type. - */ - public Class getValueType() { - return Double.class; - } -} +package org.eclipse.nebula.widgets.formattedtext; + +import java.util.Locale; + +/** + * This class provides formatting of Double values in a + * FormattedText.

+ * + * NumberFormatter returns different numeric types based on the current + * value in the Text field. DoubleFormatter is an override of NumberFormatter + * allowing to guaranty to always return Double values (Number.doubleValue()). + */ +public class DoubleFormatter extends NumberFormatter { + public DoubleFormatter() { + super(); + } + + public DoubleFormatter(Locale loc) { + super(loc); + } + + public DoubleFormatter(String editPattern, Locale loc) { + super(editPattern, loc); + } + + public DoubleFormatter(String editPattern, String displayPattern, Locale loc) { + super(editPattern, displayPattern, loc); + } + + public DoubleFormatter(String editPattern, String displayPattern) { + super(editPattern, displayPattern); + } + + public DoubleFormatter(String editPattern) { + super(editPattern); + } + + /** + * Returns the current value of the text control if it is a valid Double. + * If the buffer is flagged as modified, the value is recalculated by parsing + * with the nfEdit initialized with the edit pattern. If the + * number is not valid, returns null. + * + * @return current number value if valid, null else + * @see ITextFormatter#getValue() + */ + public Object getValue() { + Object value = super.getValue(); + if ( value instanceof Number ) { + return new Double(((Number) value).doubleValue()); + } + return super.getValue(); + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * A DoubleFormatter always returns a Double value. + * + * @return The value type. + */ + public Class getValueType() { + return Double.class; + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FloatFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FloatFormatter.java index cb2c9dfab..fbee5ad64 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FloatFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FloatFormatter.java @@ -1,65 +1,65 @@ -package org.eclipse.nebula.widgets.formattedtext; - -import java.util.Locale; - -/** - * This class provides formatting of Float values in a - * FormattedText.

- * - * NumberFormatter returns different numeric types based on the current - * value in the Text field. FloatFormatter is an override of NumberFormatter - * allowing to guaranty to always return Float values (Number.floatValue()). - */ -public class FloatFormatter extends NumberFormatter { - public FloatFormatter() { - super(); - } - - public FloatFormatter(Locale loc) { - super(loc); - } - - public FloatFormatter(String editPattern, Locale loc) { - super(editPattern, loc); - } - - public FloatFormatter(String editPattern, String displayPattern, Locale loc) { - super(editPattern, displayPattern, loc); - } - - public FloatFormatter(String editPattern, String displayPattern) { - super(editPattern, displayPattern); - } - - public FloatFormatter(String editPattern) { - super(editPattern); - } - - /** - * Returns the current value of the text control if it is a valid Float. - * If the buffer is flagged as modified, the value is recalculated by parsing - * with the nfEdit initialized with the edit pattern. If the - * number is not valid, returns null. - * - * @return current number value if valid, null else - * @see ITextFormatter#getValue() - */ - public Object getValue() { - Object value = super.getValue(); - if ( value instanceof Number ) { - return new Float(((Number) value).floatValue()); - } - return super.getValue(); - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * A FloatFormatter always returns a Float value. - * - * @return The value type. - */ - public Class getValueType() { - return Float.class; - } -} +package org.eclipse.nebula.widgets.formattedtext; + +import java.util.Locale; + +/** + * This class provides formatting of Float values in a + * FormattedText.

+ * + * NumberFormatter returns different numeric types based on the current + * value in the Text field. FloatFormatter is an override of NumberFormatter + * allowing to guaranty to always return Float values (Number.floatValue()). + */ +public class FloatFormatter extends NumberFormatter { + public FloatFormatter() { + super(); + } + + public FloatFormatter(Locale loc) { + super(loc); + } + + public FloatFormatter(String editPattern, Locale loc) { + super(editPattern, loc); + } + + public FloatFormatter(String editPattern, String displayPattern, Locale loc) { + super(editPattern, displayPattern, loc); + } + + public FloatFormatter(String editPattern, String displayPattern) { + super(editPattern, displayPattern); + } + + public FloatFormatter(String editPattern) { + super(editPattern); + } + + /** + * Returns the current value of the text control if it is a valid Float. + * If the buffer is flagged as modified, the value is recalculated by parsing + * with the nfEdit initialized with the edit pattern. If the + * number is not valid, returns null. + * + * @return current number value if valid, null else + * @see ITextFormatter#getValue() + */ + public Object getValue() { + Object value = super.getValue(); + if ( value instanceof Number ) { + return new Float(((Number) value).floatValue()); + } + return super.getValue(); + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * A FloatFormatter always returns a Float value. + * + * @return The value type. + */ + public Class getValueType() { + return Float.class; + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FormattedText.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FormattedText.java index 57fc734fe..715412eae 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FormattedText.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FormattedText.java @@ -1,287 +1,287 @@ -/******************************************************************************* - * Copyright (c) 2005, 2009 Eric Wuillai. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Eric Wuillai (eric@wdev91.com) - initial API and implementation - * Peter Schulz (eclipse-ps@kurzepost.de) - fix for bug 459484 - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; - -/** - * Formatted text viewer. Adds formatting capabilities to the Text - * widget of SWT. This control works on the same principle than the JFace - * viewers. The embedded text widget is accessible by the getControl() method, - * allowing to apply to it all necessary behaviors (layout, listeners...).

- * - * Formatting is delegated to formatter objects implementing the ITextFormatter - * interface. Each formatter class manages a base class of values (date, number...).
- * Formatters are associated by 2 different means : - *

    - *
  • By the setFormatter() method.
  • - *
  • When setValue() is called and there is currently no formatter, - * a new one is automatically created based on the class of the value.
  • - *
- * - *

Styles:

- *
- * CENTER, LEFT, RIGHT, READ_ONLY - *
- */ -public class FormattedText { - /** The key used to register the FormattedText in its Text widget data */ - public static final String TEXT_DATA_KEY = "formattedText"; - - /** Encapsulated Text widget */ - protected Text text; - /** Formatter */ - protected ITextFormatter formatter = null; - /** Save position of cursor when the focus is lost */ - protected int caretPos; - /** Layout */ - protected GridLayout layout; - /** Filter for modify events */ - protected Listener modifyFilter; - - /** Flag to activate or not beep sound on input errors */ - protected static boolean beepSound = true; - - protected static int count = 0; - protected int id = ++count; - - /** - * Creates a formatted text on a newly-created text control under the given - * parent. The text control is created using the SWT style bits - * BORDER. - * - * @param parent the parent control - */ - public FormattedText(Composite parent) { - this(parent, SWT.BORDER); - } - - /** - * Creates a formatted text on a newly-created text control under the given - * parent. The text control is created using the given SWT style bits. - * - * @param parent the parent control - * @param style the SWT style bits used to create the text - */ - public FormattedText(Composite parent, int style) { - this(new Text(parent, style & (~ (SWT.MULTI | SWT.PASSWORD | SWT.WRAP)))); - } - - /** - * Creates a formatted text on the given text control. - * - * @param t the text control - */ - public FormattedText(Text t) { - text = t; - text.setData(TEXT_DATA_KEY, this); - - text.addFocusListener(new FocusListener() { - public void focusGained(FocusEvent e) { - if ( formatter != null && text.getEditable() ) { - formatter.setIgnore(true); - setText(formatter.getEditString()); - text.setSelection(caretPos); - formatter.setIgnore(false); - } - } - - public void focusLost(FocusEvent e) { - if ( formatter != null && text.getEditable() ) { - formatter.setIgnore(true); - caretPos = text.getCaretPosition(); - String editString = formatter.getEditString(); - String displayString = formatter.getDisplayString(); - // Detect inconsistency between internal representation, - // for example, a date, and contents of the text control - if (!editString.equals(displayString)) { - // Update the formatter (caches) so it has a consistent state - formatter.setValue(formatter.getValue()); - } - setText(displayString); - formatter.setIgnore(false); - } - } - }); - - modifyFilter = new Listener() { - public void handleEvent(Event event) { - event.type = SWT.None; - } - }; - - text.addListener(SWT.Dispose, e -> { - text = null; - modifyFilter = null; - formatter = null; - }); - } - - /** - * Returns the primary Text control associated with this viewer. - * - * @return the SWT text control which displays this viewer's content - */ - public Text getControl() { - return text; - } - - /** - * Returns the formatter associated to the Text widget. - * - * @return Formatter, or null if no formatter is currently associated - */ - public ITextFormatter getFormatter() { - return formatter; - } - - /** - * Returns the current value of the widget.

- * - * The returned value is provided by the formatter and is of the type managed - * by the formatter. For example a DateFormatter will return a - * Date value.
- * If no formatter is associated, the String contained in the - * Text widget is returned. - * - * @return Current value - */ - public Object getValue() { - return formatter != null ? formatter.getValue() : text.getText(); - } - - /** - * Returns the type of value the {@link ITextFormatter} associated with this - * FormattedText handles, - * i.e. returns in {@link #getValue()}. - * - * @return The value type. - */ - public Class getValueType() { - return formatter != null ? formatter.getValueType() : String.class; - } - - /** - * Returns true if beep sound must be produced on input errors, else false. - * - * @return true / false - */ - public static boolean isBeepSound() { - return beepSound; - } - - /** - * Returns true if the current value is empty, else - * false.
- * An empty value depends of the formatter applied on the Text widget - * and is not just an empty String in the widget. Formatters can use special - * formatting characters to format the value. These characters are not - * always considered as part of the value. For example, in a DateFormatter - * the pattern uses "/" separator and always displays it in the input field. - * - * @return true if empty. - */ - public boolean isEmpty() { - return formatter != null ? formatter.isEmpty() : text.getText().length() == 0; - } - - /** - * Returns true if the current value is valid, else false. - * - * @return true if valid. - */ - public boolean isValid() { - return formatter != null ? formatter.isValid() : true; - } - - /** - * Set the beep sound to ON or OFF for all the FormattedText fields. Beep - * sound are produced by formatters on every input error. Formatter - * implementation must check this flag on before to emit a beep sound. - * - * @param beepSound true to emit beep sound on errors, else false - */ - public static void setBeepSound(boolean beepSound) { - FormattedText.beepSound = beepSound; - } - - /** - * Associates a formatter to the widget.
- * Parameter can not be null. In some situations, the FormattedText component - * must not do formatting (eg. when reusing the same object for editing of - * different types of values). In this case, use a StringFormatter. This - * formatter do no formatting. - * - * @param formatter formatter - */ - public void setFormatter(ITextFormatter formatter) { - if ( formatter == null ) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if ( this.formatter != null ) { - text.removeVerifyListener(this.formatter); - this.formatter.detach(); - } - this.formatter = formatter; - this.formatter.setText(text); - text.addVerifyListener(this.formatter); - formatter.setIgnore(true); - text.setText(formatter.getDisplayString()); - formatter.setIgnore(false); - } - - /** - * Sets the Text widget value, preventing fire of Modify events. - * - * @param value The String value to display in the widget - */ - private void setText(String value) { - Display display = text.getDisplay(); - try { - display.addFilter(SWT.Modify, modifyFilter); - text.setText(value); - } finally { - display.removeFilter(SWT.Modify, modifyFilter); - } - } - - /** - * Sets a new value.

- * - * If no formatter is currently associated to he widget, a new one is created - * by the factory based on the value's class.
- * If the value is incompatible with the formatter, an IllegalArgumentException - * is returned. - * - * @param value new value - */ - public void setValue(Object value) { - if ( formatter == null ) { - setFormatter(DefaultFormatterFactory.createFormatter(value)); - } - formatter.setValue(value); - formatter.setIgnore(true); - text.setText(text.isFocusControl() - ? formatter.getEditString() - : formatter.getDisplayString()); - formatter.setIgnore(false); - } -} +/******************************************************************************* + * Copyright (c) 2005, 2009 Eric Wuillai. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eric Wuillai (eric@wdev91.com) - initial API and implementation + * Peter Schulz (eclipse-ps@kurzepost.de) - fix for bug 459484 + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; + +/** + * Formatted text viewer. Adds formatting capabilities to the Text + * widget of SWT. This control works on the same principle than the JFace + * viewers. The embedded text widget is accessible by the getControl() method, + * allowing to apply to it all necessary behaviors (layout, listeners...).

+ * + * Formatting is delegated to formatter objects implementing the ITextFormatter + * interface. Each formatter class manages a base class of values (date, number...).
+ * Formatters are associated by 2 different means : + *

    + *
  • By the setFormatter() method.
  • + *
  • When setValue() is called and there is currently no formatter, + * a new one is automatically created based on the class of the value.
  • + *
+ * + *

Styles:

+ *
+ * CENTER, LEFT, RIGHT, READ_ONLY + *
+ */ +public class FormattedText { + /** The key used to register the FormattedText in its Text widget data */ + public static final String TEXT_DATA_KEY = "formattedText"; + + /** Encapsulated Text widget */ + protected Text text; + /** Formatter */ + protected ITextFormatter formatter = null; + /** Save position of cursor when the focus is lost */ + protected int caretPos; + /** Layout */ + protected GridLayout layout; + /** Filter for modify events */ + protected Listener modifyFilter; + + /** Flag to activate or not beep sound on input errors */ + protected static boolean beepSound = true; + + protected static int count = 0; + protected int id = ++count; + + /** + * Creates a formatted text on a newly-created text control under the given + * parent. The text control is created using the SWT style bits + * BORDER. + * + * @param parent the parent control + */ + public FormattedText(Composite parent) { + this(parent, SWT.BORDER); + } + + /** + * Creates a formatted text on a newly-created text control under the given + * parent. The text control is created using the given SWT style bits. + * + * @param parent the parent control + * @param style the SWT style bits used to create the text + */ + public FormattedText(Composite parent, int style) { + this(new Text(parent, style & (~ (SWT.MULTI | SWT.PASSWORD | SWT.WRAP)))); + } + + /** + * Creates a formatted text on the given text control. + * + * @param t the text control + */ + public FormattedText(Text t) { + text = t; + text.setData(TEXT_DATA_KEY, this); + + text.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent e) { + if ( formatter != null && text.getEditable() ) { + formatter.setIgnore(true); + setText(formatter.getEditString()); + text.setSelection(caretPos); + formatter.setIgnore(false); + } + } + + public void focusLost(FocusEvent e) { + if ( formatter != null && text.getEditable() ) { + formatter.setIgnore(true); + caretPos = text.getCaretPosition(); + String editString = formatter.getEditString(); + String displayString = formatter.getDisplayString(); + // Detect inconsistency between internal representation, + // for example, a date, and contents of the text control + if (!editString.equals(displayString)) { + // Update the formatter (caches) so it has a consistent state + formatter.setValue(formatter.getValue()); + } + setText(displayString); + formatter.setIgnore(false); + } + } + }); + + modifyFilter = new Listener() { + public void handleEvent(Event event) { + event.type = SWT.None; + } + }; + + text.addListener(SWT.Dispose, e -> { + text = null; + modifyFilter = null; + formatter = null; + }); + } + + /** + * Returns the primary Text control associated with this viewer. + * + * @return the SWT text control which displays this viewer's content + */ + public Text getControl() { + return text; + } + + /** + * Returns the formatter associated to the Text widget. + * + * @return Formatter, or null if no formatter is currently associated + */ + public ITextFormatter getFormatter() { + return formatter; + } + + /** + * Returns the current value of the widget.

+ * + * The returned value is provided by the formatter and is of the type managed + * by the formatter. For example a DateFormatter will return a + * Date value.
+ * If no formatter is associated, the String contained in the + * Text widget is returned. + * + * @return Current value + */ + public Object getValue() { + return formatter != null ? formatter.getValue() : text.getText(); + } + + /** + * Returns the type of value the {@link ITextFormatter} associated with this + * FormattedText handles, + * i.e. returns in {@link #getValue()}. + * + * @return The value type. + */ + public Class getValueType() { + return formatter != null ? formatter.getValueType() : String.class; + } + + /** + * Returns true if beep sound must be produced on input errors, else false. + * + * @return true / false + */ + public static boolean isBeepSound() { + return beepSound; + } + + /** + * Returns true if the current value is empty, else + * false.
+ * An empty value depends of the formatter applied on the Text widget + * and is not just an empty String in the widget. Formatters can use special + * formatting characters to format the value. These characters are not + * always considered as part of the value. For example, in a DateFormatter + * the pattern uses "/" separator and always displays it in the input field. + * + * @return true if empty. + */ + public boolean isEmpty() { + return formatter != null ? formatter.isEmpty() : text.getText().length() == 0; + } + + /** + * Returns true if the current value is valid, else false. + * + * @return true if valid. + */ + public boolean isValid() { + return formatter != null ? formatter.isValid() : true; + } + + /** + * Set the beep sound to ON or OFF for all the FormattedText fields. Beep + * sound are produced by formatters on every input error. Formatter + * implementation must check this flag on before to emit a beep sound. + * + * @param beepSound true to emit beep sound on errors, else false + */ + public static void setBeepSound(boolean beepSound) { + FormattedText.beepSound = beepSound; + } + + /** + * Associates a formatter to the widget.
+ * Parameter can not be null. In some situations, the FormattedText component + * must not do formatting (eg. when reusing the same object for editing of + * different types of values). In this case, use a StringFormatter. This + * formatter do no formatting. + * + * @param formatter formatter + */ + public void setFormatter(ITextFormatter formatter) { + if ( formatter == null ) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if ( this.formatter != null ) { + text.removeVerifyListener(this.formatter); + this.formatter.detach(); + } + this.formatter = formatter; + this.formatter.setText(text); + text.addVerifyListener(this.formatter); + formatter.setIgnore(true); + text.setText(formatter.getDisplayString()); + formatter.setIgnore(false); + } + + /** + * Sets the Text widget value, preventing fire of Modify events. + * + * @param value The String value to display in the widget + */ + private void setText(String value) { + Display display = text.getDisplay(); + try { + display.addFilter(SWT.Modify, modifyFilter); + text.setText(value); + } finally { + display.removeFilter(SWT.Modify, modifyFilter); + } + } + + /** + * Sets a new value.

+ * + * If no formatter is currently associated to he widget, a new one is created + * by the factory based on the value's class.
+ * If the value is incompatible with the formatter, an IllegalArgumentException + * is returned. + * + * @param value new value + */ + public void setValue(Object value) { + if ( formatter == null ) { + setFormatter(DefaultFormatterFactory.createFormatter(value)); + } + formatter.setValue(value); + formatter.setIgnore(true); + text.setText(text.isFocusControl() + ? formatter.getEditString() + : formatter.getDisplayString()); + formatter.setIgnore(false); + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FormattedTextCellEditor.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FormattedTextCellEditor.java index d2d5c665d..045200f7f 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FormattedTextCellEditor.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/FormattedTextCellEditor.java @@ -1,77 +1,77 @@ -package org.eclipse.nebula.widgets.formattedtext; - -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Text; - -/** - * A CellEditor based on a FormattedText. It extends the TextCellEditor, - * adding formatting capabilities based on an IFormatter. - * A formatter can be associated with the editor with the setFormatter method. - * If not, a formatter is automatically created at the first call of the - * setValue method, based on the type of the value. - */ -public class FormattedTextCellEditor extends TextCellEditor { - protected FormattedText formattedText; - - /** - * Creates a new formatted text cell editor parented under the given control. - * - * @param parent the parent control - */ - public FormattedTextCellEditor(Composite parent) { - super(parent); - } - - /** - * Creates a new formatted text cell editor parented under the given control. - * - * @param parent the parent control - * @param style the style bits - */ - public FormattedTextCellEditor(Composite parent, int style) { - super(parent, style); - } - - /** - * @see org.eclipse.jface.viewers.TextCellEditor#createControl(org.eclipse.swt.widgets.Composite) - */ - protected Control createControl(Composite parent) { - Text text = (Text) super.createControl(parent); - formattedText = new FormattedText(text); - return text; - } - - /** - * @see org.eclipse.jface.viewers.TextCellEditor#doGetValue() - */ - protected Object doGetValue() { - return formattedText.getValue(); - } - - /** - * @see org.eclipse.jface.viewers.TextCellEditor#doSetValue(java.lang.Object) - */ - protected void doSetValue(Object value) { - formattedText.setValue(value); - } - - /** - * Returns the FormattedText object used by this cell editor. - * - * @return FormattedText object - */ - public FormattedText getFormattedText() { - return formattedText; - } - - /** - * Sets the formatter that this cell editor must use to edit the value. - * - * @param formatter the formatter - */ - public void setFormatter(ITextFormatter formatter) { - formattedText.setFormatter(formatter); - } -} +package org.eclipse.nebula.widgets.formattedtext; + +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Text; + +/** + * A CellEditor based on a FormattedText. It extends the TextCellEditor, + * adding formatting capabilities based on an IFormatter. + * A formatter can be associated with the editor with the setFormatter method. + * If not, a formatter is automatically created at the first call of the + * setValue method, based on the type of the value. + */ +public class FormattedTextCellEditor extends TextCellEditor { + protected FormattedText formattedText; + + /** + * Creates a new formatted text cell editor parented under the given control. + * + * @param parent the parent control + */ + public FormattedTextCellEditor(Composite parent) { + super(parent); + } + + /** + * Creates a new formatted text cell editor parented under the given control. + * + * @param parent the parent control + * @param style the style bits + */ + public FormattedTextCellEditor(Composite parent, int style) { + super(parent, style); + } + + /** + * @see org.eclipse.jface.viewers.TextCellEditor#createControl(org.eclipse.swt.widgets.Composite) + */ + protected Control createControl(Composite parent) { + Text text = (Text) super.createControl(parent); + formattedText = new FormattedText(text); + return text; + } + + /** + * @see org.eclipse.jface.viewers.TextCellEditor#doGetValue() + */ + protected Object doGetValue() { + return formattedText.getValue(); + } + + /** + * @see org.eclipse.jface.viewers.TextCellEditor#doSetValue(java.lang.Object) + */ + protected void doSetValue(Object value) { + formattedText.setValue(value); + } + + /** + * Returns the FormattedText object used by this cell editor. + * + * @return FormattedText object + */ + public FormattedText getFormattedText() { + return formattedText; + } + + /** + * Sets the formatter that this cell editor must use to edit the value. + * + * @param formatter the formatter + */ + public void setFormatter(ITextFormatter formatter) { + formattedText.setFormatter(formatter); + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/IPAddressFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/IPAddressFormatter.java index f1ffa48af..acd486735 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/IPAddressFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/IPAddressFormatter.java @@ -1,346 +1,346 @@ -package org.eclipse.nebula.widgets.formattedtext; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; - -public class IPAddressFormatter extends AbstractFormatter { - - /** Current edited value */ - private StringBuffer inputCache; - /** Begin position and end position between which current caret is in */ - private int begin = 0, end = 0; - /** Key listener */ - protected Listener keyListener; - - /** - * An empty constructer.
- * An ip address will have an unique format,so there is no necessary to offer an new format - */ - public IPAddressFormatter() { - - inputCache = new StringBuffer(); - for (int i = 1; i <= 12; i++) { - inputCache.append(SPACE); - if (i != 12 && i % 3 == 0) - inputCache.append('.'); - } - - keyListener = e -> { - int currPos = text.getCaretPosition(); - int nextBegin = 4 * (currPos / 4 + 1); - int nextEnd = nextBegin + 3; - if (nextBegin <= 12 && e.character == SPACE) - text.setSelection(nextBegin, nextEnd); - else - return; - e.doit = false; - }; - } - - /** - * Locate current edited area,then (begin,end) will be represented as this area.
- * This area is just a 1/4 part of the ip address. - */ - private void locateCurrentArea() { - int pos = text.getCaretPosition(); - end = pos; - while (end < 15 && inputCache.charAt(end) != '.') - end++; - begin = end - 4; - } - - /** - * Test a 1/4 part of the ip address represented in the String format is valid or not - * - * @param ipp the 1/4 part of the address - * @return if valid,return true;else false - */ - private boolean isValidPart(String ipp) { - int num = 0; - for (char c : ipp.toCharArray()) { - int n = c - '0'; - if (n >= 0 && n <= 9) - num = 10 * num + n; - else - return false; - } - if (num >= 0 && num <= 255) - return true; - else - return false; - } - - /** - * Clear a part of the input cache when knocking DEL key.
- * Characters are replaced by spaces in the fields, but separators are - * preserved. - * - * @param b beginning index (inclusive) - * @param e end index (exclusive) - * @return Return new position of the cursor - */ - private int delClear(int b, int e) { - for (int pos = b; pos < e; pos++) { - if (inputCache.charAt(pos) != '.') - inputCache.setCharAt(pos, SPACE); - } - adjustInputCache(); - locateCurrentArea(); - if ((e > 0 && inputCache.charAt(e - 1) == SPACE) && (e < 15 && inputCache.charAt(e) == '.') || (e == 15 && inputCache.charAt(e - 1) == SPACE)) - return begin; - else - return e; - } - - /** - * Clear a part of the input cache when knocking BackSpace key.
- * Characters are replaced by spaces in the fields, but separators are - * preserved. - * - * @param b beginning index (inclusive) - * @param e end index (exclusive) - * @return Return new position of the cursor - */ - private int bspaceClear(int b, int e) { - for (int pos = b; pos < e; pos++) {// firstly,we just replace the position char of SPACE - if (inputCache.charAt(pos) != '.') - inputCache.setCharAt(pos, SPACE); - } - // use adjustInputCache function to delete non-uself middle SPACE between numbers - // and add useful SPACE in front - adjustInputCache(); - locateCurrentArea(); - - String currPart = inputCache.substring(begin + 1, end); - int p = 0;// first pos containing a none space character - while (p < 3 && currPart.charAt(p) == SPACE) - p++; - if ((e < 15) && inputCache.charAt(e) == SPACE) - return begin + p + 1; - else if ((e < 15) && inputCache.charAt(e) == '.') - return end + 1; - else - return e; - } - - /** - * When doing some modifications,the input cache should be adjusted,thus every number in - * the area will be layed next to the splitting dot flag. - */ - private void adjustInputCache() { - String[] parts = inputCache.toString().split("[.]"); - int i = 1; - for (String part : parts) { - part = part.trim(); - StringBuffer temp = new StringBuffer(part); - for (int j = 0; j < temp.length(); j++) - if (temp.charAt(j) == SPACE) - temp.deleteCharAt(j);// remove SPACE in the middle - int spaceLength = 3 - temp.length(); - while (spaceLength-- > 0) - temp.insert(0, SPACE);// insert space in front - part = temp.toString(); - inputCache.replace(4 * (i - 1), 4 * i - 1, part);// update the input cache - i++; - } - } - - /** - * Inserts a sequence of characters in the input buffer. The current content - * of the buffer is overrided. The new position of the cursor is computed and - * returned. - * - * @param txt String of characters to insert - * @param pos Starting position of insertion - * @return New position of the cursor - */ - private int insert(String txt, int pos) { - locateCurrentArea(); - String currPart = inputCache.substring(begin + 1, end); - if (txt.length() > 3) - return end; - if ((txt.length() + currPart.trim().length()) > 3) - return end; - int currPos = text.getCaretPosition(); - if (isValidPart(currPart.trim()) && currPart.trim().length() == 3 && currPos == end) - return end + 2;// step to next ip part - - StringBuffer currEdit = new StringBuffer(currPart); - int b = 0;// first pos containing a none space character - while (b < 3 && currEdit.charAt(b) == SPACE) - b++; - int relativeInsertPos = pos - begin - 1; - if (relativeInsertPos > end || relativeInsertPos < b) - relativeInsertPos = b; - currEdit.insert(relativeInsertPos, txt); - if (!isValidPart(currEdit.toString().trim())) { - beep(); - return end; - } else { - int currLength = currEdit.length();// contain all characters - currEdit.delete(0, currLength - 3);// cut it to retain only 3 characters - inputCache.replace(begin + 1, end, currEdit.toString()); - currLength = currEdit.toString().trim().length();// without SPACE length - if (currLength == 3) { - if (pos == end) - return end + 1; - else - return end; - } else { - if (pos > 0 && pos < 15 && inputCache.charAt(pos - 1) != SPACE && inputCache.charAt(pos) != SPACE) - return pos; - else if (pos < 15 && inputCache.charAt(pos) == SPACE) - return begin + b + 1; - else - return end; - } - } - } - - /** - * Called when the formatter is replaced by an other one in the FormattedText - * control. Allow to release ressources like additionnal listeners. - *

- * - * Removes the KeyListener on the text widget. - * - * @see ITextFormatter#detach() - */ - public void detach() { - text.removeListener(SWT.KeyDown, keyListener); - } - - /** - * Sets the Text widget that will be managed by this formatter. - *

- * - * The ancestor is overrided to add a key listener on the text widget. - * - * @param text Text widget - * @see ITextFormatter#setText(Text) - */ - public void setText(Text text) { - super.setText(text); - text.addListener(SWT.KeyDown, keyListener); - } - - /** - * Returns the current value formatted for display. - * This method is called by FormattedText when the Text - * widget looses focus. - * In case the input is invalid (eg. not an invalid ip address), the edit - * string is returned in place of the display string. - * - * @return display string if valid, edit string else - * @see ITextFormatter#getDisplayString() - */ - public String getDisplayString() { - return inputCache.toString(); - } - - /** - * Returns the current value formatted for input. - * This method is called by FormattedText when the Text - * widget gains focus. - * The value returned is the content of the StringBuilder used as cache. - * - * @return edit string - * @see ITextFormatter#getEditString() - */ - public String getEditString() { - return inputCache.toString(); - } - - /** - * Returns the current value of the text control if it is a valid ip address.
- * If invalid, returns null. - * - * @return current ip address if valid in which the spaces has been removed, - * null else - * @see ITextFormatter#getValue() - */ - public Object getValue() { - if (isValid()) { - StringBuffer value = new StringBuffer(inputCache); - int i = 0; - for (i = 0; i < value.length(); i++) - if (value.charAt(i) == SPACE) - value.deleteCharAt(i); - return value.toString(); - } else - return null; - } - - /** - * Returns true if current edited value is valid, else returns - * false. - * - * @return true if valid, else false - * @see ITextFormatter#isValid() - */ - public boolean isValid() { - String[] parts = inputCache.toString().split("[.]"); - for (String part : parts) { - part = part.trim(); - if (!isValidPart(part)) - return false; - } - return true; - } - - /** - * Sets the value to edit. The value provided must be a valid ip address in String format. - * - * @param value new ip address - * @throws IllegalArgumentException if not an invalid ip - * @see ITextFormatter#setValue(java.lang.Object) - */ - public void setValue(Object value) { - if (value instanceof String) { - String ip = value.toString(); - String[] parts = ip.split("[.]"); - int i = 1; - for (String part : parts) { - if (!isValidPart(part)) { - throw new IllegalArgumentException("Invalid ip address"); - } else { - inputCache.replace(4 * i - 1 - part.length(), 4 * i - 1, part); - } - i++; - } - } else if (value == null) { - delClear(0, 15); - } else { - throw new IllegalArgumentException("Invalid ip address"); - } - } - - public void verifyText(VerifyEvent e) { - if (ignore) - return; - e.doit = false; - // when knocking backspace or delete key,the caret should be have a different action - // so there are two clear functions - if (e.keyCode == SWT.BS) { - e.start = bspaceClear(e.start, e.end); - } else if (e.keyCode == SWT.DEL) { - e.start = delClear(e.start, e.end); - } else { - e.start = insert(e.text, e.start); - } - updateText(inputCache.toString(), e.start); - } - - @Override - public Class getValueType() { - return String.class; - } - - @Override - public boolean isEmpty() { - return !isValid(); - } - -} +package org.eclipse.nebula.widgets.formattedtext; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; + +public class IPAddressFormatter extends AbstractFormatter { + + /** Current edited value */ + private StringBuffer inputCache; + /** Begin position and end position between which current caret is in */ + private int begin = 0, end = 0; + /** Key listener */ + protected Listener keyListener; + + /** + * An empty constructer.
+ * An ip address will have an unique format,so there is no necessary to offer an new format + */ + public IPAddressFormatter() { + + inputCache = new StringBuffer(); + for (int i = 1; i <= 12; i++) { + inputCache.append(SPACE); + if (i != 12 && i % 3 == 0) + inputCache.append('.'); + } + + keyListener = e -> { + int currPos = text.getCaretPosition(); + int nextBegin = 4 * (currPos / 4 + 1); + int nextEnd = nextBegin + 3; + if (nextBegin <= 12 && e.character == SPACE) + text.setSelection(nextBegin, nextEnd); + else + return; + e.doit = false; + }; + } + + /** + * Locate current edited area,then (begin,end) will be represented as this area.
+ * This area is just a 1/4 part of the ip address. + */ + private void locateCurrentArea() { + int pos = text.getCaretPosition(); + end = pos; + while (end < 15 && inputCache.charAt(end) != '.') + end++; + begin = end - 4; + } + + /** + * Test a 1/4 part of the ip address represented in the String format is valid or not + * + * @param ipp the 1/4 part of the address + * @return if valid,return true;else false + */ + private boolean isValidPart(String ipp) { + int num = 0; + for (char c : ipp.toCharArray()) { + int n = c - '0'; + if (n >= 0 && n <= 9) + num = 10 * num + n; + else + return false; + } + if (num >= 0 && num <= 255) + return true; + else + return false; + } + + /** + * Clear a part of the input cache when knocking DEL key.
+ * Characters are replaced by spaces in the fields, but separators are + * preserved. + * + * @param b beginning index (inclusive) + * @param e end index (exclusive) + * @return Return new position of the cursor + */ + private int delClear(int b, int e) { + for (int pos = b; pos < e; pos++) { + if (inputCache.charAt(pos) != '.') + inputCache.setCharAt(pos, SPACE); + } + adjustInputCache(); + locateCurrentArea(); + if ((e > 0 && inputCache.charAt(e - 1) == SPACE) && (e < 15 && inputCache.charAt(e) == '.') || (e == 15 && inputCache.charAt(e - 1) == SPACE)) + return begin; + else + return e; + } + + /** + * Clear a part of the input cache when knocking BackSpace key.
+ * Characters are replaced by spaces in the fields, but separators are + * preserved. + * + * @param b beginning index (inclusive) + * @param e end index (exclusive) + * @return Return new position of the cursor + */ + private int bspaceClear(int b, int e) { + for (int pos = b; pos < e; pos++) {// firstly,we just replace the position char of SPACE + if (inputCache.charAt(pos) != '.') + inputCache.setCharAt(pos, SPACE); + } + // use adjustInputCache function to delete non-uself middle SPACE between numbers + // and add useful SPACE in front + adjustInputCache(); + locateCurrentArea(); + + String currPart = inputCache.substring(begin + 1, end); + int p = 0;// first pos containing a none space character + while (p < 3 && currPart.charAt(p) == SPACE) + p++; + if ((e < 15) && inputCache.charAt(e) == SPACE) + return begin + p + 1; + else if ((e < 15) && inputCache.charAt(e) == '.') + return end + 1; + else + return e; + } + + /** + * When doing some modifications,the input cache should be adjusted,thus every number in + * the area will be layed next to the splitting dot flag. + */ + private void adjustInputCache() { + String[] parts = inputCache.toString().split("[.]"); + int i = 1; + for (String part : parts) { + part = part.trim(); + StringBuffer temp = new StringBuffer(part); + for (int j = 0; j < temp.length(); j++) + if (temp.charAt(j) == SPACE) + temp.deleteCharAt(j);// remove SPACE in the middle + int spaceLength = 3 - temp.length(); + while (spaceLength-- > 0) + temp.insert(0, SPACE);// insert space in front + part = temp.toString(); + inputCache.replace(4 * (i - 1), 4 * i - 1, part);// update the input cache + i++; + } + } + + /** + * Inserts a sequence of characters in the input buffer. The current content + * of the buffer is overrided. The new position of the cursor is computed and + * returned. + * + * @param txt String of characters to insert + * @param pos Starting position of insertion + * @return New position of the cursor + */ + private int insert(String txt, int pos) { + locateCurrentArea(); + String currPart = inputCache.substring(begin + 1, end); + if (txt.length() > 3) + return end; + if ((txt.length() + currPart.trim().length()) > 3) + return end; + int currPos = text.getCaretPosition(); + if (isValidPart(currPart.trim()) && currPart.trim().length() == 3 && currPos == end) + return end + 2;// step to next ip part + + StringBuffer currEdit = new StringBuffer(currPart); + int b = 0;// first pos containing a none space character + while (b < 3 && currEdit.charAt(b) == SPACE) + b++; + int relativeInsertPos = pos - begin - 1; + if (relativeInsertPos > end || relativeInsertPos < b) + relativeInsertPos = b; + currEdit.insert(relativeInsertPos, txt); + if (!isValidPart(currEdit.toString().trim())) { + beep(); + return end; + } else { + int currLength = currEdit.length();// contain all characters + currEdit.delete(0, currLength - 3);// cut it to retain only 3 characters + inputCache.replace(begin + 1, end, currEdit.toString()); + currLength = currEdit.toString().trim().length();// without SPACE length + if (currLength == 3) { + if (pos == end) + return end + 1; + else + return end; + } else { + if (pos > 0 && pos < 15 && inputCache.charAt(pos - 1) != SPACE && inputCache.charAt(pos) != SPACE) + return pos; + else if (pos < 15 && inputCache.charAt(pos) == SPACE) + return begin + b + 1; + else + return end; + } + } + } + + /** + * Called when the formatter is replaced by an other one in the FormattedText + * control. Allow to release ressources like additionnal listeners. + *

+ * + * Removes the KeyListener on the text widget. + * + * @see ITextFormatter#detach() + */ + public void detach() { + text.removeListener(SWT.KeyDown, keyListener); + } + + /** + * Sets the Text widget that will be managed by this formatter. + *

+ * + * The ancestor is overrided to add a key listener on the text widget. + * + * @param text Text widget + * @see ITextFormatter#setText(Text) + */ + public void setText(Text text) { + super.setText(text); + text.addListener(SWT.KeyDown, keyListener); + } + + /** + * Returns the current value formatted for display. + * This method is called by FormattedText when the Text + * widget looses focus. + * In case the input is invalid (eg. not an invalid ip address), the edit + * string is returned in place of the display string. + * + * @return display string if valid, edit string else + * @see ITextFormatter#getDisplayString() + */ + public String getDisplayString() { + return inputCache.toString(); + } + + /** + * Returns the current value formatted for input. + * This method is called by FormattedText when the Text + * widget gains focus. + * The value returned is the content of the StringBuilder used as cache. + * + * @return edit string + * @see ITextFormatter#getEditString() + */ + public String getEditString() { + return inputCache.toString(); + } + + /** + * Returns the current value of the text control if it is a valid ip address.
+ * If invalid, returns null. + * + * @return current ip address if valid in which the spaces has been removed, + * null else + * @see ITextFormatter#getValue() + */ + public Object getValue() { + if (isValid()) { + StringBuffer value = new StringBuffer(inputCache); + int i = 0; + for (i = 0; i < value.length(); i++) + if (value.charAt(i) == SPACE) + value.deleteCharAt(i); + return value.toString(); + } else + return null; + } + + /** + * Returns true if current edited value is valid, else returns + * false. + * + * @return true if valid, else false + * @see ITextFormatter#isValid() + */ + public boolean isValid() { + String[] parts = inputCache.toString().split("[.]"); + for (String part : parts) { + part = part.trim(); + if (!isValidPart(part)) + return false; + } + return true; + } + + /** + * Sets the value to edit. The value provided must be a valid ip address in String format. + * + * @param value new ip address + * @throws IllegalArgumentException if not an invalid ip + * @see ITextFormatter#setValue(java.lang.Object) + */ + public void setValue(Object value) { + if (value instanceof String) { + String ip = value.toString(); + String[] parts = ip.split("[.]"); + int i = 1; + for (String part : parts) { + if (!isValidPart(part)) { + throw new IllegalArgumentException("Invalid ip address"); + } else { + inputCache.replace(4 * i - 1 - part.length(), 4 * i - 1, part); + } + i++; + } + } else if (value == null) { + delClear(0, 15); + } else { + throw new IllegalArgumentException("Invalid ip address"); + } + } + + public void verifyText(VerifyEvent e) { + if (ignore) + return; + e.doit = false; + // when knocking backspace or delete key,the caret should be have a different action + // so there are two clear functions + if (e.keyCode == SWT.BS) { + e.start = bspaceClear(e.start, e.end); + } else if (e.keyCode == SWT.DEL) { + e.start = delClear(e.start, e.end); + } else { + e.start = insert(e.text, e.start); + } + updateText(inputCache.toString(), e.start); + } + + @Override + public Class getValueType() { + return String.class; + } + + @Override + public boolean isEmpty() { + return !isValid(); + } + +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/ITextFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/ITextFormatter.java index fe54caec7..8d4dd4df8 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/ITextFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/ITextFormatter.java @@ -1,110 +1,110 @@ -/******************************************************************************* - * Copyright (c) 2005, 2009 Eric Wuillai. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Eric Wuillai (eric@wdev91.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.widgets.Text; - -/** - * Interface defining all the text formatters.

- * - * Each formatter is associated with a Text control and can not be - * shared. Formatters have and edit mask applied when the associated Text has - * the focus, and a display mask for when the Text looses the focus. - * The formatter must control editing keystroke by keystroke. For this is it - * declared as a VerifyListener of the Text widget. - */ -public interface ITextFormatter extends VerifyListener { - /** - * Called when the formatter is replaced by an other one in the FormattedText - * control. Allow to release resources like additional listeners. - */ - public void detach(); - - /** - * Returns the current value formatted for display. - * This method is called by FormattedText when the Text - * widget looses focus. - * - * @return display string - */ - public String getDisplayString(); - - /** - * Returns the current value formatted for editing. - * This method is called by FormattedText when the Text - * widget gains focus. - * - * @return edit string - */ - public String getEditString(); - - /** - * Returns the current value of the text control. If the current value is - * invalid for its type (ex. Date missing parts), returns null. - * - * @return current value - */ - public Object getValue(); - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}. - * - * @return The value type. - */ - public Class getValueType(); - - /** - * Returns true if current edited value is empty, else returns - * false. An empty value depends of the formatter and is not - * just an empty string in the Text widget. - * - * @return true if empty, else false - */ - public boolean isEmpty(); - - /** - * Returns true if current edited value is valid, else returns - * false. - * - * @return true if valid, else false - */ - public boolean isValid(); - - /** - * Specify whether or not VerifyEvent events must be processed. - * Those events are the base of all formatters, allowing on-the-fly - * processing of each text change in the Text widget. - * In some situations (e.g. when focus change), the FormattedText - * must change the text in the widget without formatting. - * - * @param ignore when true, VerifyEvent events are processed. - */ - public void setIgnore(boolean ignore); - - /** - * Sets the Text widget that will be managed by this formatter. - * - * @param text Text widget - */ - public void setText(Text text); - - /** - * Sets the value to edit. - * - * @param value value - */ - public void setValue(Object value); -} +/******************************************************************************* + * Copyright (c) 2005, 2009 Eric Wuillai. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eric Wuillai (eric@wdev91.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.widgets.Text; + +/** + * Interface defining all the text formatters.

+ * + * Each formatter is associated with a Text control and can not be + * shared. Formatters have and edit mask applied when the associated Text has + * the focus, and a display mask for when the Text looses the focus. + * The formatter must control editing keystroke by keystroke. For this is it + * declared as a VerifyListener of the Text widget. + */ +public interface ITextFormatter extends VerifyListener { + /** + * Called when the formatter is replaced by an other one in the FormattedText + * control. Allow to release resources like additional listeners. + */ + public void detach(); + + /** + * Returns the current value formatted for display. + * This method is called by FormattedText when the Text + * widget looses focus. + * + * @return display string + */ + public String getDisplayString(); + + /** + * Returns the current value formatted for editing. + * This method is called by FormattedText when the Text + * widget gains focus. + * + * @return edit string + */ + public String getEditString(); + + /** + * Returns the current value of the text control. If the current value is + * invalid for its type (ex. Date missing parts), returns null. + * + * @return current value + */ + public Object getValue(); + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}. + * + * @return The value type. + */ + public Class getValueType(); + + /** + * Returns true if current edited value is empty, else returns + * false. An empty value depends of the formatter and is not + * just an empty string in the Text widget. + * + * @return true if empty, else false + */ + public boolean isEmpty(); + + /** + * Returns true if current edited value is valid, else returns + * false. + * + * @return true if valid, else false + */ + public boolean isValid(); + + /** + * Specify whether or not VerifyEvent events must be processed. + * Those events are the base of all formatters, allowing on-the-fly + * processing of each text change in the Text widget. + * In some situations (e.g. when focus change), the FormattedText + * must change the text in the widget without formatting. + * + * @param ignore when true, VerifyEvent events are processed. + */ + public void setIgnore(boolean ignore); + + /** + * Sets the Text widget that will be managed by this formatter. + * + * @param text Text widget + */ + public void setText(Text text); + + /** + * Sets the value to edit. + * + * @param value value + */ + public void setValue(Object value); +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/IntegerFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/IntegerFormatter.java index 95228eb18..4ae121b30 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/IntegerFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/IntegerFormatter.java @@ -1,65 +1,65 @@ -package org.eclipse.nebula.widgets.formattedtext; - -import java.util.Locale; - -/** - * This class provides formatting of Integer values in a - * FormattedText.

- * - * NumberFormatter returns different numeric types based on the current - * value in the Text field. IntegerFormatter is an override of NumberFormatter - * allowing to guaranty to always return Integer values (Number.intValue()). - */ -public class IntegerFormatter extends NumberFormatter { - public IntegerFormatter() { - super(); - } - - public IntegerFormatter(Locale loc) { - super(loc); - } - - public IntegerFormatter(String editPattern, Locale loc) { - super(editPattern, loc); - } - - public IntegerFormatter(String editPattern, String displayPattern, Locale loc) { - super(editPattern, displayPattern, loc); - } - - public IntegerFormatter(String editPattern, String displayPattern) { - super(editPattern, displayPattern); - } - - public IntegerFormatter(String editPattern) { - super(editPattern); - } - - /** - * Returns the current value of the text control if it is a valid Integer. - * If the buffer is flagged as modified, the value is recalculated by parsing - * with the nfEdit initialized with the edit pattern. If the - * number is not valid, returns null. - * - * @return current number value if valid, null else - * @see ITextFormatter#getValue() - */ - public Object getValue() { - Object value = super.getValue(); - if ( value instanceof Number ) { - return new Integer(((Number) value).intValue()); - } - return super.getValue(); - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * An IntegerFormatter always returns an Integer value. - * - * @return The value type. - */ - public Class getValueType() { - return Integer.class; - } -} +package org.eclipse.nebula.widgets.formattedtext; + +import java.util.Locale; + +/** + * This class provides formatting of Integer values in a + * FormattedText.

+ * + * NumberFormatter returns different numeric types based on the current + * value in the Text field. IntegerFormatter is an override of NumberFormatter + * allowing to guaranty to always return Integer values (Number.intValue()). + */ +public class IntegerFormatter extends NumberFormatter { + public IntegerFormatter() { + super(); + } + + public IntegerFormatter(Locale loc) { + super(loc); + } + + public IntegerFormatter(String editPattern, Locale loc) { + super(editPattern, loc); + } + + public IntegerFormatter(String editPattern, String displayPattern, Locale loc) { + super(editPattern, displayPattern, loc); + } + + public IntegerFormatter(String editPattern, String displayPattern) { + super(editPattern, displayPattern); + } + + public IntegerFormatter(String editPattern) { + super(editPattern); + } + + /** + * Returns the current value of the text control if it is a valid Integer. + * If the buffer is flagged as modified, the value is recalculated by parsing + * with the nfEdit initialized with the edit pattern. If the + * number is not valid, returns null. + * + * @return current number value if valid, null else + * @see ITextFormatter#getValue() + */ + public Object getValue() { + Object value = super.getValue(); + if ( value instanceof Number ) { + return new Integer(((Number) value).intValue()); + } + return super.getValue(); + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * An IntegerFormatter always returns an Integer value. + * + * @return The value type. + */ + public Class getValueType() { + return Integer.class; + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/LongFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/LongFormatter.java index 99844aac3..89ee261d3 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/LongFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/LongFormatter.java @@ -1,65 +1,65 @@ -package org.eclipse.nebula.widgets.formattedtext; - -import java.util.Locale; - -/** - * This class provides formatting of Long values in a - * FormattedText.

- * - * NumberFormatter returns different numeric types based on the current - * value in the Text field. LongFormatter is an override of NumberFormatter - * allowing to guaranty to always return Long values (Number.longValue()). - */ -public class LongFormatter extends NumberFormatter { - public LongFormatter() { - super(); - } - - public LongFormatter(Locale loc) { - super(loc); - } - - public LongFormatter(String editPattern, Locale loc) { - super(editPattern, loc); - } - - public LongFormatter(String editPattern, String displayPattern, Locale loc) { - super(editPattern, displayPattern, loc); - } - - public LongFormatter(String editPattern, String displayPattern) { - super(editPattern, displayPattern); - } - - public LongFormatter(String editPattern) { - super(editPattern); - } - - /** - * Returns the current value of the text control if it is a valid Long. - * If the buffer is flagged as modified, the value is recalculated by parsing - * with the nfEdit initialized with the edit pattern. If the - * number is not valid, returns null. - * - * @return current number value if valid, null else - * @see ITextFormatter#getValue() - */ - public Object getValue() { - Object value = super.getValue(); - if ( value instanceof Number ) { - return new Long(((Number) value).longValue()); - } - return super.getValue(); - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * A LongFormatter always returns a Long value. - * - * @return The value type. - */ - public Class getValueType() { - return Long.class; - } -} +package org.eclipse.nebula.widgets.formattedtext; + +import java.util.Locale; + +/** + * This class provides formatting of Long values in a + * FormattedText.

+ * + * NumberFormatter returns different numeric types based on the current + * value in the Text field. LongFormatter is an override of NumberFormatter + * allowing to guaranty to always return Long values (Number.longValue()). + */ +public class LongFormatter extends NumberFormatter { + public LongFormatter() { + super(); + } + + public LongFormatter(Locale loc) { + super(loc); + } + + public LongFormatter(String editPattern, Locale loc) { + super(editPattern, loc); + } + + public LongFormatter(String editPattern, String displayPattern, Locale loc) { + super(editPattern, displayPattern, loc); + } + + public LongFormatter(String editPattern, String displayPattern) { + super(editPattern, displayPattern); + } + + public LongFormatter(String editPattern) { + super(editPattern); + } + + /** + * Returns the current value of the text control if it is a valid Long. + * If the buffer is flagged as modified, the value is recalculated by parsing + * with the nfEdit initialized with the edit pattern. If the + * number is not valid, returns null. + * + * @return current number value if valid, null else + * @see ITextFormatter#getValue() + */ + public Object getValue() { + Object value = super.getValue(); + if ( value instanceof Number ) { + return new Long(((Number) value).longValue()); + } + return super.getValue(); + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * A LongFormatter always returns a Long value. + * + * @return The value type. + */ + public Class getValueType() { + return Long.class; + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/MaskFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/MaskFormatter.java index 9d6b6b784..d26c3a412 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/MaskFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/MaskFormatter.java @@ -1,343 +1,343 @@ -/******************************************************************************* - * Copyright (c) 2005, 2009 Eric Wuillai. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Eric Wuillai (eric@wdev91.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.VerifyEvent; - -/** - * This class provides formatting of String values in a - * FormattedText.

- * - *

Pattern Characters

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
SymbolMeaning
#Digit
AAlphanumeric
UAlphanumeric converted in uppercase
LAlphanumeric converted in lowercase
- * All other characters are considered as separators. - * - *

Examples

- * newFormatter("(###) UUU-AAAA");
- * setValue("123aBcDeF"); -> will display as "(123) ABC-DeF". - */ -public class MaskFormatter extends AbstractFormatter { - private static final char P_DIGIT = '#'; - private static final char P_ALPHANUM = 'A'; - private static final char P_UPPERCASE = 'U'; - private static final char P_LOWERCASE = 'L'; - - private static final char P_UHEXDIGIT = 'X'; - private static final char P_LHEXDIGIT = 'x'; - - /** Edit mask */ - protected String editPattern; - /** Buffer for the edit value */ - protected StringBuffer editValue; - /** Number of editable positions in the mask */ - protected int positions; - /** Current number of characters in the buffer (except mask characters) */ - protected int count = 0; - - /** - * Constructs a new instance with the given edit mask. - * - * @param editPattern edit mask - */ - public MaskFormatter(String editPattern) { - if (editPattern == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - this.editPattern = editPattern; - - // Initializes the buffer with the formatting characters - editValue = new StringBuffer(editPattern.length()); - for (int i = 0; i < editPattern.length(); i++) { - char c = editPattern.charAt(i); - if (c != P_DIGIT && c != P_ALPHANUM && c != P_UPPERCASE - && c != P_LOWERCASE && c != P_UHEXDIGIT && c != P_LHEXDIGIT) { - editValue.append(c); - } else { - editValue.append(SPACE); - positions++; - } - } - } - - /** - * Clear a part of the edition cache. Mask characters are preserved in their - * positions. - * - * @param start - * beginning index - * @param len - * length of portion to clear - */ - protected void clearText(int start, int len) { - for (int i = start; i < start + len && i < editValue.length(); i++) { - char c = editPattern.charAt(i); - if (c == P_DIGIT || c == P_ALPHANUM || c == P_UPPERCASE - || c == P_LOWERCASE || c == P_UHEXDIGIT || c == P_LHEXDIGIT) { - if (editValue.charAt(i) != SPACE) { - count--; - } - editValue.setCharAt(i, SPACE); - } - } - } - - /** - * Returns the current value formatted for display.

- * There is no difference in this formatter between edit and display values. - * So this method returns the edit string. - * - * @return display string - * @see ITextFormatter#getDisplayString() - */ - public String getDisplayString() { - return getEditString(); - } - - /** - * Returns the current value formatted for editing. This method is called by - * FormattedText when the Text widget gains focus. - * The value returned is the content of the StringBuilder - * editValue used as cache. - * - * @return edit string - * @see ITextFormatter#getEditString() - */ - public String getEditString() { - return editValue.toString(); - } - - /** - * Returns the current value. The value returned is the content of the edit - * cache without any mask characters. - * - * @return current string value - * @see ITextFormatter#getValue() - */ - public Object getValue() { - StringBuffer value = new StringBuffer(editValue.length()); - for (int i = 0; i < editValue.length(); i++) { - char c = editPattern.charAt(i); - if (c == P_DIGIT || c == P_ALPHANUM || c == P_UPPERCASE - || c == P_LOWERCASE || c == P_UHEXDIGIT || c != P_LHEXDIGIT) { - value.append(editValue.charAt(i)); - } - } - return value.toString(); - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, i.e. - * returns in {@link #getValue()}.
- * A MaskFormatter always returns a String value. - * - * @return The value type. - */ - public Class getValueType() { - return String.class; - } - - /** - * Inserts a sequence of characters in the edit buffer. The current content - * of the buffer is override. The new position of the cursor is computed and - * returned. Mask characters are preserved in their positions. - * - * @param txt String of characters to insert - * @param start Starting position of insertion - * @return New position of the cursor - */ - protected int insertText(String txt, int start) { - int i = start, j = 0; - char p, c, o; - - while (i < editPattern.length() && j < txt.length()) { - p = editPattern.charAt(i); - c = txt.charAt(j); - o = editValue.charAt(i); - switch (p) { - case P_DIGIT: - if (Character.isDigit(c)) { - editValue.setCharAt(i, c); - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - break; - case P_UPPERCASE: - if (Character.isLetterOrDigit(c)) { - editValue.setCharAt(i, Character.toUpperCase(c)); - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - break; - case P_LOWERCASE: - if (Character.isLetterOrDigit(c)) { - editValue.setCharAt(i, Character.toLowerCase(c)); - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - break; - case P_ALPHANUM: - if (Character.isLetterOrDigit(c)) { - editValue.setCharAt(i, c); - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - break; - case P_UHEXDIGIT: - if (isHexDigit(c)) { - editValue.setCharAt(i, Character.toUpperCase(c)); - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - break; - case P_LHEXDIGIT: - if (isHexDigit(c)) { - editValue.setCharAt(i, Character.toLowerCase(c)); - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - break; - default: // Separator - if (p != c) { - if (Character.isLetterOrDigit(c)) { - i++; - continue; - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - o = '*'; - break; - } - if (o == SPACE && c != SPACE) { - count++; - } - i++; - j++; - } - return i; - } - - /** - * Returns true if current edited value is empty, else returns - * false.
- * A value is considered as empty in a MaskFormatter if the edit buffer - * contains no characters except the mask characters. - * - * @return true if empty, else false - */ - public boolean isEmpty() { - return count == 0; - } - - /** - * Returns true if current edited value is valid, else returns - * false. An empty value is considered as valid. - * - * @return true if valid, else false - * @see ITextFormatter#isValid() - */ - public boolean isValid() { - return (count == 0 || count == positions); - } - - /** - * Sets the value to edit. The value provided must be a String. - * - * @param value string value - * @throws IllegalArgumentException if not a string - * @see ITextFormatter#setValue(java.lang.Object) - */ - public void setValue(Object value) { - if (value instanceof String) { - insertText((String) value, 0); - updateText(editValue.toString(), 0); - } else if (value == null) { - clearText(0, editValue.length()); - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - - /** - * Handles a VerifyEvent sent when the text is about to be - * modified. This method is the entry point of all operations of formatting. - * - * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) - */ - public void verifyText(VerifyEvent e) { - if (ignore) { - return; - } - e.doit = false; - if (e.keyCode == SWT.BS || e.keyCode == SWT.DEL) { - // Clears - clearText(e.start, (e.end > e.start) ? e.end - e.start : 1); - updateText(editValue.toString(), e.start); - } else { - // Inserts - int p; - try { - p = insertText(e.text, e.start); - if (e.end - e.start > e.text.length()) { - clearText(e.start + e.text.length(), e.end - e.start - e.text.length()); - } - } catch (IllegalArgumentException iae) { - beep(); - p = e.start; - } - - // Computes new position of the cursor - char c; - while (p < editPattern.length() - && (c = editPattern.charAt(p)) != P_DIGIT - && c != P_ALPHANUM && c != P_UPPERCASE && c != P_LOWERCASE - && c != P_UHEXDIGIT && c != P_LHEXDIGIT) { - p++; - } - - updateText(editValue.toString(), p); - } - } - - protected boolean isHexDigit(char ch) { - boolean test = false; - try { - test = Character.digit(ch, 16) > -1.; - } catch (Exception e) { - return false; - } - return test; - } -} +/******************************************************************************* + * Copyright (c) 2005, 2009 Eric Wuillai. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eric Wuillai (eric@wdev91.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.VerifyEvent; + +/** + * This class provides formatting of String values in a + * FormattedText.

+ * + *

Pattern Characters

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
SymbolMeaning
#Digit
AAlphanumeric
UAlphanumeric converted in uppercase
LAlphanumeric converted in lowercase
+ * All other characters are considered as separators. + * + *

Examples

+ * newFormatter("(###) UUU-AAAA");
+ * setValue("123aBcDeF"); -> will display as "(123) ABC-DeF". + */ +public class MaskFormatter extends AbstractFormatter { + private static final char P_DIGIT = '#'; + private static final char P_ALPHANUM = 'A'; + private static final char P_UPPERCASE = 'U'; + private static final char P_LOWERCASE = 'L'; + + private static final char P_UHEXDIGIT = 'X'; + private static final char P_LHEXDIGIT = 'x'; + + /** Edit mask */ + protected String editPattern; + /** Buffer for the edit value */ + protected StringBuffer editValue; + /** Number of editable positions in the mask */ + protected int positions; + /** Current number of characters in the buffer (except mask characters) */ + protected int count = 0; + + /** + * Constructs a new instance with the given edit mask. + * + * @param editPattern edit mask + */ + public MaskFormatter(String editPattern) { + if (editPattern == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + this.editPattern = editPattern; + + // Initializes the buffer with the formatting characters + editValue = new StringBuffer(editPattern.length()); + for (int i = 0; i < editPattern.length(); i++) { + char c = editPattern.charAt(i); + if (c != P_DIGIT && c != P_ALPHANUM && c != P_UPPERCASE + && c != P_LOWERCASE && c != P_UHEXDIGIT && c != P_LHEXDIGIT) { + editValue.append(c); + } else { + editValue.append(SPACE); + positions++; + } + } + } + + /** + * Clear a part of the edition cache. Mask characters are preserved in their + * positions. + * + * @param start + * beginning index + * @param len + * length of portion to clear + */ + protected void clearText(int start, int len) { + for (int i = start; i < start + len && i < editValue.length(); i++) { + char c = editPattern.charAt(i); + if (c == P_DIGIT || c == P_ALPHANUM || c == P_UPPERCASE + || c == P_LOWERCASE || c == P_UHEXDIGIT || c == P_LHEXDIGIT) { + if (editValue.charAt(i) != SPACE) { + count--; + } + editValue.setCharAt(i, SPACE); + } + } + } + + /** + * Returns the current value formatted for display.

+ * There is no difference in this formatter between edit and display values. + * So this method returns the edit string. + * + * @return display string + * @see ITextFormatter#getDisplayString() + */ + public String getDisplayString() { + return getEditString(); + } + + /** + * Returns the current value formatted for editing. This method is called by + * FormattedText when the Text widget gains focus. + * The value returned is the content of the StringBuilder + * editValue used as cache. + * + * @return edit string + * @see ITextFormatter#getEditString() + */ + public String getEditString() { + return editValue.toString(); + } + + /** + * Returns the current value. The value returned is the content of the edit + * cache without any mask characters. + * + * @return current string value + * @see ITextFormatter#getValue() + */ + public Object getValue() { + StringBuffer value = new StringBuffer(editValue.length()); + for (int i = 0; i < editValue.length(); i++) { + char c = editPattern.charAt(i); + if (c == P_DIGIT || c == P_ALPHANUM || c == P_UPPERCASE + || c == P_LOWERCASE || c == P_UHEXDIGIT || c != P_LHEXDIGIT) { + value.append(editValue.charAt(i)); + } + } + return value.toString(); + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, i.e. + * returns in {@link #getValue()}.
+ * A MaskFormatter always returns a String value. + * + * @return The value type. + */ + public Class getValueType() { + return String.class; + } + + /** + * Inserts a sequence of characters in the edit buffer. The current content + * of the buffer is override. The new position of the cursor is computed and + * returned. Mask characters are preserved in their positions. + * + * @param txt String of characters to insert + * @param start Starting position of insertion + * @return New position of the cursor + */ + protected int insertText(String txt, int start) { + int i = start, j = 0; + char p, c, o; + + while (i < editPattern.length() && j < txt.length()) { + p = editPattern.charAt(i); + c = txt.charAt(j); + o = editValue.charAt(i); + switch (p) { + case P_DIGIT: + if (Character.isDigit(c)) { + editValue.setCharAt(i, c); + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + break; + case P_UPPERCASE: + if (Character.isLetterOrDigit(c)) { + editValue.setCharAt(i, Character.toUpperCase(c)); + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + break; + case P_LOWERCASE: + if (Character.isLetterOrDigit(c)) { + editValue.setCharAt(i, Character.toLowerCase(c)); + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + break; + case P_ALPHANUM: + if (Character.isLetterOrDigit(c)) { + editValue.setCharAt(i, c); + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + break; + case P_UHEXDIGIT: + if (isHexDigit(c)) { + editValue.setCharAt(i, Character.toUpperCase(c)); + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + break; + case P_LHEXDIGIT: + if (isHexDigit(c)) { + editValue.setCharAt(i, Character.toLowerCase(c)); + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + break; + default: // Separator + if (p != c) { + if (Character.isLetterOrDigit(c)) { + i++; + continue; + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + o = '*'; + break; + } + if (o == SPACE && c != SPACE) { + count++; + } + i++; + j++; + } + return i; + } + + /** + * Returns true if current edited value is empty, else returns + * false.
+ * A value is considered as empty in a MaskFormatter if the edit buffer + * contains no characters except the mask characters. + * + * @return true if empty, else false + */ + public boolean isEmpty() { + return count == 0; + } + + /** + * Returns true if current edited value is valid, else returns + * false. An empty value is considered as valid. + * + * @return true if valid, else false + * @see ITextFormatter#isValid() + */ + public boolean isValid() { + return (count == 0 || count == positions); + } + + /** + * Sets the value to edit. The value provided must be a String. + * + * @param value string value + * @throws IllegalArgumentException if not a string + * @see ITextFormatter#setValue(java.lang.Object) + */ + public void setValue(Object value) { + if (value instanceof String) { + insertText((String) value, 0); + updateText(editValue.toString(), 0); + } else if (value == null) { + clearText(0, editValue.length()); + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + + /** + * Handles a VerifyEvent sent when the text is about to be + * modified. This method is the entry point of all operations of formatting. + * + * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) + */ + public void verifyText(VerifyEvent e) { + if (ignore) { + return; + } + e.doit = false; + if (e.keyCode == SWT.BS || e.keyCode == SWT.DEL) { + // Clears + clearText(e.start, (e.end > e.start) ? e.end - e.start : 1); + updateText(editValue.toString(), e.start); + } else { + // Inserts + int p; + try { + p = insertText(e.text, e.start); + if (e.end - e.start > e.text.length()) { + clearText(e.start + e.text.length(), e.end - e.start - e.text.length()); + } + } catch (IllegalArgumentException iae) { + beep(); + p = e.start; + } + + // Computes new position of the cursor + char c; + while (p < editPattern.length() + && (c = editPattern.charAt(p)) != P_DIGIT + && c != P_ALPHANUM && c != P_UPPERCASE && c != P_LOWERCASE + && c != P_UHEXDIGIT && c != P_LHEXDIGIT) { + p++; + } + + updateText(editValue.toString(), p); + } + } + + protected boolean isHexDigit(char ch) { + boolean test = false; + try { + test = Character.digit(ch, 16) > -1.; + } catch (Exception e) { + return false; + } + return test; + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/NumberFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/NumberFormatter.java index 1291f7abd..63f216a86 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/NumberFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/NumberFormatter.java @@ -1,752 +1,752 @@ -/******************************************************************************* - * Copyright (c) 2005, 2009 Eric Wuillai. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Eric Wuillai (eric@wdev91.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.text.ParseException; -import java.util.Hashtable; -import java.util.Locale; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.VerifyEvent; - -/** - * This class provides formatting of Number values in a - * FormattedText.

- * - * Formatter is composed of an edit pattern and a display pattern.
- * Display pattern uses the same syntax than DecimalFormat, and - * uses it to compute the value to display.
- * Edit pattern is more limited and composed of two part, the int part and - * the decimal part. Formatting characters allow to specify number of digits, - * minimal length, decimal position, grouping and negative sign.

- * - *

Patterns Characters

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
SymbolMeaning
0Digit
#Digit, zero shows as absent
.Decimal separator
-Minus sign
,Grouping separator
- * - *

Examples

- *
    - *
  • new NumberFormatter("#,##0.00") - 1234.5 will edit and - * display as "1,234.50".
  • - *
- */ -public class NumberFormatter extends AbstractFormatter { - private static final char P_DIGIT = '#'; - private static final char P_ZERODIGIT = '0'; - private static final char P_DECIMAL_SEP = '.'; - private static final char P_GROUP_SEP = ','; - private static final char P_MINUS = '-'; - - /** Cache of number patterns by locales */ - protected static Hashtable cachedPatterns = new Hashtable<>(); - - /** Number formatter for display */ - protected DecimalFormat nfDisplay; - /** Number formatter for display edit */ - protected DecimalFormat nfEdit; - /** Buffer for the edit value */ - protected StringBuffer editValue; - /** Number containing the current value */ - protected Number value; - /** Edit pattern */ - protected String editPattern; - /** The locale used */ - protected Locale locale; - /** Length of groups (0 if no group separator) */ - protected int groupLen = 0; - /** Current number of digits of the int part */ - protected int intCount = 0; - /** Maximum number of digits of the int part */ - protected int intLen = 0; - /** Maximum number of digits of the decimal part */ - protected int decimalLen = 0; - /** Minimum number of digits of the int part (complement by 0) */ - protected int zeroIntLen = 0; - /** Minimum number of digits of the decimal part (complement by 0) */ - protected int zeroDecimalLen = 0; - /** Flag for display of the negative sign */ - protected boolean minus = false; - /** Flag indicating that the current value is negative */ - protected boolean negative = false; - /** Symbols used to format numbers */ - protected DecimalFormatSymbols symbols; - /** Flag indicating the use of the 0xAO (no-break space) grouping separator */ - protected boolean nbspSeparator; - /** Flag for display of the decimal separator */ - protected boolean alwaysShowDec; - /** Flag indicating that the buffer is modified and the Number value must be computed */ - protected boolean modified; - /** Flag indicating that the int part has a fixed length */ - protected boolean fixedInt = true; - /** Flag indicating that the decimal part has a fixed length */ - protected boolean fixedDec = true; - /** Length of the prefix part in the cache */ - protected int prefixLen = 0; - /** Length of the suffix part in the cache */ - protected int suffixLen = 0; - - /** - * Constructs a new instance with all defaults : - *
    - *
  • edit mask from NumberPatterns for the default locale
  • - *
  • display mask identical to the edit mask
  • - *
  • default locale
  • - *
- */ - public NumberFormatter() { - this(null, null, Locale.getDefault()); - } - - /** - * Constructs a new instance with default edit and display masks for the given - * locale. - * - * @param loc locale - */ - public NumberFormatter(Locale loc) { - this(null, null, loc); - } - - /** - * Constructs a new instance with the given edit mask. Display mask is - * identical to the edit mask, and locale is the default one. - * - * @param editPattern edit mask - */ - public NumberFormatter(String editPattern) { - this(editPattern, null, Locale.getDefault()); - } - - /** - * Constructs a new instance with the given edit mask and locale. Display mask - * is identical to the edit mask. - * - * @param editPattern edit mask - * @param loc locale - */ - public NumberFormatter(String editPattern, Locale loc) { - this(editPattern, null, loc); - } - - /** - * Constructs a new instance with the given edit and display masks. Uses the - * default locale. - * - * @param editPattern edit mask - * @param displayPattern display mask - */ - public NumberFormatter(String editPattern, String displayPattern) { - this(editPattern, displayPattern, Locale.getDefault()); - } - - /** - * Constructs a new instance with the given masks and locale. - * - * @param editPattern edit mask - * @param displayPattern display mask - * @param loc locale - */ - public NumberFormatter(String editPattern, String displayPattern, Locale loc) { - this.locale = loc; - alwaysShowDec = false; - setPatterns(editPattern, displayPattern, loc); - setValue(null); - } - - /** - * Clears a part of the edition cache. The start and len parameters are - * adjusted to avoid clearing in prefix and suffix parts of the cache. - * - * @param start beginning index - * @param len length of portion to clear - */ - protected void clearText(int start, int len) { - if ( start < prefixLen ) { - len -= prefixLen - start; - start = prefixLen; - } - if ( start + len >= editValue.length() - suffixLen ) { - len = editValue.length() - suffixLen - start; - } - int d = editValue.indexOf(EMPTY + symbols.getDecimalSeparator()); - boolean decimal = d >= start && d < start + len; - for (int i = 0; i < len; i++) { - char c = editValue.charAt(start + i); - if ( c >= '0' && c <= '9' ) { - if ( d < 0 || start + i < d ) { - intCount--; - } - } else if ( c == symbols.getMinusSign() ) { - negative = false; - } - } - editValue.delete(start, start + len); - if ( decimal && (start < editValue.length() || alwaysShowDec) ) { - editValue.insert(start, symbols.getDecimalSeparator()); - } - } - - /** - * Formats the edit buffer. Inserts group separators to the right places, - * deletes excess decimal digits and add 0 to complete to the minimal length - * of int and decimal parts. The position of the cursor is preserved. - * - * @param curseur Current position of the cursor - * @return New position of the cursor - */ - protected int format(int curseur) { - int i = prefixLen + (negative ? 1 : 0); - char c; - - // Inserts zeros in the int part - while ( intCount < zeroIntLen ) { - editValue.insert(i, '0'); - intCount++; - curseur++; - } - while ( intCount > zeroIntLen ) { - if ( editValue.charAt(i) == '0' ) { - intCount--; - } else if ( editValue.charAt(i) != symbols.getGroupingSeparator() ) { - break; - } - editValue.deleteCharAt(i); - if ( curseur > i ) curseur--; - } - - // Recreates the groups in the int part - if ( groupLen > 0 ) { - int n = intCount > groupLen ? groupLen - intCount % groupLen : 0; - if ( n == groupLen ) { - n = 0; - } - for (; i < editValue.length() - suffixLen; i++) { - c = editValue.charAt(i); - if ( c >= '0' && c <= '9' ) { - if ( n == groupLen ) { - editValue.insert(i, symbols.getGroupingSeparator()); - if ( curseur >= i ) { - curseur++; - } - n = 0; - } else { - n++; - } - } else if ( c == symbols.getGroupingSeparator() ) { - if ( n != groupLen ) { - editValue.deleteCharAt(i); - if ( curseur >= i ) { - curseur--; - } - i--; - } else { - n = 0; - } - } else if ( c == symbols.getDecimalSeparator() ) { - if ( i > 0 && editValue.charAt(i - 1) == symbols.getGroupingSeparator() ) { - editValue.deleteCharAt(i - 1); - if ( curseur >= i ) { - curseur--; - } - i--; - } - break; - } else { - break; - } - } - } - - // Truncates / completes by zeros the decimal part - i = editValue.indexOf(EMPTY + symbols.getDecimalSeparator()); - if ( i < 0 && (zeroDecimalLen > 0 || alwaysShowDec) ) { - i = editValue.length() - suffixLen; - editValue.insert(i, symbols.getDecimalSeparator()); - } - if ( i >= 0 ) { - int j; - for (j = i + 1; j < editValue.length() - suffixLen;) { - c = editValue.charAt(j); - if ( c == symbols.getGroupingSeparator() ) { - editValue.deleteCharAt(j); - } else if ( c < '0' || c > '9' ) { - break; - } else { - j++; - } - } - if ( fixedDec && (j - i - 1) > decimalLen ) { - editValue.delete(i + decimalLen + 1, j); - if ( curseur > i + decimalLen ) { - curseur = i + decimalLen; - } - } else { - while ( (j - i - 1) < zeroDecimalLen ) { - editValue.insert(j++, '0'); - } - } - } - - return curseur; - } - - /** - * Returns the default edit pattern for a given locale. - * - * @param loc locale - * @return Edit pattern - */ - protected String getDefaultPattern(Locale loc) { - String edit = cachedPatterns.get(loc); - if ( edit == null ) { - NumberFormat nf = NumberFormat.getNumberInstance(loc); - if ( ! (nf instanceof DecimalFormat) ) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - edit = ((DecimalFormat) nf).toPattern(); - int i = edit.indexOf(((DecimalFormat) nf).getDecimalFormatSymbols() - .getPatternSeparator()); - if ( i >= 0 ) { - edit = edit.substring(0, i); - } - cachedPatterns.put(loc, edit); - } - return edit; - } - - /** - * Returns the current value formatted for display. - * This method is called by FormattedText when the Text - * widget looses focus. - * The displayed value is the result of formatting on the Number - * with a DecimalFormat for the display pattern passed in - * constructor. - * - * @return display string if valid, empty string else - * @see ITextFormatter#getDisplayString() - */ - public String getDisplayString() { - return editValue.substring(0, prefixLen) - + ((getValue() != null - ? nfDisplay.format(value) : EMPTY)) - + editValue.substring(editValue.length() - suffixLen); - } - - /** - * Returns the current value formatted for editing. - * This method is called by FormattedText when the Text - * widget gains focus. - * The value returned is the content of the StringBuilder editValue - * used as cache. - * - * @return edit string - * @see ITextFormatter#getEditString() - */ - public String getEditString() { - return editValue.toString(); - } - - /** - * Returns the current value of the text control if it is a valid Number. - * If the buffer is flagged as modified, the value is recalculated by parsing - * with the nfEdit initialized with the edit pattern. If the - * number is not valid, returns null. - * - * @return current number value if valid, null else - * @see ITextFormatter#getValue() - */ - public Object getValue() { - if ( modified ) { - try { - value = nfEdit.parse(editValue.substring(prefixLen, editValue.length() - suffixLen)); - } catch (ParseException e1) { - if ( zeroIntLen + zeroDecimalLen == 0 - && (editValue.length() == 0 - || editValue.charAt(0) == symbols.getDecimalSeparator()) ) { - value = null; - } else { - value = new Integer(0); - } - } - modified = false; - } - return value; - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * A NumberFormatter always returns a Number value. - * - * @return The value type. - */ - public Class getValueType() { - return Number.class; - } - - /** - * Returns true if current edited value is empty, else returns - * false.
- * - * @return true if empty, else false - */ - public boolean isEmpty() { - return ! isValid(); - } - - /** - * Returns true if current edited value is valid, else returns - * false.
- * A NumberFormatter is valid if the cached value is not null. - * - * @return true if valid, else false - * @see ITextFormatter#isValid() - */ - public boolean isValid() { - return getValue() != null; - } - - /** - * Sets the flag to always display the decimal separator, even if the decimal - * part is empty. - * - * @param show true / false - */ - public void setDecimalSeparatorAlwaysShown(boolean show) { - alwaysShowDec = show; - int i = editValue.lastIndexOf(EMPTY + symbols.getDecimalSeparator()); - if ( alwaysShowDec ) { - if ( i == -1 ) { - editValue.append(symbols.getDecimalSeparator()); - } - } else { - if ( i > -1 && i == editValue.length() - 1 ) { - editValue.deleteCharAt(i); - } - } - } - - /** - * Sets the fixed length flags.
- * By default, int and decimal part of the pattern have a fixed length. - * - * @param fixedInt flag for int part - * @param fixedDec flag for decimal part - */ - public void setFixedLengths(boolean fixedInt, boolean fixedDec) { - this.fixedInt = fixedInt; - this.fixedDec = fixedDec; - } - - /** - * Sets the patterns and initializes the technical attributes used to manage - * the operations. - * - * @param edit edit pattern - * @param display display pattern - * @param loc Locale to use - * @throws IllegalArgumentException if a pattern is invalid - */ - protected void setPatterns(String edit, String display, Locale loc) { - // Symbols - symbols = new DecimalFormatSymbols(loc); - nbspSeparator = symbols.getGroupingSeparator() == 0xA0; - - // Get default edit pattern if null - if ( edit == null ) { - edit = getDefaultPattern(loc); - } - - // Analyze the edit pattern - boolean grouping = false; - boolean decimal = false; - groupLen = intLen = decimalLen = zeroIntLen = zeroDecimalLen = 0; - minus = false; - int i; - for (i = 0; i < edit.length(); i++) { - switch ( edit.charAt(i) ) { - case P_MINUS : - if ( i != 0 ) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - minus = true; - break; - case P_GROUP_SEP : - if ( ! decimal ) { - grouping = true; - groupLen = 0; - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - break; - case P_DECIMAL_SEP : - grouping = false; - decimal = true; - break; - case P_ZERODIGIT : - if ( decimal ) { - zeroDecimalLen++; - } else { - zeroIntLen++; - } - // Continue on P_DIGIT... - case P_DIGIT : - if ( decimal ) { - decimalLen++; - } else { - intLen++; - if ( grouping ) { - groupLen++; - } - } - break; - default : - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - editPattern = edit; - nfEdit = new DecimalFormat(minus ? editPattern.substring(1) : editPattern, - symbols); - editValue = new StringBuffer(); - - // Create the display formatter - nfDisplay = display != null ? new DecimalFormat(display, symbols) : nfEdit; - - // Initialize the edit cache - intCount = 0; - for (i = 0; i < zeroIntLen; i++) { - editValue.append('0'); - intCount++; - } - if ( alwaysShowDec || zeroDecimalLen > 0 ) { - editValue.append(symbols.getDecimalSeparator()); - } - for (i = 0; i < zeroDecimalLen; i++) { - editValue.append('0'); - } - } - - /** - * Sets a prefix to display before the value.
- * - * To clear the current prefix, call the setPrefix method with a - * null parameter. - * - * @param prefix prefix to display, or null to clear - */ - protected void setPrefix(String prefix) { - if ( prefixLen > 0 ) { - editValue.delete(0, prefixLen); - prefixLen = 0; - } - if ( prefix != null ) { - editValue.insert(0, prefix); - prefixLen = prefix.length(); - } - } - - /** - * Sets a suffix to display after the value.
- * - * To clear the current suffix, call the setSuffix method with a - * null parameter. - * - * @param suffix suffix to display, or null to clear - */ - protected void setSuffix(String suffix) { - if ( suffixLen > 0 ) { - editValue.delete(editValue.length() - suffixLen, editValue.length()); - suffixLen = 0; - } - if ( suffix != null ) { - editValue.append(suffix); - suffixLen = suffix.length(); - } - } - - /** - * Sets the value to edit. The value provided must be a Number. - * - * @param value number value - * @throws IllegalArgumentException if not a number - * @see ITextFormatter#setValue(java.lang.Object) - */ - public void setValue(Object value) { - boolean decimal = false; - if ( value instanceof Number ) { - this.value = (Number) value; - editValue.delete(prefixLen, editValue.length() - suffixLen); - editValue.insert(prefixLen, nfEdit.format(this.value)); - intCount = 0; - for (int i = prefixLen; i < editValue.length() - suffixLen; i++) { - char c = editValue.charAt(i); - if ( c == symbols.getDecimalSeparator() ) { - decimal = true; - } else if ( c >= '0' && c <= '9' ) { - if ( ! decimal ) { - intCount++; - } - } - } - modified = false; - } else if ( value == null ) { - clearText(0, editValue.length()); - updateText(editValue.toString(), format(0)); - if ( zeroIntLen + zeroDecimalLen > 0 ) { - this.value = new Integer(0); - } else { - this.value = null; - } - modified = false; - } else { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - - /** - * Handles a VerifyEvent sent when the text is about to be modified. - * This method is the entry point of all operations of formatting. - * - * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) - */ - public void verifyText(VerifyEvent e) { - if ( ignore ) { - return; - } - - int p; // Current insertion position in the edit cache - e.doit = false; - - if ( e.keyCode == SWT.BS || e.keyCode == SWT.DEL ) { - clearText(e.start, (e.end > e.start) ? e.end - e.start : 1); - p = e.start; - } else { - if ( e.end > e.start ) { - clearText(e.start, e.end - e.start); - } - p = e.start; - - int d = editValue.indexOf(EMPTY + symbols.getDecimalSeparator()); // Decimal separator position - for (int i = 0; i < e.text.length(); i++) { - if ( p < prefixLen || p > editValue.length() - suffixLen ) break; - char c = e.text.charAt(i); - if ( c >= '0' && c <= '9' ) { - // Controls the number of digits by group - if ( d >= 0 && p > d ) { - if ( fixedDec && p > d + decimalLen ) { - beep(); - break; - } - } else { - if ( fixedInt && intCount >= intLen ) { - beep(); - break; - } - if ( d >= 0 ) { - d++; - } - intCount++; - } - // Insert the char - editValue.insert(p++, c); - } else if ( groupLen > 0 - && (c == symbols.getGroupingSeparator() - || (c == ' ' && nbspSeparator)) ) { - /* - * Some locales (eg. French) return a no-break space as the grouping - * separator. This character is not natural to use for users. So we - * recognize too the simple space as the grouping separator. - * - * Java bug: 4510618 - */ - if ( d >= 0 && p > d ) { - beep(); - break; - } - int n = editValue.indexOf(EMPTY + symbols.getGroupingSeparator(), p); - if ( n > p ) { - p = n + 1; - } - } else if ( c == symbols.getMinusSign() ) { - if ( p != prefixLen || ! minus ) { - beep(); // Minus sign only possible in first position - break; - } - if ( this.editValue.length() == 0 || editValue.charAt(0) != c ) { - editValue.insert(p++, c); - negative = true; - d++; - } else { - editValue.deleteCharAt(0); - negative = false; - d--; - } - } else if ( c == symbols.getDecimalSeparator() - && (decimalLen > 0 || ! fixedDec ) ) { - if ( d >= 0 ) { - if ( d < p ) { - beep(); - break; - } else { - p = d + 1; - continue; - } - } - d = p; - editValue.insert(p++, c); - intCount = 0; - for (int j = 0; j < d; j++) { - char c1 = editValue.charAt(j); - if ( c1 >= '0' && c1 <= '9' ) { - intCount++; - } - } - } else { - beep(); - break; - } - } - } - p = format(p); - modified = true; - updateText(getEditString(), p); - } -} +/******************************************************************************* + * Copyright (c) 2005, 2009 Eric Wuillai. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eric Wuillai (eric@wdev91.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.Hashtable; +import java.util.Locale; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.VerifyEvent; + +/** + * This class provides formatting of Number values in a + * FormattedText.

+ * + * Formatter is composed of an edit pattern and a display pattern.
+ * Display pattern uses the same syntax than DecimalFormat, and + * uses it to compute the value to display.
+ * Edit pattern is more limited and composed of two part, the int part and + * the decimal part. Formatting characters allow to specify number of digits, + * minimal length, decimal position, grouping and negative sign.

+ * + *

Patterns Characters

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
SymbolMeaning
0Digit
#Digit, zero shows as absent
.Decimal separator
-Minus sign
,Grouping separator
+ * + *

Examples

+ *
    + *
  • new NumberFormatter("#,##0.00") - 1234.5 will edit and + * display as "1,234.50".
  • + *
+ */ +public class NumberFormatter extends AbstractFormatter { + private static final char P_DIGIT = '#'; + private static final char P_ZERODIGIT = '0'; + private static final char P_DECIMAL_SEP = '.'; + private static final char P_GROUP_SEP = ','; + private static final char P_MINUS = '-'; + + /** Cache of number patterns by locales */ + protected static Hashtable cachedPatterns = new Hashtable<>(); + + /** Number formatter for display */ + protected DecimalFormat nfDisplay; + /** Number formatter for display edit */ + protected DecimalFormat nfEdit; + /** Buffer for the edit value */ + protected StringBuffer editValue; + /** Number containing the current value */ + protected Number value; + /** Edit pattern */ + protected String editPattern; + /** The locale used */ + protected Locale locale; + /** Length of groups (0 if no group separator) */ + protected int groupLen = 0; + /** Current number of digits of the int part */ + protected int intCount = 0; + /** Maximum number of digits of the int part */ + protected int intLen = 0; + /** Maximum number of digits of the decimal part */ + protected int decimalLen = 0; + /** Minimum number of digits of the int part (complement by 0) */ + protected int zeroIntLen = 0; + /** Minimum number of digits of the decimal part (complement by 0) */ + protected int zeroDecimalLen = 0; + /** Flag for display of the negative sign */ + protected boolean minus = false; + /** Flag indicating that the current value is negative */ + protected boolean negative = false; + /** Symbols used to format numbers */ + protected DecimalFormatSymbols symbols; + /** Flag indicating the use of the 0xAO (no-break space) grouping separator */ + protected boolean nbspSeparator; + /** Flag for display of the decimal separator */ + protected boolean alwaysShowDec; + /** Flag indicating that the buffer is modified and the Number value must be computed */ + protected boolean modified; + /** Flag indicating that the int part has a fixed length */ + protected boolean fixedInt = true; + /** Flag indicating that the decimal part has a fixed length */ + protected boolean fixedDec = true; + /** Length of the prefix part in the cache */ + protected int prefixLen = 0; + /** Length of the suffix part in the cache */ + protected int suffixLen = 0; + + /** + * Constructs a new instance with all defaults : + *
    + *
  • edit mask from NumberPatterns for the default locale
  • + *
  • display mask identical to the edit mask
  • + *
  • default locale
  • + *
+ */ + public NumberFormatter() { + this(null, null, Locale.getDefault()); + } + + /** + * Constructs a new instance with default edit and display masks for the given + * locale. + * + * @param loc locale + */ + public NumberFormatter(Locale loc) { + this(null, null, loc); + } + + /** + * Constructs a new instance with the given edit mask. Display mask is + * identical to the edit mask, and locale is the default one. + * + * @param editPattern edit mask + */ + public NumberFormatter(String editPattern) { + this(editPattern, null, Locale.getDefault()); + } + + /** + * Constructs a new instance with the given edit mask and locale. Display mask + * is identical to the edit mask. + * + * @param editPattern edit mask + * @param loc locale + */ + public NumberFormatter(String editPattern, Locale loc) { + this(editPattern, null, loc); + } + + /** + * Constructs a new instance with the given edit and display masks. Uses the + * default locale. + * + * @param editPattern edit mask + * @param displayPattern display mask + */ + public NumberFormatter(String editPattern, String displayPattern) { + this(editPattern, displayPattern, Locale.getDefault()); + } + + /** + * Constructs a new instance with the given masks and locale. + * + * @param editPattern edit mask + * @param displayPattern display mask + * @param loc locale + */ + public NumberFormatter(String editPattern, String displayPattern, Locale loc) { + this.locale = loc; + alwaysShowDec = false; + setPatterns(editPattern, displayPattern, loc); + setValue(null); + } + + /** + * Clears a part of the edition cache. The start and len parameters are + * adjusted to avoid clearing in prefix and suffix parts of the cache. + * + * @param start beginning index + * @param len length of portion to clear + */ + protected void clearText(int start, int len) { + if ( start < prefixLen ) { + len -= prefixLen - start; + start = prefixLen; + } + if ( start + len >= editValue.length() - suffixLen ) { + len = editValue.length() - suffixLen - start; + } + int d = editValue.indexOf(EMPTY + symbols.getDecimalSeparator()); + boolean decimal = d >= start && d < start + len; + for (int i = 0; i < len; i++) { + char c = editValue.charAt(start + i); + if ( c >= '0' && c <= '9' ) { + if ( d < 0 || start + i < d ) { + intCount--; + } + } else if ( c == symbols.getMinusSign() ) { + negative = false; + } + } + editValue.delete(start, start + len); + if ( decimal && (start < editValue.length() || alwaysShowDec) ) { + editValue.insert(start, symbols.getDecimalSeparator()); + } + } + + /** + * Formats the edit buffer. Inserts group separators to the right places, + * deletes excess decimal digits and add 0 to complete to the minimal length + * of int and decimal parts. The position of the cursor is preserved. + * + * @param curseur Current position of the cursor + * @return New position of the cursor + */ + protected int format(int curseur) { + int i = prefixLen + (negative ? 1 : 0); + char c; + + // Inserts zeros in the int part + while ( intCount < zeroIntLen ) { + editValue.insert(i, '0'); + intCount++; + curseur++; + } + while ( intCount > zeroIntLen ) { + if ( editValue.charAt(i) == '0' ) { + intCount--; + } else if ( editValue.charAt(i) != symbols.getGroupingSeparator() ) { + break; + } + editValue.deleteCharAt(i); + if ( curseur > i ) curseur--; + } + + // Recreates the groups in the int part + if ( groupLen > 0 ) { + int n = intCount > groupLen ? groupLen - intCount % groupLen : 0; + if ( n == groupLen ) { + n = 0; + } + for (; i < editValue.length() - suffixLen; i++) { + c = editValue.charAt(i); + if ( c >= '0' && c <= '9' ) { + if ( n == groupLen ) { + editValue.insert(i, symbols.getGroupingSeparator()); + if ( curseur >= i ) { + curseur++; + } + n = 0; + } else { + n++; + } + } else if ( c == symbols.getGroupingSeparator() ) { + if ( n != groupLen ) { + editValue.deleteCharAt(i); + if ( curseur >= i ) { + curseur--; + } + i--; + } else { + n = 0; + } + } else if ( c == symbols.getDecimalSeparator() ) { + if ( i > 0 && editValue.charAt(i - 1) == symbols.getGroupingSeparator() ) { + editValue.deleteCharAt(i - 1); + if ( curseur >= i ) { + curseur--; + } + i--; + } + break; + } else { + break; + } + } + } + + // Truncates / completes by zeros the decimal part + i = editValue.indexOf(EMPTY + symbols.getDecimalSeparator()); + if ( i < 0 && (zeroDecimalLen > 0 || alwaysShowDec) ) { + i = editValue.length() - suffixLen; + editValue.insert(i, symbols.getDecimalSeparator()); + } + if ( i >= 0 ) { + int j; + for (j = i + 1; j < editValue.length() - suffixLen;) { + c = editValue.charAt(j); + if ( c == symbols.getGroupingSeparator() ) { + editValue.deleteCharAt(j); + } else if ( c < '0' || c > '9' ) { + break; + } else { + j++; + } + } + if ( fixedDec && (j - i - 1) > decimalLen ) { + editValue.delete(i + decimalLen + 1, j); + if ( curseur > i + decimalLen ) { + curseur = i + decimalLen; + } + } else { + while ( (j - i - 1) < zeroDecimalLen ) { + editValue.insert(j++, '0'); + } + } + } + + return curseur; + } + + /** + * Returns the default edit pattern for a given locale. + * + * @param loc locale + * @return Edit pattern + */ + protected String getDefaultPattern(Locale loc) { + String edit = cachedPatterns.get(loc); + if ( edit == null ) { + NumberFormat nf = NumberFormat.getNumberInstance(loc); + if ( ! (nf instanceof DecimalFormat) ) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + edit = ((DecimalFormat) nf).toPattern(); + int i = edit.indexOf(((DecimalFormat) nf).getDecimalFormatSymbols() + .getPatternSeparator()); + if ( i >= 0 ) { + edit = edit.substring(0, i); + } + cachedPatterns.put(loc, edit); + } + return edit; + } + + /** + * Returns the current value formatted for display. + * This method is called by FormattedText when the Text + * widget looses focus. + * The displayed value is the result of formatting on the Number + * with a DecimalFormat for the display pattern passed in + * constructor. + * + * @return display string if valid, empty string else + * @see ITextFormatter#getDisplayString() + */ + public String getDisplayString() { + return editValue.substring(0, prefixLen) + + ((getValue() != null + ? nfDisplay.format(value) : EMPTY)) + + editValue.substring(editValue.length() - suffixLen); + } + + /** + * Returns the current value formatted for editing. + * This method is called by FormattedText when the Text + * widget gains focus. + * The value returned is the content of the StringBuilder editValue + * used as cache. + * + * @return edit string + * @see ITextFormatter#getEditString() + */ + public String getEditString() { + return editValue.toString(); + } + + /** + * Returns the current value of the text control if it is a valid Number. + * If the buffer is flagged as modified, the value is recalculated by parsing + * with the nfEdit initialized with the edit pattern. If the + * number is not valid, returns null. + * + * @return current number value if valid, null else + * @see ITextFormatter#getValue() + */ + public Object getValue() { + if ( modified ) { + try { + value = nfEdit.parse(editValue.substring(prefixLen, editValue.length() - suffixLen)); + } catch (ParseException e1) { + if ( zeroIntLen + zeroDecimalLen == 0 + && (editValue.length() == 0 + || editValue.charAt(0) == symbols.getDecimalSeparator()) ) { + value = null; + } else { + value = new Integer(0); + } + } + modified = false; + } + return value; + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * A NumberFormatter always returns a Number value. + * + * @return The value type. + */ + public Class getValueType() { + return Number.class; + } + + /** + * Returns true if current edited value is empty, else returns + * false.
+ * + * @return true if empty, else false + */ + public boolean isEmpty() { + return ! isValid(); + } + + /** + * Returns true if current edited value is valid, else returns + * false.
+ * A NumberFormatter is valid if the cached value is not null. + * + * @return true if valid, else false + * @see ITextFormatter#isValid() + */ + public boolean isValid() { + return getValue() != null; + } + + /** + * Sets the flag to always display the decimal separator, even if the decimal + * part is empty. + * + * @param show true / false + */ + public void setDecimalSeparatorAlwaysShown(boolean show) { + alwaysShowDec = show; + int i = editValue.lastIndexOf(EMPTY + symbols.getDecimalSeparator()); + if ( alwaysShowDec ) { + if ( i == -1 ) { + editValue.append(symbols.getDecimalSeparator()); + } + } else { + if ( i > -1 && i == editValue.length() - 1 ) { + editValue.deleteCharAt(i); + } + } + } + + /** + * Sets the fixed length flags.
+ * By default, int and decimal part of the pattern have a fixed length. + * + * @param fixedInt flag for int part + * @param fixedDec flag for decimal part + */ + public void setFixedLengths(boolean fixedInt, boolean fixedDec) { + this.fixedInt = fixedInt; + this.fixedDec = fixedDec; + } + + /** + * Sets the patterns and initializes the technical attributes used to manage + * the operations. + * + * @param edit edit pattern + * @param display display pattern + * @param loc Locale to use + * @throws IllegalArgumentException if a pattern is invalid + */ + protected void setPatterns(String edit, String display, Locale loc) { + // Symbols + symbols = new DecimalFormatSymbols(loc); + nbspSeparator = symbols.getGroupingSeparator() == 0xA0; + + // Get default edit pattern if null + if ( edit == null ) { + edit = getDefaultPattern(loc); + } + + // Analyze the edit pattern + boolean grouping = false; + boolean decimal = false; + groupLen = intLen = decimalLen = zeroIntLen = zeroDecimalLen = 0; + minus = false; + int i; + for (i = 0; i < edit.length(); i++) { + switch ( edit.charAt(i) ) { + case P_MINUS : + if ( i != 0 ) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + minus = true; + break; + case P_GROUP_SEP : + if ( ! decimal ) { + grouping = true; + groupLen = 0; + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + break; + case P_DECIMAL_SEP : + grouping = false; + decimal = true; + break; + case P_ZERODIGIT : + if ( decimal ) { + zeroDecimalLen++; + } else { + zeroIntLen++; + } + // Continue on P_DIGIT... + case P_DIGIT : + if ( decimal ) { + decimalLen++; + } else { + intLen++; + if ( grouping ) { + groupLen++; + } + } + break; + default : + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + editPattern = edit; + nfEdit = new DecimalFormat(minus ? editPattern.substring(1) : editPattern, + symbols); + editValue = new StringBuffer(); + + // Create the display formatter + nfDisplay = display != null ? new DecimalFormat(display, symbols) : nfEdit; + + // Initialize the edit cache + intCount = 0; + for (i = 0; i < zeroIntLen; i++) { + editValue.append('0'); + intCount++; + } + if ( alwaysShowDec || zeroDecimalLen > 0 ) { + editValue.append(symbols.getDecimalSeparator()); + } + for (i = 0; i < zeroDecimalLen; i++) { + editValue.append('0'); + } + } + + /** + * Sets a prefix to display before the value.
+ * + * To clear the current prefix, call the setPrefix method with a + * null parameter. + * + * @param prefix prefix to display, or null to clear + */ + protected void setPrefix(String prefix) { + if ( prefixLen > 0 ) { + editValue.delete(0, prefixLen); + prefixLen = 0; + } + if ( prefix != null ) { + editValue.insert(0, prefix); + prefixLen = prefix.length(); + } + } + + /** + * Sets a suffix to display after the value.
+ * + * To clear the current suffix, call the setSuffix method with a + * null parameter. + * + * @param suffix suffix to display, or null to clear + */ + protected void setSuffix(String suffix) { + if ( suffixLen > 0 ) { + editValue.delete(editValue.length() - suffixLen, editValue.length()); + suffixLen = 0; + } + if ( suffix != null ) { + editValue.append(suffix); + suffixLen = suffix.length(); + } + } + + /** + * Sets the value to edit. The value provided must be a Number. + * + * @param value number value + * @throws IllegalArgumentException if not a number + * @see ITextFormatter#setValue(java.lang.Object) + */ + public void setValue(Object value) { + boolean decimal = false; + if ( value instanceof Number ) { + this.value = (Number) value; + editValue.delete(prefixLen, editValue.length() - suffixLen); + editValue.insert(prefixLen, nfEdit.format(this.value)); + intCount = 0; + for (int i = prefixLen; i < editValue.length() - suffixLen; i++) { + char c = editValue.charAt(i); + if ( c == symbols.getDecimalSeparator() ) { + decimal = true; + } else if ( c >= '0' && c <= '9' ) { + if ( ! decimal ) { + intCount++; + } + } + } + modified = false; + } else if ( value == null ) { + clearText(0, editValue.length()); + updateText(editValue.toString(), format(0)); + if ( zeroIntLen + zeroDecimalLen > 0 ) { + this.value = new Integer(0); + } else { + this.value = null; + } + modified = false; + } else { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + + /** + * Handles a VerifyEvent sent when the text is about to be modified. + * This method is the entry point of all operations of formatting. + * + * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) + */ + public void verifyText(VerifyEvent e) { + if ( ignore ) { + return; + } + + int p; // Current insertion position in the edit cache + e.doit = false; + + if ( e.keyCode == SWT.BS || e.keyCode == SWT.DEL ) { + clearText(e.start, (e.end > e.start) ? e.end - e.start : 1); + p = e.start; + } else { + if ( e.end > e.start ) { + clearText(e.start, e.end - e.start); + } + p = e.start; + + int d = editValue.indexOf(EMPTY + symbols.getDecimalSeparator()); // Decimal separator position + for (int i = 0; i < e.text.length(); i++) { + if ( p < prefixLen || p > editValue.length() - suffixLen ) break; + char c = e.text.charAt(i); + if ( c >= '0' && c <= '9' ) { + // Controls the number of digits by group + if ( d >= 0 && p > d ) { + if ( fixedDec && p > d + decimalLen ) { + beep(); + break; + } + } else { + if ( fixedInt && intCount >= intLen ) { + beep(); + break; + } + if ( d >= 0 ) { + d++; + } + intCount++; + } + // Insert the char + editValue.insert(p++, c); + } else if ( groupLen > 0 + && (c == symbols.getGroupingSeparator() + || (c == ' ' && nbspSeparator)) ) { + /* + * Some locales (eg. French) return a no-break space as the grouping + * separator. This character is not natural to use for users. So we + * recognize too the simple space as the grouping separator. + * + * Java bug: 4510618 + */ + if ( d >= 0 && p > d ) { + beep(); + break; + } + int n = editValue.indexOf(EMPTY + symbols.getGroupingSeparator(), p); + if ( n > p ) { + p = n + 1; + } + } else if ( c == symbols.getMinusSign() ) { + if ( p != prefixLen || ! minus ) { + beep(); // Minus sign only possible in first position + break; + } + if ( this.editValue.length() == 0 || editValue.charAt(0) != c ) { + editValue.insert(p++, c); + negative = true; + d++; + } else { + editValue.deleteCharAt(0); + negative = false; + d--; + } + } else if ( c == symbols.getDecimalSeparator() + && (decimalLen > 0 || ! fixedDec ) ) { + if ( d >= 0 ) { + if ( d < p ) { + beep(); + break; + } else { + p = d + 1; + continue; + } + } + d = p; + editValue.insert(p++, c); + intCount = 0; + for (int j = 0; j < d; j++) { + char c1 = editValue.charAt(j); + if ( c1 >= '0' && c1 <= '9' ) { + intCount++; + } + } + } else { + beep(); + break; + } + } + } + p = format(p); + modified = true; + updateText(getEditString(), p); + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/ShortFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/ShortFormatter.java index 795d2ae1a..9629923f5 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/ShortFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/ShortFormatter.java @@ -1,119 +1,119 @@ -/******************************************************************************* - * Copyright (c) 2014 Mario Hofmann. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Mario Hofmann (eclispe@hofmann-coswig.de) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import java.util.Locale; - -/** - * This class provides formatting of {@link Short} values in a {@link FormattedText}. - *

- * ShortFormatter returns different numeric types based on the current - * value in the Text field. ShortFormatter is an override of NumberFormatter - * allowing to guaranty to always return {@link Short} values ({@link Number#shortValue()}). - *

- */ -public class ShortFormatter extends NumberFormatter { - /** - * Constructs a new instance with all defaults. - * - * @see NumberFormatter#NumberFormatter() - */ - public ShortFormatter() { - super(); - } - - /** - * Constructs a new instance with default edit and display masks for the given - * locale. - * - * @param loc the {@link Locale locale} - */ - public ShortFormatter(Locale loc) { - super(loc); - } - - /** - * Constructs a new instance with the given edit mask and locale. Display mask - * is identical to the edit mask. - * - * @param editPattern the edit mask - * @param loc the {@link Locale locale} - */ - public ShortFormatter(String editPattern, Locale loc) { - super(editPattern, loc); - } - - /** - * Constructs a new instance with the given masks and locale. - * - * @param editPattern the edit mask - * @param displayPattern the display mask - * @param loc the {@link Locale locale} - */ - public ShortFormatter(String editPattern, String displayPattern, Locale loc) { - super(editPattern, displayPattern, loc); - } - - /** - * Constructs a new instance with the given edit and display masks. Uses the - * default locale. - * - * @param editPattern the edit mask - * @param displayPattern the display mask - */ - public ShortFormatter(String editPattern, String displayPattern) { - super(editPattern, displayPattern); - } - - /** - * Constructs a new instance with the given edit mask. Display mask is - * identical to the edit mask, and locale is the default one. - * - * @param editPattern the edit mask - */ - public ShortFormatter(String editPattern) { - super(editPattern); - } - - /** - * Returns the current value of the text control if it is a valid {@link Short}. - * If the buffer is flagged as modified, the value is recalculated by parsing - * with the {@code nfEdit} initialized with the edit pattern. If the - * number is not valid, returns {@code null}. - * - * @return current {@link Short} value if valid, else {@code null} - * @see ITextFormatter#getValue() - */ - public Object getValue() { - Object value = super.getValue(); - if (value instanceof Short) { - return value; - } else if (value instanceof Number) { - return new Short(((Number) value).shortValue()); - } else { - return null; - } - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * A ShortFormatter always returns an Short value. - * - * @return The value type. - */ - public Class getValueType() { - return Short.class; - } -} +/******************************************************************************* + * Copyright (c) 2014 Mario Hofmann. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Mario Hofmann (eclispe@hofmann-coswig.de) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import java.util.Locale; + +/** + * This class provides formatting of {@link Short} values in a {@link FormattedText}. + *

+ * ShortFormatter returns different numeric types based on the current + * value in the Text field. ShortFormatter is an override of NumberFormatter + * allowing to guaranty to always return {@link Short} values ({@link Number#shortValue()}). + *

+ */ +public class ShortFormatter extends NumberFormatter { + /** + * Constructs a new instance with all defaults. + * + * @see NumberFormatter#NumberFormatter() + */ + public ShortFormatter() { + super(); + } + + /** + * Constructs a new instance with default edit and display masks for the given + * locale. + * + * @param loc the {@link Locale locale} + */ + public ShortFormatter(Locale loc) { + super(loc); + } + + /** + * Constructs a new instance with the given edit mask and locale. Display mask + * is identical to the edit mask. + * + * @param editPattern the edit mask + * @param loc the {@link Locale locale} + */ + public ShortFormatter(String editPattern, Locale loc) { + super(editPattern, loc); + } + + /** + * Constructs a new instance with the given masks and locale. + * + * @param editPattern the edit mask + * @param displayPattern the display mask + * @param loc the {@link Locale locale} + */ + public ShortFormatter(String editPattern, String displayPattern, Locale loc) { + super(editPattern, displayPattern, loc); + } + + /** + * Constructs a new instance with the given edit and display masks. Uses the + * default locale. + * + * @param editPattern the edit mask + * @param displayPattern the display mask + */ + public ShortFormatter(String editPattern, String displayPattern) { + super(editPattern, displayPattern); + } + + /** + * Constructs a new instance with the given edit mask. Display mask is + * identical to the edit mask, and locale is the default one. + * + * @param editPattern the edit mask + */ + public ShortFormatter(String editPattern) { + super(editPattern); + } + + /** + * Returns the current value of the text control if it is a valid {@link Short}. + * If the buffer is flagged as modified, the value is recalculated by parsing + * with the {@code nfEdit} initialized with the edit pattern. If the + * number is not valid, returns {@code null}. + * + * @return current {@link Short} value if valid, else {@code null} + * @see ITextFormatter#getValue() + */ + public Object getValue() { + Object value = super.getValue(); + if (value instanceof Short) { + return value; + } else if (value instanceof Number) { + return new Short(((Number) value).shortValue()); + } else { + return null; + } + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * A ShortFormatter always returns an Short value. + * + * @return The value type. + */ + public Class getValueType() { + return Short.class; + } +} diff --git a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/StringFormatter.java b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/StringFormatter.java index 54aa5035f..ac068586d 100644 --- a/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/StringFormatter.java +++ b/widgets/formattedtext/org.eclipse.nebula.widgets.formattedtext/src/org/eclipse/nebula/widgets/formattedtext/StringFormatter.java @@ -1,123 +1,123 @@ -/******************************************************************************* - * Copyright (c) 2005, 2009 Eric Wuillai. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Eric Wuillai (eric@wdev91.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.formattedtext; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.VerifyEvent; - -/** - * Default formatter for the String class.
- * This formatter is a kind of NullFormatter and do no formatting, allowing - * the edit of simple String values, without constraints.
- * It is registered in the DefaultFormatterFactory as the default formatter - * for String values. - */ -public class StringFormatter extends AbstractFormatter { - /** - * Returns the current value formatted for display.

- * There is no difference in this formatter between edit and display values. - * So this method returns the edit string. - * - * @return display string - * @see ITextFormatter#getDisplayString() - */ - public String getDisplayString() { - return getEditString(); - } - - /** - * Returns the current value formatted for editing. - * This method is called by FormattedText when the Text - * widget gains focus.
- * This formatter has no formatting features. So it simply return the Text - * widget content. - * - * @return edit string - * @see ITextFormatter#getEditString() - */ - public String getEditString() { - return text.getText(); - } - - /** - * Returns the current value.
- * This formatter has no formatting features. So it simply return the Text - * widget content. - * - * @return current string value - * @see ITextFormatter#getValue() - */ - public Object getValue() { - return text.getText(); - } - - /** - * Returns the type of value this {@link ITextFormatter} handles, - * i.e. returns in {@link #getValue()}.
- * A StringFormatter always returns a String value. - * - * @return The value type. - */ - public Class getValueType() { - return String.class; - } - - /** - * Returns true if current edited value is empty, else returns - * false.
- * A string is empty if its length is 0. - * - * @return true if empty, else false - */ - public boolean isEmpty() { - return text.getText().length() == 0; - } - - /** - * Returns true if current edited value is valid, else returns - * false.
- * StringFormatter always return true. - * - * @return true - * @see ITextFormatter#isValid() - */ - public boolean isValid() { - return true; - } - - /** - * Sets the value to edit. The value provided must be a String. - * The Text widget is simply updated with the value. - * - * @param value string value - * @throws IllegalArgumentException if not a string - * @see ITextFormatter#setValue(java.lang.Object) - */ - public void setValue(Object value) { - if ( ! (value instanceof String) ) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - text.setText((String) value); - } - - /** - * Handles a VerifyEvent sent when the text is about to be modified. - * This method is the entry point of all operations of formatting.
- * This formatter has no formatting features. So this method do nothing. - * - * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) - */ - public void verifyText(VerifyEvent e) { - } -} +/******************************************************************************* + * Copyright (c) 2005, 2009 Eric Wuillai. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Eric Wuillai (eric@wdev91.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.formattedtext; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.VerifyEvent; + +/** + * Default formatter for the String class.
+ * This formatter is a kind of NullFormatter and do no formatting, allowing + * the edit of simple String values, without constraints.
+ * It is registered in the DefaultFormatterFactory as the default formatter + * for String values. + */ +public class StringFormatter extends AbstractFormatter { + /** + * Returns the current value formatted for display.

+ * There is no difference in this formatter between edit and display values. + * So this method returns the edit string. + * + * @return display string + * @see ITextFormatter#getDisplayString() + */ + public String getDisplayString() { + return getEditString(); + } + + /** + * Returns the current value formatted for editing. + * This method is called by FormattedText when the Text + * widget gains focus.
+ * This formatter has no formatting features. So it simply return the Text + * widget content. + * + * @return edit string + * @see ITextFormatter#getEditString() + */ + public String getEditString() { + return text.getText(); + } + + /** + * Returns the current value.
+ * This formatter has no formatting features. So it simply return the Text + * widget content. + * + * @return current string value + * @see ITextFormatter#getValue() + */ + public Object getValue() { + return text.getText(); + } + + /** + * Returns the type of value this {@link ITextFormatter} handles, + * i.e. returns in {@link #getValue()}.
+ * A StringFormatter always returns a String value. + * + * @return The value type. + */ + public Class getValueType() { + return String.class; + } + + /** + * Returns true if current edited value is empty, else returns + * false.
+ * A string is empty if its length is 0. + * + * @return true if empty, else false + */ + public boolean isEmpty() { + return text.getText().length() == 0; + } + + /** + * Returns true if current edited value is valid, else returns + * false.
+ * StringFormatter always return true. + * + * @return true + * @see ITextFormatter#isValid() + */ + public boolean isValid() { + return true; + } + + /** + * Sets the value to edit. The value provided must be a String. + * The Text widget is simply updated with the value. + * + * @param value string value + * @throws IllegalArgumentException if not a string + * @see ITextFormatter#setValue(java.lang.Object) + */ + public void setValue(Object value) { + if ( ! (value instanceof String) ) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + text.setText((String) value); + } + + /** + * Handles a VerifyEvent sent when the text is about to be modified. + * This method is the entry point of all operations of formatting.
+ * This formatter has no formatting features. So this method do nothing. + * + * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) + */ + public void verifyText(VerifyEvent e) { + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/.classpath b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/.classpath +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/.settings/org.eclipse.jdt.core.prefs b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/META-INF/MANIFEST.MF b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/META-INF/MANIFEST.MF index c1b46de72..e23c5a47a 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/META-INF/MANIFEST.MF +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/META-INF/MANIFEST.MF @@ -1,13 +1,13 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Gallery Example -Bundle-SymbolicName: org.eclipse.nebula.widgets.gallery.example;singleton:=true -Bundle-Version: 1.0.0.qualifier -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.nebula.widgets.gallery;bundle-version="0.5.3", - org.eclipse.nebula.examples;bundle-version="1.0.4" -Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.widgets.gallery.example +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Gallery Example +Bundle-SymbolicName: org.eclipse.nebula.widgets.gallery.example;singleton:=true +Bundle-Version: 1.0.0.qualifier +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.nebula.widgets.gallery;bundle-version="0.5.3", + org.eclipse.nebula.examples;bundle-version="1.0.4" +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.widgets.gallery.example diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/src/org/eclipse/nebula/widgets/gallery/example/AnimationExampleTab.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/src/org/eclipse/nebula/widgets/gallery/example/AnimationExampleTab.java index de0e240da..bc14989b8 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/src/org/eclipse/nebula/widgets/gallery/example/AnimationExampleTab.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/src/org/eclipse/nebula/widgets/gallery/example/AnimationExampleTab.java @@ -1,61 +1,61 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.gallery.example; - -import org.eclipse.nebula.animation.AnimationRunner; -import org.eclipse.nebula.animation.effects.AlphaEffect; -import org.eclipse.nebula.animation.movement.ExpoOut; -import org.eclipse.nebula.examples.AbstractExampleTab; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PlatformUI; - -/** - * Demonstrates the Nebula animation package - * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - */ -public class AnimationExampleTab extends AbstractExampleTab { - - public String[] createLinks() { - String[] links = new String[1]; - links[0] = "Gallery Home Page (includes Animation)"; - return links; - } - - public Control createControl(Composite parent) { - Composite c = new Composite(parent, SWT.None); - c.setLayout(new RowLayout()); - Button b = new Button(c, SWT.None); - b.setText("Fade"); - b.addListener(SWT.Selection, e -> { - Shell s = new Shell(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.CLOSE | SWT.TITLE); - s.setAlpha(0); - s.open(); - AnimationRunner runner = new AnimationRunner(); - runner.runEffect(new AlphaEffect(s, 0, 255, 1000, new ExpoOut(), null, null)); - AlphaEffect.fadeOnClose(s, 1000, new ExpoOut(), runner); - }); - return c; - } - - public void createParameters(Composite parent) { - parent.setLayout(new RowLayout()); - } - -} +/******************************************************************************* + * Copyright (c) 2006-2009 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.gallery.example; + +import org.eclipse.nebula.animation.AnimationRunner; +import org.eclipse.nebula.animation.effects.AlphaEffect; +import org.eclipse.nebula.animation.movement.ExpoOut; +import org.eclipse.nebula.examples.AbstractExampleTab; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +/** + * Demonstrates the Nebula animation package + * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + */ +public class AnimationExampleTab extends AbstractExampleTab { + + public String[] createLinks() { + String[] links = new String[1]; + links[0] = "Gallery Home Page (includes Animation)"; + return links; + } + + public Control createControl(Composite parent) { + Composite c = new Composite(parent, SWT.None); + c.setLayout(new RowLayout()); + Button b = new Button(c, SWT.None); + b.setText("Fade"); + b.addListener(SWT.Selection, e -> { + Shell s = new Shell(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.CLOSE | SWT.TITLE); + s.setAlpha(0); + s.open(); + AnimationRunner runner = new AnimationRunner(); + runner.runEffect(new AlphaEffect(s, 0, 255, 1000, new ExpoOut(), null, null)); + AlphaEffect.fadeOnClose(s, 1000, new ExpoOut(), runner); + }); + return c; + } + + public void createParameters(Composite parent) { + parent.setLayout(new RowLayout()); + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/src/org/eclipse/nebula/widgets/gallery/example/GalleryExampleTab.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/src/org/eclipse/nebula/widgets/gallery/example/GalleryExampleTab.java index 023118f5a..be65d2bf6 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/src/org/eclipse/nebula/widgets/gallery/example/GalleryExampleTab.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.example/src/org/eclipse/nebula/widgets/gallery/example/GalleryExampleTab.java @@ -1,545 +1,545 @@ -/******************************************************************************* - * Copyright (c) 2006-2007 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.gallery.example; - -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.nebula.animation.ScrollingSmoother; -import org.eclipse.nebula.animation.movement.BounceOut; -import org.eclipse.nebula.animation.movement.ElasticOut; -import org.eclipse.nebula.animation.movement.ExpoOut; -import org.eclipse.nebula.animation.movement.IMovement; -import org.eclipse.nebula.animation.movement.LinearInOut; -import org.eclipse.nebula.examples.AbstractExampleTab; -import org.eclipse.nebula.examples.ExamplesView; -import org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer; -import org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer; -import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; -import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; -import org.eclipse.nebula.widgets.gallery.Gallery; -import org.eclipse.nebula.widgets.gallery.GalleryItem; -import org.eclipse.nebula.widgets.gallery.ListItemRenderer; -import org.eclipse.nebula.widgets.gallery.NoGroupRenderer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Scale; -import org.eclipse.swt.widgets.Spinner; - -/** - * Demonstrates the Gallery widget. - * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - */ -public class GalleryExampleTab extends AbstractExampleTab { - Gallery g = null; - - Listener groupParamSelectionListener = e -> { - if (g != null) { - g.setGroupRenderer(getGroupRenderer()); - } - }; - - Listener itemRendererParamSelectionListener = e -> { - if (g != null) { - g.setItemRenderer(getItemRenderer()); - } - }; - Listener contentParamSelectionListener = e -> clearAndPopulateGallery(g); - - Image womanImage = null; - Image bgImage = null; - Image eclipseImage = null; - - ScrollingSmoother scrollingSmoother; - - // Style options - - Button bMulti = null; - - Button bHScroll = null; - - Button bVScroll = null; - - // Animation options - Button bAnimation = null; - - // Data options - Button bGroupImage = null; - Button bGroupDescription = null; - Button bItemDescription = null; - - // Size options - Scale scale = null; - - Scale itemWidthScale = null; - - Scale itemHeightScale = null; - - Scale marginsScale = null; - - DefaultGalleryItemRenderer itemRenderer = null; - - AbstractGridGroupRenderer groupRenderer = null; - - private Button bLayoutAutoMargin; - - private Button bLayoutAlwaysExpanded; - - private Combo cAnimationMovement; - - private Spinner sAnimationDuration; - - private Button bLayoutLowQualityOnAction; - - private Button bItemDropShadow; - private Spinner sItemDropShadowSize; - private Button bItemLabel; - private Combo cItemRenderer; - private Button bDecoratorLeft; - private Button bDecoratorUp; - private Button bDecoratorRight; - private Button bDecoratorDown; - private Spinner sDecoratorNumber; - private Combo cGroupRenderer; - - public Control createControl(Composite parent) { - int style = SWT.NONE; - - if (bMulti.getSelection()) - style |= SWT.MULTI; - - if (bHScroll.getSelection()) - style |= SWT.H_SCROLL; - - if (bVScroll.getSelection()) - style |= SWT.V_SCROLL; - - g = new Gallery(parent, style); - scrollingSmoother = new ScrollingSmoother(g, new ExpoOut()); - scrollingSmoother.smoothControl(bAnimation.getSelection()); - - if (groupRenderer != null) { - groupRenderer.dispose(); - } - groupRenderer = getGroupRenderer(); - g.setGroupRenderer(groupRenderer); - - if (itemRenderer != null) { - itemRenderer.dispose(); - } - g.setItemRenderer(getItemRenderer()); - - // Create item image - if (womanImage == null) { - womanImage = ExamplesView.getImage("icons/woman3.png"); - } - if (bgImage == null) { - bgImage = ExamplesView.getImage("icons/background_small.png"); - } - - if (eclipseImage == null) { - eclipseImage = ExamplesView.getImage("icons/eclipse.png"); - } - - g.setLowQualityOnUserAction(bLayoutLowQualityOnAction.getSelection()); - // Add items. - this.clearAndPopulateGallery(g); - - return g; - } - - private AbstractGalleryItemRenderer getItemRenderer() { - AbstractGalleryItemRenderer result = null; - - if (cItemRenderer.getSelectionIndex() == 0) { - DefaultGalleryItemRenderer renderer = new DefaultGalleryItemRenderer(); - renderer.setShowLabels(bItemLabel.getSelection()); - renderer.setDropShadowsSize(sItemDropShadowSize.getSelection()); - renderer.setDropShadows(bItemDropShadow.getSelection()); - result = renderer; - } else { - ListItemRenderer renderer = new ListItemRenderer(); - renderer.setShowLabels(bItemLabel.getSelection()); - renderer.setDropShadowsSize(sItemDropShadowSize.getSelection()); - renderer.setDropShadows(bItemDropShadow.getSelection()); - result = renderer; - } - - return result; - - } - - private AbstractGridGroupRenderer getGroupRenderer() { - - AbstractGridGroupRenderer result = null; - if (cGroupRenderer.getSelectionIndex() == 0) { - DefaultGalleryGroupRenderer groupRenderer = new DefaultGalleryGroupRenderer(); - - if (bAnimation.getSelection()) { - // Animation - groupRenderer.setAnimation(true); - - // Movement - IMovement m = null; - switch (cAnimationMovement.getSelectionIndex()) { - case 1: - m = new BounceOut(); - break; - case 2: - m = new ElasticOut(); - break; - case 3: - m = new LinearInOut(); - break; - default: - m = new ExpoOut(); - break; - } - groupRenderer.setAnimationCloseMovement(m); - groupRenderer.setAnimationOpenMovement(m); - - // Length - groupRenderer.setAnimationLength(sAnimationDuration.getSelection()); - } else { - groupRenderer.setAnimation(false); - } - result = groupRenderer; - } else { - NoGroupRenderer groupRenderer = new NoGroupRenderer(); - result = groupRenderer; - } - - result.setItemWidth(this.itemWidthScale.getSelection()); - result.setItemHeight(this.itemHeightScale.getSelection()); - result.setMinMargin(this.marginsScale.getSelection()); - - result.setAutoMargin(bLayoutAutoMargin.getSelection()); - result.setAlwaysExpanded(bLayoutAlwaysExpanded.getSelection()); - - scrollingSmoother.smoothControl(bAnimation.getSelection()); - - return result; - - } - - private void clearAndPopulateGallery(Gallery g) { - g.removeAll(); - - if ((g.getStyle() & SWT.VIRTUAL) == 0) { - this.populateGalleryWithGroups(g); - } else { - // Virtual mode. - // TODO: Virtual mode example - } - - } - - /** - * Add 10 groups containing 10 to 100 items each. - * - * @param g - */ - private void populateGalleryWithGroups(Gallery g) { - for (int i = 0; i < 10; i++) { - GalleryItem gi1 = new GalleryItem(g, SWT.None); - gi1.setText("Group " + i + ".jpg"); - - if (bGroupImage.getSelection()) { - gi1.setImage(womanImage); - } - - if (bGroupDescription.getSelection()) { - gi1.setText(1, "Group description"); - } - - if (i % 2 == 0) { - gi1.setExpanded(true); - } - - for (int j = 0; j < (10 * (i + 1)); j++) { - GalleryItem gi2 = new GalleryItem(gi1, SWT.None); - if (j % 2 == 0) { - gi2.setImage(womanImage); - } else { - gi2.setImage(bgImage); - } - gi2.setText("Eclipse " + i + " " + j + ".jpg"); - if (bItemDescription.getSelection()) { - gi2.setText(1, "Image description"); - } - - if (bDecoratorLeft.getSelection()) { - gi2.setData(DefaultGalleryItemRenderer.OVERLAY_TOP_LEFT, - getDecoratorImage(eclipseImage, sDecoratorNumber.getSelection())); - } - if (bDecoratorUp.getSelection()) { - gi2.setData(DefaultGalleryItemRenderer.OVERLAY_TOP_RIGHT, - getDecoratorImage(eclipseImage, sDecoratorNumber.getSelection())); - } - if (bDecoratorRight.getSelection()) { - gi2.setData(DefaultGalleryItemRenderer.OVERLAY_BOTTOM_RIGHT, - getDecoratorImage(eclipseImage, sDecoratorNumber.getSelection())); - } - if (bDecoratorDown.getSelection()) { - gi2.setData(DefaultGalleryItemRenderer.OVERLAY_BOTTOM_LEFT, - getDecoratorImage(eclipseImage, sDecoratorNumber.getSelection())); - } - } - } - } - - private Object getDecoratorImage(Image img, int nb) { - switch (nb) { - case 0: - return null; - - case 1: - return img; - - default: - Image[] result = new Image[nb]; - for (int i = 0; i < nb; i++) { - result[i] = img; - } - return result; - } - - } - - public String[] createLinks() { - String[] links = new String[4]; - - links[0] = "Gallery Home Page"; - - links[1] = "Snippets"; - - links[2] = "Bugs"; - - links[3] = "Projet plan"; - - return links; - } - - private Button createButton(Composite parent, int style, String text, boolean selected, - boolean createExampleOnChange) { - Button button = new Button(parent, style); - button.setText(text); - button.setSelection(selected); - if (createExampleOnChange) { - button.addListener(SWT.Selection, e -> recreateExample()); - } - return button; - } - - private Group createEmptyGroup(Composite parent, String text) { - Group styleGroup = new Group(parent, SWT.NONE); - styleGroup.setText(text); - GridData gd = new GridData(); - gd.horizontalSpan = 3; - gd.horizontalAlignment = SWT.FILL; - styleGroup.setLayoutData(gd); - - return styleGroup; - } - - private void createStyleGroup(Composite parent) { - Group styleGroup = createEmptyGroup(parent, "Style"); - styleGroup.setLayout(new RowLayout()); - - bMulti = createButton(styleGroup, SWT.CHECK, "SWT.MULTI", false, true); - bVScroll = createButton(styleGroup, SWT.RADIO, "SWT.V_SCROLL", true, true); - bHScroll = createButton(styleGroup, SWT.RADIO, "SWT.H_SCROLL", false, true); - } - - private void createAnimationGroup(Composite parent) { - Group animationGroup = createEmptyGroup(parent, "Animation"); - animationGroup.setLayout(new RowLayout()); - - bAnimation = createButton(animationGroup, SWT.CHECK, "Animations", false, false); - bAnimation.addListener(SWT.Selection, groupParamSelectionListener); - - cAnimationMovement = new Combo(animationGroup, SWT.READ_ONLY); - cAnimationMovement.setItems(new String[] { "ExpoOut", "BounceOut", "ElasticOut", "LinearInOut" }); - cAnimationMovement.setText("ExpoOut"); - cAnimationMovement.addListener(SWT.Selection, groupParamSelectionListener); - - sAnimationDuration = new Spinner(animationGroup, SWT.NONE); - sAnimationDuration.setMinimum(250); - sAnimationDuration.setMaximum(5000); - sAnimationDuration.setIncrement(100); - sAnimationDuration.setSelection(500); - sAnimationDuration.addListener(SWT.Selection, groupParamSelectionListener); - } - - private void createDataGroup(Composite parent) { - Group dataGroup = createEmptyGroup(parent, "Data"); - dataGroup.setLayout(new RowLayout()); - - bGroupImage = createButton(dataGroup, SWT.CHECK, "Group image", false, true); - bGroupDescription = createButton(dataGroup, SWT.CHECK, "Group descriptions", false, true); - bItemDescription = createButton(dataGroup, SWT.CHECK, "Item descriptions", false, true); - } - - private void createLayoutGroup(Composite parent) { - Group dataGroup = createEmptyGroup(parent, "Layout"); - dataGroup.setLayout(new RowLayout()); - - bLayoutAutoMargin = createButton(dataGroup, SWT.CHECK, "Auto Margins", false, true); - bLayoutAlwaysExpanded = createButton(dataGroup, SWT.CHECK, "Always expanded", false, true); - - bLayoutLowQualityOnAction = createButton(dataGroup, SWT.CHECK, "Low quality on user action", false, true); - - } - - private void createDecoratorsGroup(Composite parent) { - Group dataGroup = createEmptyGroup(parent, "Decorators"); - dataGroup.setLayout(new RowLayout()); - - sDecoratorNumber = new Spinner(dataGroup, SWT.NONE); - sDecoratorNumber.setMinimum(1); - sDecoratorNumber.setMaximum(5); - sDecoratorNumber.setIncrement(1); - sDecoratorNumber.setSelection(1); - sDecoratorNumber.addListener(SWT.Selection, contentParamSelectionListener); - - bDecoratorLeft = createButton(dataGroup, SWT.CHECK, "Top Left", false, false); - bDecoratorLeft.addListener(SWT.Selection, contentParamSelectionListener); - bDecoratorUp = createButton(dataGroup, SWT.CHECK, "Top Right", false, false); - bDecoratorUp.addListener(SWT.Selection, contentParamSelectionListener); - bDecoratorRight = createButton(dataGroup, SWT.CHECK, "Bottom Right", false, false); - bDecoratorRight.addListener(SWT.Selection, contentParamSelectionListener); - bDecoratorDown = createButton(dataGroup, SWT.CHECK, "Bottom Left", false, false); - bDecoratorDown.addListener(SWT.Selection, contentParamSelectionListener); - } - - private void createItemParametersGroup(Composite parent) { - Group dataGroup = createEmptyGroup(parent, "Item parameters"); - dataGroup.setLayout(new RowLayout()); - - cItemRenderer = new Combo(dataGroup, SWT.READ_ONLY); - cItemRenderer.setItems(new String[] { "Icon", "List" }); - cItemRenderer.setText("Icon"); - cItemRenderer.addListener(SWT.Selection, itemRendererParamSelectionListener); - - bItemDropShadow = createButton(dataGroup, SWT.CHECK, "Drop shadow", false, true); - - sItemDropShadowSize = new Spinner(dataGroup, SWT.NONE); - sItemDropShadowSize.setMinimum(0); - sItemDropShadowSize.setMaximum(20); - sItemDropShadowSize.setIncrement(1); - sItemDropShadowSize.setSelection(5); - sItemDropShadowSize.addListener(SWT.Selection, itemRendererParamSelectionListener); - - bItemLabel = createButton(dataGroup, SWT.CHECK, "Display labels", false, true); - } - - private void createGroupParametersGroup(Composite parent) { - Group dataGroup = createEmptyGroup(parent, "Group parameters"); - GridLayoutFactory.swtDefaults().margins(3, 3).numColumns(3).applyTo(dataGroup); - - cGroupRenderer = new Combo(dataGroup, SWT.READ_ONLY); - cGroupRenderer.setItems(new String[] { "Show groups", "Hide groups" }); - cGroupRenderer.setText("Show groups"); - cGroupRenderer.addListener(SWT.Selection, groupParamSelectionListener); - GridData gridData = new GridData(); - gridData.horizontalSpan = 3; - cGroupRenderer.setLayoutData(gridData); - - // Scale : set item size - scale = createScale(dataGroup, "Item size", 16, 512, 16, 64); - scale.addListener(SWT.Selection, e -> { - if (g != null) { - groupRenderer.setItemSize(scale.getSelection(), scale.getSelection()); - itemWidthScale.setSelection(scale.getSelection()); - itemHeightScale.setSelection(scale.getSelection()); - g.setGroupRenderer(groupRenderer); - } - }); - - // Scale : set item width - this.itemWidthScale = createScale(dataGroup, "Item width", 16, 512, 16, 64); - itemWidthScale.addListener(SWT.Selection, e -> { - if (g != null) { - groupRenderer.setItemWidth(itemWidthScale.getSelection()); - g.setGroupRenderer(groupRenderer); - } - }); - - // Scale : set item height - this.itemHeightScale = createScale(dataGroup, "Item height", 16, 512, 16, 64); - itemHeightScale.addListener(SWT.Selection, e -> { - if (g != null) { - groupRenderer.setItemHeight(itemHeightScale.getSelection()); - g.setGroupRenderer(groupRenderer); - } - }); - - // Scale : set margins size - this.marginsScale = createScale(dataGroup, "Margins", 0, 128, 16, 10); - marginsScale.addListener(SWT.Selection, e -> { - if (g != null) { - groupRenderer.setMinMargin(marginsScale.getSelection()); - g.setGroupRenderer(groupRenderer); - } - }); - - } - - public void createParameters(Composite parent) { - GridLayoutFactory.swtDefaults().margins(0, 0).numColumns(3).applyTo(parent); - createStyleGroup(parent); - createAnimationGroup(parent); - createDataGroup(parent); - createDecoratorsGroup(parent); - createLayoutGroup(parent); - createGroupParametersGroup(parent); - createItemParametersGroup(parent); - - Button b = new Button(parent, SWT.NONE); - b.setText("deselectAll"); - b.addListener(SWT.Selection, e -> g.deselectAll()); - - } - - private Scale createScale(Composite parent, String text, int min, int max, int increment, int value) { - GridData gridData = new GridData(); - - Label l = new Label(parent, SWT.NONE); - l.setText(text); - gridData.horizontalSpan = 1; - l.setLayoutData(gridData); - - Scale scale = new Scale(parent, SWT.NONE); - gridData = new GridData(); - gridData.horizontalAlignment = GridData.FILL; - gridData.grabExcessHorizontalSpace = true; - gridData.horizontalSpan = 2; - scale.setLayoutData(gridData); - - scale.setMaximum(max); - scale.setMinimum(min); - scale.setPageIncrement(increment); - scale.setSelection(value); - - return scale; - } -} +/******************************************************************************* + * Copyright (c) 2006-2007 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.gallery.example; + +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.nebula.animation.ScrollingSmoother; +import org.eclipse.nebula.animation.movement.BounceOut; +import org.eclipse.nebula.animation.movement.ElasticOut; +import org.eclipse.nebula.animation.movement.ExpoOut; +import org.eclipse.nebula.animation.movement.IMovement; +import org.eclipse.nebula.animation.movement.LinearInOut; +import org.eclipse.nebula.examples.AbstractExampleTab; +import org.eclipse.nebula.examples.ExamplesView; +import org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer; +import org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer; +import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; +import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; +import org.eclipse.nebula.widgets.gallery.Gallery; +import org.eclipse.nebula.widgets.gallery.GalleryItem; +import org.eclipse.nebula.widgets.gallery.ListItemRenderer; +import org.eclipse.nebula.widgets.gallery.NoGroupRenderer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Scale; +import org.eclipse.swt.widgets.Spinner; + +/** + * Demonstrates the Gallery widget. + * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + */ +public class GalleryExampleTab extends AbstractExampleTab { + Gallery g = null; + + Listener groupParamSelectionListener = e -> { + if (g != null) { + g.setGroupRenderer(getGroupRenderer()); + } + }; + + Listener itemRendererParamSelectionListener = e -> { + if (g != null) { + g.setItemRenderer(getItemRenderer()); + } + }; + Listener contentParamSelectionListener = e -> clearAndPopulateGallery(g); + + Image womanImage = null; + Image bgImage = null; + Image eclipseImage = null; + + ScrollingSmoother scrollingSmoother; + + // Style options + + Button bMulti = null; + + Button bHScroll = null; + + Button bVScroll = null; + + // Animation options + Button bAnimation = null; + + // Data options + Button bGroupImage = null; + Button bGroupDescription = null; + Button bItemDescription = null; + + // Size options + Scale scale = null; + + Scale itemWidthScale = null; + + Scale itemHeightScale = null; + + Scale marginsScale = null; + + DefaultGalleryItemRenderer itemRenderer = null; + + AbstractGridGroupRenderer groupRenderer = null; + + private Button bLayoutAutoMargin; + + private Button bLayoutAlwaysExpanded; + + private Combo cAnimationMovement; + + private Spinner sAnimationDuration; + + private Button bLayoutLowQualityOnAction; + + private Button bItemDropShadow; + private Spinner sItemDropShadowSize; + private Button bItemLabel; + private Combo cItemRenderer; + private Button bDecoratorLeft; + private Button bDecoratorUp; + private Button bDecoratorRight; + private Button bDecoratorDown; + private Spinner sDecoratorNumber; + private Combo cGroupRenderer; + + public Control createControl(Composite parent) { + int style = SWT.NONE; + + if (bMulti.getSelection()) + style |= SWT.MULTI; + + if (bHScroll.getSelection()) + style |= SWT.H_SCROLL; + + if (bVScroll.getSelection()) + style |= SWT.V_SCROLL; + + g = new Gallery(parent, style); + scrollingSmoother = new ScrollingSmoother(g, new ExpoOut()); + scrollingSmoother.smoothControl(bAnimation.getSelection()); + + if (groupRenderer != null) { + groupRenderer.dispose(); + } + groupRenderer = getGroupRenderer(); + g.setGroupRenderer(groupRenderer); + + if (itemRenderer != null) { + itemRenderer.dispose(); + } + g.setItemRenderer(getItemRenderer()); + + // Create item image + if (womanImage == null) { + womanImage = ExamplesView.getImage("icons/woman3.png"); + } + if (bgImage == null) { + bgImage = ExamplesView.getImage("icons/background_small.png"); + } + + if (eclipseImage == null) { + eclipseImage = ExamplesView.getImage("icons/eclipse.png"); + } + + g.setLowQualityOnUserAction(bLayoutLowQualityOnAction.getSelection()); + // Add items. + this.clearAndPopulateGallery(g); + + return g; + } + + private AbstractGalleryItemRenderer getItemRenderer() { + AbstractGalleryItemRenderer result = null; + + if (cItemRenderer.getSelectionIndex() == 0) { + DefaultGalleryItemRenderer renderer = new DefaultGalleryItemRenderer(); + renderer.setShowLabels(bItemLabel.getSelection()); + renderer.setDropShadowsSize(sItemDropShadowSize.getSelection()); + renderer.setDropShadows(bItemDropShadow.getSelection()); + result = renderer; + } else { + ListItemRenderer renderer = new ListItemRenderer(); + renderer.setShowLabels(bItemLabel.getSelection()); + renderer.setDropShadowsSize(sItemDropShadowSize.getSelection()); + renderer.setDropShadows(bItemDropShadow.getSelection()); + result = renderer; + } + + return result; + + } + + private AbstractGridGroupRenderer getGroupRenderer() { + + AbstractGridGroupRenderer result = null; + if (cGroupRenderer.getSelectionIndex() == 0) { + DefaultGalleryGroupRenderer groupRenderer = new DefaultGalleryGroupRenderer(); + + if (bAnimation.getSelection()) { + // Animation + groupRenderer.setAnimation(true); + + // Movement + IMovement m = null; + switch (cAnimationMovement.getSelectionIndex()) { + case 1: + m = new BounceOut(); + break; + case 2: + m = new ElasticOut(); + break; + case 3: + m = new LinearInOut(); + break; + default: + m = new ExpoOut(); + break; + } + groupRenderer.setAnimationCloseMovement(m); + groupRenderer.setAnimationOpenMovement(m); + + // Length + groupRenderer.setAnimationLength(sAnimationDuration.getSelection()); + } else { + groupRenderer.setAnimation(false); + } + result = groupRenderer; + } else { + NoGroupRenderer groupRenderer = new NoGroupRenderer(); + result = groupRenderer; + } + + result.setItemWidth(this.itemWidthScale.getSelection()); + result.setItemHeight(this.itemHeightScale.getSelection()); + result.setMinMargin(this.marginsScale.getSelection()); + + result.setAutoMargin(bLayoutAutoMargin.getSelection()); + result.setAlwaysExpanded(bLayoutAlwaysExpanded.getSelection()); + + scrollingSmoother.smoothControl(bAnimation.getSelection()); + + return result; + + } + + private void clearAndPopulateGallery(Gallery g) { + g.removeAll(); + + if ((g.getStyle() & SWT.VIRTUAL) == 0) { + this.populateGalleryWithGroups(g); + } else { + // Virtual mode. + // TODO: Virtual mode example + } + + } + + /** + * Add 10 groups containing 10 to 100 items each. + * + * @param g + */ + private void populateGalleryWithGroups(Gallery g) { + for (int i = 0; i < 10; i++) { + GalleryItem gi1 = new GalleryItem(g, SWT.None); + gi1.setText("Group " + i + ".jpg"); + + if (bGroupImage.getSelection()) { + gi1.setImage(womanImage); + } + + if (bGroupDescription.getSelection()) { + gi1.setText(1, "Group description"); + } + + if (i % 2 == 0) { + gi1.setExpanded(true); + } + + for (int j = 0; j < (10 * (i + 1)); j++) { + GalleryItem gi2 = new GalleryItem(gi1, SWT.None); + if (j % 2 == 0) { + gi2.setImage(womanImage); + } else { + gi2.setImage(bgImage); + } + gi2.setText("Eclipse " + i + " " + j + ".jpg"); + if (bItemDescription.getSelection()) { + gi2.setText(1, "Image description"); + } + + if (bDecoratorLeft.getSelection()) { + gi2.setData(DefaultGalleryItemRenderer.OVERLAY_TOP_LEFT, + getDecoratorImage(eclipseImage, sDecoratorNumber.getSelection())); + } + if (bDecoratorUp.getSelection()) { + gi2.setData(DefaultGalleryItemRenderer.OVERLAY_TOP_RIGHT, + getDecoratorImage(eclipseImage, sDecoratorNumber.getSelection())); + } + if (bDecoratorRight.getSelection()) { + gi2.setData(DefaultGalleryItemRenderer.OVERLAY_BOTTOM_RIGHT, + getDecoratorImage(eclipseImage, sDecoratorNumber.getSelection())); + } + if (bDecoratorDown.getSelection()) { + gi2.setData(DefaultGalleryItemRenderer.OVERLAY_BOTTOM_LEFT, + getDecoratorImage(eclipseImage, sDecoratorNumber.getSelection())); + } + } + } + } + + private Object getDecoratorImage(Image img, int nb) { + switch (nb) { + case 0: + return null; + + case 1: + return img; + + default: + Image[] result = new Image[nb]; + for (int i = 0; i < nb; i++) { + result[i] = img; + } + return result; + } + + } + + public String[] createLinks() { + String[] links = new String[4]; + + links[0] = "Gallery Home Page"; + + links[1] = "Snippets"; + + links[2] = "Bugs"; + + links[3] = "Projet plan"; + + return links; + } + + private Button createButton(Composite parent, int style, String text, boolean selected, + boolean createExampleOnChange) { + Button button = new Button(parent, style); + button.setText(text); + button.setSelection(selected); + if (createExampleOnChange) { + button.addListener(SWT.Selection, e -> recreateExample()); + } + return button; + } + + private Group createEmptyGroup(Composite parent, String text) { + Group styleGroup = new Group(parent, SWT.NONE); + styleGroup.setText(text); + GridData gd = new GridData(); + gd.horizontalSpan = 3; + gd.horizontalAlignment = SWT.FILL; + styleGroup.setLayoutData(gd); + + return styleGroup; + } + + private void createStyleGroup(Composite parent) { + Group styleGroup = createEmptyGroup(parent, "Style"); + styleGroup.setLayout(new RowLayout()); + + bMulti = createButton(styleGroup, SWT.CHECK, "SWT.MULTI", false, true); + bVScroll = createButton(styleGroup, SWT.RADIO, "SWT.V_SCROLL", true, true); + bHScroll = createButton(styleGroup, SWT.RADIO, "SWT.H_SCROLL", false, true); + } + + private void createAnimationGroup(Composite parent) { + Group animationGroup = createEmptyGroup(parent, "Animation"); + animationGroup.setLayout(new RowLayout()); + + bAnimation = createButton(animationGroup, SWT.CHECK, "Animations", false, false); + bAnimation.addListener(SWT.Selection, groupParamSelectionListener); + + cAnimationMovement = new Combo(animationGroup, SWT.READ_ONLY); + cAnimationMovement.setItems(new String[] { "ExpoOut", "BounceOut", "ElasticOut", "LinearInOut" }); + cAnimationMovement.setText("ExpoOut"); + cAnimationMovement.addListener(SWT.Selection, groupParamSelectionListener); + + sAnimationDuration = new Spinner(animationGroup, SWT.NONE); + sAnimationDuration.setMinimum(250); + sAnimationDuration.setMaximum(5000); + sAnimationDuration.setIncrement(100); + sAnimationDuration.setSelection(500); + sAnimationDuration.addListener(SWT.Selection, groupParamSelectionListener); + } + + private void createDataGroup(Composite parent) { + Group dataGroup = createEmptyGroup(parent, "Data"); + dataGroup.setLayout(new RowLayout()); + + bGroupImage = createButton(dataGroup, SWT.CHECK, "Group image", false, true); + bGroupDescription = createButton(dataGroup, SWT.CHECK, "Group descriptions", false, true); + bItemDescription = createButton(dataGroup, SWT.CHECK, "Item descriptions", false, true); + } + + private void createLayoutGroup(Composite parent) { + Group dataGroup = createEmptyGroup(parent, "Layout"); + dataGroup.setLayout(new RowLayout()); + + bLayoutAutoMargin = createButton(dataGroup, SWT.CHECK, "Auto Margins", false, true); + bLayoutAlwaysExpanded = createButton(dataGroup, SWT.CHECK, "Always expanded", false, true); + + bLayoutLowQualityOnAction = createButton(dataGroup, SWT.CHECK, "Low quality on user action", false, true); + + } + + private void createDecoratorsGroup(Composite parent) { + Group dataGroup = createEmptyGroup(parent, "Decorators"); + dataGroup.setLayout(new RowLayout()); + + sDecoratorNumber = new Spinner(dataGroup, SWT.NONE); + sDecoratorNumber.setMinimum(1); + sDecoratorNumber.setMaximum(5); + sDecoratorNumber.setIncrement(1); + sDecoratorNumber.setSelection(1); + sDecoratorNumber.addListener(SWT.Selection, contentParamSelectionListener); + + bDecoratorLeft = createButton(dataGroup, SWT.CHECK, "Top Left", false, false); + bDecoratorLeft.addListener(SWT.Selection, contentParamSelectionListener); + bDecoratorUp = createButton(dataGroup, SWT.CHECK, "Top Right", false, false); + bDecoratorUp.addListener(SWT.Selection, contentParamSelectionListener); + bDecoratorRight = createButton(dataGroup, SWT.CHECK, "Bottom Right", false, false); + bDecoratorRight.addListener(SWT.Selection, contentParamSelectionListener); + bDecoratorDown = createButton(dataGroup, SWT.CHECK, "Bottom Left", false, false); + bDecoratorDown.addListener(SWT.Selection, contentParamSelectionListener); + } + + private void createItemParametersGroup(Composite parent) { + Group dataGroup = createEmptyGroup(parent, "Item parameters"); + dataGroup.setLayout(new RowLayout()); + + cItemRenderer = new Combo(dataGroup, SWT.READ_ONLY); + cItemRenderer.setItems(new String[] { "Icon", "List" }); + cItemRenderer.setText("Icon"); + cItemRenderer.addListener(SWT.Selection, itemRendererParamSelectionListener); + + bItemDropShadow = createButton(dataGroup, SWT.CHECK, "Drop shadow", false, true); + + sItemDropShadowSize = new Spinner(dataGroup, SWT.NONE); + sItemDropShadowSize.setMinimum(0); + sItemDropShadowSize.setMaximum(20); + sItemDropShadowSize.setIncrement(1); + sItemDropShadowSize.setSelection(5); + sItemDropShadowSize.addListener(SWT.Selection, itemRendererParamSelectionListener); + + bItemLabel = createButton(dataGroup, SWT.CHECK, "Display labels", false, true); + } + + private void createGroupParametersGroup(Composite parent) { + Group dataGroup = createEmptyGroup(parent, "Group parameters"); + GridLayoutFactory.swtDefaults().margins(3, 3).numColumns(3).applyTo(dataGroup); + + cGroupRenderer = new Combo(dataGroup, SWT.READ_ONLY); + cGroupRenderer.setItems(new String[] { "Show groups", "Hide groups" }); + cGroupRenderer.setText("Show groups"); + cGroupRenderer.addListener(SWT.Selection, groupParamSelectionListener); + GridData gridData = new GridData(); + gridData.horizontalSpan = 3; + cGroupRenderer.setLayoutData(gridData); + + // Scale : set item size + scale = createScale(dataGroup, "Item size", 16, 512, 16, 64); + scale.addListener(SWT.Selection, e -> { + if (g != null) { + groupRenderer.setItemSize(scale.getSelection(), scale.getSelection()); + itemWidthScale.setSelection(scale.getSelection()); + itemHeightScale.setSelection(scale.getSelection()); + g.setGroupRenderer(groupRenderer); + } + }); + + // Scale : set item width + this.itemWidthScale = createScale(dataGroup, "Item width", 16, 512, 16, 64); + itemWidthScale.addListener(SWT.Selection, e -> { + if (g != null) { + groupRenderer.setItemWidth(itemWidthScale.getSelection()); + g.setGroupRenderer(groupRenderer); + } + }); + + // Scale : set item height + this.itemHeightScale = createScale(dataGroup, "Item height", 16, 512, 16, 64); + itemHeightScale.addListener(SWT.Selection, e -> { + if (g != null) { + groupRenderer.setItemHeight(itemHeightScale.getSelection()); + g.setGroupRenderer(groupRenderer); + } + }); + + // Scale : set margins size + this.marginsScale = createScale(dataGroup, "Margins", 0, 128, 16, 10); + marginsScale.addListener(SWT.Selection, e -> { + if (g != null) { + groupRenderer.setMinMargin(marginsScale.getSelection()); + g.setGroupRenderer(groupRenderer); + } + }); + + } + + public void createParameters(Composite parent) { + GridLayoutFactory.swtDefaults().margins(0, 0).numColumns(3).applyTo(parent); + createStyleGroup(parent); + createAnimationGroup(parent); + createDataGroup(parent); + createDecoratorsGroup(parent); + createLayoutGroup(parent); + createGroupParametersGroup(parent); + createItemParametersGroup(parent); + + Button b = new Button(parent, SWT.NONE); + b.setText("deselectAll"); + b.addListener(SWT.Selection, e -> g.deselectAll()); + + } + + private Scale createScale(Composite parent, String text, int min, int max, int increment, int value) { + GridData gridData = new GridData(); + + Label l = new Label(parent, SWT.NONE); + l.setText(text); + gridData.horizontalSpan = 1; + l.setLayoutData(gridData); + + Scale scale = new Scale(parent, SWT.NONE); + gridData = new GridData(); + gridData.horizontalAlignment = GridData.FILL; + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalSpan = 2; + scale.setLayoutData(gridData); + + scale.setMaximum(max); + scale.setMinimum(min); + scale.setPageIncrement(increment); + scale.setSelection(value); + + return scale; + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/.classpath b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/.classpath index e00865a3c..2026e10c7 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/.classpath +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/.classpath @@ -1,11 +1,11 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/.settings/org.eclipse.jdt.core.prefs b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/.settings/org.eclipse.jdt.core.prefs index e2e9c66d8..f2525a8b9 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/.settings/org.eclipse.jdt.core.prefs @@ -1,14 +1,14 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/META-INF/MANIFEST.MF b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/META-INF/MANIFEST.MF index 8a434915f..48fb78f25 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/META-INF/MANIFEST.MF +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/META-INF/MANIFEST.MF @@ -1,13 +1,13 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Gallery Tests -Bundle-SymbolicName: org.eclipse.nebula.widgets.gallery.tests -Bundle-Version: 1.0.0.qualifier -Require-Bundle: org.eclipse.nebula.widgets.gallery, - org.junit, - org.eclipse.swt, - org.eclipse.jface;resolution:=optional, - org.eclipse.core.runtime;resolution:=optional -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.widgets.gallery.tests +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Gallery Tests +Bundle-SymbolicName: org.eclipse.nebula.widgets.gallery.tests +Bundle-Version: 1.0.0.qualifier +Require-Bundle: org.eclipse.nebula.widgets.gallery, + org.junit, + org.eclipse.swt, + org.eclipse.jface;resolution:=optional, + org.eclipse.core.runtime;resolution:=optional +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.widgets.gallery.tests diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/src/org/eclipse/nebula/widgets/gallery/tests/Bug217988Test.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/src/org/eclipse/nebula/widgets/gallery/tests/Bug217988Test.java index 4a3d9fd1d..e10f240d7 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/src/org/eclipse/nebula/widgets/gallery/tests/Bug217988Test.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/src/org/eclipse/nebula/widgets/gallery/tests/Bug217988Test.java @@ -1,135 +1,135 @@ -package org.eclipse.nebula.widgets.gallery.tests; - -import java.util.Arrays; - -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.nebula.jface.galleryviewer.GalleryTreeViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -import junit.framework.TestCase; - -public class Bug217988Test extends TestCase { - - private Shell s = null; - private Display d = null; - private boolean createdDisplay = false; - - protected void setUp() throws Exception { - d = Display.getCurrent(); - if( d == null ){ - d = new Display(); - createdDisplay = true; - } - s = new Shell(d, SWT.NONE); - super.setUp(); - } - - protected void tearDown() throws Exception { - if( createdDisplay){ - d.dispose(); - } - super.tearDown(); - } - - // Items class - static public class Foo { - - private String name; - private int value; - - public Foo(String message) { - this.name = message; - } - - public Foo(String name, int value) { - this.name = name; - this.value = value; - } - - public String toString() { - return name; - } - - public String getName() { - return name; - } - - public int getValue() { - return value; - } - - } - - // Content provider - public static class GalleryTestContentProvider implements ITreeContentProvider { - - public static final int NUM_GROUPS = 1; - public static final int NUM_ITEMS = 20; - - String[] groups = new String[NUM_GROUPS]; - Foo[][] items = new Foo[NUM_GROUPS][NUM_ITEMS]; - - public GalleryTestContentProvider() { - for (int i = 0; i < NUM_GROUPS; i++) { - groups[i] = "Group " + (i + 1); - for (int j = 0; j < NUM_ITEMS; j++) { - items[i][j] = new Foo("Item " + ((i * NUM_ITEMS) + (j + 1)), (i * NUM_ITEMS) + (j + 1)); - } - } - } - - public Object[] getChildren(Object parentElement) { - int idx = Arrays.asList(groups).indexOf(parentElement); - return items[idx]; - } - - public Object getParent(Object element) { - return null; - } - - public boolean hasChildren(Object element) { - if (element instanceof Foo) { - return false; - } - return ((String) element).startsWith("Group"); - } - - public Object[] getElements(Object inputElement) { - return groups; - } - - public void dispose() { - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - } - - public static class GalleryTestLabelProvider extends LabelProvider { - - public Image getImage(Object element) { - return null; - } - - } - - public void testBug217988() { - GalleryTreeViewer viewer = new GalleryTreeViewer(s); - - viewer.setContentProvider(new GalleryTestContentProvider()); - viewer.setLabelProvider(new GalleryTestLabelProvider()); - viewer.setComparator(new ViewerComparator()); - viewer.setInput(new Object()); - - // Setting input raised a NPE - viewer.setInput(new Object()); - } - -} +package org.eclipse.nebula.widgets.gallery.tests; + +import java.util.Arrays; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.nebula.jface.galleryviewer.GalleryTreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import junit.framework.TestCase; + +public class Bug217988Test extends TestCase { + + private Shell s = null; + private Display d = null; + private boolean createdDisplay = false; + + protected void setUp() throws Exception { + d = Display.getCurrent(); + if( d == null ){ + d = new Display(); + createdDisplay = true; + } + s = new Shell(d, SWT.NONE); + super.setUp(); + } + + protected void tearDown() throws Exception { + if( createdDisplay){ + d.dispose(); + } + super.tearDown(); + } + + // Items class + static public class Foo { + + private String name; + private int value; + + public Foo(String message) { + this.name = message; + } + + public Foo(String name, int value) { + this.name = name; + this.value = value; + } + + public String toString() { + return name; + } + + public String getName() { + return name; + } + + public int getValue() { + return value; + } + + } + + // Content provider + public static class GalleryTestContentProvider implements ITreeContentProvider { + + public static final int NUM_GROUPS = 1; + public static final int NUM_ITEMS = 20; + + String[] groups = new String[NUM_GROUPS]; + Foo[][] items = new Foo[NUM_GROUPS][NUM_ITEMS]; + + public GalleryTestContentProvider() { + for (int i = 0; i < NUM_GROUPS; i++) { + groups[i] = "Group " + (i + 1); + for (int j = 0; j < NUM_ITEMS; j++) { + items[i][j] = new Foo("Item " + ((i * NUM_ITEMS) + (j + 1)), (i * NUM_ITEMS) + (j + 1)); + } + } + } + + public Object[] getChildren(Object parentElement) { + int idx = Arrays.asList(groups).indexOf(parentElement); + return items[idx]; + } + + public Object getParent(Object element) { + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof Foo) { + return false; + } + return ((String) element).startsWith("Group"); + } + + public Object[] getElements(Object inputElement) { + return groups; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + } + + public static class GalleryTestLabelProvider extends LabelProvider { + + public Image getImage(Object element) { + return null; + } + + } + + public void testBug217988() { + GalleryTreeViewer viewer = new GalleryTreeViewer(s); + + viewer.setContentProvider(new GalleryTestContentProvider()); + viewer.setLabelProvider(new GalleryTestLabelProvider()); + viewer.setComparator(new ViewerComparator()); + viewer.setInput(new Object()); + + // Setting input raised a NPE + viewer.setInput(new Object()); + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/src/org/eclipse/nebula/widgets/gallery/tests/GalleryVirtualBehaviorTest.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/src/org/eclipse/nebula/widgets/gallery/tests/GalleryVirtualBehaviorTest.java index 5fdd76a2c..d3838260c 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/src/org/eclipse/nebula/widgets/gallery/tests/GalleryVirtualBehaviorTest.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery.tests/src/org/eclipse/nebula/widgets/gallery/tests/GalleryVirtualBehaviorTest.java @@ -1,135 +1,135 @@ -package org.eclipse.nebula.widgets.gallery.tests; - -import java.util.ArrayList; - -import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; -import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; -import org.eclipse.nebula.widgets.gallery.Gallery; -import org.eclipse.nebula.widgets.gallery.GalleryItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeItem; -import org.eclipse.swt.widgets.Widget; - -import junit.framework.TestCase; - -public class GalleryVirtualBehaviorTest extends TestCase { - Display d = null; - Shell s = null; - private boolean createdDisplay = false; - - protected void setUp() throws Exception { - d = Display.getCurrent(); - if( d == null ){ - d = new Display(); - createdDisplay = true; - } - s = new Shell(d, SWT.NONE); - super.setUp(); - } - - protected void tearDown() throws Exception { - if( createdDisplay){ - d.dispose(); - } - super.tearDown(); - } - - private Gallery createGallery(int flags) { - Gallery g = new Gallery(s, flags); - - // Renderers - DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer(); - gr.setMinMargin(2); - gr.setItemHeight(56); - gr.setItemWidth(72); - gr.setAutoMargin(true); - g.setGroupRenderer(gr); - - DefaultGalleryItemRenderer ir = new DefaultGalleryItemRenderer(); - g.setItemRenderer(ir); - - return g; - } - - public void testGalleryVirtualNew() { - Gallery widget = createGallery(SWT.V_SCROLL | SWT.VIRTUAL); - final ArrayList setDataCalls = new ArrayList<>(); - widget.addListener(SWT.SetData, new Listener() { - public void handleEvent(Event event) { - setDataCalls.add(event.item); - } - }); - - assertEquals(0, widget.getItemCount()); - - GalleryItem item1 = new GalleryItem(widget, SWT.NONE); - assertEquals(1, widget.getItemCount()); - assertEquals(item1, widget.getItem(0)); - assertFalse( setDataCalls.contains(item1)); - - GalleryItem item2 = new GalleryItem(item1, SWT.NONE); - assertEquals(1, widget.getItemCount()); - assertEquals(1, item1.getItemCount()); - assertEquals(item2, item1.getItem(0)); - assertFalse( setDataCalls.contains(item2)); - - item1.dispose(); - assertEquals( 0, widget.getItemCount()); - assertTrue( item2.isDisposed()); - - // Test removeAll - item1 = new GalleryItem(widget, SWT.NONE); - assertEquals(1, widget.getItemCount()); - assertEquals(item1, widget.getItem(0)); - assertFalse( setDataCalls.contains(item1)); - - widget.removeAll(); - assertEquals(0, widget.getItemCount()); - - } - - /** - * This test is for the reference behavior of Tree - */ - public void testTreeVirtualNew() { - Tree widget = new Tree(s, SWT.VIRTUAL); - final ArrayList setDataCalls = new ArrayList<>(); - widget.addListener(SWT.SetData, new Listener() { - public void handleEvent(Event event) { - setDataCalls.add(event.item); - } - }); - - - assertEquals(0, widget.getItemCount()); - TreeItem item1 = new TreeItem(widget, SWT.NONE); - assertEquals(1, widget.getItemCount()); - assertEquals(item1, widget.getItem(0)); - assertFalse( setDataCalls.contains(item1)); - - TreeItem item2 = new TreeItem(item1, SWT.NONE); - assertEquals(1, widget.getItemCount()); - assertEquals(1, item1.getItemCount()); - assertEquals(item2, item1.getItem(0)); - assertFalse( setDataCalls.contains(item2)); - - item1.dispose(); - assertEquals( 0, widget.getItemCount()); - assertTrue( item2.isDisposed()); - - // Test removeAll - item1 = new TreeItem(widget, SWT.NONE); - assertEquals(1, widget.getItemCount()); - assertEquals(item1, widget.getItem(0)); - assertFalse( setDataCalls.contains(item1)); - - widget.removeAll(); - assertEquals(0, widget.getItemCount()); - - } -} +package org.eclipse.nebula.widgets.gallery.tests; + +import java.util.ArrayList; + +import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; +import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; +import org.eclipse.nebula.widgets.gallery.Gallery; +import org.eclipse.nebula.widgets.gallery.GalleryItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; + +import junit.framework.TestCase; + +public class GalleryVirtualBehaviorTest extends TestCase { + Display d = null; + Shell s = null; + private boolean createdDisplay = false; + + protected void setUp() throws Exception { + d = Display.getCurrent(); + if( d == null ){ + d = new Display(); + createdDisplay = true; + } + s = new Shell(d, SWT.NONE); + super.setUp(); + } + + protected void tearDown() throws Exception { + if( createdDisplay){ + d.dispose(); + } + super.tearDown(); + } + + private Gallery createGallery(int flags) { + Gallery g = new Gallery(s, flags); + + // Renderers + DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer(); + gr.setMinMargin(2); + gr.setItemHeight(56); + gr.setItemWidth(72); + gr.setAutoMargin(true); + g.setGroupRenderer(gr); + + DefaultGalleryItemRenderer ir = new DefaultGalleryItemRenderer(); + g.setItemRenderer(ir); + + return g; + } + + public void testGalleryVirtualNew() { + Gallery widget = createGallery(SWT.V_SCROLL | SWT.VIRTUAL); + final ArrayList setDataCalls = new ArrayList<>(); + widget.addListener(SWT.SetData, new Listener() { + public void handleEvent(Event event) { + setDataCalls.add(event.item); + } + }); + + assertEquals(0, widget.getItemCount()); + + GalleryItem item1 = new GalleryItem(widget, SWT.NONE); + assertEquals(1, widget.getItemCount()); + assertEquals(item1, widget.getItem(0)); + assertFalse( setDataCalls.contains(item1)); + + GalleryItem item2 = new GalleryItem(item1, SWT.NONE); + assertEquals(1, widget.getItemCount()); + assertEquals(1, item1.getItemCount()); + assertEquals(item2, item1.getItem(0)); + assertFalse( setDataCalls.contains(item2)); + + item1.dispose(); + assertEquals( 0, widget.getItemCount()); + assertTrue( item2.isDisposed()); + + // Test removeAll + item1 = new GalleryItem(widget, SWT.NONE); + assertEquals(1, widget.getItemCount()); + assertEquals(item1, widget.getItem(0)); + assertFalse( setDataCalls.contains(item1)); + + widget.removeAll(); + assertEquals(0, widget.getItemCount()); + + } + + /** + * This test is for the reference behavior of Tree + */ + public void testTreeVirtualNew() { + Tree widget = new Tree(s, SWT.VIRTUAL); + final ArrayList setDataCalls = new ArrayList<>(); + widget.addListener(SWT.SetData, new Listener() { + public void handleEvent(Event event) { + setDataCalls.add(event.item); + } + }); + + + assertEquals(0, widget.getItemCount()); + TreeItem item1 = new TreeItem(widget, SWT.NONE); + assertEquals(1, widget.getItemCount()); + assertEquals(item1, widget.getItem(0)); + assertFalse( setDataCalls.contains(item1)); + + TreeItem item2 = new TreeItem(item1, SWT.NONE); + assertEquals(1, widget.getItemCount()); + assertEquals(1, item1.getItemCount()); + assertEquals(item2, item1.getItem(0)); + assertFalse( setDataCalls.contains(item2)); + + item1.dispose(); + assertEquals( 0, widget.getItemCount()); + assertTrue( item2.isDisposed()); + + // Test removeAll + item1 = new TreeItem(widget, SWT.NONE); + assertEquals(1, widget.getItemCount()); + assertEquals(item1, widget.getItem(0)); + assertFalse( setDataCalls.contains(item1)); + + widget.removeAll(); + assertEquals(0, widget.getItemCount()); + + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/.classpath b/widgets/gallery/org.eclipse.nebula.widgets.gallery/.classpath index 92e333a4b..c3ba59e4c 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/.classpath +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/.settings/org.eclipse.jdt.core.prefs b/widgets/gallery/org.eclipse.nebula.widgets.gallery/.settings/org.eclipse.jdt.core.prefs index 6fcf0101b..dbb3bf537 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/.settings/org.eclipse.jdt.core.prefs @@ -1,301 +1,301 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes= -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true -org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true -org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true -org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true -org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true +eclipse.preferences.version=1 +org.eclipse.jdt.core.codeComplete.argumentPrefixes= +org.eclipse.jdt.core.codeComplete.argumentSuffixes= +org.eclipse.jdt.core.codeComplete.fieldPrefixes= +org.eclipse.jdt.core.codeComplete.fieldSuffixes= +org.eclipse.jdt.core.codeComplete.localPrefixes= +org.eclipse.jdt.core.codeComplete.localSuffixes= +org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= +org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true +org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true +org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true +org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true +org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/META-INF/MANIFEST.MF b/widgets/gallery/org.eclipse.nebula.widgets.gallery/META-INF/MANIFEST.MF index fa3f4100f..6aa9e7e13 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/META-INF/MANIFEST.MF +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/META-INF/MANIFEST.MF @@ -1,15 +1,15 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Gallery Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.gallery -Bundle-Version: 1.0.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.swt, - org.eclipse.jface;resolution:=optional -Export-Package: org.eclipse.nebula.animation, - org.eclipse.nebula.animation.effects, - org.eclipse.nebula.animation.movement, - org.eclipse.nebula.jface.galleryviewer, - org.eclipse.nebula.widgets.gallery -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.widgets.gallery +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Gallery Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.gallery +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.swt, + org.eclipse.jface;resolution:=optional +Export-Package: org.eclipse.nebula.animation, + org.eclipse.nebula.animation.effects, + org.eclipse.nebula.animation.movement, + org.eclipse.nebula.jface.galleryviewer, + org.eclipse.nebula.widgets.gallery +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.widgets.gallery diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/ScrollingSmoother.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/ScrollingSmoother.java index cafac4643..3d95e27ed 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/ScrollingSmoother.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/ScrollingSmoother.java @@ -1,204 +1,204 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.animation; - -import org.eclipse.nebula.animation.effects.IEffect; -import org.eclipse.nebula.animation.effects.MoveScrollBarEffect; -import org.eclipse.nebula.animation.movement.IMovement; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ScrollBar; -import org.eclipse.swt.widgets.Scrollable; - -/** - *

- * Allows to replace the default scrolling behavior by an animation effect. - *

- * - *

- * Compatible with : - *

- *
    - *
  • Shell
  • - *
  • StyledText
  • - *
  • Canvas
  • - *
  • Gallery
  • - *
- * - * - * @author Nicolas Richeton - * - */ -public class ScrollingSmoother { - - Scrollable component; - - ScrollBar verticalScrollBar; - - ScrollBar horizontalScrollBar; - - IMovement movement = null; - - int duration = 2000; - - AnimationRunner animationRunner = new AnimationRunner(); - - /** - * Create a Scrolling Smoother instance over a scrollable widget. This - * effect can then be activated using - * {@link ScrollingSmoother#smoothControl(boolean)}. - * - * @see ScrollingSmoother#smoothControl(boolean) - * - * @param c2 - * @param movement - */ - public ScrollingSmoother(final Scrollable c2, IMovement movement) { - this.component = c2; - verticalScrollBar = c2.getVerticalBar(); - horizontalScrollBar = c2.getHorizontalBar(); - this.movement = movement; - } - - /** - * Create a Scrolling Smoother instance over a scrollable widget. This - * effect can then be activated using - * {@link ScrollingSmoother#smoothControl(boolean)}. - * - * @see ScrollingSmoother#smoothControl(boolean) - * - * @param c2 - * @param movement - * @param duration - */ - public ScrollingSmoother(final Scrollable c2, IMovement movement, - int duration) { - this(c2, movement); - this.duration = duration; - } - - /** - * Get current effect duration (ms). - * - * @return - */ - public int getDuration() { - return duration; - } - - /** - * Set effect duration (ms). - * - * @param duration - */ - public void setDuration(int duration) { - this.duration = duration; - } - - /** - * Set the FPS (frame per second) to use with the animator. - * - * @param fps - */ - public void setFPS(int fps) { - animationRunner = new AnimationRunner(fps); - } - - protected ScrollBar getScrollbar(Event event) { - ScrollBar result = verticalScrollBar; - - if (result == null) { - result = horizontalScrollBar; - } - - return result; - } - - Listener mouseWheelListener = event -> { - // Remove standard behavior - event.doit = false; - - // Get scrollbar on which the event occurred. - ScrollBar currentScrollBar = getScrollbar(event); - - int start = currentScrollBar.getSelection(); - int end = start; - - // If an effect is currently running, get the current and target - // values. - IEffect current = animationRunner.getEffect(); - if (current instanceof MoveScrollBarEffect) { - MoveScrollBarEffect mseffect = (MoveScrollBarEffect) current; - start = mseffect.getCurrent(); - end = mseffect.getEnd(); - } - - end -= event.count * currentScrollBar.getIncrement(); - - if (end > currentScrollBar.getMaximum() - currentScrollBar.getThumb()) { - end = currentScrollBar.getMaximum() - currentScrollBar.getThumb(); - } - - if (end < currentScrollBar.getMinimum()) { - end = currentScrollBar.getMinimum(); - } - - animationRunner.runEffect(new MoveScrollBarEffect(currentScrollBar, - start, end, duration, movement, null, null)); - }; - - /** - * Enable or disable scrolling effect. - * - * @param enable - * true or false. - */ - public void smoothControl(boolean enable) { - if (enable) { - component.addListener(SWT.MouseWheel, mouseWheelListener); - - if (verticalScrollBar != null) - verticalScrollBar.addListener(SWT.Selection, - cancelEffectIfUserSelection); - - if (horizontalScrollBar != null) - horizontalScrollBar.addListener(SWT.Selection, - cancelEffectIfUserSelection); - - } else { - component.removeListener(SWT.MouseWheel, mouseWheelListener); - - if (verticalScrollBar != null) - verticalScrollBar.removeListener(SWT.Selection, - cancelEffectIfUserSelection); - - if (horizontalScrollBar != null) - horizontalScrollBar.removeListener(SWT.Selection, - cancelEffectIfUserSelection); - - } - } - - Listener cancelEffectIfUserSelection = e -> { - // data contains an instance of MoveScrollBarEffect if the selection - // was generated by this effect. Otherwise this is an user - // selection. - if (!(e.data instanceof MoveScrollBarEffect)) { - animationRunner.cancel(); - } - }; - -} +/******************************************************************************* + * Copyright (c) 2006-2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.animation; + +import org.eclipse.nebula.animation.effects.IEffect; +import org.eclipse.nebula.animation.effects.MoveScrollBarEffect; +import org.eclipse.nebula.animation.movement.IMovement; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Scrollable; + +/** + *

+ * Allows to replace the default scrolling behavior by an animation effect. + *

+ * + *

+ * Compatible with : + *

+ *
    + *
  • Shell
  • + *
  • StyledText
  • + *
  • Canvas
  • + *
  • Gallery
  • + *
+ * + * + * @author Nicolas Richeton + * + */ +public class ScrollingSmoother { + + Scrollable component; + + ScrollBar verticalScrollBar; + + ScrollBar horizontalScrollBar; + + IMovement movement = null; + + int duration = 2000; + + AnimationRunner animationRunner = new AnimationRunner(); + + /** + * Create a Scrolling Smoother instance over a scrollable widget. This + * effect can then be activated using + * {@link ScrollingSmoother#smoothControl(boolean)}. + * + * @see ScrollingSmoother#smoothControl(boolean) + * + * @param c2 + * @param movement + */ + public ScrollingSmoother(final Scrollable c2, IMovement movement) { + this.component = c2; + verticalScrollBar = c2.getVerticalBar(); + horizontalScrollBar = c2.getHorizontalBar(); + this.movement = movement; + } + + /** + * Create a Scrolling Smoother instance over a scrollable widget. This + * effect can then be activated using + * {@link ScrollingSmoother#smoothControl(boolean)}. + * + * @see ScrollingSmoother#smoothControl(boolean) + * + * @param c2 + * @param movement + * @param duration + */ + public ScrollingSmoother(final Scrollable c2, IMovement movement, + int duration) { + this(c2, movement); + this.duration = duration; + } + + /** + * Get current effect duration (ms). + * + * @return + */ + public int getDuration() { + return duration; + } + + /** + * Set effect duration (ms). + * + * @param duration + */ + public void setDuration(int duration) { + this.duration = duration; + } + + /** + * Set the FPS (frame per second) to use with the animator. + * + * @param fps + */ + public void setFPS(int fps) { + animationRunner = new AnimationRunner(fps); + } + + protected ScrollBar getScrollbar(Event event) { + ScrollBar result = verticalScrollBar; + + if (result == null) { + result = horizontalScrollBar; + } + + return result; + } + + Listener mouseWheelListener = event -> { + // Remove standard behavior + event.doit = false; + + // Get scrollbar on which the event occurred. + ScrollBar currentScrollBar = getScrollbar(event); + + int start = currentScrollBar.getSelection(); + int end = start; + + // If an effect is currently running, get the current and target + // values. + IEffect current = animationRunner.getEffect(); + if (current instanceof MoveScrollBarEffect) { + MoveScrollBarEffect mseffect = (MoveScrollBarEffect) current; + start = mseffect.getCurrent(); + end = mseffect.getEnd(); + } + + end -= event.count * currentScrollBar.getIncrement(); + + if (end > currentScrollBar.getMaximum() - currentScrollBar.getThumb()) { + end = currentScrollBar.getMaximum() - currentScrollBar.getThumb(); + } + + if (end < currentScrollBar.getMinimum()) { + end = currentScrollBar.getMinimum(); + } + + animationRunner.runEffect(new MoveScrollBarEffect(currentScrollBar, + start, end, duration, movement, null, null)); + }; + + /** + * Enable or disable scrolling effect. + * + * @param enable + * true or false. + */ + public void smoothControl(boolean enable) { + if (enable) { + component.addListener(SWT.MouseWheel, mouseWheelListener); + + if (verticalScrollBar != null) + verticalScrollBar.addListener(SWT.Selection, + cancelEffectIfUserSelection); + + if (horizontalScrollBar != null) + horizontalScrollBar.addListener(SWT.Selection, + cancelEffectIfUserSelection); + + } else { + component.removeListener(SWT.MouseWheel, mouseWheelListener); + + if (verticalScrollBar != null) + verticalScrollBar.removeListener(SWT.Selection, + cancelEffectIfUserSelection); + + if (horizontalScrollBar != null) + horizontalScrollBar.removeListener(SWT.Selection, + cancelEffectIfUserSelection); + + } + } + + Listener cancelEffectIfUserSelection = e -> { + // data contains an instance of MoveScrollBarEffect if the selection + // was generated by this effect. Otherwise this is an user + // selection. + if (!(e.data instanceof MoveScrollBarEffect)) { + animationRunner.cancel(); + } + }; + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/AbstractEffect.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/AbstractEffect.java index 00753783f..ca524b271 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/AbstractEffect.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/AbstractEffect.java @@ -1,134 +1,134 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.animation.effects; - -import org.eclipse.nebula.animation.movement.IMovement; - -/** - * Abstract implementation for an effect. - * - * @author Nicolas Richeton - * - */ -public abstract class AbstractEffect implements IEffect { - - protected boolean done = false; - protected IMovement easingFunction; - protected long length = 0; - protected Runnable runnableOnCancel = null; - protected Runnable runnableOnStop = null; - - /** - * Create a new effect. - * - * @param lengthMilli - * @param movement - */ - public AbstractEffect(long lengthMilli, IMovement movement) { - this(lengthMilli, movement, null, null); - } - - /** - * Create a new effect, with listeners for stop and cancel events. - * - * @param lengthMilli - * @param movement - * @param onStop - * @param onCancel - */ - public AbstractEffect(long lengthMilli, IMovement movement, Runnable onStop, - Runnable onCancel) { - this.length = lengthMilli; - easingFunction = movement; - this.runnableOnCancel = onCancel; - this.runnableOnStop = onStop; - } - - /** - * Apply this effect. - * - * @param currentTime - */ - public abstract void applyEffect(final long currentTime); - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#cancel() - */ - public void cancel() { - done = true; - doCancel(); - } - - /** - * Run the onCancel runnable if any. - */ - protected void doCancel() { - if (runnableOnCancel != null) - runnableOnCancel.run(); - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#doEffect() - */ - public void doEffect() { - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#doEffect(long) - */ - public void doEffect(long time) { - long currentTime = time; - if (currentTime > length) { - currentTime = length; - } - applyEffect(currentTime); - processEnd(currentTime); - } - - /** - * Run the onStop runnable if any. - */ - protected void doStop() { - if (runnableOnStop != null) - runnableOnStop.run(); - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#getLength() - */ - public long getLength() { - return length; - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#isDone() - */ - public boolean isDone() { - return done; - } - - /** - * Check if the effect has ended. In that case, start the onStop runnable. - */ - public void processEnd(long time) { - if (done) - return; - - if (time == length) { - done = true; - doStop(); - } - } -} +/******************************************************************************* + * Copyright (c) 2006-2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.animation.effects; + +import org.eclipse.nebula.animation.movement.IMovement; + +/** + * Abstract implementation for an effect. + * + * @author Nicolas Richeton + * + */ +public abstract class AbstractEffect implements IEffect { + + protected boolean done = false; + protected IMovement easingFunction; + protected long length = 0; + protected Runnable runnableOnCancel = null; + protected Runnable runnableOnStop = null; + + /** + * Create a new effect. + * + * @param lengthMilli + * @param movement + */ + public AbstractEffect(long lengthMilli, IMovement movement) { + this(lengthMilli, movement, null, null); + } + + /** + * Create a new effect, with listeners for stop and cancel events. + * + * @param lengthMilli + * @param movement + * @param onStop + * @param onCancel + */ + public AbstractEffect(long lengthMilli, IMovement movement, Runnable onStop, + Runnable onCancel) { + this.length = lengthMilli; + easingFunction = movement; + this.runnableOnCancel = onCancel; + this.runnableOnStop = onStop; + } + + /** + * Apply this effect. + * + * @param currentTime + */ + public abstract void applyEffect(final long currentTime); + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#cancel() + */ + public void cancel() { + done = true; + doCancel(); + } + + /** + * Run the onCancel runnable if any. + */ + protected void doCancel() { + if (runnableOnCancel != null) + runnableOnCancel.run(); + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#doEffect() + */ + public void doEffect() { + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#doEffect(long) + */ + public void doEffect(long time) { + long currentTime = time; + if (currentTime > length) { + currentTime = length; + } + applyEffect(currentTime); + processEnd(currentTime); + } + + /** + * Run the onStop runnable if any. + */ + protected void doStop() { + if (runnableOnStop != null) + runnableOnStop.run(); + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#getLength() + */ + public long getLength() { + return length; + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#isDone() + */ + public boolean isDone() { + return done; + } + + /** + * Check if the effect has ended. In that case, start the onStop runnable. + */ + public void processEnd(long time) { + if (done) + return; + + if (time == length) { + done = true; + doStop(); + } + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/AlphaEffect.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/AlphaEffect.java index 8f796f5cd..f7f9733c3 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/AlphaEffect.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/AlphaEffect.java @@ -1,115 +1,115 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.animation.effects; - -import org.eclipse.nebula.animation.AnimationRunner; -import org.eclipse.nebula.animation.movement.IMovement; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Shell; - -/** - * Set the alpha value of a Shell - * - * @author Nicolas Richeton - * - */ -public class AlphaEffect extends AbstractEffect { - - /** - * @deprecated - * @param w - * @param alpha - * @param duration - * @param movement - * @param onStop - * @param onCancel - */ - public static void setAlpha(AnimationRunner runner, Shell w, int alpha, - int duration, IMovement movement, Runnable onStop, - Runnable onCancel) { - AlphaEffect effect = new AlphaEffect(w, w.getAlpha(), alpha, duration, - movement, onStop, onCancel); - runner.runEffect(effect); - } - - /** - * Add a listener that will fade the window when it get closed. - * - * @param shell - * @param duration - * @param easing - * @deprecated Use {@link #fadeOnClose(Shell,int,IMovement,AnimationRunner)} - * instead - */ - public static void fadeOnClose(final Shell shell, final int duration, - final IMovement easing) { - fadeOnClose(shell, duration, easing, null); - } - - /** - * Add a listener that will fade the window when it get closed. - * - * @param shell - * @param duration - * @param easing - * @param runner - * : The AnimationRunner to use, or null - * - */ - public static void fadeOnClose(final Shell shell, final int duration, - final IMovement easing, AnimationRunner runner) { - - final AnimationRunner useRunner; - if (runner != null) { - useRunner = runner; - } else { - useRunner = new AnimationRunner(); - } - - final Runnable closeListener = () -> shell.dispose(); - - shell.addListener(SWT.Close, e -> { - e.doit = false; - setAlpha(useRunner, shell, 0, duration, easing, closeListener, - null); - }); - - } - - int start, end, step; - - Shell shell = null; - - public AlphaEffect(Shell shell, int start, int end, long lengthMilli, - IMovement movement, Runnable onStop, Runnable onCancel) { - super(lengthMilli, movement, onStop, onCancel); - - this.start = start; - this.end = end; - step = end - start; - this.shell = shell; - easingFunction.init(0, 1, (int) lengthMilli); - - } - - public void applyEffect(final long currentTime) { - if (shell.isDisposed()) - return; - - shell.setAlpha((int) (start - + step * easingFunction.getValue((int) currentTime))); - } - +/******************************************************************************* + * Copyright (c) 2006-2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.animation.effects; + +import org.eclipse.nebula.animation.AnimationRunner; +import org.eclipse.nebula.animation.movement.IMovement; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Shell; + +/** + * Set the alpha value of a Shell + * + * @author Nicolas Richeton + * + */ +public class AlphaEffect extends AbstractEffect { + + /** + * @deprecated + * @param w + * @param alpha + * @param duration + * @param movement + * @param onStop + * @param onCancel + */ + public static void setAlpha(AnimationRunner runner, Shell w, int alpha, + int duration, IMovement movement, Runnable onStop, + Runnable onCancel) { + AlphaEffect effect = new AlphaEffect(w, w.getAlpha(), alpha, duration, + movement, onStop, onCancel); + runner.runEffect(effect); + } + + /** + * Add a listener that will fade the window when it get closed. + * + * @param shell + * @param duration + * @param easing + * @deprecated Use {@link #fadeOnClose(Shell,int,IMovement,AnimationRunner)} + * instead + */ + public static void fadeOnClose(final Shell shell, final int duration, + final IMovement easing) { + fadeOnClose(shell, duration, easing, null); + } + + /** + * Add a listener that will fade the window when it get closed. + * + * @param shell + * @param duration + * @param easing + * @param runner + * : The AnimationRunner to use, or null + * + */ + public static void fadeOnClose(final Shell shell, final int duration, + final IMovement easing, AnimationRunner runner) { + + final AnimationRunner useRunner; + if (runner != null) { + useRunner = runner; + } else { + useRunner = new AnimationRunner(); + } + + final Runnable closeListener = () -> shell.dispose(); + + shell.addListener(SWT.Close, e -> { + e.doit = false; + setAlpha(useRunner, shell, 0, duration, easing, closeListener, + null); + }); + + } + + int start, end, step; + + Shell shell = null; + + public AlphaEffect(Shell shell, int start, int end, long lengthMilli, + IMovement movement, Runnable onStop, Runnable onCancel) { + super(lengthMilli, movement, onStop, onCancel); + + this.start = start; + this.end = end; + step = end - start; + this.shell = shell; + easingFunction.init(0, 1, (int) lengthMilli); + + } + + public void applyEffect(final long currentTime) { + if (shell.isDisposed()) + return; + + shell.setAlpha((int) (start + + step * easingFunction.getValue((int) currentTime))); + } + } \ No newline at end of file diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/CrossFadeEffect.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/CrossFadeEffect.java index 233f4b9b3..6472d59ff 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/CrossFadeEffect.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/CrossFadeEffect.java @@ -1,153 +1,153 @@ -/******************************************************************************* - * Copyright (c) 2006-2010 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.animation.effects; - -import org.eclipse.nebula.animation.movement.IMovement; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; - -/** - * Cross fade images in a target object. The target must implement - * {@link IImageObject}. - * - * @author Nicolas Richeton - */ -public class CrossFadeEffect extends AbstractEffect { - public interface IImageObject { - /** - * Get the current image of this object - * - * @return - */ - Image getImage(); - - /** - * Set the image of this object - * - * @param c - */ - void setImage(Image i); - } - - Image buffer = null; - double easingValue; - GC gc = null; - Image image1 = null; - Image image2 = null; - IImageObject obj = null; - - /** - * Cross fade from image1 to image2 on obj. - * - * @param obj - * @param image1 - * @param image2 - * @param lengthMilli - * @param movement - */ - public CrossFadeEffect(IImageObject obj, Image image1, Image image2, - long lengthMilli, IMovement movement) { - this(obj, image1, image2, lengthMilli, movement, null, null); - } - - /** - * Cross fade from image1 to image2 on obj. - * - * @param obj - * @param image1 - * @param image2 - * @param lengthMilli - * @param movement - * @param onStop - */ - public CrossFadeEffect(IImageObject obj, Image image1, Image image2, - long lengthMilli, IMovement movement, Runnable onStop) { - this(obj, image1, image2, lengthMilli, movement, onStop, null); - } - - /** - * Cross fade from image1 to image2 on obj. - * - * @param obj - * @param image1 - * @param image2 - * @param lengthMilli - * @param movement - * @param onStop - * @param onCancel - */ - public CrossFadeEffect(IImageObject obj, Image image1, Image image2, - long lengthMilli, IMovement movement, Runnable onStop, - Runnable onCancel) { - super(lengthMilli, movement, onStop, onCancel); - this.obj = obj; - this.image1 = image1; - this.image2 = image2; - - if (!image1.getBounds().equals(image2.getBounds())) { - throw new IllegalArgumentException( - "Both image must have the same dimensions"); - } - - easingFunction.init(0, 1, (int) lengthMilli); - - buffer = new Image(image1.getDevice(), image1.getBounds().width, - image1.getBounds().height); - gc = new GC(buffer); - } - - /** - * @see org.eclipse.nebula.animation.effects.AbstractEffect#applyEffect(long) - */ - public void applyEffect(long currentTime) { - easingValue = easingFunction.getValue(currentTime); - - if (easingValue == 0) { - obj.setImage(image1); - } else if (easingValue == 1) { - obj.setImage(image2); - } else { - gc.setAlpha(255); - gc.drawImage(image1, 0, 0); - gc.setAlpha((int) (255 * easingValue)); - gc.drawImage(image2, 0, 0); - obj.setImage(buffer); - } - } - - /** - * Clear resources. - */ - protected void cleanup() { - gc.dispose(); - buffer.dispose(); - } - - /** - * @see org.eclipse.nebula.animation.effects.AbstractEffect#doCancel() - */ - protected void doCancel() { - obj.setImage(image2); - super.doCancel(); - cleanup(); - } - - /** - * @see org.eclipse.nebula.animation.effects.AbstractEffect#doStop() - */ - protected void doStop() { - super.doStop(); - cleanup(); - } -} +/******************************************************************************* + * Copyright (c) 2006-2010 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.animation.effects; + +import org.eclipse.nebula.animation.movement.IMovement; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; + +/** + * Cross fade images in a target object. The target must implement + * {@link IImageObject}. + * + * @author Nicolas Richeton + */ +public class CrossFadeEffect extends AbstractEffect { + public interface IImageObject { + /** + * Get the current image of this object + * + * @return + */ + Image getImage(); + + /** + * Set the image of this object + * + * @param c + */ + void setImage(Image i); + } + + Image buffer = null; + double easingValue; + GC gc = null; + Image image1 = null; + Image image2 = null; + IImageObject obj = null; + + /** + * Cross fade from image1 to image2 on obj. + * + * @param obj + * @param image1 + * @param image2 + * @param lengthMilli + * @param movement + */ + public CrossFadeEffect(IImageObject obj, Image image1, Image image2, + long lengthMilli, IMovement movement) { + this(obj, image1, image2, lengthMilli, movement, null, null); + } + + /** + * Cross fade from image1 to image2 on obj. + * + * @param obj + * @param image1 + * @param image2 + * @param lengthMilli + * @param movement + * @param onStop + */ + public CrossFadeEffect(IImageObject obj, Image image1, Image image2, + long lengthMilli, IMovement movement, Runnable onStop) { + this(obj, image1, image2, lengthMilli, movement, onStop, null); + } + + /** + * Cross fade from image1 to image2 on obj. + * + * @param obj + * @param image1 + * @param image2 + * @param lengthMilli + * @param movement + * @param onStop + * @param onCancel + */ + public CrossFadeEffect(IImageObject obj, Image image1, Image image2, + long lengthMilli, IMovement movement, Runnable onStop, + Runnable onCancel) { + super(lengthMilli, movement, onStop, onCancel); + this.obj = obj; + this.image1 = image1; + this.image2 = image2; + + if (!image1.getBounds().equals(image2.getBounds())) { + throw new IllegalArgumentException( + "Both image must have the same dimensions"); + } + + easingFunction.init(0, 1, (int) lengthMilli); + + buffer = new Image(image1.getDevice(), image1.getBounds().width, + image1.getBounds().height); + gc = new GC(buffer); + } + + /** + * @see org.eclipse.nebula.animation.effects.AbstractEffect#applyEffect(long) + */ + public void applyEffect(long currentTime) { + easingValue = easingFunction.getValue(currentTime); + + if (easingValue == 0) { + obj.setImage(image1); + } else if (easingValue == 1) { + obj.setImage(image2); + } else { + gc.setAlpha(255); + gc.drawImage(image1, 0, 0); + gc.setAlpha((int) (255 * easingValue)); + gc.drawImage(image2, 0, 0); + obj.setImage(buffer); + } + } + + /** + * Clear resources. + */ + protected void cleanup() { + gc.dispose(); + buffer.dispose(); + } + + /** + * @see org.eclipse.nebula.animation.effects.AbstractEffect#doCancel() + */ + protected void doCancel() { + obj.setImage(image2); + super.doCancel(); + cleanup(); + } + + /** + * @see org.eclipse.nebula.animation.effects.AbstractEffect#doStop() + */ + protected void doStop() { + super.doStop(); + cleanup(); + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/IEffect.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/IEffect.java index 8e15dbbcd..1d1c0c879 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/IEffect.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/IEffect.java @@ -1,55 +1,55 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.animation.effects; - -/** - * All animation effects must implement this interface. - *

- * Note : an effect should not do initialization in constructor, but at the - * first call to doEffect(). For instance, a move effect should not get the - * initial position of an object in the constructor, because the object may have - * moved between creation and effect start. - *

- * - * @author Nicolas Richeton - */ -public interface IEffect { - - /** - * Set the effect as done and run the cancel runnable. - */ - public void cancel(); - - /** - * Apply effect to the target according to the given time. - * - * @param time - * - Current time in ms. This value may be larger than the effect - * length. - */ - public void doEffect(long time); - - /** - * Get effect length - * - * @return length (ms) - */ - public long getLength(); - - /** - * @return true if the effect as already reached its end. - */ - public boolean isDone(); -} +/******************************************************************************* + * Copyright (c) 2006-2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.animation.effects; + +/** + * All animation effects must implement this interface. + *

+ * Note : an effect should not do initialization in constructor, but at the + * first call to doEffect(). For instance, a move effect should not get the + * initial position of an object in the constructor, because the object may have + * moved between creation and effect start. + *

+ * + * @author Nicolas Richeton + */ +public interface IEffect { + + /** + * Set the effect as done and run the cancel runnable. + */ + public void cancel(); + + /** + * Apply effect to the target according to the given time. + * + * @param time + * - Current time in ms. This value may be larger than the effect + * length. + */ + public void doEffect(long time); + + /** + * Get effect length + * + * @return length (ms) + */ + public long getLength(); + + /** + * @return true if the effect as already reached its end. + */ + public boolean isDone(); +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/ParallelEffect.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/ParallelEffect.java index d1cab4315..f2d3f45a2 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/ParallelEffect.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/ParallelEffect.java @@ -1,145 +1,145 @@ -/******************************************************************************* - * Copyright (c) 2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.animation.effects; - -import java.util.List; - -/** - * A wrapper for running effects in parallel. - * - * @author Nicolas Richeton - * - */ -public class ParallelEffect implements IEffect { - - IEffect[] effects = null; - long length = 0; - Runnable onCancel; - Runnable onStop; - - /** - * Wrap several effects and start them in parallel. - * - * @param effects - */ - public ParallelEffect(IEffect[] effects) { - this(effects, null, null); - } - - /** - * Wrap several effects and start them in parallel. - * - * @param effects - * @param onStop - * @param onCancel - */ - public ParallelEffect(IEffect[] effects, Runnable onStop, - Runnable onCancel) { - this.effects = effects; - this.onCancel = onCancel; - this.onStop = onStop; - - // Get total length - if (effects != null) { - IEffect e = null; - for (int i = effects.length - 1; i >= 0; i--) { - e = (IEffect) effects[i]; - if (e.getLength() > length) { - length = e.getLength(); - } - } - } - } - - /** - * Wrap several effects and start them in parallel. - * - * @param effects - */ - public ParallelEffect(List effects) { - this(effects, null, null); - } - - /** - * Wrap several effects and start them in parallel. - * - * @param effects - * @param onStop - * @param onCancel - */ - public ParallelEffect(List effects, Runnable onStop, - Runnable onCancel) { - this((IEffect[]) effects.toArray(), onStop, onCancel); - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#cancel() - */ - public void cancel() { - if (effects != null) { - for (int i = effects.length - 1; i >= 0; i--) { - effects[i].cancel(); - } - } - - // Call cancel runnable - if (onCancel != null) { - onCancel.run(); - } - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#doEffect(long) - */ - public void doEffect(long time) { - if (effects != null) { - for (int i = effects.length - 1; i >= 0; i--) { - effects[i].doEffect(time); - } - } - - // Call stop runnable - if (onStop != null && isDone()) { - onStop.run(); - } - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#getLength() - */ - public long getLength() { - return length; - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#isDone() - */ - public boolean isDone() { - - if (effects != null) { - // Ensure all effects are done. - boolean done = true; - for (int i = effects.length - 1; i >= 0; i--) { - if (!effects[i].isDone()) { - done = false; - } - } - return done; - } - - // No effects ? always done. - return true; - } - -} +/******************************************************************************* + * Copyright (c) 2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.animation.effects; + +import java.util.List; + +/** + * A wrapper for running effects in parallel. + * + * @author Nicolas Richeton + * + */ +public class ParallelEffect implements IEffect { + + IEffect[] effects = null; + long length = 0; + Runnable onCancel; + Runnable onStop; + + /** + * Wrap several effects and start them in parallel. + * + * @param effects + */ + public ParallelEffect(IEffect[] effects) { + this(effects, null, null); + } + + /** + * Wrap several effects and start them in parallel. + * + * @param effects + * @param onStop + * @param onCancel + */ + public ParallelEffect(IEffect[] effects, Runnable onStop, + Runnable onCancel) { + this.effects = effects; + this.onCancel = onCancel; + this.onStop = onStop; + + // Get total length + if (effects != null) { + IEffect e = null; + for (int i = effects.length - 1; i >= 0; i--) { + e = (IEffect) effects[i]; + if (e.getLength() > length) { + length = e.getLength(); + } + } + } + } + + /** + * Wrap several effects and start them in parallel. + * + * @param effects + */ + public ParallelEffect(List effects) { + this(effects, null, null); + } + + /** + * Wrap several effects and start them in parallel. + * + * @param effects + * @param onStop + * @param onCancel + */ + public ParallelEffect(List effects, Runnable onStop, + Runnable onCancel) { + this((IEffect[]) effects.toArray(), onStop, onCancel); + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#cancel() + */ + public void cancel() { + if (effects != null) { + for (int i = effects.length - 1; i >= 0; i--) { + effects[i].cancel(); + } + } + + // Call cancel runnable + if (onCancel != null) { + onCancel.run(); + } + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#doEffect(long) + */ + public void doEffect(long time) { + if (effects != null) { + for (int i = effects.length - 1; i >= 0; i--) { + effects[i].doEffect(time); + } + } + + // Call stop runnable + if (onStop != null && isDone()) { + onStop.run(); + } + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#getLength() + */ + public long getLength() { + return length; + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#isDone() + */ + public boolean isDone() { + + if (effects != null) { + // Ensure all effects are done. + boolean done = true; + for (int i = effects.length - 1; i >= 0; i--) { + if (!effects[i].isDone()) { + done = false; + } + } + return done; + } + + // No effects ? always done. + return true; + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/SequenceEffect.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/SequenceEffect.java index 53daece9e..e69673a38 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/SequenceEffect.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/SequenceEffect.java @@ -1,112 +1,112 @@ -/******************************************************************************* - * Copyright (c) 2006-2010 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.animation.effects; - -/** - * Run several effects one after another. - * - * @author Nicolas Richeton - * - */ -public class SequenceEffect implements IEffect { - int currentEffect = 0; - IEffect[] effects = null; - long length = 0; - Runnable onCancel; - Runnable onStop; - long start = 0; - - /** - * Run several effects one after another. - *

- * Note : - *

    - *
  • onStop and onCancel runnables applies to the whole sequence - * effect.
  • - *
  • Each effect can have its own onStop and onCancel.
  • - *
- *

- * - * @param effects - * @param onStop - * @param onCancel - */ - public SequenceEffect(IEffect[] effects, Runnable onStop, - Runnable onCancel) { - this.effects = effects; - this.onCancel = onCancel; - this.onStop = onStop; - - if (effects != null) { - IEffect e = null; - for (int i = effects.length - 1; i >= 0; i--) { - e = effects[i]; - length += e.getLength(); - } - } - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#cancel() - */ - public void cancel() { - for (int i = currentEffect; i < effects.length; i++) { - effects[currentEffect].cancel(); - } - - // Call cancel runnable - if (onCancel != null) { - onCancel.run(); - } - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#doEffect(long) - */ - public void doEffect(long time) { - if (currentEffect >= effects.length) { - return; - } - - effects[currentEffect].doEffect(time - start); - if (effects[currentEffect].isDone()) { - start += effects[currentEffect].getLength(); - currentEffect++; - } - - // Call stop runnable - if (onStop != null && isDone()) { - onStop.run(); - } - - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#getLength() - */ - public long getLength() { - return length; - } - - /** - * @see org.eclipse.nebula.animation.effects.IEffect#isDone() - */ - public boolean isDone() { - if (effects == null) { - return true; - } - return effects[effects.length - 1].isDone(); - } - -} +/******************************************************************************* + * Copyright (c) 2006-2010 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.animation.effects; + +/** + * Run several effects one after another. + * + * @author Nicolas Richeton + * + */ +public class SequenceEffect implements IEffect { + int currentEffect = 0; + IEffect[] effects = null; + long length = 0; + Runnable onCancel; + Runnable onStop; + long start = 0; + + /** + * Run several effects one after another. + *

+ * Note : + *

    + *
  • onStop and onCancel runnables applies to the whole sequence + * effect.
  • + *
  • Each effect can have its own onStop and onCancel.
  • + *
+ *

+ * + * @param effects + * @param onStop + * @param onCancel + */ + public SequenceEffect(IEffect[] effects, Runnable onStop, + Runnable onCancel) { + this.effects = effects; + this.onCancel = onCancel; + this.onStop = onStop; + + if (effects != null) { + IEffect e = null; + for (int i = effects.length - 1; i >= 0; i--) { + e = effects[i]; + length += e.getLength(); + } + } + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#cancel() + */ + public void cancel() { + for (int i = currentEffect; i < effects.length; i++) { + effects[currentEffect].cancel(); + } + + // Call cancel runnable + if (onCancel != null) { + onCancel.run(); + } + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#doEffect(long) + */ + public void doEffect(long time) { + if (currentEffect >= effects.length) { + return; + } + + effects[currentEffect].doEffect(time - start); + if (effects[currentEffect].isDone()) { + start += effects[currentEffect].getLength(); + currentEffect++; + } + + // Call stop runnable + if (onStop != null && isDone()) { + onStop.run(); + } + + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#getLength() + */ + public long getLength() { + return length; + } + + /** + * @see org.eclipse.nebula.animation.effects.IEffect#isDone() + */ + public boolean isDone() { + if (effects == null) { + return true; + } + return effects[effects.length - 1].isDone(); + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/SetColorEffect.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/SetColorEffect.java index c16a3e3e2..a182d6838 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/SetColorEffect.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/effects/SetColorEffect.java @@ -1,137 +1,137 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.animation.effects; - -import org.eclipse.nebula.animation.movement.IMovement; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Display; - -/** - * Progressively changes the color of an object. - * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - * - */ -public class SetColorEffect extends AbstractEffect { - - /** - * Objects on which the SetColorEffect is applied must implements this - * interface. This allows to use this effect on different widgets and select - * the right color to change (foreground, background). - * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - * - */ - public interface IColoredObject { - /** - * Set the color of this object - * - * @param c - */ - void setColor(Color c); - - /** - * Get the current color of this object - * - * @return - */ - Color getColor(); - } - - Color src; - Color dest; - int diffR, diffG, diffB; - - IColoredObject control = null; - - /** - *

- * Create a new effect on object control. - *

- * - *

- * Source and destination color will not be disposed during or after the - * animation. All other temporary colors created by this effect will be - * disposed automatically. - *

- * - * @param control - * @param src - * @param dest - * @param lengthMilli - * @param movement - * @param onStop - * can be a Runnable or null - * @param onCancel - * can be a Runnable or null - */ - public SetColorEffect(IColoredObject control, Color src, Color dest, - long lengthMilli, IMovement movement, Runnable onStop, - Runnable onCancel) { - super(lengthMilli, movement, onStop, onCancel); - this.src = src; - this.dest = dest; - this.diffR = dest.getRed() - src.getRed(); - this.diffG = dest.getGreen() - src.getGreen(); - this.diffB = dest.getBlue() - src.getBlue(); - this.control = control; - - easingFunction.init(0, 1, (int) lengthMilli); - } - - /** - * @see org.eclipse.nebula.animation.effects.AbstractEffect#applyEffect(long) - */ - public void applyEffect(final long currentTime) { - - Color currentColor = control.getColor(); - - // Get the next color values - int nextRed = (int) (src.getRed() - + diffR * easingFunction.getValue(currentTime)); - int nextGreen = (int) (src.getGreen() - + diffG * easingFunction.getValue(currentTime)); - int nextBlue = (int) (src.getBlue() - + diffB * easingFunction.getValue(currentTime)); - - RGB nextRGB = new RGB(nextRed, nextGreen, nextBlue); - - if (currentColor == null || !nextRGB.equals(currentColor.getRGB())) { - - Color nextColor = new Color(Display.getCurrent(), nextRed, - nextGreen, nextBlue); - - // If this is the destination color, dispose the newly created color - // and use the destination one instead. - if (dest.getRGB().equals(nextColor.getRGB())) { - nextColor.dispose(); - nextColor = dest; - } - - control.setColor(nextColor); - - // If the previous color is not the source or destination one, - // dispose it. - if (currentColor != null && !currentColor.isDisposed()) { - if (dest != currentColor && src != currentColor) { - currentColor.dispose(); - } - } - - } - - } -} +/******************************************************************************* + * Copyright (c) 2006-2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.animation.effects; + +import org.eclipse.nebula.animation.movement.IMovement; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +/** + * Progressively changes the color of an object. + * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + * + */ +public class SetColorEffect extends AbstractEffect { + + /** + * Objects on which the SetColorEffect is applied must implements this + * interface. This allows to use this effect on different widgets and select + * the right color to change (foreground, background). + * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + * + */ + public interface IColoredObject { + /** + * Set the color of this object + * + * @param c + */ + void setColor(Color c); + + /** + * Get the current color of this object + * + * @return + */ + Color getColor(); + } + + Color src; + Color dest; + int diffR, diffG, diffB; + + IColoredObject control = null; + + /** + *

+ * Create a new effect on object control. + *

+ * + *

+ * Source and destination color will not be disposed during or after the + * animation. All other temporary colors created by this effect will be + * disposed automatically. + *

+ * + * @param control + * @param src + * @param dest + * @param lengthMilli + * @param movement + * @param onStop + * can be a Runnable or null + * @param onCancel + * can be a Runnable or null + */ + public SetColorEffect(IColoredObject control, Color src, Color dest, + long lengthMilli, IMovement movement, Runnable onStop, + Runnable onCancel) { + super(lengthMilli, movement, onStop, onCancel); + this.src = src; + this.dest = dest; + this.diffR = dest.getRed() - src.getRed(); + this.diffG = dest.getGreen() - src.getGreen(); + this.diffB = dest.getBlue() - src.getBlue(); + this.control = control; + + easingFunction.init(0, 1, (int) lengthMilli); + } + + /** + * @see org.eclipse.nebula.animation.effects.AbstractEffect#applyEffect(long) + */ + public void applyEffect(final long currentTime) { + + Color currentColor = control.getColor(); + + // Get the next color values + int nextRed = (int) (src.getRed() + + diffR * easingFunction.getValue(currentTime)); + int nextGreen = (int) (src.getGreen() + + diffG * easingFunction.getValue(currentTime)); + int nextBlue = (int) (src.getBlue() + + diffB * easingFunction.getValue(currentTime)); + + RGB nextRGB = new RGB(nextRed, nextGreen, nextBlue); + + if (currentColor == null || !nextRGB.equals(currentColor.getRGB())) { + + Color nextColor = new Color(Display.getCurrent(), nextRed, + nextGreen, nextBlue); + + // If this is the destination color, dispose the newly created color + // and use the destination one instead. + if (dest.getRGB().equals(nextColor.getRGB())) { + nextColor.dispose(); + nextColor = dest; + } + + control.setColor(nextColor); + + // If the previous color is not the source or destination one, + // dispose it. + if (currentColor != null && !currentColor.isDisposed()) { + if (dest != currentColor && src != currentColor) { + currentColor.dispose(); + } + } + + } + + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/AbstractMovement.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/AbstractMovement.java index b54fd43cd..9b46d0b63 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/AbstractMovement.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/AbstractMovement.java @@ -1,43 +1,43 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.animation.movement; - -/** - * Abstract implementation of IMovement. - * - * @author Nicolas Richeton - */ -public abstract class AbstractMovement implements IMovement { - - protected double min; - protected double max; - protected double duration; - - /** - * @see org.eclipse.nebula.animation.movement.IMovement#getValue(double) - */ - public abstract double getValue(double step); - - /** - * @see org.eclipse.nebula.animation.movement.IMovement#init(double, double, - * int) - */ - public void init(double minValue, double maxValue, int steps) { - this.min = minValue; - this.max = maxValue; - this.duration = steps; - } - -} +/******************************************************************************* + * Copyright (c) 2006-2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.animation.movement; + +/** + * Abstract implementation of IMovement. + * + * @author Nicolas Richeton + */ +public abstract class AbstractMovement implements IMovement { + + protected double min; + protected double max; + protected double duration; + + /** + * @see org.eclipse.nebula.animation.movement.IMovement#getValue(double) + */ + public abstract double getValue(double step); + + /** + * @see org.eclipse.nebula.animation.movement.IMovement#init(double, double, + * int) + */ + public void init(double minValue, double maxValue, int steps) { + this.min = minValue; + this.max = maxValue; + this.duration = steps; + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/ExpoOut.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/ExpoOut.java index 9bea7e4b1..8c2bfb6f4 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/ExpoOut.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/ExpoOut.java @@ -1,46 +1,46 @@ -/******************************************************************************* - * Copyright (c) 2008 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.animation.movement; - -/** - * Moves fast at first then slow down until it reaches the max value. - * - * @author Nicolas Richeton - * - */ -public class ExpoOut extends AbstractMovement { - - float increment; - - /** - * @see org.sharemedia.gui.viewers.impl.gl.IMovement#getValue(int) - */ - public double getValue(double step) { - float currentCos = 1.0f - (float) Math.exp(((float) step) * increment); - if (step != duration) - return min + max * currentCos; - else - return max; - } - - /** - * @see org.sharemedia.gui.viewers.impl.gl.IMovement#init(float, float, int) - */ - public void init(double min, double max, int steps) { - increment = -10.0f / steps; - super.init(min, max, steps); - } - -} +/******************************************************************************* + * Copyright (c) 2008 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.animation.movement; + +/** + * Moves fast at first then slow down until it reaches the max value. + * + * @author Nicolas Richeton + * + */ +public class ExpoOut extends AbstractMovement { + + float increment; + + /** + * @see org.sharemedia.gui.viewers.impl.gl.IMovement#getValue(int) + */ + public double getValue(double step) { + float currentCos = 1.0f - (float) Math.exp(((float) step) * increment); + if (step != duration) + return min + max * currentCos; + else + return max; + } + + /** + * @see org.sharemedia.gui.viewers.impl.gl.IMovement#init(float, float, int) + */ + public void init(double min, double max, int steps) { + increment = -10.0f / steps; + super.init(min, max, steps); + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/LinearInOut.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/LinearInOut.java index 941617b4a..c68de48c5 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/LinearInOut.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/animation/movement/LinearInOut.java @@ -1,41 +1,41 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.animation.movement; - -/** - * Moves at a constant speed. - * - * @author Nicolas Richeton - */ -public class LinearInOut extends AbstractMovement { - - double increment; - - /** - * @see org.sharemedia.gui.viewers.impl.gl.IMovement#getValue(int) - */ - public double getValue(double step) { - return min + increment * step; - } - - /** - * @see org.sharemedia.gui.viewers.impl.gl.IMovement#init(float, float, int) - */ - public void init(double min, double max, int steps) { - increment = (max - min) / steps; - super.init(min, max, steps); - } - -} +/******************************************************************************* + * Copyright (c) 2006-2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.animation.movement; + +/** + * Moves at a constant speed. + * + * @author Nicolas Richeton + */ +public class LinearInOut extends AbstractMovement { + + double increment; + + /** + * @see org.sharemedia.gui.viewers.impl.gl.IMovement#getValue(int) + */ + public double getValue(double step) { + return min + increment * step; + } + + /** + * @see org.sharemedia.gui.viewers.impl.gl.IMovement#init(float, float, int) + */ + public void init(double min, double max, int steps) { + increment = (max - min) / steps; + super.init(min, max, steps); + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/FlatTreeContentProvider.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/FlatTreeContentProvider.java index b24ee83dc..01da3e7c1 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/FlatTreeContentProvider.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/FlatTreeContentProvider.java @@ -1,111 +1,111 @@ -/******************************************************************************* - * Copyright (c) 2007-2008 Peter Centgraf. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Peter Centgraf - initial implementation - *******************************************************************************/ -package org.eclipse.nebula.jface.galleryviewer; - -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -/** - * Adaptor that converts an {@link IStructuredContentProvider} into an - * {@link ITreeContentProvider} that places the nested contents inside a single - * root node. - * - * @author Peter Centgraf - * @since Dec 6, 2007 - */ -public class FlatTreeContentProvider implements ITreeContentProvider { - - protected final Object rootNode; - protected final IStructuredContentProvider provider; - protected final Object[] roots; - - /** - * Adapts an {@link IStructuredContentProvider} into an - * {@link ITreeContentProvider} that places the nested contents inside a - * single root node. - * - * @param provider - * the {@link IStructuredContentProvider} to adapt - */ - public FlatTreeContentProvider(IStructuredContentProvider provider) { - this(provider, ""); - } - - /** - * Adapts an {@link IStructuredContentProvider} into an - * {@link ITreeContentProvider} that places the nested contents inside the - * given root node. - * - * @param provider - * the {@link IStructuredContentProvider} to adapt - * @param the - * single root node for the tree - */ - public FlatTreeContentProvider(IStructuredContentProvider provider, - Object rootNode) { - this.provider = provider; - this.rootNode = rootNode; - - roots = new Object[] { rootNode }; - } - - /** - * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) - */ - public Object getParent(Object element) { - if (element == rootNode) { - return null; - } else { - return rootNode; - } - } - - /** - * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) - */ - public boolean hasChildren(Object element) { - return element == rootNode; - } - - /** - * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) - */ - public Object[] getElements(Object inputElement) { - return roots; - } - - /** - * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) - */ - public Object[] getChildren(Object parentElement) { - return provider.getElements(parentElement); - } - - /** - * @see org.eclipse.jface.viewers.IContentProvider#dispose() - */ - public void dispose() { - provider.dispose(); - } - - /** - * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, - * java.lang.Object, java.lang.Object) - */ - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - provider.inputChanged(viewer, oldInput, newInput); - } - -} +/******************************************************************************* + * Copyright (c) 2007-2008 Peter Centgraf. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Peter Centgraf - initial implementation + *******************************************************************************/ +package org.eclipse.nebula.jface.galleryviewer; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * Adaptor that converts an {@link IStructuredContentProvider} into an + * {@link ITreeContentProvider} that places the nested contents inside a single + * root node. + * + * @author Peter Centgraf + * @since Dec 6, 2007 + */ +public class FlatTreeContentProvider implements ITreeContentProvider { + + protected final Object rootNode; + protected final IStructuredContentProvider provider; + protected final Object[] roots; + + /** + * Adapts an {@link IStructuredContentProvider} into an + * {@link ITreeContentProvider} that places the nested contents inside a + * single root node. + * + * @param provider + * the {@link IStructuredContentProvider} to adapt + */ + public FlatTreeContentProvider(IStructuredContentProvider provider) { + this(provider, ""); + } + + /** + * Adapts an {@link IStructuredContentProvider} into an + * {@link ITreeContentProvider} that places the nested contents inside the + * given root node. + * + * @param provider + * the {@link IStructuredContentProvider} to adapt + * @param the + * single root node for the tree + */ + public FlatTreeContentProvider(IStructuredContentProvider provider, + Object rootNode) { + this.provider = provider; + this.rootNode = rootNode; + + roots = new Object[] { rootNode }; + } + + /** + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element == rootNode) { + return null; + } else { + return rootNode; + } + } + + /** + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + return element == rootNode; + } + + /** + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return roots; + } + + /** + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object parentElement) { + return provider.getElements(parentElement); + } + + /** + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + provider.dispose(); + } + + /** + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + provider.inputChanged(viewer, oldInput, newInput); + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/GalleryTreeViewer.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/GalleryTreeViewer.java index 48d4ceb06..00b124bd5 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/GalleryTreeViewer.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/GalleryTreeViewer.java @@ -1,505 +1,505 @@ -/******************************************************************************* - * Copyright (c) 2007-2008 Peter Centgraf. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Peter Centgraf - initial implementation - *******************************************************************************/ -package org.eclipse.nebula.jface.galleryviewer; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; -import org.eclipse.jface.viewers.IContentProvider; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.ITreePathContentProvider; -import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.TreeSelection; -import org.eclipse.jface.viewers.ViewerCell; -import org.eclipse.jface.viewers.ViewerRow; -import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; -import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; -import org.eclipse.nebula.widgets.gallery.Gallery; -import org.eclipse.nebula.widgets.gallery.GalleryItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.TreeListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.Widget; - -/** - * A concrete viewer based on a Nebula Gallery control. - *

- * This class is not intended to be subclassed outside the viewer framework. It - * is designed to be instantiated with a pre-existing Nebula Gallery control and - * configured with a domain-specific content provider, label provider, element - * filter (optional), and element sorter (optional). - *

- * - *

- * SWT.VIRTUAL is currently unsupported - *

- * - *

- * THIS VIEWER SHOULD BE CONSIDERED AS ALPHA - *

- * - * @author Peter Centgraf - * @contributor Nicolas Richeton - * @since Dec 5, 2007 - */ -public class GalleryTreeViewer extends AbstractTreeViewer { - - protected Gallery gallery; - - /** - * true if we are inside a preservingSelection() call - */ - protected boolean preservingSelection; - - /** - * The row object reused - */ - private GalleryViewerRow cachedRow; - - /** - * Creates a gallery viewer on a newly-created gallery control under the - * given parent. The gallery control is created using the SWT style bits - * MULTI, V_SCROLL, and BORDER. The viewer has no - * input, no content provider, a default label provider, no sorter, and no - * filters. - * - * @param parent - * the parent control - */ - public GalleryTreeViewer(Composite parent) { - this(parent, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER); - } - - /** - * Creates a gallery viewer on a newly-created gallery control under the - * given parent. The gallery control is created using the given SWT style - * bits. The viewer has no input, no content provider, a default label - * provider, no sorter, and no filters. - * - * @param parent - * the parent control - * @param style - * the SWT style bits used to create the gallery. - */ - public GalleryTreeViewer(Composite parent, int style) { - gallery = new Gallery(parent, style); - gallery.setGroupRenderer(new DefaultGalleryGroupRenderer()); - gallery.setItemRenderer(new DefaultGalleryItemRenderer()); - super.setAutoExpandLevel(ALL_LEVELS); - - hookControl(gallery); - } - - /** - * Creates a gallery viewer on the given gallery control. The viewer has no - * input, no content provider, a default label provider, no sorter, and no - * filters. - * - * @param gallery - * the gallery control - */ - public GalleryTreeViewer(Gallery gallery) { - super(); - this.gallery = gallery; - super.setAutoExpandLevel(ALL_LEVELS); - - hookControl(gallery); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#addTreeListener(org.eclipse - * .swt.widgets.Control, org.eclipse.swt.events.TreeListener) - */ - protected void addTreeListener(Control control, TreeListener listener) { - ((Gallery) control).addTreeListener(listener); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChild(org.eclipse.swt - * .widgets.Widget, int) - */ - protected Item getChild(Widget widget, int index) { - if (widget instanceof GalleryItem) { - return ((GalleryItem) widget).getItem(index); - } - if (widget instanceof Gallery) { - return ((Gallery) widget).getItem(index); - } - return null; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChildren(org.eclipse. - * swt.widgets.Widget) - */ - protected Item[] getChildren(Widget widget) { - if (widget instanceof GalleryItem) { - return ((GalleryItem) widget).getItems(); - } - if (widget instanceof Gallery) { - return ((Gallery) widget).getItems(); - } - return null; - } - - protected Widget getColumnViewerOwner(int columnIndex) { - if (columnIndex == 0) { - return getGallery(); - } - return null; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getExpanded(org.eclipse. - * swt.widgets.Item) - */ - protected boolean getExpanded(Item item) { - return ((GalleryItem) item).isExpanded(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemCount(org.eclipse - * .swt.widgets.Control) - */ - protected int getItemCount(Control control) { - return ((Gallery) control).getItemCount(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemCount(org.eclipse - * .swt.widgets.Item) - */ - protected int getItemCount(Item item) { - return ((GalleryItem) item).getItemCount(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItems(org.eclipse.swt - * .widgets.Item) - */ - protected Item[] getItems(Item item) { - return ((GalleryItem) item).getItems(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getParentItem(org.eclipse - * .swt.widgets.Item) - */ - protected Item getParentItem(Item item) { - return ((GalleryItem) item).getParentItem(); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#getSelection(org.eclipse - * .swt.widgets.Control) - */ - protected Item[] getSelection(Control control) { - Item[] selection = ((Gallery) control).getSelection(); - if (selection == null) { - return new GalleryItem[0]; - } - - List notDisposed = new ArrayList<>(selection.length); - for (int i = 0; i < selection.length; i++) { - if (!selection[i].isDisposed()) { - notDisposed.add((GalleryItem) selection[i]); - } else { - System.out.println("GalleryItem was disposed (ignoring)"); - } - } - selection = notDisposed.toArray(new GalleryItem[notDisposed.size()]); - - return selection; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#newItem(org.eclipse.swt. - * widgets.Widget, int, int) - */ - protected Item newItem(Widget parent, int style, int index) { - - GalleryItem item; - - if (parent instanceof GalleryItem) { - item = (GalleryItem) createNewRowPart(getViewerRowFromItem(parent), - style, index).getItem(); - } else { - item = (GalleryItem) createNewRowPart(null, style, index).getItem(); - } - - return item; - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#removeAll(org.eclipse.swt - * .widgets.Control) - */ - protected void removeAll(Control control) { - ((Gallery) control).removeAll(); - } - - public void setAutoExpandLevel(int level) { - throw new UnsupportedOperationException( - "Gallery must be fully expanded."); - } - - /** - *

- * Gallery expects contents to have exactly 2 levels of hierarchy, with - * groups as the root elements and image thumbnails as direct children of - * the groups. This method accepts ITreeContentProvider and - * ITreePathContentProvider as-is, and relies on the providers to return - * contents with the correct structure. - *

- *

- * This method also accepts IStructuredContentProvider and wraps it in a - * FlatTreeContentProvider with an empty string as the root node. If you - * need a different root node, construct your own FlatTreeContentProvider - * and pass it here. If you want the Gallery to suppress the collapsable - * group header, call - *

- * getGallery().setGroupRenderer(new NoGroupRenderer()); - */ - public void setContentProvider(IContentProvider provider) { - if (provider instanceof IStructuredContentProvider - && !(provider instanceof ITreeContentProvider - || provider instanceof ITreePathContentProvider)) { - // Wrap a table-style contents with a single root node. - super.setContentProvider(new FlatTreeContentProvider( - (IStructuredContentProvider) provider)); - } else { - super.setContentProvider(provider); - } - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#setExpanded(org.eclipse. - * swt.widgets.Item, boolean) - */ - protected void setExpanded(Item item, boolean expand) { - ((GalleryItem) item).setExpanded(expand); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#setSelection(java.util.List) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void setSelection(List items) { - Item[] current = getSelection(getGallery()); - - // Don't bother resetting the same selection - if (isSameSelection(items, current)) { - return; - } - - GalleryItem[] newItems = new GalleryItem[items.size()]; - items.toArray(newItems); - getGallery().setSelection(newItems); - } - - /** - * @see org.eclipse.jface.viewers.AbstractTreeViewer#showItem(org.eclipse.swt - * .widgets.Item) - */ - protected void showItem(Item item) { - gallery.showItem((GalleryItem) item); - } - - /** - * @see org.eclipse.jface.viewers.Viewer#getControl() - */ - public Control getControl() { - return gallery; - } - - /** - * Returns this gallery viewer's gallery. - * - * @return the gallery control - */ - public Gallery getGallery() { - return gallery; - } - - protected Item getItemAt(Point point) { - return gallery.getItem(point); - } - - protected ColumnViewerEditor createViewerEditor() { - // TODO: implement editing support - return null; - } - - /** - * For a GalleryViewer with a gallery with the VIRTUAL style bit set, set - * the number of children of the given element or tree path. To set the - * number of children of the invisible root of the gallery, you can pass the - * input object or an empty tree path. - * - * @param elementOrTreePath - * the element, or tree path - * @param count - * - * @since 3.2 - */ - public void setChildCount(final Object elementOrTreePath, final int count) { - preservingSelection(() -> { - if (internalIsInputOrEmptyPath(elementOrTreePath)) { - getGallery().setItemCount(count); - return; - } - Widget[] items = internalFindItems(elementOrTreePath); - for (int i = 0; i < items.length; i++) { - GalleryItem galleryItem = (GalleryItem) items[i]; - galleryItem.setItemCount(count); - } - }); - } - - /** - * @see org.eclipse.jface.viewers.ColumnViewer#getRowPartFromItem(org.eclipse - * .swt.widgets.Widget) - */ - protected ViewerRow getViewerRowFromItem(Widget item) { - if (cachedRow == null) { - cachedRow = new GalleryViewerRow((GalleryItem) item); - } else { - cachedRow.setItem((GalleryItem) item); - } - - return cachedRow; - } - - /** - * Create a new ViewerRow at rowIndex - * - * @param parent - * @param style - * @param rowIndex - * @return ViewerRow - */ - private ViewerRow createNewRowPart(ViewerRow parent, int style, - int rowIndex) { - if (parent == null) { - if (rowIndex >= 0) { - return getViewerRowFromItem( - new GalleryItem(gallery, style, rowIndex)); - } - return getViewerRowFromItem(new GalleryItem(gallery, style)); - } - - if (rowIndex >= 0) { - return getViewerRowFromItem(new GalleryItem( - (GalleryItem) parent.getItem(), SWT.NONE, rowIndex)); - } - - return getViewerRowFromItem( - new GalleryItem((GalleryItem) parent.getItem(), SWT.NONE)); - } - - /** - * Removes the element at the specified index of the parent. The selection - * is updated if required. - * - * @param parentOrTreePath - * the parent element, the input element, or a tree path to the - * parent element - * @param index - * child index - * @since 3.3 - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void remove(final Object parentOrTreePath, final int index) { - final List oldSelection = new LinkedList( - Arrays.asList(((TreeSelection) getSelection()).getPaths())); - preservingSelection(() -> { - TreePath removedPath = null; - if (internalIsInputOrEmptyPath(parentOrTreePath)) { - Gallery gallery = (Gallery) getControl(); - if (index < gallery.getItemCount()) { - GalleryItem item = gallery.getItem(index); - if (item.getData() != null) { - removedPath = getTreePathFromItem(item); - disassociate(item); - } - item.dispose(); - } - } else { - Widget[] parentItems = internalFindItems(parentOrTreePath); - for (int i = 0; i < parentItems.length; i++) { - GalleryItem parentItem = (GalleryItem) parentItems[i]; - if (index < parentItem.getItemCount()) { - GalleryItem item = parentItem.getItem(index); - if (item.getData() != null) { - removedPath = getTreePathFromItem(item); - disassociate(item); - } - item.dispose(); - } - } - } - if (removedPath != null) { - boolean removed = false; - for (Iterator it = oldSelection.iterator(); it.hasNext();) { - TreePath path = (TreePath) it.next(); - if (path.startsWith(removedPath, getComparer())) { - it.remove(); - removed = true; - } - } - if (removed) { - setSelection(new TreeSelection( - (TreePath[]) oldSelection - .toArray(new TreePath[oldSelection.size()]), - getComparer()), false); - } - - } - }); - } - - public void editElement(Object element, int column) { - if (element instanceof TreePath) { - setSelection(new TreeSelection((TreePath) element)); - GalleryItem[] items = gallery.getSelection(); - - if (items.length == 1) { - ViewerRow row = getViewerRowFromItem(items[0]); - - if (row != null) { - ViewerCell cell = row.getCell(column); - if (cell != null) { - getControl().setRedraw(false); - triggerEditorActivationEvent( - new ColumnViewerEditorActivationEvent(cell)); - getControl().setRedraw(true); - } - } - } - } else { - super.editElement(element, column); - } - } - -} +/******************************************************************************* + * Copyright (c) 2007-2008 Peter Centgraf. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Peter Centgraf - initial implementation + *******************************************************************************/ +package org.eclipse.nebula.jface.galleryviewer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.ITreePathContentProvider; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.jface.viewers.ViewerRow; +import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; +import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; +import org.eclipse.nebula.widgets.gallery.Gallery; +import org.eclipse.nebula.widgets.gallery.GalleryItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.TreeListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Widget; + +/** + * A concrete viewer based on a Nebula Gallery control. + *

+ * This class is not intended to be subclassed outside the viewer framework. It + * is designed to be instantiated with a pre-existing Nebula Gallery control and + * configured with a domain-specific content provider, label provider, element + * filter (optional), and element sorter (optional). + *

+ * + *

+ * SWT.VIRTUAL is currently unsupported + *

+ * + *

+ * THIS VIEWER SHOULD BE CONSIDERED AS ALPHA + *

+ * + * @author Peter Centgraf + * @contributor Nicolas Richeton + * @since Dec 5, 2007 + */ +public class GalleryTreeViewer extends AbstractTreeViewer { + + protected Gallery gallery; + + /** + * true if we are inside a preservingSelection() call + */ + protected boolean preservingSelection; + + /** + * The row object reused + */ + private GalleryViewerRow cachedRow; + + /** + * Creates a gallery viewer on a newly-created gallery control under the + * given parent. The gallery control is created using the SWT style bits + * MULTI, V_SCROLL, and BORDER. The viewer has no + * input, no content provider, a default label provider, no sorter, and no + * filters. + * + * @param parent + * the parent control + */ + public GalleryTreeViewer(Composite parent) { + this(parent, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER); + } + + /** + * Creates a gallery viewer on a newly-created gallery control under the + * given parent. The gallery control is created using the given SWT style + * bits. The viewer has no input, no content provider, a default label + * provider, no sorter, and no filters. + * + * @param parent + * the parent control + * @param style + * the SWT style bits used to create the gallery. + */ + public GalleryTreeViewer(Composite parent, int style) { + gallery = new Gallery(parent, style); + gallery.setGroupRenderer(new DefaultGalleryGroupRenderer()); + gallery.setItemRenderer(new DefaultGalleryItemRenderer()); + super.setAutoExpandLevel(ALL_LEVELS); + + hookControl(gallery); + } + + /** + * Creates a gallery viewer on the given gallery control. The viewer has no + * input, no content provider, a default label provider, no sorter, and no + * filters. + * + * @param gallery + * the gallery control + */ + public GalleryTreeViewer(Gallery gallery) { + super(); + this.gallery = gallery; + super.setAutoExpandLevel(ALL_LEVELS); + + hookControl(gallery); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#addTreeListener(org.eclipse + * .swt.widgets.Control, org.eclipse.swt.events.TreeListener) + */ + protected void addTreeListener(Control control, TreeListener listener) { + ((Gallery) control).addTreeListener(listener); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChild(org.eclipse.swt + * .widgets.Widget, int) + */ + protected Item getChild(Widget widget, int index) { + if (widget instanceof GalleryItem) { + return ((GalleryItem) widget).getItem(index); + } + if (widget instanceof Gallery) { + return ((Gallery) widget).getItem(index); + } + return null; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChildren(org.eclipse. + * swt.widgets.Widget) + */ + protected Item[] getChildren(Widget widget) { + if (widget instanceof GalleryItem) { + return ((GalleryItem) widget).getItems(); + } + if (widget instanceof Gallery) { + return ((Gallery) widget).getItems(); + } + return null; + } + + protected Widget getColumnViewerOwner(int columnIndex) { + if (columnIndex == 0) { + return getGallery(); + } + return null; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getExpanded(org.eclipse. + * swt.widgets.Item) + */ + protected boolean getExpanded(Item item) { + return ((GalleryItem) item).isExpanded(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemCount(org.eclipse + * .swt.widgets.Control) + */ + protected int getItemCount(Control control) { + return ((Gallery) control).getItemCount(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItemCount(org.eclipse + * .swt.widgets.Item) + */ + protected int getItemCount(Item item) { + return ((GalleryItem) item).getItemCount(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getItems(org.eclipse.swt + * .widgets.Item) + */ + protected Item[] getItems(Item item) { + return ((GalleryItem) item).getItems(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getParentItem(org.eclipse + * .swt.widgets.Item) + */ + protected Item getParentItem(Item item) { + return ((GalleryItem) item).getParentItem(); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getSelection(org.eclipse + * .swt.widgets.Control) + */ + protected Item[] getSelection(Control control) { + Item[] selection = ((Gallery) control).getSelection(); + if (selection == null) { + return new GalleryItem[0]; + } + + List notDisposed = new ArrayList<>(selection.length); + for (int i = 0; i < selection.length; i++) { + if (!selection[i].isDisposed()) { + notDisposed.add((GalleryItem) selection[i]); + } else { + System.out.println("GalleryItem was disposed (ignoring)"); + } + } + selection = notDisposed.toArray(new GalleryItem[notDisposed.size()]); + + return selection; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#newItem(org.eclipse.swt. + * widgets.Widget, int, int) + */ + protected Item newItem(Widget parent, int style, int index) { + + GalleryItem item; + + if (parent instanceof GalleryItem) { + item = (GalleryItem) createNewRowPart(getViewerRowFromItem(parent), + style, index).getItem(); + } else { + item = (GalleryItem) createNewRowPart(null, style, index).getItem(); + } + + return item; + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#removeAll(org.eclipse.swt + * .widgets.Control) + */ + protected void removeAll(Control control) { + ((Gallery) control).removeAll(); + } + + public void setAutoExpandLevel(int level) { + throw new UnsupportedOperationException( + "Gallery must be fully expanded."); + } + + /** + *

+ * Gallery expects contents to have exactly 2 levels of hierarchy, with + * groups as the root elements and image thumbnails as direct children of + * the groups. This method accepts ITreeContentProvider and + * ITreePathContentProvider as-is, and relies on the providers to return + * contents with the correct structure. + *

+ *

+ * This method also accepts IStructuredContentProvider and wraps it in a + * FlatTreeContentProvider with an empty string as the root node. If you + * need a different root node, construct your own FlatTreeContentProvider + * and pass it here. If you want the Gallery to suppress the collapsable + * group header, call + *

+ * getGallery().setGroupRenderer(new NoGroupRenderer()); + */ + public void setContentProvider(IContentProvider provider) { + if (provider instanceof IStructuredContentProvider + && !(provider instanceof ITreeContentProvider + || provider instanceof ITreePathContentProvider)) { + // Wrap a table-style contents with a single root node. + super.setContentProvider(new FlatTreeContentProvider( + (IStructuredContentProvider) provider)); + } else { + super.setContentProvider(provider); + } + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#setExpanded(org.eclipse. + * swt.widgets.Item, boolean) + */ + protected void setExpanded(Item item, boolean expand) { + ((GalleryItem) item).setExpanded(expand); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#setSelection(java.util.List) + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected void setSelection(List items) { + Item[] current = getSelection(getGallery()); + + // Don't bother resetting the same selection + if (isSameSelection(items, current)) { + return; + } + + GalleryItem[] newItems = new GalleryItem[items.size()]; + items.toArray(newItems); + getGallery().setSelection(newItems); + } + + /** + * @see org.eclipse.jface.viewers.AbstractTreeViewer#showItem(org.eclipse.swt + * .widgets.Item) + */ + protected void showItem(Item item) { + gallery.showItem((GalleryItem) item); + } + + /** + * @see org.eclipse.jface.viewers.Viewer#getControl() + */ + public Control getControl() { + return gallery; + } + + /** + * Returns this gallery viewer's gallery. + * + * @return the gallery control + */ + public Gallery getGallery() { + return gallery; + } + + protected Item getItemAt(Point point) { + return gallery.getItem(point); + } + + protected ColumnViewerEditor createViewerEditor() { + // TODO: implement editing support + return null; + } + + /** + * For a GalleryViewer with a gallery with the VIRTUAL style bit set, set + * the number of children of the given element or tree path. To set the + * number of children of the invisible root of the gallery, you can pass the + * input object or an empty tree path. + * + * @param elementOrTreePath + * the element, or tree path + * @param count + * + * @since 3.2 + */ + public void setChildCount(final Object elementOrTreePath, final int count) { + preservingSelection(() -> { + if (internalIsInputOrEmptyPath(elementOrTreePath)) { + getGallery().setItemCount(count); + return; + } + Widget[] items = internalFindItems(elementOrTreePath); + for (int i = 0; i < items.length; i++) { + GalleryItem galleryItem = (GalleryItem) items[i]; + galleryItem.setItemCount(count); + } + }); + } + + /** + * @see org.eclipse.jface.viewers.ColumnViewer#getRowPartFromItem(org.eclipse + * .swt.widgets.Widget) + */ + protected ViewerRow getViewerRowFromItem(Widget item) { + if (cachedRow == null) { + cachedRow = new GalleryViewerRow((GalleryItem) item); + } else { + cachedRow.setItem((GalleryItem) item); + } + + return cachedRow; + } + + /** + * Create a new ViewerRow at rowIndex + * + * @param parent + * @param style + * @param rowIndex + * @return ViewerRow + */ + private ViewerRow createNewRowPart(ViewerRow parent, int style, + int rowIndex) { + if (parent == null) { + if (rowIndex >= 0) { + return getViewerRowFromItem( + new GalleryItem(gallery, style, rowIndex)); + } + return getViewerRowFromItem(new GalleryItem(gallery, style)); + } + + if (rowIndex >= 0) { + return getViewerRowFromItem(new GalleryItem( + (GalleryItem) parent.getItem(), SWT.NONE, rowIndex)); + } + + return getViewerRowFromItem( + new GalleryItem((GalleryItem) parent.getItem(), SWT.NONE)); + } + + /** + * Removes the element at the specified index of the parent. The selection + * is updated if required. + * + * @param parentOrTreePath + * the parent element, the input element, or a tree path to the + * parent element + * @param index + * child index + * @since 3.3 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void remove(final Object parentOrTreePath, final int index) { + final List oldSelection = new LinkedList( + Arrays.asList(((TreeSelection) getSelection()).getPaths())); + preservingSelection(() -> { + TreePath removedPath = null; + if (internalIsInputOrEmptyPath(parentOrTreePath)) { + Gallery gallery = (Gallery) getControl(); + if (index < gallery.getItemCount()) { + GalleryItem item = gallery.getItem(index); + if (item.getData() != null) { + removedPath = getTreePathFromItem(item); + disassociate(item); + } + item.dispose(); + } + } else { + Widget[] parentItems = internalFindItems(parentOrTreePath); + for (int i = 0; i < parentItems.length; i++) { + GalleryItem parentItem = (GalleryItem) parentItems[i]; + if (index < parentItem.getItemCount()) { + GalleryItem item = parentItem.getItem(index); + if (item.getData() != null) { + removedPath = getTreePathFromItem(item); + disassociate(item); + } + item.dispose(); + } + } + } + if (removedPath != null) { + boolean removed = false; + for (Iterator it = oldSelection.iterator(); it.hasNext();) { + TreePath path = (TreePath) it.next(); + if (path.startsWith(removedPath, getComparer())) { + it.remove(); + removed = true; + } + } + if (removed) { + setSelection(new TreeSelection( + (TreePath[]) oldSelection + .toArray(new TreePath[oldSelection.size()]), + getComparer()), false); + } + + } + }); + } + + public void editElement(Object element, int column) { + if (element instanceof TreePath) { + setSelection(new TreeSelection((TreePath) element)); + GalleryItem[] items = gallery.getSelection(); + + if (items.length == 1) { + ViewerRow row = getViewerRowFromItem(items[0]); + + if (row != null) { + ViewerCell cell = row.getCell(column); + if (cell != null) { + getControl().setRedraw(false); + triggerEditorActivationEvent( + new ColumnViewerEditorActivationEvent(cell)); + getControl().setRedraw(true); + } + } + } + } else { + super.editElement(element, column); + } + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/GalleryViewerRow.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/GalleryViewerRow.java index d22ee42a3..608750c54 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/GalleryViewerRow.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/jface/galleryviewer/GalleryViewerRow.java @@ -1,254 +1,254 @@ -/******************************************************************************* - * Copyright (c) 2007-2008 Peter Centgraf. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Peter Centgraf - initial implementation - *******************************************************************************/ -package org.eclipse.nebula.jface.galleryviewer; - -import java.util.LinkedList; - -import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.ViewerRow; -import org.eclipse.nebula.widgets.gallery.GalleryItem; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Widget; - -/** - * ViewerRow adapter for the Nebula Gallery widget. - * - * @author Peter Centgraf - * @since Dec 5, 2007 - */ -public class GalleryViewerRow extends ViewerRow { - - protected GalleryItem item; - - /** - * Constructs a ViewerRow adapter for a GalleryItem. - * - * @param item - * the GalleryItem to adapt - */ - public GalleryViewerRow(GalleryItem item) { - this.item = item; - } - - public void setItem(GalleryItem item) { - this.item = item; - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#clone() - */ - public Object clone() { - return new GalleryViewerRow(item); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getBackground(int) - */ - public Color getBackground(int columnIndex) { - // XXX: should this use getBackgroundColor() instead? - return item.getBackground(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getBounds() - */ - public Rectangle getBounds() { - return item.getBounds(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getBounds(int) - */ - public Rectangle getBounds(int columnIndex) { - return item.getBounds(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getColumnCount() - */ - public int getColumnCount() { - return 0; - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getControl() - */ - public Control getControl() { - return item.getParent(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getElement() - */ - public Object getElement() { - return item.getData(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getFont(int) - */ - public Font getFont(int columnIndex) { - return item.getFont(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getForeground(int) - */ - public Color getForeground(int columnIndex) { - return item.getForeground(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getImage(int) - */ - public Image getImage(int columnIndex) { - return item.getImage(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getItem() - */ - public Widget getItem() { - return item; - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getNeighbor(int, boolean) - */ - public ViewerRow getNeighbor(int direction, boolean sameLevel) { - if (direction == ViewerRow.ABOVE) { - // TODO: handle grouping - return getRowAbove(); - } else if (direction == ViewerRow.BELOW) { - // TODO: handle grouping - return getRowBelow(); - } else { - throw new IllegalArgumentException( - "Illegal value of direction argument."); //$NON-NLS-1$ - } - } - - protected ViewerRow getRowAbove() { - if (item.getParentItem() == null) { - int index = item.getParent().indexOf(item) - 1; - - if (index >= 0) { - return new GalleryViewerRow(item.getParent().getItem(index)); - } - } else { - GalleryItem parentItem = item.getParentItem(); - int index = parentItem.indexOf(item) - 1; - - if (index >= 0) { - return new GalleryViewerRow(parentItem.getItem(index)); - } - } - - return null; - } - - protected ViewerRow getRowBelow() { - if (item.getParentItem() == null) { - int index = item.getParent().indexOf(item) + 1; - - if (index < item.getParent().getItemCount()) { - GalleryItem tmp = item.getParent().getItem(index); - if (tmp != null) { - return new GalleryViewerRow(tmp); - } - } - } else { - GalleryItem parentItem = item.getParentItem(); - int index = parentItem.indexOf(item) + 1; - - if (index < parentItem.getItemCount()) { - GalleryItem tmp = parentItem.getItem(index); - if (tmp != null) { - return new GalleryViewerRow(tmp); - } - } - } - - return null; - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getText(int) - */ - public String getText(int columnIndex) { - return item.getText(); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#getTreePath() - */ - public TreePath getTreePath() { - LinkedList path = new LinkedList<>(); - path.add(item.getData()); - - GalleryItem curItem = item; - while (curItem.getParentItem() != null) { - path.addFirst(curItem.getParentItem().getData()); - curItem = curItem.getParentItem(); - } - return new TreePath(path.toArray()); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setBackground(int, - * org.eclipse.swt.graphics.Color) - */ - public void setBackground(int columnIndex, Color color) { - item.setBackground(color); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setFont(int, - * org.eclipse.swt.graphics.Font) - */ - public void setFont(int columnIndex, Font font) { - item.setFont(font); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setForeground(int, - * org.eclipse.swt.graphics.Color) - */ - public void setForeground(int columnIndex, Color color) { - item.setForeground(color); - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setImage(int, - * org.eclipse.swt.graphics.Image) - */ - public void setImage(int columnIndex, Image image) { - Image oldImage = item.getImage(); - if (image != oldImage) { - item.setImage(image); - } - } - - /** - * @see org.eclipse.jface.viewers.ViewerRow#setText(int, java.lang.String) - */ - public void setText(int columnIndex, String text) { - item.setText(text == null ? "" : text); - } - -} +/******************************************************************************* + * Copyright (c) 2007-2008 Peter Centgraf. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Peter Centgraf - initial implementation + *******************************************************************************/ +package org.eclipse.nebula.jface.galleryviewer; + +import java.util.LinkedList; + +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.ViewerRow; +import org.eclipse.nebula.widgets.gallery.GalleryItem; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Widget; + +/** + * ViewerRow adapter for the Nebula Gallery widget. + * + * @author Peter Centgraf + * @since Dec 5, 2007 + */ +public class GalleryViewerRow extends ViewerRow { + + protected GalleryItem item; + + /** + * Constructs a ViewerRow adapter for a GalleryItem. + * + * @param item + * the GalleryItem to adapt + */ + public GalleryViewerRow(GalleryItem item) { + this.item = item; + } + + public void setItem(GalleryItem item) { + this.item = item; + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#clone() + */ + public Object clone() { + return new GalleryViewerRow(item); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getBackground(int) + */ + public Color getBackground(int columnIndex) { + // XXX: should this use getBackgroundColor() instead? + return item.getBackground(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getBounds() + */ + public Rectangle getBounds() { + return item.getBounds(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getBounds(int) + */ + public Rectangle getBounds(int columnIndex) { + return item.getBounds(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getColumnCount() + */ + public int getColumnCount() { + return 0; + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getControl() + */ + public Control getControl() { + return item.getParent(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getElement() + */ + public Object getElement() { + return item.getData(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getFont(int) + */ + public Font getFont(int columnIndex) { + return item.getFont(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getForeground(int) + */ + public Color getForeground(int columnIndex) { + return item.getForeground(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getImage(int) + */ + public Image getImage(int columnIndex) { + return item.getImage(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getItem() + */ + public Widget getItem() { + return item; + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getNeighbor(int, boolean) + */ + public ViewerRow getNeighbor(int direction, boolean sameLevel) { + if (direction == ViewerRow.ABOVE) { + // TODO: handle grouping + return getRowAbove(); + } else if (direction == ViewerRow.BELOW) { + // TODO: handle grouping + return getRowBelow(); + } else { + throw new IllegalArgumentException( + "Illegal value of direction argument."); //$NON-NLS-1$ + } + } + + protected ViewerRow getRowAbove() { + if (item.getParentItem() == null) { + int index = item.getParent().indexOf(item) - 1; + + if (index >= 0) { + return new GalleryViewerRow(item.getParent().getItem(index)); + } + } else { + GalleryItem parentItem = item.getParentItem(); + int index = parentItem.indexOf(item) - 1; + + if (index >= 0) { + return new GalleryViewerRow(parentItem.getItem(index)); + } + } + + return null; + } + + protected ViewerRow getRowBelow() { + if (item.getParentItem() == null) { + int index = item.getParent().indexOf(item) + 1; + + if (index < item.getParent().getItemCount()) { + GalleryItem tmp = item.getParent().getItem(index); + if (tmp != null) { + return new GalleryViewerRow(tmp); + } + } + } else { + GalleryItem parentItem = item.getParentItem(); + int index = parentItem.indexOf(item) + 1; + + if (index < parentItem.getItemCount()) { + GalleryItem tmp = parentItem.getItem(index); + if (tmp != null) { + return new GalleryViewerRow(tmp); + } + } + } + + return null; + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getText(int) + */ + public String getText(int columnIndex) { + return item.getText(); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#getTreePath() + */ + public TreePath getTreePath() { + LinkedList path = new LinkedList<>(); + path.add(item.getData()); + + GalleryItem curItem = item; + while (curItem.getParentItem() != null) { + path.addFirst(curItem.getParentItem().getData()); + curItem = curItem.getParentItem(); + } + return new TreePath(path.toArray()); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setBackground(int, + * org.eclipse.swt.graphics.Color) + */ + public void setBackground(int columnIndex, Color color) { + item.setBackground(color); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setFont(int, + * org.eclipse.swt.graphics.Font) + */ + public void setFont(int columnIndex, Font font) { + item.setFont(font); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setForeground(int, + * org.eclipse.swt.graphics.Color) + */ + public void setForeground(int columnIndex, Color color) { + item.setForeground(color); + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setImage(int, + * org.eclipse.swt.graphics.Image) + */ + public void setImage(int columnIndex, Image image) { + Image oldImage = item.getImage(); + if (image != oldImage) { + item.setImage(image); + } + } + + /** + * @see org.eclipse.jface.viewers.ViewerRow#setText(int, java.lang.String) + */ + public void setText(int columnIndex, String text) { + item.setText(text == null ? "" : text); + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/AbstractGalleryGroupRenderer.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/AbstractGalleryGroupRenderer.java index e5f53831a..dde507b16 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/AbstractGalleryGroupRenderer.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/AbstractGalleryGroupRenderer.java @@ -1,332 +1,332 @@ -/******************************************************************************* - * Copyright (c) 2006-2007 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.gallery; - -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Event; - -/** - *

- * Base class used to implement a custom gallery group renderer. - *

- *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. - *

- * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - */ -public abstract class AbstractGalleryGroupRenderer { - - protected Gallery gallery; - - protected boolean expanded; - - /** - * Get the expand/collapse state of the current group - * - * @return true is the current group is expanded - */ - public boolean isExpanded() { - return this.expanded; - } - - /** - * @see AbstractGalleryGroupRenderer#isExpanded() - * @param selected - */ - public void setExpanded(boolean selected) { - this.expanded = selected; - } - - /** - * This method is called before drawing the first item. It can be used to - * calculate some values (like font metrics) that will be used for each - * item. - * - * @param gc - */ - public void preDraw(GC gc) { - // Nothing required here. This method can be overridden when needed. - } - - /** - * This method is called after drawing the last item. It may be used to - * cleanup and release resources created in preDraw(). - * - * @param gc - */ - public void postDraw(GC gc) { - // Nothing required here. This method can be overridden when needed. - } - - /** - * Group size informations can be retrieved from group. Clipping - * informations - * - * @param gc - * @param group - * @param x - * @param y - */ - public abstract void draw(GC gc, GalleryItem group, int x, int y, int clipX, - int clipY, int clipWidth, int clipHeight); - - public abstract void dispose(); - - /** - * Returns the item that should be selected when the current item is 'item' - * and the 'key' is pressed - * - * @param item - * @param key - * @return - */ - public abstract GalleryItem getNextItem(GalleryItem item, int key); - - /** - * This method is called before the layout of the first item. It can be used - * to calculate some values (like font metrics) that will be used for each - * item. - * - * @param gc - */ - public void preLayout(GC gc) { - // Nothing required here. This method can be overridden when needed. - } - - /** - * This method is called after the layout of the last item. - * - * @param gc - */ - public void postLayout(GC gc) { - // Nothing required here. This method can be overridden when needed. - } - - /** - * This method is called on each root item when the Gallery changes (resize, - * item addition or removal) in order to update the gallery size. - * - * The implementation must update the item internal size (px) using - * setGroupSize(item, size); before returning. - * - * @param gc - * @param group - */ - public abstract void layout(GC gc, GalleryItem group); - - /** - * Returns the item at coords relative to the parent group. - * - * @param group - * @param coords - * @return - */ - public abstract GalleryItem getItem(GalleryItem group, Point coords); - - /** - * Returns the size of a group. - * - * @param item - * @return - */ - public abstract Rectangle getSize(GalleryItem item); - - /** - * This method can be implemented to handle mouse down events at the group - * level. Usually to interact with custom group UI. - * - * @param group - * The group on which the mouse click occured - * @param e - * The original mouse event - * @param coords - * The pointer coordinates relative to the group - * @return false if event was handled by the group renderer and Gallery - * should not try to handle this event as a click on a GalleryItem. - */ - public abstract boolean mouseDown(GalleryItem group, Event e, Point coords); - - public Gallery getGallery() { - return this.gallery; - } - - public void setGallery(Gallery gallery) { - this.gallery = gallery; - } - - protected Point getGroupSize(GalleryItem item) { - return new Point(item.width, item.height); - - } - - protected Point getGroupPosition(GalleryItem item) { - return new Point(item.x, item.y); - } - - protected void setGroupSize(GalleryItem item, Point size) { - item.width = size.x; - item.height = size.y; - } - - /** - * This method can be used as a condition to print trace or debug - * informations in standard output. - * - * @return true if Debug mode is enabled - */ - protected boolean isDebugMode() { - return Gallery.DEBUG; - } - - /** - * Notifies the Gallery that the control expanded/collapsed state has - * changed. - * - * @param group - */ - protected void notifyTreeListeners(GalleryItem group) { - gallery.notifyTreeListeners(group, group.isExpanded()); - } - - /** - * Forces an update of the gallery layout. - * - * @param keeplocation - * if true, the gallery will try to keep the current visible - * items in the client area after the new layout has been - * calculated. - */ - protected void updateStructuralValues(boolean keeplocation) { - gallery.updateStructuralValues(null, keeplocation); - } - - protected void updateScrollBarsProperties() { - gallery.updateScrollBarsProperties(); - } - - /** - * Returns the preferred Scrollbar increment for the current gallery layout. - * - * @return - */ - public int getScrollBarIncrement() { - return 16; - } - - /** - * Returns item background color. This method is called by - * {@link GalleryItem#getBackground()} and should be overridden by any group - * renderer which use additional colors. - * - * Note that item renderer is automatically used for items. - * - * @param item - * a GalleryItem - * @return Color The current background color (never null) - */ - protected Color getBackground(GalleryItem item) { - if (item != null) { - - if (item.getParentItem() == null - && gallery.getItemRenderer() != null) { - // This is an item, let the renderer decide - return gallery.getItemRenderer().getBackground(item); - } - - // This is a group, or no item renderer. Use standard SWT behavior : - - // Use item color first - if (item.background != null) { - return item.background; - } - - // Then parent color. - return item.getParent().getBackground(); - - } - return null; - } - - /** - * Returns item foreground color. This method is called by - * {@link GalleryItem#getForeground()} and should be overridden by any group - * renderer which use additional colors. - * - * Note that item renderer is automatically used for items. - * - * @param item - * a GalleryItem - * @return The current foreground (never null) - */ - protected Color getForeground(GalleryItem item) { - if (item != null) { - - if (item.getParentItem() != null - && gallery.getItemRenderer() != null) { - // This is an item, let the renderer decide - return gallery.getItemRenderer().getForeground(item); - } - // This is a group, or no item renderer. Use standard SWT behavior : - - // Use item color first - if (item.foreground != null) { - return item.foreground; - } - - // Then parent color. - return item.getParent().getForeground(); - - } - return null; - } - - /** - * Returns item font. This method is called by {@link GalleryItem#getFont()} - * and should be overridden by any group renderer which use additional - * fonts. - * - * Note that item renderer is automatically used for items. - * - * @param item - * a GalleryItem - * @return The current item Font (never null) - */ - protected Font getFont(GalleryItem item) { - if (item != null) { - - if (item.getParentItem() != null - && gallery.getItemRenderer() != null) { - // This is an item, let the renderer decide - return gallery.getItemRenderer().getFont(item); - } - // This is a group, or no item renderer. Use standard SWT behavior : - - // Use item font first - if (item.font != null) { - return item.font; - } - - // Then parent font. - return item.getParent().getFont(); - - } - return null; - } - -} +/******************************************************************************* + * Copyright (c) 2006-2007 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.gallery; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Event; + +/** + *

+ * Base class used to implement a custom gallery group renderer. + *

+ *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. + *

+ * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + */ +public abstract class AbstractGalleryGroupRenderer { + + protected Gallery gallery; + + protected boolean expanded; + + /** + * Get the expand/collapse state of the current group + * + * @return true is the current group is expanded + */ + public boolean isExpanded() { + return this.expanded; + } + + /** + * @see AbstractGalleryGroupRenderer#isExpanded() + * @param selected + */ + public void setExpanded(boolean selected) { + this.expanded = selected; + } + + /** + * This method is called before drawing the first item. It can be used to + * calculate some values (like font metrics) that will be used for each + * item. + * + * @param gc + */ + public void preDraw(GC gc) { + // Nothing required here. This method can be overridden when needed. + } + + /** + * This method is called after drawing the last item. It may be used to + * cleanup and release resources created in preDraw(). + * + * @param gc + */ + public void postDraw(GC gc) { + // Nothing required here. This method can be overridden when needed. + } + + /** + * Group size informations can be retrieved from group. Clipping + * informations + * + * @param gc + * @param group + * @param x + * @param y + */ + public abstract void draw(GC gc, GalleryItem group, int x, int y, int clipX, + int clipY, int clipWidth, int clipHeight); + + public abstract void dispose(); + + /** + * Returns the item that should be selected when the current item is 'item' + * and the 'key' is pressed + * + * @param item + * @param key + * @return + */ + public abstract GalleryItem getNextItem(GalleryItem item, int key); + + /** + * This method is called before the layout of the first item. It can be used + * to calculate some values (like font metrics) that will be used for each + * item. + * + * @param gc + */ + public void preLayout(GC gc) { + // Nothing required here. This method can be overridden when needed. + } + + /** + * This method is called after the layout of the last item. + * + * @param gc + */ + public void postLayout(GC gc) { + // Nothing required here. This method can be overridden when needed. + } + + /** + * This method is called on each root item when the Gallery changes (resize, + * item addition or removal) in order to update the gallery size. + * + * The implementation must update the item internal size (px) using + * setGroupSize(item, size); before returning. + * + * @param gc + * @param group + */ + public abstract void layout(GC gc, GalleryItem group); + + /** + * Returns the item at coords relative to the parent group. + * + * @param group + * @param coords + * @return + */ + public abstract GalleryItem getItem(GalleryItem group, Point coords); + + /** + * Returns the size of a group. + * + * @param item + * @return + */ + public abstract Rectangle getSize(GalleryItem item); + + /** + * This method can be implemented to handle mouse down events at the group + * level. Usually to interact with custom group UI. + * + * @param group + * The group on which the mouse click occured + * @param e + * The original mouse event + * @param coords + * The pointer coordinates relative to the group + * @return false if event was handled by the group renderer and Gallery + * should not try to handle this event as a click on a GalleryItem. + */ + public abstract boolean mouseDown(GalleryItem group, Event e, Point coords); + + public Gallery getGallery() { + return this.gallery; + } + + public void setGallery(Gallery gallery) { + this.gallery = gallery; + } + + protected Point getGroupSize(GalleryItem item) { + return new Point(item.width, item.height); + + } + + protected Point getGroupPosition(GalleryItem item) { + return new Point(item.x, item.y); + } + + protected void setGroupSize(GalleryItem item, Point size) { + item.width = size.x; + item.height = size.y; + } + + /** + * This method can be used as a condition to print trace or debug + * informations in standard output. + * + * @return true if Debug mode is enabled + */ + protected boolean isDebugMode() { + return Gallery.DEBUG; + } + + /** + * Notifies the Gallery that the control expanded/collapsed state has + * changed. + * + * @param group + */ + protected void notifyTreeListeners(GalleryItem group) { + gallery.notifyTreeListeners(group, group.isExpanded()); + } + + /** + * Forces an update of the gallery layout. + * + * @param keeplocation + * if true, the gallery will try to keep the current visible + * items in the client area after the new layout has been + * calculated. + */ + protected void updateStructuralValues(boolean keeplocation) { + gallery.updateStructuralValues(null, keeplocation); + } + + protected void updateScrollBarsProperties() { + gallery.updateScrollBarsProperties(); + } + + /** + * Returns the preferred Scrollbar increment for the current gallery layout. + * + * @return + */ + public int getScrollBarIncrement() { + return 16; + } + + /** + * Returns item background color. This method is called by + * {@link GalleryItem#getBackground()} and should be overridden by any group + * renderer which use additional colors. + * + * Note that item renderer is automatically used for items. + * + * @param item + * a GalleryItem + * @return Color The current background color (never null) + */ + protected Color getBackground(GalleryItem item) { + if (item != null) { + + if (item.getParentItem() == null + && gallery.getItemRenderer() != null) { + // This is an item, let the renderer decide + return gallery.getItemRenderer().getBackground(item); + } + + // This is a group, or no item renderer. Use standard SWT behavior : + + // Use item color first + if (item.background != null) { + return item.background; + } + + // Then parent color. + return item.getParent().getBackground(); + + } + return null; + } + + /** + * Returns item foreground color. This method is called by + * {@link GalleryItem#getForeground()} and should be overridden by any group + * renderer which use additional colors. + * + * Note that item renderer is automatically used for items. + * + * @param item + * a GalleryItem + * @return The current foreground (never null) + */ + protected Color getForeground(GalleryItem item) { + if (item != null) { + + if (item.getParentItem() != null + && gallery.getItemRenderer() != null) { + // This is an item, let the renderer decide + return gallery.getItemRenderer().getForeground(item); + } + // This is a group, or no item renderer. Use standard SWT behavior : + + // Use item color first + if (item.foreground != null) { + return item.foreground; + } + + // Then parent color. + return item.getParent().getForeground(); + + } + return null; + } + + /** + * Returns item font. This method is called by {@link GalleryItem#getFont()} + * and should be overridden by any group renderer which use additional + * fonts. + * + * Note that item renderer is automatically used for items. + * + * @param item + * a GalleryItem + * @return The current item Font (never null) + */ + protected Font getFont(GalleryItem item) { + if (item != null) { + + if (item.getParentItem() != null + && gallery.getItemRenderer() != null) { + // This is an item, let the renderer decide + return gallery.getItemRenderer().getFont(item); + } + // This is a group, or no item renderer. Use standard SWT behavior : + + // Use item font first + if (item.font != null) { + return item.font; + } + + // Then parent font. + return item.getParent().getFont(); + + } + return null; + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/AbstractGridGroupRenderer.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/AbstractGridGroupRenderer.java index fcf2a45ba..a0187264d 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/AbstractGridGroupRenderer.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/AbstractGridGroupRenderer.java @@ -1,921 +1,921 @@ -/******************************************************************************* - * Copyright (c) 2006-2007 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - * Richard Michalsky - bug 197959 - *******************************************************************************/ -package org.eclipse.nebula.widgets.gallery; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Item; - -/** - *

- * Abstract class which provides low-level support for a grid-based group. - * renderer. - *

- *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. - *

- * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - * @contributor Richard Michalsky (bug 197959) - * @contributor Robert Handschmann (bug 215817) - */ - -public abstract class AbstractGridGroupRenderer - extends AbstractGalleryGroupRenderer { - - static final int DEFAULT_SIZE = 96; - - protected int minMargin; - - protected int margin; - - protected boolean autoMargin; - - protected int itemWidth = DEFAULT_SIZE; - - protected int itemHeight = DEFAULT_SIZE; - - public static final String H_COUNT = "g.h"; //$NON-NLS-1$ - - public static final String V_COUNT = "g.v"; //$NON-NLS-1$ - - protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ - - private static final int END = 0; - - private static final int START = 1; - - /** - * If true, groups are always expanded and toggle button is not displayed - */ - private boolean alwaysExpanded = false; - - public void draw(GC gc, GalleryItem group, int x, int y, int clipX, - int clipY, int clipWidth, int clipHeight) { - } - - public GalleryItem getItem(GalleryItem group, Point coords) { - return null; - } - - public Rectangle getSize(GalleryItem item) { - return null; - } - - public void layout(GC gc, GalleryItem group) { - } - - /** - * If true, groups are always expanded and toggle button is not displayed - * - * @return true if groups are always expanded - */ - public boolean isAlwaysExpanded() { - return alwaysExpanded; - } - - /** - * Return item expand state (item.isExpanded()) Returns always true is - * alwaysExpanded is set to true. - * - * @param item - * @return - */ - protected boolean isGroupExpanded(GalleryItem item) { - if (alwaysExpanded) - return true; - - if (item == null) - return false; - - return item.isExpanded(); - } - - /** - * If true, groups are always expanded and toggle button is not displayed if - * false, expand status depends on each item. - * - * @param alwaysExpanded - */ - public void setAlwaysExpanded(boolean alwaysExpanded) { - this.alwaysExpanded = alwaysExpanded; - } - - public int getMinMargin() { - return minMargin; - } - - public int getItemWidth() { - return itemWidth; - } - - public void setItemWidth(int itemWidth) { - this.itemWidth = itemWidth; - - updateGallery(); - } - - public int getItemHeight() { - return itemHeight; - } - - public void setItemHeight(int itemHeight) { - this.itemHeight = itemHeight; - - updateGallery(); - } - - private void updateGallery() { - // Update gallery - if (gallery != null) { - gallery.updateStructuralValues(null, true); - gallery.updateScrollBarsProperties(); - gallery.redraw(); - } - } - - public void setItemSize(int width, int height) { - this.itemHeight = height; - this.itemWidth = width; - - updateGallery(); - } - - public void setMinMargin(int minMargin) { - this.minMargin = minMargin; - - updateGallery(); - } - - public boolean isAutoMargin() { - return autoMargin; - } - - public void setAutoMargin(boolean autoMargin) { - this.autoMargin = autoMargin; - - updateGallery(); - } - - protected int calculateMargins(int size, int count, int itemSize) { - int margin = this.minMargin; - margin += Math.round((float) (size - this.minMargin - - (count * (itemSize + this.minMargin))) / (count + 1)); - return margin; - } - - protected Point getSize(int nbx, int nby, int itemSizeX, int itemSizeY, - int minMargin, int autoMargin) { - int x = 0, y = 0; - - if (gallery.isVertical()) { - x = nbx * itemSizeX + (nbx - 1) * margin + 2 * minMargin; - y = nby * itemSizeY + nby * minMargin; - } else { - x = nbx * itemSizeX + nbx * minMargin; - y = nby * itemSizeY + (nby - 1) * margin + 2 * minMargin; - } - return new Point(x, y); - } - - /** - * Draw a child item. Only used when useGroup is true. - * - * @param gc - * @param index - * @param selected - * @param parent - */ - protected void drawItem(GC gc, int index, boolean selected, - GalleryItem parent, int offsetY) { - - if (Gallery.DEBUG) - System.out.println("Draw item ? " + index); //$NON-NLS-1$ - - if (index < parent.getItemCount()) { - int hCount = ((Integer) parent.getData(H_COUNT)).intValue(); - int vCount = ((Integer) parent.getData(V_COUNT)).intValue(); - - if (Gallery.DEBUG) - System.out.println("hCount : " + hCount + " vCount : " //$NON-NLS-1$//$NON-NLS-2$ - + vCount); - - int posX, posY; - if (gallery.isVertical()) { - posX = index % hCount; - posY = (index - posX) / hCount; - } else { - posY = index % vCount; - posX = (index - posY) / vCount; - } - - Item item = parent.getItem(index); - - // No item ? return - if (item == null) - return; - - GalleryItem gItem = (GalleryItem) item; - - int xPixelPos, yPixelPos; - if (gallery.isVertical()) { - xPixelPos = posX * (itemWidth + margin) + margin; - yPixelPos = posY * (itemHeight + minMargin) - gallery.translate - /* + minMargin */ - + ((parent == null) ? 0 : (parent.y) + offsetY); - gItem.x = xPixelPos; - gItem.y = yPixelPos + gallery.translate; - } else { - xPixelPos = posX * (itemWidth + minMargin) - gallery.translate - /* + minMargin */ - + ((parent == null) ? 0 : (parent.x) + offsetY); - yPixelPos = posY * (itemHeight + margin) + margin; - gItem.x = xPixelPos + gallery.translate; - gItem.y = yPixelPos; - } - - gItem.height = itemHeight; - gItem.width = itemWidth; - - gallery.sendPaintItemEvent(item, index, gc, xPixelPos, yPixelPos, - this.itemWidth, this.itemHeight); - - if (gallery.getItemRenderer() != null) { - // gc.setClipping(xPixelPos, yPixelPos, itemWidth, itemHeight); - gallery.getItemRenderer().setSelected(selected); - if (Gallery.DEBUG) - System.out.println("itemRender.draw"); //$NON-NLS-1$ - Rectangle oldClipping = gc.getClipping(); - - gc.setClipping(oldClipping.intersection(new Rectangle(xPixelPos, - yPixelPos, itemWidth, itemHeight))); - gallery.getItemRenderer().draw(gc, gItem, index, xPixelPos, - yPixelPos, itemWidth, itemHeight); - gc.setClipping(oldClipping); - if (Gallery.DEBUG) - System.out.println("itemRender done"); //$NON-NLS-1$ - } - - } - } - - protected int[] getVisibleItems(GalleryItem group, int x, int y, int clipX, - int clipY, int clipWidth, int clipHeight, int offset) { - int[] indexes; - - if (gallery.isVertical()) { - int count = ((Integer) group.getData(H_COUNT)).intValue(); - // TODO: Not used ATM - // int vCount = ((Integer) group.getData(V_COUNT)).intValue(); - - int firstLine = (clipY - y - offset - minMargin) - / (itemHeight + minMargin); - if (firstLine < 0) - firstLine = 0; - - int firstItem = firstLine * count; - if (Gallery.DEBUG) - System.out.println("First line : " + firstLine); //$NON-NLS-1$ - - int lastLine = (clipY - y - offset + clipHeight - minMargin) - / (itemHeight + minMargin); - - if (lastLine < firstLine) - lastLine = firstLine; - - if (Gallery.DEBUG) - System.out.println("Last line : " + lastLine); //$NON-NLS-1$ - - int lastItem = (lastLine + 1) * count; - - // exit if no item selected - if (lastItem - firstItem == 0) - return null; - - indexes = new int[lastItem - firstItem]; - for (int i = 0; i < (lastItem - firstItem); i++) { - indexes[i] = firstItem + i; - } - - } else { - int count = ((Integer) group.getData(V_COUNT)).intValue(); - - int firstLine = (clipX - x - offset - minMargin) - / (itemWidth + minMargin); - if (firstLine < 0) - firstLine = 0; - - int firstItem = firstLine * count; - if (Gallery.DEBUG) - System.out.println("First line : " + firstLine); //$NON-NLS-1$ - - int lastLine = (clipX - x - offset + clipWidth - minMargin) - / (itemWidth + minMargin); - - if (lastLine < firstLine) - lastLine = firstLine; - - if (Gallery.DEBUG) - System.out.println("Last line : " + lastLine); //$NON-NLS-1$ - - int lastItem = (lastLine + 1) * count; - - // exit if no item selected - if (lastItem - firstItem == 0) - return null; - - indexes = new int[lastItem - firstItem]; - for (int i = 0; i < (lastItem - firstItem); i++) { - indexes[i] = firstItem + i; - } - } - - return indexes; - } - - /** - * Calculate how many items are displayed horizontally and vertically. - * - * @param size - * @param nbItems - * @param itemSize - * @return - */ - protected Point gridLayout(int size, int nbItems, int itemSize) { - int x = 0, y = 0; - - if (nbItems == 0) - return new Point(x, y); - - x = (size - minMargin) / (itemSize + minMargin); - if (x > 0) { - y = (int) Math.ceil((double) nbItems / (double) x); - } else { - // Show at least one item; - y = nbItems; - x = 1; - } - - return new Point(x, y); - } - - public void dispose() { - // Nothing required here. This method can be overridden when needed. - } - - public boolean mouseDown(GalleryItem group, MouseEvent e, Point coords) { - return false; - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer#preLayout - * (org.eclipse.swt.graphics.GC) - */ - public void preLayout(GC gc) { - // Reset margin to minimal value before "best fit" calculation - this.margin = this.minMargin; - super.preLayout(gc); - } - - protected Point getLayoutData(GalleryItem item) { - Integer hCount = ((Integer) item.getData(H_COUNT)); - Integer vCount = ((Integer) item.getData(V_COUNT)); - - if (hCount == null || vCount == null) - return null; - - return new Point(hCount.intValue(), vCount.intValue()); - } - - protected Rectangle getSize(GalleryItem item, int offsetY) { - - GalleryItem parent = item.getParentItem(); - if (parent != null) { - int index = parent.indexOf(item); - - Point layoutData = getLayoutData(parent); - if (layoutData == null) - return null; - - int hCount = layoutData.x; - int vCount = layoutData.y; - - if (Gallery.DEBUG) - System.out.println("hCount : " + hCount + " vCount : " //$NON-NLS-1$ //$NON-NLS-2$ - + vCount); - - if (gallery.isVertical()) { - int posX = index % hCount; - int posY = (index - posX) / hCount; - - int xPixelPos = posX * (itemWidth + margin) + margin; - int yPixelPos = posY * (itemHeight + minMargin) - + ((parent == null) ? 0 : (parent.y) + offsetY); - - return new Rectangle(xPixelPos, yPixelPos, this.itemWidth, - this.itemHeight); - } - - // gallery is horizontal - int posY = index % vCount; - int posX = (index - posY) / vCount; - - int yPixelPos = posY * (itemHeight + margin) + margin; - int xPixelPos = posX * (itemWidth + minMargin) - + ((parent == null) ? 0 : (parent.x) + offsetY); - - return new Rectangle(xPixelPos, yPixelPos, this.itemWidth, - this.itemHeight); - } - - return null; - } - - /** - * Get item at pixel position - * - * @param coords - * @return - */ - protected GalleryItem getItem(GalleryItem group, Point coords, - int offsetY) { - if (Gallery.DEBUG) { - System.out.println("getitem " + coords.x + " " + coords.y); //$NON-NLS-1$//$NON-NLS-2$ - } - - int itemNb; - if (gallery.isVertical()) { - Integer tmp = (Integer) group.getData(H_COUNT); - if (tmp == null) - return null; - int hCount = tmp.intValue(); - - // Calculate where the item should be if it exists - int posX = (coords.x - margin) / (itemWidth + margin); - - // Check if the users clicked on the X margin. - int posOnItem = (coords.x - margin) % (itemWidth + margin); - if (posOnItem > itemWidth || posOnItem < 0) { - return null; - } - - if (posX >= hCount) // Nothing there - return null; - - if (coords.y - group.y < offsetY) - return null; - - int posY = (coords.y - group.y - offsetY) - / (itemHeight + minMargin); - - // Check if the users clicked on the Y margin. - if (((coords.y - group.y - offsetY) - % (itemHeight + minMargin)) > itemHeight) { - return null; - } - itemNb = posX + posY * hCount; - } else { - Integer tmp = (Integer) group.getData(V_COUNT); - if (tmp == null) - return null; - int vCount = tmp.intValue(); - - // Calculate where the item should be if it exists - int posY = (coords.y - margin) / (itemHeight + margin); - - // Check if the users clicked on the X margin. - int posOnItem = (coords.y - margin) % (itemHeight + margin); - if (posOnItem > itemHeight || posOnItem < 0) { - return null; - } - - if (posY >= vCount) // Nothing there - return null; - - if (coords.x - group.x < offsetY) - return null; - - int posX = (coords.x - group.x - offsetY) / (itemWidth + minMargin); - - // Check if the users clicked on the X margin. - if (((coords.x - group.x - offsetY) - % (itemWidth + minMargin)) > itemWidth) { - return null; - } - itemNb = posY + posX * vCount; - } - - if (Gallery.DEBUG) { - System.out.println("Item found : " + itemNb); //$NON-NLS-1$ - } - - if (itemNb < group.getItemCount()) { - return group.getItem(itemNb); - } - - return null; - } - - private GalleryItem goLeft(GalleryItem group, int posParam) { - int pos = posParam - 1; - - if (pos < 0) { - // Look for next non-empty group and get the last item - GalleryItem item = null; - GalleryItem currentGroup = group; - while (item == null && currentGroup != null) { - currentGroup = this.getPreviousGroup(currentGroup); - if (currentGroup == null || currentGroup.getItemCount() == 0) { - continue; - } - item = this.getFirstItem(currentGroup, END); - } - return item; - } - - // else - return group.getItem(pos); - } - - private GalleryItem goRight(GalleryItem group, int posParam) { - int pos = posParam + 1; - - if (pos >= group.getItemCount()) { - // Look for next non-empty group and get the first item - GalleryItem item = null; - GalleryItem currentGroup = group; - while (item == null && currentGroup != null) { - currentGroup = this.getNextGroup(currentGroup); - item = this.getFirstItem(currentGroup, START); - } - return item; - } - - // else - return group.getItem(pos); - } - - private GalleryItem goUp(GalleryItem group, int posParam, int hCount, - int lineCount) { - - if (lineCount == 0) { - return null; - } - - // Optimization when only one group involved - if (posParam - hCount * lineCount >= 0) { - return group.getItem(posParam - hCount * lineCount); - } - - // Get next item. - GalleryItem next = goUp(group, posParam, hCount); - if (next == null) { - return null; - } - - GalleryItem newItem = null; - for (int i = 1; i < lineCount; i++) { - newItem = goUp(next.getParentItem(), - next.getParentItem().indexOf(next), hCount); - if (newItem == next || newItem == null) { - break; - } - - next = newItem; - } - - return next; - } - - private GalleryItem goDown(GalleryItem group, int posParam, int hCount, - int lineCount) { - - if (lineCount == 0) { - return null; - } - - // Optimization when only one group involved - if (posParam + hCount * lineCount < group.getItemCount()) { - return group.getItem(posParam + hCount * lineCount); - } - - // Get next item. - GalleryItem next = goDown(group, posParam, hCount); - if (next == null) { - return null; - } - - GalleryItem newItem = null; - for (int i = 1; i < lineCount; i++) { - newItem = goDown(next.getParentItem(), - next.getParentItem().indexOf(next), hCount); - if (newItem == next || newItem == null) { - break; - } - - next = newItem; - } - - return next; - } - - /** - * Get the next item, when going up. - * - * @param group - * current group - * @param posParam - * index of currently selected item - * @param hCount - * size of a line - * @return - */ - private GalleryItem goUp(GalleryItem group, int posParam, int hCount) { - int colPos = posParam % hCount; - int pos = posParam - hCount; - - if (pos < 0) { - // Look for next non-empty group and get the last item - GalleryItem item = null; - GalleryItem currentGroup = group; - while (item == null && currentGroup != null) { - currentGroup = this.getPreviousGroup(currentGroup); - item = this.getItemAt(currentGroup, colPos, END); - } - return item; - } - - // else - return group.getItem(pos); - } - - /** - * Get the next item, when going down. - * - * @param group - * current group - * @param posParam - * index of currently selected item - * @param hCount - * size of a line - * @return - */ - private GalleryItem goDown(GalleryItem group, int posParam, int hCount) { - int colPos = posParam % hCount; - int pos = posParam + hCount; - - if (pos >= group.getItemCount()) { - // Look for next non-empty group and get the first item - GalleryItem item = null; - GalleryItem currentGroup = group; - while (item == null && currentGroup != null) { - currentGroup = this.getNextGroup(currentGroup); - if (currentGroup == null || currentGroup.getItemCount() == 0) { - continue; - } - item = this.getItemAt(currentGroup, colPos, START); - } - return item; - - } - - // else - return group.getItem(pos); - } - - /** - * Get maximum visible lines. - * - * @return - */ - private int getMaxVisibleLines() { - - // TODO: support group titles (fewer lines are visible if one or more - // group titles are displayed). This method should probably be - // implemented in the group renderer and not in the abstract class. - - // Gallery is vertical - if (gallery.isVertical()) { - return gallery.getClientArea().height / itemHeight; - } - - // Gallery is horizontal - return gallery.getClientArea().width / itemWidth; - } - - public GalleryItem getNextItem(GalleryItem item, int key) { - // Key navigation is useless with an empty gallery - if (gallery.getItemCount() == 0) { - return null; - } - - // Check for current selection - if (item == null) { - // No current selection, select the first item - if (gallery.getItemCount() > 0) { - GalleryItem firstGroup = gallery.getItem(0); - if (firstGroup != null && firstGroup.getItemCount() > 0) { - return firstGroup.getItem(0); - } - - } - return null; - } - - // Check for groups - if (item.getParentItem() == null) { - // Key navigation is only available for child items ATM - return null; - } - - GalleryItem group = item.getParentItem(); - - // Handle HOME and END - switch (key) { - case SWT.HOME: - gallery.getItem(0).setExpanded(true); - return getFirstItem(gallery.getItem(0), START); - - case SWT.END: - gallery.getItem(gallery.getItemCount() - 1).setExpanded(true); - return getFirstItem(gallery.getItem(gallery.getItemCount() - 1), - END); - } - - int pos = group.indexOf(item); - GalleryItem next = null; - - // Handle arrows and page up / down - if (gallery.isVertical()) { - int hCount = ((Integer) group.getData(H_COUNT)).intValue(); - int maxVisibleRows = getMaxVisibleLines(); - switch (key) { - case SWT.ARROW_LEFT: - next = goLeft(group, pos); - break; - - case SWT.ARROW_RIGHT: - next = goRight(group, pos); - break; - - case SWT.ARROW_UP: - next = goUp(group, pos, hCount, 1); - break; - - case SWT.ARROW_DOWN: - next = goDown(group, pos, hCount, 1); - break; - - case SWT.PAGE_UP: - next = goUp(group, pos, hCount, - Math.max(maxVisibleRows - 1, 1)); - break; - - case SWT.PAGE_DOWN: - next = goDown(group, pos, hCount, - Math.max(maxVisibleRows - 1, 1)); - break; - } - } else { - int vCount = ((Integer) group.getData(V_COUNT)).intValue(); - int maxVisibleColumns = getMaxVisibleLines(); - switch (key) { - case SWT.ARROW_LEFT: - next = goUp(group, pos, vCount); - break; - - case SWT.ARROW_RIGHT: - next = goDown(group, pos, vCount); - break; - - case SWT.ARROW_UP: - next = goLeft(group, pos); - break; - - case SWT.ARROW_DOWN: - next = goRight(group, pos); - break; - - case SWT.PAGE_UP: - next = goUp(group, pos, - vCount * Math.max(maxVisibleColumns - 1, 1)); - break; - - case SWT.PAGE_DOWN: - next = goDown(group, pos, - vCount * Math.max(maxVisibleColumns - 1, 1)); - break; - - } - } - - return next; - } - - private GalleryItem getPreviousGroup(GalleryItem group) { - int gPos = gallery.indexOf(group); - while (gPos > 0) { - GalleryItem newGroup = gallery.getItem(gPos - 1); - if (isGroupExpanded(newGroup)) - return newGroup; - gPos--; - } - - return null; - } - - private GalleryItem getNextGroup(GalleryItem group) { - int gPos = gallery.indexOf(group); - while (gPos < gallery.getItemCount() - 1) { - GalleryItem newGroup = gallery.getItem(gPos + 1); - if (isGroupExpanded(newGroup)) - return newGroup; - gPos++; - } - - return null; - } - - private GalleryItem getFirstItem(GalleryItem group, int from) { - if (group == null) - return null; - - switch (from) { - case END: - return group.getItem(group.getItemCount() - 1); - - case START: - default: - return group.getItem(0); - } - - } - - /** - * Return the child item of group which is at column 'pos' starting from - * direction. If this item doesn't exists, returns the nearest item. - * - * @param group - * @param pos - * @param from - * START or END - * @return - */ - private GalleryItem getItemAt(GalleryItem group, int pos, int from) { - if (group == null) - return null; - - int hCount = ((Integer) group.getData(H_COUNT)).intValue(); - int offset = 0; - switch (from) { - case END: - if (group.getItemCount() == 0) - return null; - - // Last item column - int endPos = group.getItemCount() % hCount; - - // If last item column is 0, the line is full - if (endPos == 0) { - endPos = hCount - 1; - offset--; - } - - // If there is an item at column 'pos' - if (pos < endPos) { - int nbLines = (group.getItemCount() / hCount) + offset; - return group.getItem(nbLines * hCount + pos); - } - - // Get the last item. - return group - .getItem((group.getItemCount() / hCount + offset) * hCount - + endPos - 1); - - case START: - default: - if (pos >= group.getItemCount()) - return group.getItem(group.getItemCount() - 1); - - return group.getItem(pos); - - } - - } - -} +/******************************************************************************* + * Copyright (c) 2006-2007 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + * Richard Michalsky - bug 197959 + *******************************************************************************/ +package org.eclipse.nebula.widgets.gallery; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Item; + +/** + *

+ * Abstract class which provides low-level support for a grid-based group. + * renderer. + *

+ *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. + *

+ * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + * @contributor Richard Michalsky (bug 197959) + * @contributor Robert Handschmann (bug 215817) + */ + +public abstract class AbstractGridGroupRenderer + extends AbstractGalleryGroupRenderer { + + static final int DEFAULT_SIZE = 96; + + protected int minMargin; + + protected int margin; + + protected boolean autoMargin; + + protected int itemWidth = DEFAULT_SIZE; + + protected int itemHeight = DEFAULT_SIZE; + + public static final String H_COUNT = "g.h"; //$NON-NLS-1$ + + public static final String V_COUNT = "g.v"; //$NON-NLS-1$ + + protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + private static final int END = 0; + + private static final int START = 1; + + /** + * If true, groups are always expanded and toggle button is not displayed + */ + private boolean alwaysExpanded = false; + + public void draw(GC gc, GalleryItem group, int x, int y, int clipX, + int clipY, int clipWidth, int clipHeight) { + } + + public GalleryItem getItem(GalleryItem group, Point coords) { + return null; + } + + public Rectangle getSize(GalleryItem item) { + return null; + } + + public void layout(GC gc, GalleryItem group) { + } + + /** + * If true, groups are always expanded and toggle button is not displayed + * + * @return true if groups are always expanded + */ + public boolean isAlwaysExpanded() { + return alwaysExpanded; + } + + /** + * Return item expand state (item.isExpanded()) Returns always true is + * alwaysExpanded is set to true. + * + * @param item + * @return + */ + protected boolean isGroupExpanded(GalleryItem item) { + if (alwaysExpanded) + return true; + + if (item == null) + return false; + + return item.isExpanded(); + } + + /** + * If true, groups are always expanded and toggle button is not displayed if + * false, expand status depends on each item. + * + * @param alwaysExpanded + */ + public void setAlwaysExpanded(boolean alwaysExpanded) { + this.alwaysExpanded = alwaysExpanded; + } + + public int getMinMargin() { + return minMargin; + } + + public int getItemWidth() { + return itemWidth; + } + + public void setItemWidth(int itemWidth) { + this.itemWidth = itemWidth; + + updateGallery(); + } + + public int getItemHeight() { + return itemHeight; + } + + public void setItemHeight(int itemHeight) { + this.itemHeight = itemHeight; + + updateGallery(); + } + + private void updateGallery() { + // Update gallery + if (gallery != null) { + gallery.updateStructuralValues(null, true); + gallery.updateScrollBarsProperties(); + gallery.redraw(); + } + } + + public void setItemSize(int width, int height) { + this.itemHeight = height; + this.itemWidth = width; + + updateGallery(); + } + + public void setMinMargin(int minMargin) { + this.minMargin = minMargin; + + updateGallery(); + } + + public boolean isAutoMargin() { + return autoMargin; + } + + public void setAutoMargin(boolean autoMargin) { + this.autoMargin = autoMargin; + + updateGallery(); + } + + protected int calculateMargins(int size, int count, int itemSize) { + int margin = this.minMargin; + margin += Math.round((float) (size - this.minMargin + - (count * (itemSize + this.minMargin))) / (count + 1)); + return margin; + } + + protected Point getSize(int nbx, int nby, int itemSizeX, int itemSizeY, + int minMargin, int autoMargin) { + int x = 0, y = 0; + + if (gallery.isVertical()) { + x = nbx * itemSizeX + (nbx - 1) * margin + 2 * minMargin; + y = nby * itemSizeY + nby * minMargin; + } else { + x = nbx * itemSizeX + nbx * minMargin; + y = nby * itemSizeY + (nby - 1) * margin + 2 * minMargin; + } + return new Point(x, y); + } + + /** + * Draw a child item. Only used when useGroup is true. + * + * @param gc + * @param index + * @param selected + * @param parent + */ + protected void drawItem(GC gc, int index, boolean selected, + GalleryItem parent, int offsetY) { + + if (Gallery.DEBUG) + System.out.println("Draw item ? " + index); //$NON-NLS-1$ + + if (index < parent.getItemCount()) { + int hCount = ((Integer) parent.getData(H_COUNT)).intValue(); + int vCount = ((Integer) parent.getData(V_COUNT)).intValue(); + + if (Gallery.DEBUG) + System.out.println("hCount : " + hCount + " vCount : " //$NON-NLS-1$//$NON-NLS-2$ + + vCount); + + int posX, posY; + if (gallery.isVertical()) { + posX = index % hCount; + posY = (index - posX) / hCount; + } else { + posY = index % vCount; + posX = (index - posY) / vCount; + } + + Item item = parent.getItem(index); + + // No item ? return + if (item == null) + return; + + GalleryItem gItem = (GalleryItem) item; + + int xPixelPos, yPixelPos; + if (gallery.isVertical()) { + xPixelPos = posX * (itemWidth + margin) + margin; + yPixelPos = posY * (itemHeight + minMargin) - gallery.translate + /* + minMargin */ + + ((parent == null) ? 0 : (parent.y) + offsetY); + gItem.x = xPixelPos; + gItem.y = yPixelPos + gallery.translate; + } else { + xPixelPos = posX * (itemWidth + minMargin) - gallery.translate + /* + minMargin */ + + ((parent == null) ? 0 : (parent.x) + offsetY); + yPixelPos = posY * (itemHeight + margin) + margin; + gItem.x = xPixelPos + gallery.translate; + gItem.y = yPixelPos; + } + + gItem.height = itemHeight; + gItem.width = itemWidth; + + gallery.sendPaintItemEvent(item, index, gc, xPixelPos, yPixelPos, + this.itemWidth, this.itemHeight); + + if (gallery.getItemRenderer() != null) { + // gc.setClipping(xPixelPos, yPixelPos, itemWidth, itemHeight); + gallery.getItemRenderer().setSelected(selected); + if (Gallery.DEBUG) + System.out.println("itemRender.draw"); //$NON-NLS-1$ + Rectangle oldClipping = gc.getClipping(); + + gc.setClipping(oldClipping.intersection(new Rectangle(xPixelPos, + yPixelPos, itemWidth, itemHeight))); + gallery.getItemRenderer().draw(gc, gItem, index, xPixelPos, + yPixelPos, itemWidth, itemHeight); + gc.setClipping(oldClipping); + if (Gallery.DEBUG) + System.out.println("itemRender done"); //$NON-NLS-1$ + } + + } + } + + protected int[] getVisibleItems(GalleryItem group, int x, int y, int clipX, + int clipY, int clipWidth, int clipHeight, int offset) { + int[] indexes; + + if (gallery.isVertical()) { + int count = ((Integer) group.getData(H_COUNT)).intValue(); + // TODO: Not used ATM + // int vCount = ((Integer) group.getData(V_COUNT)).intValue(); + + int firstLine = (clipY - y - offset - minMargin) + / (itemHeight + minMargin); + if (firstLine < 0) + firstLine = 0; + + int firstItem = firstLine * count; + if (Gallery.DEBUG) + System.out.println("First line : " + firstLine); //$NON-NLS-1$ + + int lastLine = (clipY - y - offset + clipHeight - minMargin) + / (itemHeight + minMargin); + + if (lastLine < firstLine) + lastLine = firstLine; + + if (Gallery.DEBUG) + System.out.println("Last line : " + lastLine); //$NON-NLS-1$ + + int lastItem = (lastLine + 1) * count; + + // exit if no item selected + if (lastItem - firstItem == 0) + return null; + + indexes = new int[lastItem - firstItem]; + for (int i = 0; i < (lastItem - firstItem); i++) { + indexes[i] = firstItem + i; + } + + } else { + int count = ((Integer) group.getData(V_COUNT)).intValue(); + + int firstLine = (clipX - x - offset - minMargin) + / (itemWidth + minMargin); + if (firstLine < 0) + firstLine = 0; + + int firstItem = firstLine * count; + if (Gallery.DEBUG) + System.out.println("First line : " + firstLine); //$NON-NLS-1$ + + int lastLine = (clipX - x - offset + clipWidth - minMargin) + / (itemWidth + minMargin); + + if (lastLine < firstLine) + lastLine = firstLine; + + if (Gallery.DEBUG) + System.out.println("Last line : " + lastLine); //$NON-NLS-1$ + + int lastItem = (lastLine + 1) * count; + + // exit if no item selected + if (lastItem - firstItem == 0) + return null; + + indexes = new int[lastItem - firstItem]; + for (int i = 0; i < (lastItem - firstItem); i++) { + indexes[i] = firstItem + i; + } + } + + return indexes; + } + + /** + * Calculate how many items are displayed horizontally and vertically. + * + * @param size + * @param nbItems + * @param itemSize + * @return + */ + protected Point gridLayout(int size, int nbItems, int itemSize) { + int x = 0, y = 0; + + if (nbItems == 0) + return new Point(x, y); + + x = (size - minMargin) / (itemSize + minMargin); + if (x > 0) { + y = (int) Math.ceil((double) nbItems / (double) x); + } else { + // Show at least one item; + y = nbItems; + x = 1; + } + + return new Point(x, y); + } + + public void dispose() { + // Nothing required here. This method can be overridden when needed. + } + + public boolean mouseDown(GalleryItem group, MouseEvent e, Point coords) { + return false; + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer#preLayout + * (org.eclipse.swt.graphics.GC) + */ + public void preLayout(GC gc) { + // Reset margin to minimal value before "best fit" calculation + this.margin = this.minMargin; + super.preLayout(gc); + } + + protected Point getLayoutData(GalleryItem item) { + Integer hCount = ((Integer) item.getData(H_COUNT)); + Integer vCount = ((Integer) item.getData(V_COUNT)); + + if (hCount == null || vCount == null) + return null; + + return new Point(hCount.intValue(), vCount.intValue()); + } + + protected Rectangle getSize(GalleryItem item, int offsetY) { + + GalleryItem parent = item.getParentItem(); + if (parent != null) { + int index = parent.indexOf(item); + + Point layoutData = getLayoutData(parent); + if (layoutData == null) + return null; + + int hCount = layoutData.x; + int vCount = layoutData.y; + + if (Gallery.DEBUG) + System.out.println("hCount : " + hCount + " vCount : " //$NON-NLS-1$ //$NON-NLS-2$ + + vCount); + + if (gallery.isVertical()) { + int posX = index % hCount; + int posY = (index - posX) / hCount; + + int xPixelPos = posX * (itemWidth + margin) + margin; + int yPixelPos = posY * (itemHeight + minMargin) + + ((parent == null) ? 0 : (parent.y) + offsetY); + + return new Rectangle(xPixelPos, yPixelPos, this.itemWidth, + this.itemHeight); + } + + // gallery is horizontal + int posY = index % vCount; + int posX = (index - posY) / vCount; + + int yPixelPos = posY * (itemHeight + margin) + margin; + int xPixelPos = posX * (itemWidth + minMargin) + + ((parent == null) ? 0 : (parent.x) + offsetY); + + return new Rectangle(xPixelPos, yPixelPos, this.itemWidth, + this.itemHeight); + } + + return null; + } + + /** + * Get item at pixel position + * + * @param coords + * @return + */ + protected GalleryItem getItem(GalleryItem group, Point coords, + int offsetY) { + if (Gallery.DEBUG) { + System.out.println("getitem " + coords.x + " " + coords.y); //$NON-NLS-1$//$NON-NLS-2$ + } + + int itemNb; + if (gallery.isVertical()) { + Integer tmp = (Integer) group.getData(H_COUNT); + if (tmp == null) + return null; + int hCount = tmp.intValue(); + + // Calculate where the item should be if it exists + int posX = (coords.x - margin) / (itemWidth + margin); + + // Check if the users clicked on the X margin. + int posOnItem = (coords.x - margin) % (itemWidth + margin); + if (posOnItem > itemWidth || posOnItem < 0) { + return null; + } + + if (posX >= hCount) // Nothing there + return null; + + if (coords.y - group.y < offsetY) + return null; + + int posY = (coords.y - group.y - offsetY) + / (itemHeight + minMargin); + + // Check if the users clicked on the Y margin. + if (((coords.y - group.y - offsetY) + % (itemHeight + minMargin)) > itemHeight) { + return null; + } + itemNb = posX + posY * hCount; + } else { + Integer tmp = (Integer) group.getData(V_COUNT); + if (tmp == null) + return null; + int vCount = tmp.intValue(); + + // Calculate where the item should be if it exists + int posY = (coords.y - margin) / (itemHeight + margin); + + // Check if the users clicked on the X margin. + int posOnItem = (coords.y - margin) % (itemHeight + margin); + if (posOnItem > itemHeight || posOnItem < 0) { + return null; + } + + if (posY >= vCount) // Nothing there + return null; + + if (coords.x - group.x < offsetY) + return null; + + int posX = (coords.x - group.x - offsetY) / (itemWidth + minMargin); + + // Check if the users clicked on the X margin. + if (((coords.x - group.x - offsetY) + % (itemWidth + minMargin)) > itemWidth) { + return null; + } + itemNb = posY + posX * vCount; + } + + if (Gallery.DEBUG) { + System.out.println("Item found : " + itemNb); //$NON-NLS-1$ + } + + if (itemNb < group.getItemCount()) { + return group.getItem(itemNb); + } + + return null; + } + + private GalleryItem goLeft(GalleryItem group, int posParam) { + int pos = posParam - 1; + + if (pos < 0) { + // Look for next non-empty group and get the last item + GalleryItem item = null; + GalleryItem currentGroup = group; + while (item == null && currentGroup != null) { + currentGroup = this.getPreviousGroup(currentGroup); + if (currentGroup == null || currentGroup.getItemCount() == 0) { + continue; + } + item = this.getFirstItem(currentGroup, END); + } + return item; + } + + // else + return group.getItem(pos); + } + + private GalleryItem goRight(GalleryItem group, int posParam) { + int pos = posParam + 1; + + if (pos >= group.getItemCount()) { + // Look for next non-empty group and get the first item + GalleryItem item = null; + GalleryItem currentGroup = group; + while (item == null && currentGroup != null) { + currentGroup = this.getNextGroup(currentGroup); + item = this.getFirstItem(currentGroup, START); + } + return item; + } + + // else + return group.getItem(pos); + } + + private GalleryItem goUp(GalleryItem group, int posParam, int hCount, + int lineCount) { + + if (lineCount == 0) { + return null; + } + + // Optimization when only one group involved + if (posParam - hCount * lineCount >= 0) { + return group.getItem(posParam - hCount * lineCount); + } + + // Get next item. + GalleryItem next = goUp(group, posParam, hCount); + if (next == null) { + return null; + } + + GalleryItem newItem = null; + for (int i = 1; i < lineCount; i++) { + newItem = goUp(next.getParentItem(), + next.getParentItem().indexOf(next), hCount); + if (newItem == next || newItem == null) { + break; + } + + next = newItem; + } + + return next; + } + + private GalleryItem goDown(GalleryItem group, int posParam, int hCount, + int lineCount) { + + if (lineCount == 0) { + return null; + } + + // Optimization when only one group involved + if (posParam + hCount * lineCount < group.getItemCount()) { + return group.getItem(posParam + hCount * lineCount); + } + + // Get next item. + GalleryItem next = goDown(group, posParam, hCount); + if (next == null) { + return null; + } + + GalleryItem newItem = null; + for (int i = 1; i < lineCount; i++) { + newItem = goDown(next.getParentItem(), + next.getParentItem().indexOf(next), hCount); + if (newItem == next || newItem == null) { + break; + } + + next = newItem; + } + + return next; + } + + /** + * Get the next item, when going up. + * + * @param group + * current group + * @param posParam + * index of currently selected item + * @param hCount + * size of a line + * @return + */ + private GalleryItem goUp(GalleryItem group, int posParam, int hCount) { + int colPos = posParam % hCount; + int pos = posParam - hCount; + + if (pos < 0) { + // Look for next non-empty group and get the last item + GalleryItem item = null; + GalleryItem currentGroup = group; + while (item == null && currentGroup != null) { + currentGroup = this.getPreviousGroup(currentGroup); + item = this.getItemAt(currentGroup, colPos, END); + } + return item; + } + + // else + return group.getItem(pos); + } + + /** + * Get the next item, when going down. + * + * @param group + * current group + * @param posParam + * index of currently selected item + * @param hCount + * size of a line + * @return + */ + private GalleryItem goDown(GalleryItem group, int posParam, int hCount) { + int colPos = posParam % hCount; + int pos = posParam + hCount; + + if (pos >= group.getItemCount()) { + // Look for next non-empty group and get the first item + GalleryItem item = null; + GalleryItem currentGroup = group; + while (item == null && currentGroup != null) { + currentGroup = this.getNextGroup(currentGroup); + if (currentGroup == null || currentGroup.getItemCount() == 0) { + continue; + } + item = this.getItemAt(currentGroup, colPos, START); + } + return item; + + } + + // else + return group.getItem(pos); + } + + /** + * Get maximum visible lines. + * + * @return + */ + private int getMaxVisibleLines() { + + // TODO: support group titles (fewer lines are visible if one or more + // group titles are displayed). This method should probably be + // implemented in the group renderer and not in the abstract class. + + // Gallery is vertical + if (gallery.isVertical()) { + return gallery.getClientArea().height / itemHeight; + } + + // Gallery is horizontal + return gallery.getClientArea().width / itemWidth; + } + + public GalleryItem getNextItem(GalleryItem item, int key) { + // Key navigation is useless with an empty gallery + if (gallery.getItemCount() == 0) { + return null; + } + + // Check for current selection + if (item == null) { + // No current selection, select the first item + if (gallery.getItemCount() > 0) { + GalleryItem firstGroup = gallery.getItem(0); + if (firstGroup != null && firstGroup.getItemCount() > 0) { + return firstGroup.getItem(0); + } + + } + return null; + } + + // Check for groups + if (item.getParentItem() == null) { + // Key navigation is only available for child items ATM + return null; + } + + GalleryItem group = item.getParentItem(); + + // Handle HOME and END + switch (key) { + case SWT.HOME: + gallery.getItem(0).setExpanded(true); + return getFirstItem(gallery.getItem(0), START); + + case SWT.END: + gallery.getItem(gallery.getItemCount() - 1).setExpanded(true); + return getFirstItem(gallery.getItem(gallery.getItemCount() - 1), + END); + } + + int pos = group.indexOf(item); + GalleryItem next = null; + + // Handle arrows and page up / down + if (gallery.isVertical()) { + int hCount = ((Integer) group.getData(H_COUNT)).intValue(); + int maxVisibleRows = getMaxVisibleLines(); + switch (key) { + case SWT.ARROW_LEFT: + next = goLeft(group, pos); + break; + + case SWT.ARROW_RIGHT: + next = goRight(group, pos); + break; + + case SWT.ARROW_UP: + next = goUp(group, pos, hCount, 1); + break; + + case SWT.ARROW_DOWN: + next = goDown(group, pos, hCount, 1); + break; + + case SWT.PAGE_UP: + next = goUp(group, pos, hCount, + Math.max(maxVisibleRows - 1, 1)); + break; + + case SWT.PAGE_DOWN: + next = goDown(group, pos, hCount, + Math.max(maxVisibleRows - 1, 1)); + break; + } + } else { + int vCount = ((Integer) group.getData(V_COUNT)).intValue(); + int maxVisibleColumns = getMaxVisibleLines(); + switch (key) { + case SWT.ARROW_LEFT: + next = goUp(group, pos, vCount); + break; + + case SWT.ARROW_RIGHT: + next = goDown(group, pos, vCount); + break; + + case SWT.ARROW_UP: + next = goLeft(group, pos); + break; + + case SWT.ARROW_DOWN: + next = goRight(group, pos); + break; + + case SWT.PAGE_UP: + next = goUp(group, pos, + vCount * Math.max(maxVisibleColumns - 1, 1)); + break; + + case SWT.PAGE_DOWN: + next = goDown(group, pos, + vCount * Math.max(maxVisibleColumns - 1, 1)); + break; + + } + } + + return next; + } + + private GalleryItem getPreviousGroup(GalleryItem group) { + int gPos = gallery.indexOf(group); + while (gPos > 0) { + GalleryItem newGroup = gallery.getItem(gPos - 1); + if (isGroupExpanded(newGroup)) + return newGroup; + gPos--; + } + + return null; + } + + private GalleryItem getNextGroup(GalleryItem group) { + int gPos = gallery.indexOf(group); + while (gPos < gallery.getItemCount() - 1) { + GalleryItem newGroup = gallery.getItem(gPos + 1); + if (isGroupExpanded(newGroup)) + return newGroup; + gPos++; + } + + return null; + } + + private GalleryItem getFirstItem(GalleryItem group, int from) { + if (group == null) + return null; + + switch (from) { + case END: + return group.getItem(group.getItemCount() - 1); + + case START: + default: + return group.getItem(0); + } + + } + + /** + * Return the child item of group which is at column 'pos' starting from + * direction. If this item doesn't exists, returns the nearest item. + * + * @param group + * @param pos + * @param from + * START or END + * @return + */ + private GalleryItem getItemAt(GalleryItem group, int pos, int from) { + if (group == null) + return null; + + int hCount = ((Integer) group.getData(H_COUNT)).intValue(); + int offset = 0; + switch (from) { + case END: + if (group.getItemCount() == 0) + return null; + + // Last item column + int endPos = group.getItemCount() % hCount; + + // If last item column is 0, the line is full + if (endPos == 0) { + endPos = hCount - 1; + offset--; + } + + // If there is an item at column 'pos' + if (pos < endPos) { + int nbLines = (group.getItemCount() / hCount) + offset; + return group.getItem(nbLines * hCount + pos); + } + + // Get the last item. + return group + .getItem((group.getItemCount() / hCount + offset) * hCount + + endPos - 1); + + case START: + default: + if (pos >= group.getItemCount()) + return group.getItem(group.getItemCount() - 1); + + return group.getItem(pos); + + } + + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/DefaultGalleryGroupRenderer.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/DefaultGalleryGroupRenderer.java index 9a15db12b..e090ee21d 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/DefaultGalleryGroupRenderer.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/DefaultGalleryGroupRenderer.java @@ -1,1039 +1,1039 @@ -/******************************************************************************* - * Copyright (c) 2006-2007 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - * Richard Michalsky - bug 195443 - *******************************************************************************/ -package org.eclipse.nebula.widgets.gallery; - -import org.eclipse.nebula.animation.AnimationRunner; -import org.eclipse.nebula.animation.movement.IMovement; -import org.eclipse.nebula.animation.movement.LinearInOut; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -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.graphics.Transform; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Item; - -/** - *

- * Default group renderer used by the Gallery widget. Supports multi-line text, - * images, animation and several other features. - *

- *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. - *

- * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - * @contributor Richard Michalsky (bug 195443) - * - */ -public class DefaultGalleryGroupRenderer extends AbstractGridGroupRenderer { - - private AnimationRunner animationRunner = new AnimationRunner(); - - private static final String PARENTHESIS_OPEN = " ("; //$NON-NLS-1$ - - private static final String PARENTHESIS_CLOSE = ")"; //$NON-NLS-1$ - - private int fontHeight = 0; - - private int titleHeight = fontHeight + 5; - - private Color titleForeground; - - private Color descriptionColor; - - private Color titleBackground = null; - - private boolean titleBackgroundGradient = true; - - // Used for gradient - private Color titleBackground2 = null; - - private int maxImageWidth = 32; - - private int maxImageHeight = 32; - - private Point imageSize = null; - /** - * If true, this flag will enable a special behavior when the items are so - * large that only one can fit in the client area. In this case, items are - * always resized and centered to fit best in the client area. - */ - private boolean fillIfSingleColumn = false; - - /** - * This flag is set during layout, if fillIfSigle is true, and if there is - * only one column or row - */ - private boolean fill = false; - - /** - * True if margins have already been calculated. Prevents margins - * calculation for each group - */ - boolean marginCalculated = false; - - private Font font = null; - - protected boolean animation = false; - - protected int animationLength = 500; - - protected IMovement animationOpenMovement = new LinearInOut(); - - protected IMovement animationCloseMovement = new LinearInOut(); - - protected static final String DATA_ANIMATION = "org.eclipse.nebula.gallery.internal.animation"; //$NON-NLS-1$ - - /** - * This group renderer draws a title line, then items in a grid layout. - */ - public DefaultGalleryGroupRenderer() { - super(); - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer# - * setGallery (org.eclipse.nebula.widgets.gallery.Gallery) - */ - public void setGallery(Gallery gallery) { - super.setGallery(gallery); - - // Set defaults - if (titleForeground == null) { - // Reset defaults. - this.setTitleForeground(null); - } - - if (titleBackground == null) { - // Reset default gradient. - setTitleBackgroundGradient(null, null); - } - - if (descriptionColor == null) { - descriptionColor = gallery.getDisplay() - .getSystemColor(SWT.COLOR_DARK_BLUE); - } - - } - - /** - * Draw group background using system default gradient or the user-defined - * color. - * - * @param gc - * @param item - * TODO - * @param x - * @param y - * @param width - * @param height - */ - protected void drawGroupBackground(GC gc, GalleryItem item, int x, int y, - int width, int height) { - Color itemLocalBackground = item.getBackground(true); - if (!titleBackgroundGradient || itemLocalBackground != null) { - // User defined background - gc.setBackground(itemLocalBackground != null ? itemLocalBackground - : titleBackground); - gc.fillRectangle(x, y, width, height); - } else { - // Default gradient Background - gc.setBackground(this.titleBackground); - gc.setForeground(this.titleBackground2); - gc.fillGradientRectangle(x, y, width, height, true); - } - } - - /** - * Draw the toggle button. - * - * @param gc - * @param x - * @param y - * @param group - */ - protected int drawGroupToggleButton(GC gc, int x, int y, - GalleryItem group) { - if (!isAlwaysExpanded()) { - // Toggle Button - - int xShift = RendererHelper.getShift(titleHeight, 9); - int yShift = RendererHelper.getShift(titleHeight, 9); - - int toggleX = x + xShift; - int toggleY = y + yShift; - - gc.setBackground( - gc.getDevice().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - gc.fillRectangle(toggleX, toggleY, 8, 8); - - gc.setForeground( - gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - gc.drawLine(toggleX + 2, toggleY + 4, toggleX + 6, toggleY + 4); - if (!expanded) { - gc.drawLine(toggleX + 4, toggleY + 2, toggleX + 4, toggleY + 6); - } - gc.setForeground(gc.getDevice() - .getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - gc.drawRectangle(toggleX, toggleY, 8, 8); - - } - - return titleHeight + minMargin; - } - - protected Rectangle getToggleButtonBounds() { - return new Rectangle( - minMargin + RendererHelper.getShift(titleHeight, 9), - RendererHelper.getShift(titleHeight, 9), 9, 9); - } - - protected int getGroupHeight(GalleryItem group) { - int groupHeight = titleHeight; - - if (group.getImage() != null) { - Point imageSize = RendererHelper.getBestSize( - group.getImage().getBounds().width, - group.getImage().getBounds().height, maxImageWidth, - maxImageHeight); - groupHeight = Math.max(titleHeight, imageSize.y + 2 * minMargin); - } - - // Ensure there is enough room to display all text. - int lineCount = 1; - if (group.getText(1) != null - && !EMPTY_STRING.equals(group.getText(1))) { - lineCount++; - } - - if (group.getText(2) != null - && !EMPTY_STRING.equals(group.getText(2))) { - lineCount++; - } - - groupHeight = Math.max(groupHeight, lineCount * (fontHeight + 2) + 2); - - return groupHeight; - } - - protected void drawGroup(GC gc, GalleryItem group, int x, int y, int clipX, - int clipY, int clipWidth, int clipHeight) { - // Do not paint group if on single column and filling on. - if (fill) - return; - - imageSize = null; - if (group.getImage() != null) { - imageSize = RendererHelper.getBestSize( - group.getImage().getBounds().width, - group.getImage().getBounds().height, maxImageWidth, - maxImageHeight); - } - int groupHeight = getGroupHeight(group); - - if (gallery.isVertical()) { - int baseX = x + minMargin; - int baseY = y; - - // Center if image - if (group.getImage() != null) { - baseY += (imageSize.y - fontHeight) / 2; - } - - int textY = baseY + 2; - for (int i = 1; i < 3; i++) { - if (group.getText(i) != null - && !EMPTY_STRING.equals(group.getText(i))) { - textY -= fontHeight / 2 + 1; - } - } - textY = Math.max(y + 2, textY); - - // Title background - drawGroupBackground(gc, group, x, y, group.width, groupHeight); - - baseX += drawGroupToggleButton(gc, baseX, textY - 1, group); - baseX += drawGroupImage(gc, group, baseX, y, imageSize); - - // Color for text - gc.setForeground(group.getForeground(true) != null - ? group.getForeground(true) - : titleForeground); - - // Title text - gc.setFont(getFont(group)); - gc.drawText(getGroupTitle(group), baseX, textY, true); - - // Description - gc.setForeground(descriptionColor); - for (int i = 1; i < 3; i++) { - if (group.getText(i) != null - && !EMPTY_STRING.equals(group.getText(i))) { - gc.drawText(group.getText(i), baseX, - textY + i * (2 + fontHeight), true); - } - } - - } else { - - Transform transform = new Transform(gc.getDevice()); - transform.rotate(-90); - gc.setTransform(transform); - - int baseX = x; - int baseY = y - group.height; - - // Center if image - if (group.getImage() != null) { - baseX += (imageSize.y - fontHeight) / 2; - } - - int textX = baseX + 2; - for (int i = 1; i < 3; i++) { - if (group.getText(i) != null) { - textX -= fontHeight / 2 + 1; - } - } - textX = Math.max(x + 2, textX); - - // Title background - drawGroupBackground(gc, group, y - group.height, x, group.height, - groupHeight); - - baseY += drawGroupToggleButton(gc, baseY, textX - 1, group); - baseY += drawGroupImage(gc, group, baseY, x, imageSize); - - // Color for text - gc.setForeground(group.foreground != null ? group.foreground - : titleForeground); - - // Title text - gc.setFont(getFont(group)); - - gc.drawText(getGroupTitle(group), baseY, textX, true); - - gc.setForeground(descriptionColor); - for (int i = 1; i < 3; i++) { - if (group.getText(i) != null) { - gc.drawText(group.getText(i), baseY, - textX + i * (2 + fontHeight), true); - } - } - gc.setTransform(null); - transform.dispose(); - } - } - - private int drawGroupImage(GC gc, GalleryItem group, int x, int y, - Point imageSize2) { - if (imageSize2 == null) - return 0; - - Image img = group.getImage(); - Rectangle imgSize = img.getBounds(); - - Point offset = RendererHelper.getImageOffset(imageSize2.x, imageSize2.y, - maxImageWidth, getGroupHeight(group)); - gc.drawImage(img, 0, 0, imgSize.width, imgSize.height, x + offset.x, - y + offset.y, imageSize2.x, imageSize2.y); - - return maxImageWidth + 2 * minMargin; - } - - protected String getGroupTitle(GalleryItem group) { - StringBuffer titleBuffer = new StringBuffer(); - titleBuffer.append(group.getText()); - titleBuffer.append(PARENTHESIS_OPEN); - titleBuffer.append(group.getItemCount()); - titleBuffer.append(PARENTHESIS_CLOSE); - return titleBuffer.toString(); - } - - /** - * Returns a group offset (size of title + margin) - * - * @param item - * @return group offset or 0 if the item is not a group - */ - protected int getGroupOffset(GalleryItem item) { - if (item.getParentItem() != null) { - return 0; - } - - return getGroupHeight(item) + minMargin; - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#draw(org - * .eclipse.swt.graphics.GC, - * org.eclipse.nebula.widgets.gallery.GalleryItem, int, int, int, int, - * int, int) - */ - public void draw(GC gc, GalleryItem group, int x, int y, int clipX, - int clipY, int clipWidth, int clipHeight) { - // Draw group - drawGroup(gc, group, x, y, clipX, clipY, clipWidth, clipHeight); - - int groupOffset = getGroupOffset(group); - - // Display item - if (isGroupExpanded(group)) { - int[] indexes = getVisibleItems(group, x, y, clipX, clipY, - clipWidth, clipHeight, groupOffset); - - if (fill) { - indexes = new int[] { indexes[0] }; - } - - if (indexes != null && indexes.length > 0) { - for (int i = indexes.length - 1; i >= 0; i--) { - - boolean selected = group - .isSelected(group.getItem(indexes[i])); - - if (Gallery.DEBUG) { - System.out.println("Selected : " + selected //$NON-NLS-1$ - + " index : " + indexes[i] + "item : " //$NON-NLS-1$//$NON-NLS-2$ - + group.getItem(indexes[i])); - } - - drawItem(gc, indexes[i], selected, group, groupOffset); - - } - } - } - } - - public void layout(GC gc, GalleryItem group) { - - int countLocal = group.getItemCount(); - - double animationRatio = 1; - - // If animation is used, load the current size ratio from the object - // itself. - if (animation) { - Object animationGroupData = group - .getData(DefaultGalleryGroupRenderer.DATA_ANIMATION); - if (animationGroupData != null - && animationGroupData instanceof Double) { - animationRatio = ((Double) animationGroupData).doubleValue(); - if (animationRatio < 0) { - animationRatio = 0; - } - } - } - - if (gallery.isVertical()) { - int sizeX = group.width; - group.height = getGroupOffset(group); - - Point l = gridLayout(sizeX, countLocal, itemWidth); - int hCount = l.x; - int vCount = l.y; - - if (autoMargin && hCount > 0) { - // If margins have not been calculated - if (!marginCalculated) { - // Calculate best margins - margin = calculateMargins(sizeX, hCount, itemWidth); - marginCalculated = true; - - if (Gallery.DEBUG) - System.out.println("margin " + margin); //$NON-NLS-1$ - } - } - - if (isGroupExpanded(group)) { - - Point s = this.getSize(hCount, vCount, itemWidth, itemHeight, - minMargin, margin); - group.height += s.y * animationRatio; - - if (Gallery.DEBUG) - System.out.println("group.height " + group.height); //$NON-NLS-1$ - - group.setData(H_COUNT, new Integer(hCount)); - group.setData(V_COUNT, new Integer(vCount)); - if (Gallery.DEBUG) - System.out.println("Hnb" + hCount + "Vnb" + vCount); //$NON-NLS-1$//$NON-NLS-2$ - - fill = (fillIfSingleColumn && hCount == 1); - } - - } else { - // Horizontal - int sizeY = group.height; - group.width = getGroupOffset(group); - - Point l = gridLayout(sizeY, countLocal, itemHeight); - int vCount = l.x; - int hCount = l.y; - if (autoMargin && vCount > 0) { - // Calculate best margins - margin = calculateMargins(sizeY, vCount, itemHeight); - marginCalculated = true; - - if (Gallery.DEBUG) - System.out.println("margin " + margin); //$NON-NLS-1$ - } - - if (isGroupExpanded(group)) { - - Point s = this.getSize(hCount, vCount, itemWidth, itemHeight, - minMargin, margin); - group.width += s.x * animationRatio; - - group.setData(H_COUNT, new Integer(hCount)); - group.setData(V_COUNT, new Integer(vCount)); - - fill = (fillIfSingleColumn && vCount == 1); - - } - } - - } - - public void preDraw(GC gc) { - pre(gc); - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#preLayout - * (org.eclipse.swt.graphics.GC) - */ - public void preLayout(GC gc) { - this.marginCalculated = false; - pre(gc); - super.preLayout(gc); - } - - /** - * Prepare font metrics and title height for both preLayout and preDraw. - * - * @param myGc - */ - private void pre(GC myGc) { - GC gc = myGc; - boolean gcCreated = false; - - if (gc == null) { - gc = new GC(gallery, SWT.NONE); - gcCreated = true; - } - - // Get font height - gc.setFont(font); - fontHeight = gc.getFontMetrics().getHeight(); - - // Compute title height & grid offset - titleHeight = fontHeight + 5; - - if (gcCreated) - gc.dispose(); - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#getItem( - * org.eclipse.nebula.widgets.gallery.GalleryItem, - * org.eclipse.swt.graphics.Point) - */ - public GalleryItem getItem(GalleryItem group, Point coords) { - // Cannot select an item if the group is not expanded - if (!isGroupExpanded(group)) - return null; - - return super.getItem(group, coords, getGroupOffset(group)); - } - - protected void startGroupAnimation(GalleryItem group, boolean doOpen) { - if (animation) { - if (group.getData(DATA_ANIMATION) == null) { - group.setData(DATA_ANIMATION, new Double(doOpen ? 0 : 1)); - } - - int start, end; - IMovement movement; - if (doOpen) { - start = 0; - end = 1; - movement = animationOpenMovement; - } else { - start = 1; - end = 0; - movement = animationCloseMovement; - - } - - animationRunner.runEffect(new GalleryGroupResizeEffect(group, start, - end, animationLength, movement, null, null)); - } - - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer#mouseDown(org.eclipse.nebula.widgets.gallery.GalleryItem, - * org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Point) - */ - public boolean mouseDown(final GalleryItem group, Event e, Point coords) { - - if (gallery.isVertical()) { // V_SCROLL - if (coords.y - group.y <= getGroupHeight(group)) { - - if (!isAlwaysExpanded() - && coords.x - group.x <= getToggleButtonBounds().x - + getToggleButtonBounds().width - && coords.x - group.x > getToggleButtonBounds().x) { - // This is a click on the toggle button : expand/collapse - // the group - // Note : if groups are always expanded, there is no toggle - // button and the test is ignored - - // Toggle expand state - boolean doOpen = !group.isExpanded(); - startGroupAnimation(group, doOpen); - group._setExpanded(doOpen, false); - - // Deselect items if group is collapsed - if (!isGroupExpanded(group)) { - group.deselectAll(); - } - - // Notify listeners - gallery.notifyTreeListeners(group, isGroupExpanded(group)); - - if (!animation) { - // Update library - gallery.updateStructuralValues(group, false); - gallery.updateScrollBarsProperties(); - gallery.redraw(); - } - - } else { - // Click on the title bar : Select all children. Only work - // if multiple items can be selected (SWT.MULTI) - if (isGroupExpanded(group) - && (this.getGallery().getStyle() & SWT.MULTI) > 0) { - // Cancel previous selection - if ((e.stateMask & SWT.MOD1) == 0) { - gallery.deselectAll(); - } - - // Select all and notify - group.selectAll(); - gallery.notifySelectionListeners(group, - gallery.indexOf(group), false); - gallery.redraw(); - } - } - // Event was handled at the group level, stop further - // processing. - return false; - } - } else { // H_SCROLL - if (coords.x - group.x <= getGroupHeight(group)) { - - if (!isAlwaysExpanded() - && group.height - coords.y - + 5 <= (getToggleButtonBounds().x - + getToggleButtonBounds().width) - && group.height - coords.y - + 5 > getToggleButtonBounds().x) { - // This is a click on the toggle button : expand/collapse - // the group - // Note : if groups are always expanded, there is no toggle - // button and the test is ignored - - // Toggle expand state - // Toggle expand state - boolean doOpen = !group.isExpanded(); - startGroupAnimation(group, doOpen); - group._setExpanded(doOpen, false); - - // Deselect items if group is collapsed - if (!isGroupExpanded(group)) { - group.deselectAll(); - } - // Notify listeners - gallery.notifyTreeListeners(group, isGroupExpanded(group)); - - // Update library - if (!animation) { - gallery.updateStructuralValues(null, false); - gallery.updateScrollBarsProperties(); - gallery.redraw(); - } - - } else { - // Click on the title bar : Select all children. Only work - // if multiple items can be selected (SWT.MULTI) - if (isGroupExpanded(group) - && (this.getGallery().getStyle() & SWT.MULTI) > 0) { - - // Cancel previous selection - if ((e.stateMask & SWT.MOD1) == 0) { - gallery.deselectAll(); - } - - // Select all and notify - group.selectAll(); - gallery.notifySelectionListeners(group, - gallery.indexOf(group), false); - gallery.redraw(); - } - } - // Event was handled at the group level, stop further - // processing. - return false; - } - } - - // Mouse down event was not handled at the group level, continue with - // standard mouse down event processing. - return true; - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#getSize( - * org.eclipse.nebula.widgets.gallery.GalleryItem) - */ - public Rectangle getSize(GalleryItem item) { - // If the item is not a group, get its parent - GalleryItem group = item.getParentItem(); - if (group == null) { - group = item; - } - - return super.getSize(item, getGroupOffset(group)); - } - - /** - * Get group title text color. - * - * @return current color. - */ - public Color getTitleForeground() { - return titleForeground; - } - - /** - * Change group title text color. - * - * @param titleColor - * Color or null to revert to default. - */ - public void setTitleForeground(Color titleColor) { - if (titleColor == null) { - if (gallery == null) { - throw new IllegalArgumentException( - "Please associate this renderer with a Gallery before trying to reset foreground defaults"); //$NON-NLS-1$ - } - titleForeground = gallery.getDisplay() - .getSystemColor(SWT.COLOR_TITLE_FOREGROUND); - } else { - this.titleForeground = titleColor; - } - } - - public Color getTitleBackground() { - return titleBackground; - } - - public void setTitleBackground(Color titleBackground) { - this.titleBackgroundGradient = false; - this.titleBackground = titleBackground; - } - - public void setTitleBackgroundGradient(Color gradientBackground, - Color gradientForeground) { - this.titleBackgroundGradient = true; - - if (gradientBackground != null && gradientForeground != null) { - this.titleBackground = gradientBackground; - this.titleBackground2 = gradientForeground; - } else { - if (gallery == null) { - throw new IllegalArgumentException( - "Please associate this renderer with a Gallery before trying to reset background defaults"); //$NON-NLS-1$ - } - - // Default gradient Background - this.titleBackground = gallery.getDisplay() - .getSystemColor(SWT.COLOR_TITLE_BACKGROUND); - this.titleBackground2 = gallery.getDisplay() - .getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT); - } - } - - /** - * Returns the font used for drawing the group title or null if - * system font is used. - * - * @return the font - */ - public Font getFont() { - return font; - } - - /** - * Set the font for drawing the group title or null to use system - * font. - * - * @param font - * the font to set - */ - public void setFont(Font font) { - if (this.font != font) { - this.font = font; - if (getGallery() != null) - getGallery().redraw(); - } - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#drawItem - * (org.eclipse.swt.graphics.GC, int, boolean, - * org.eclipse.nebula.widgets.gallery.GalleryItem, int) - */ - protected void drawItem(GC gc, int index, boolean selected, - GalleryItem parent, int offsetY) { - - if (fill) { - Item item = parent.getItem(index); - - // No item ? return - if (item == null) - return; - - GalleryItem gItem = (GalleryItem) item; - - Rectangle area = gallery.getClientArea(); - - gItem.x = area.x; - gItem.y = area.y + gallery.translate; - - gItem.height = area.height; - gItem.width = area.width; - - gallery.sendPaintItemEvent(item, index, gc, area.x, area.y, - area.width, area.height); - - if (gallery.getItemRenderer() != null) { - gallery.getItemRenderer().setSelected(selected); - gallery.getItemRenderer().draw(gc, gItem, index, area.x, area.y, - area.width, area.height); - } - - return; - } - - super.drawItem(gc, index, selected, parent, offsetY); - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer# - * getScrollBarIncrement() - */ - public int getScrollBarIncrement() { - if (fill) { - if (gallery.isVertical()) { - // Vertical fill - return gallery.getClientArea().height; - } - - // Horizontal fill - return gallery.getClientArea().width; - } - - // Standard behavior - return super.getScrollBarIncrement(); - } - - /** - * @see #setFillIfSingleColumn(boolean) - * @return - */ - public boolean isFillIfSingleColumn() { - return fillIfSingleColumn; - } - - /** - *

- * Experimental feature. - *

- *

- * If set to true, this will enable a special behavior when the items are so - * large that only one can fit in the client area. In this case, items are - * always resized and centered to fit best in the client area. - *

- *

- * See bug 266613 : https://bugs.eclipse.org/266613 - *

- * - * @param fillIfSingle - */ - public void setFillIfSingleColumn(boolean fillIfSingle) { - this.fillIfSingleColumn = fillIfSingle; - } - - /** - * @see #setMaxImageWidth(int) - * @return - */ - public int getMaxImageWidth() { - return maxImageWidth; - } - - /** - * Set the maximum width for a group image in the title bar. - * - * @see GalleryItem#setImage(Image) - * - * @param imageWidth - */ - public void setMaxImageWidth(int imageWidth) { - this.maxImageWidth = imageWidth; - } - - /** - * @see #setMaxImageHeight(int) - * @return - */ - public int getMaxImageHeight() { - return maxImageHeight; - } - - /** - * Set the maximum height for a group image in the title bar. - * - * @see GalleryItem#setImage(Image) - * - * @param imageHeight - */ - public void setMaxImageHeight(int imageHeight) { - this.maxImageHeight = imageHeight; - } - - /** - * @see #setAnimation(boolean) - * @return - */ - public boolean isAnimation() { - return animation; - } - - /** - * Enable animation for group expand/collapse. - * - * @see #setAnimationLength(int) - * @see #setAnimationOpenMovement(IMovement) - * - * @param animation - */ - public void setAnimation(boolean animation) { - this.animation = animation; - } - - /** - * @see #setAnimationLength(int) - * @return - */ - public int getAnimationLength() { - return animationLength; - } - - /** - * Set the length of the animation - * - * @see #setAnimation(boolean) - * @see #setAnimationOpenMovement(IMovement) - * - * @param animationLength - */ - public void setAnimationLength(int animationLength) { - this.animationLength = animationLength; - } - - /** - * Get the current movement used for animation - * - * @see #setAnimationOpenMovement(IMovement) - * - * @return - */ - public IMovement getAnimationOpenMovement() { - return animationOpenMovement; - } - - /** - * @see #setAnimationCloseMovement(IMovement) - * @return - */ - public IMovement getAnimationCloseMovement() { - return animationCloseMovement; - } - - /** - * - * Set the movement used for open animation. - * - * @see #setAnimation(boolean) - * @see #setAnimationLength(int) - * - * @param animationMovement - */ - public void setAnimationOpenMovement(IMovement animationMovement) { - this.animationOpenMovement = animationMovement; - } - - /** - * - * Set the movement used for close animation. - * - * @see #setAnimation(boolean) - * @see #setAnimationLength(int) - * @param animationMovement - */ - public void setAnimationCloseMovement(IMovement animationMovement) { - this.animationCloseMovement = animationMovement; - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer# - * isGroupExpanded (org.eclipse.nebula.widgets.gallery.GalleryItem) - */ - protected boolean isGroupExpanded(GalleryItem item) { - - if (animation) { - if (item.getData( - DefaultGalleryGroupRenderer.DATA_ANIMATION) != null) - return true; - } - return super.isGroupExpanded(item); - } - - public boolean isTitleBackgroundGradient() { - return titleBackgroundGradient; - } - - public Color getTitleBackground2() { - return titleBackground2; - } - -} +/******************************************************************************* + * Copyright (c) 2006-2007 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + * Richard Michalsky - bug 195443 + *******************************************************************************/ +package org.eclipse.nebula.widgets.gallery; + +import org.eclipse.nebula.animation.AnimationRunner; +import org.eclipse.nebula.animation.movement.IMovement; +import org.eclipse.nebula.animation.movement.LinearInOut; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +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.graphics.Transform; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; + +/** + *

+ * Default group renderer used by the Gallery widget. Supports multi-line text, + * images, animation and several other features. + *

+ *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. + *

+ * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + * @contributor Richard Michalsky (bug 195443) + * + */ +public class DefaultGalleryGroupRenderer extends AbstractGridGroupRenderer { + + private AnimationRunner animationRunner = new AnimationRunner(); + + private static final String PARENTHESIS_OPEN = " ("; //$NON-NLS-1$ + + private static final String PARENTHESIS_CLOSE = ")"; //$NON-NLS-1$ + + private int fontHeight = 0; + + private int titleHeight = fontHeight + 5; + + private Color titleForeground; + + private Color descriptionColor; + + private Color titleBackground = null; + + private boolean titleBackgroundGradient = true; + + // Used for gradient + private Color titleBackground2 = null; + + private int maxImageWidth = 32; + + private int maxImageHeight = 32; + + private Point imageSize = null; + /** + * If true, this flag will enable a special behavior when the items are so + * large that only one can fit in the client area. In this case, items are + * always resized and centered to fit best in the client area. + */ + private boolean fillIfSingleColumn = false; + + /** + * This flag is set during layout, if fillIfSigle is true, and if there is + * only one column or row + */ + private boolean fill = false; + + /** + * True if margins have already been calculated. Prevents margins + * calculation for each group + */ + boolean marginCalculated = false; + + private Font font = null; + + protected boolean animation = false; + + protected int animationLength = 500; + + protected IMovement animationOpenMovement = new LinearInOut(); + + protected IMovement animationCloseMovement = new LinearInOut(); + + protected static final String DATA_ANIMATION = "org.eclipse.nebula.gallery.internal.animation"; //$NON-NLS-1$ + + /** + * This group renderer draws a title line, then items in a grid layout. + */ + public DefaultGalleryGroupRenderer() { + super(); + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer# + * setGallery (org.eclipse.nebula.widgets.gallery.Gallery) + */ + public void setGallery(Gallery gallery) { + super.setGallery(gallery); + + // Set defaults + if (titleForeground == null) { + // Reset defaults. + this.setTitleForeground(null); + } + + if (titleBackground == null) { + // Reset default gradient. + setTitleBackgroundGradient(null, null); + } + + if (descriptionColor == null) { + descriptionColor = gallery.getDisplay() + .getSystemColor(SWT.COLOR_DARK_BLUE); + } + + } + + /** + * Draw group background using system default gradient or the user-defined + * color. + * + * @param gc + * @param item + * TODO + * @param x + * @param y + * @param width + * @param height + */ + protected void drawGroupBackground(GC gc, GalleryItem item, int x, int y, + int width, int height) { + Color itemLocalBackground = item.getBackground(true); + if (!titleBackgroundGradient || itemLocalBackground != null) { + // User defined background + gc.setBackground(itemLocalBackground != null ? itemLocalBackground + : titleBackground); + gc.fillRectangle(x, y, width, height); + } else { + // Default gradient Background + gc.setBackground(this.titleBackground); + gc.setForeground(this.titleBackground2); + gc.fillGradientRectangle(x, y, width, height, true); + } + } + + /** + * Draw the toggle button. + * + * @param gc + * @param x + * @param y + * @param group + */ + protected int drawGroupToggleButton(GC gc, int x, int y, + GalleryItem group) { + if (!isAlwaysExpanded()) { + // Toggle Button + + int xShift = RendererHelper.getShift(titleHeight, 9); + int yShift = RendererHelper.getShift(titleHeight, 9); + + int toggleX = x + xShift; + int toggleY = y + yShift; + + gc.setBackground( + gc.getDevice().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + gc.fillRectangle(toggleX, toggleY, 8, 8); + + gc.setForeground( + gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + gc.drawLine(toggleX + 2, toggleY + 4, toggleX + 6, toggleY + 4); + if (!expanded) { + gc.drawLine(toggleX + 4, toggleY + 2, toggleX + 4, toggleY + 6); + } + gc.setForeground(gc.getDevice() + .getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + gc.drawRectangle(toggleX, toggleY, 8, 8); + + } + + return titleHeight + minMargin; + } + + protected Rectangle getToggleButtonBounds() { + return new Rectangle( + minMargin + RendererHelper.getShift(titleHeight, 9), + RendererHelper.getShift(titleHeight, 9), 9, 9); + } + + protected int getGroupHeight(GalleryItem group) { + int groupHeight = titleHeight; + + if (group.getImage() != null) { + Point imageSize = RendererHelper.getBestSize( + group.getImage().getBounds().width, + group.getImage().getBounds().height, maxImageWidth, + maxImageHeight); + groupHeight = Math.max(titleHeight, imageSize.y + 2 * minMargin); + } + + // Ensure there is enough room to display all text. + int lineCount = 1; + if (group.getText(1) != null + && !EMPTY_STRING.equals(group.getText(1))) { + lineCount++; + } + + if (group.getText(2) != null + && !EMPTY_STRING.equals(group.getText(2))) { + lineCount++; + } + + groupHeight = Math.max(groupHeight, lineCount * (fontHeight + 2) + 2); + + return groupHeight; + } + + protected void drawGroup(GC gc, GalleryItem group, int x, int y, int clipX, + int clipY, int clipWidth, int clipHeight) { + // Do not paint group if on single column and filling on. + if (fill) + return; + + imageSize = null; + if (group.getImage() != null) { + imageSize = RendererHelper.getBestSize( + group.getImage().getBounds().width, + group.getImage().getBounds().height, maxImageWidth, + maxImageHeight); + } + int groupHeight = getGroupHeight(group); + + if (gallery.isVertical()) { + int baseX = x + minMargin; + int baseY = y; + + // Center if image + if (group.getImage() != null) { + baseY += (imageSize.y - fontHeight) / 2; + } + + int textY = baseY + 2; + for (int i = 1; i < 3; i++) { + if (group.getText(i) != null + && !EMPTY_STRING.equals(group.getText(i))) { + textY -= fontHeight / 2 + 1; + } + } + textY = Math.max(y + 2, textY); + + // Title background + drawGroupBackground(gc, group, x, y, group.width, groupHeight); + + baseX += drawGroupToggleButton(gc, baseX, textY - 1, group); + baseX += drawGroupImage(gc, group, baseX, y, imageSize); + + // Color for text + gc.setForeground(group.getForeground(true) != null + ? group.getForeground(true) + : titleForeground); + + // Title text + gc.setFont(getFont(group)); + gc.drawText(getGroupTitle(group), baseX, textY, true); + + // Description + gc.setForeground(descriptionColor); + for (int i = 1; i < 3; i++) { + if (group.getText(i) != null + && !EMPTY_STRING.equals(group.getText(i))) { + gc.drawText(group.getText(i), baseX, + textY + i * (2 + fontHeight), true); + } + } + + } else { + + Transform transform = new Transform(gc.getDevice()); + transform.rotate(-90); + gc.setTransform(transform); + + int baseX = x; + int baseY = y - group.height; + + // Center if image + if (group.getImage() != null) { + baseX += (imageSize.y - fontHeight) / 2; + } + + int textX = baseX + 2; + for (int i = 1; i < 3; i++) { + if (group.getText(i) != null) { + textX -= fontHeight / 2 + 1; + } + } + textX = Math.max(x + 2, textX); + + // Title background + drawGroupBackground(gc, group, y - group.height, x, group.height, + groupHeight); + + baseY += drawGroupToggleButton(gc, baseY, textX - 1, group); + baseY += drawGroupImage(gc, group, baseY, x, imageSize); + + // Color for text + gc.setForeground(group.foreground != null ? group.foreground + : titleForeground); + + // Title text + gc.setFont(getFont(group)); + + gc.drawText(getGroupTitle(group), baseY, textX, true); + + gc.setForeground(descriptionColor); + for (int i = 1; i < 3; i++) { + if (group.getText(i) != null) { + gc.drawText(group.getText(i), baseY, + textX + i * (2 + fontHeight), true); + } + } + gc.setTransform(null); + transform.dispose(); + } + } + + private int drawGroupImage(GC gc, GalleryItem group, int x, int y, + Point imageSize2) { + if (imageSize2 == null) + return 0; + + Image img = group.getImage(); + Rectangle imgSize = img.getBounds(); + + Point offset = RendererHelper.getImageOffset(imageSize2.x, imageSize2.y, + maxImageWidth, getGroupHeight(group)); + gc.drawImage(img, 0, 0, imgSize.width, imgSize.height, x + offset.x, + y + offset.y, imageSize2.x, imageSize2.y); + + return maxImageWidth + 2 * minMargin; + } + + protected String getGroupTitle(GalleryItem group) { + StringBuffer titleBuffer = new StringBuffer(); + titleBuffer.append(group.getText()); + titleBuffer.append(PARENTHESIS_OPEN); + titleBuffer.append(group.getItemCount()); + titleBuffer.append(PARENTHESIS_CLOSE); + return titleBuffer.toString(); + } + + /** + * Returns a group offset (size of title + margin) + * + * @param item + * @return group offset or 0 if the item is not a group + */ + protected int getGroupOffset(GalleryItem item) { + if (item.getParentItem() != null) { + return 0; + } + + return getGroupHeight(item) + minMargin; + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#draw(org + * .eclipse.swt.graphics.GC, + * org.eclipse.nebula.widgets.gallery.GalleryItem, int, int, int, int, + * int, int) + */ + public void draw(GC gc, GalleryItem group, int x, int y, int clipX, + int clipY, int clipWidth, int clipHeight) { + // Draw group + drawGroup(gc, group, x, y, clipX, clipY, clipWidth, clipHeight); + + int groupOffset = getGroupOffset(group); + + // Display item + if (isGroupExpanded(group)) { + int[] indexes = getVisibleItems(group, x, y, clipX, clipY, + clipWidth, clipHeight, groupOffset); + + if (fill) { + indexes = new int[] { indexes[0] }; + } + + if (indexes != null && indexes.length > 0) { + for (int i = indexes.length - 1; i >= 0; i--) { + + boolean selected = group + .isSelected(group.getItem(indexes[i])); + + if (Gallery.DEBUG) { + System.out.println("Selected : " + selected //$NON-NLS-1$ + + " index : " + indexes[i] + "item : " //$NON-NLS-1$//$NON-NLS-2$ + + group.getItem(indexes[i])); + } + + drawItem(gc, indexes[i], selected, group, groupOffset); + + } + } + } + } + + public void layout(GC gc, GalleryItem group) { + + int countLocal = group.getItemCount(); + + double animationRatio = 1; + + // If animation is used, load the current size ratio from the object + // itself. + if (animation) { + Object animationGroupData = group + .getData(DefaultGalleryGroupRenderer.DATA_ANIMATION); + if (animationGroupData != null + && animationGroupData instanceof Double) { + animationRatio = ((Double) animationGroupData).doubleValue(); + if (animationRatio < 0) { + animationRatio = 0; + } + } + } + + if (gallery.isVertical()) { + int sizeX = group.width; + group.height = getGroupOffset(group); + + Point l = gridLayout(sizeX, countLocal, itemWidth); + int hCount = l.x; + int vCount = l.y; + + if (autoMargin && hCount > 0) { + // If margins have not been calculated + if (!marginCalculated) { + // Calculate best margins + margin = calculateMargins(sizeX, hCount, itemWidth); + marginCalculated = true; + + if (Gallery.DEBUG) + System.out.println("margin " + margin); //$NON-NLS-1$ + } + } + + if (isGroupExpanded(group)) { + + Point s = this.getSize(hCount, vCount, itemWidth, itemHeight, + minMargin, margin); + group.height += s.y * animationRatio; + + if (Gallery.DEBUG) + System.out.println("group.height " + group.height); //$NON-NLS-1$ + + group.setData(H_COUNT, new Integer(hCount)); + group.setData(V_COUNT, new Integer(vCount)); + if (Gallery.DEBUG) + System.out.println("Hnb" + hCount + "Vnb" + vCount); //$NON-NLS-1$//$NON-NLS-2$ + + fill = (fillIfSingleColumn && hCount == 1); + } + + } else { + // Horizontal + int sizeY = group.height; + group.width = getGroupOffset(group); + + Point l = gridLayout(sizeY, countLocal, itemHeight); + int vCount = l.x; + int hCount = l.y; + if (autoMargin && vCount > 0) { + // Calculate best margins + margin = calculateMargins(sizeY, vCount, itemHeight); + marginCalculated = true; + + if (Gallery.DEBUG) + System.out.println("margin " + margin); //$NON-NLS-1$ + } + + if (isGroupExpanded(group)) { + + Point s = this.getSize(hCount, vCount, itemWidth, itemHeight, + minMargin, margin); + group.width += s.x * animationRatio; + + group.setData(H_COUNT, new Integer(hCount)); + group.setData(V_COUNT, new Integer(vCount)); + + fill = (fillIfSingleColumn && vCount == 1); + + } + } + + } + + public void preDraw(GC gc) { + pre(gc); + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#preLayout + * (org.eclipse.swt.graphics.GC) + */ + public void preLayout(GC gc) { + this.marginCalculated = false; + pre(gc); + super.preLayout(gc); + } + + /** + * Prepare font metrics and title height for both preLayout and preDraw. + * + * @param myGc + */ + private void pre(GC myGc) { + GC gc = myGc; + boolean gcCreated = false; + + if (gc == null) { + gc = new GC(gallery, SWT.NONE); + gcCreated = true; + } + + // Get font height + gc.setFont(font); + fontHeight = gc.getFontMetrics().getHeight(); + + // Compute title height & grid offset + titleHeight = fontHeight + 5; + + if (gcCreated) + gc.dispose(); + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#getItem( + * org.eclipse.nebula.widgets.gallery.GalleryItem, + * org.eclipse.swt.graphics.Point) + */ + public GalleryItem getItem(GalleryItem group, Point coords) { + // Cannot select an item if the group is not expanded + if (!isGroupExpanded(group)) + return null; + + return super.getItem(group, coords, getGroupOffset(group)); + } + + protected void startGroupAnimation(GalleryItem group, boolean doOpen) { + if (animation) { + if (group.getData(DATA_ANIMATION) == null) { + group.setData(DATA_ANIMATION, new Double(doOpen ? 0 : 1)); + } + + int start, end; + IMovement movement; + if (doOpen) { + start = 0; + end = 1; + movement = animationOpenMovement; + } else { + start = 1; + end = 0; + movement = animationCloseMovement; + + } + + animationRunner.runEffect(new GalleryGroupResizeEffect(group, start, + end, animationLength, movement, null, null)); + } + + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer#mouseDown(org.eclipse.nebula.widgets.gallery.GalleryItem, + * org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Point) + */ + public boolean mouseDown(final GalleryItem group, Event e, Point coords) { + + if (gallery.isVertical()) { // V_SCROLL + if (coords.y - group.y <= getGroupHeight(group)) { + + if (!isAlwaysExpanded() + && coords.x - group.x <= getToggleButtonBounds().x + + getToggleButtonBounds().width + && coords.x - group.x > getToggleButtonBounds().x) { + // This is a click on the toggle button : expand/collapse + // the group + // Note : if groups are always expanded, there is no toggle + // button and the test is ignored + + // Toggle expand state + boolean doOpen = !group.isExpanded(); + startGroupAnimation(group, doOpen); + group._setExpanded(doOpen, false); + + // Deselect items if group is collapsed + if (!isGroupExpanded(group)) { + group.deselectAll(); + } + + // Notify listeners + gallery.notifyTreeListeners(group, isGroupExpanded(group)); + + if (!animation) { + // Update library + gallery.updateStructuralValues(group, false); + gallery.updateScrollBarsProperties(); + gallery.redraw(); + } + + } else { + // Click on the title bar : Select all children. Only work + // if multiple items can be selected (SWT.MULTI) + if (isGroupExpanded(group) + && (this.getGallery().getStyle() & SWT.MULTI) > 0) { + // Cancel previous selection + if ((e.stateMask & SWT.MOD1) == 0) { + gallery.deselectAll(); + } + + // Select all and notify + group.selectAll(); + gallery.notifySelectionListeners(group, + gallery.indexOf(group), false); + gallery.redraw(); + } + } + // Event was handled at the group level, stop further + // processing. + return false; + } + } else { // H_SCROLL + if (coords.x - group.x <= getGroupHeight(group)) { + + if (!isAlwaysExpanded() + && group.height - coords.y + + 5 <= (getToggleButtonBounds().x + + getToggleButtonBounds().width) + && group.height - coords.y + + 5 > getToggleButtonBounds().x) { + // This is a click on the toggle button : expand/collapse + // the group + // Note : if groups are always expanded, there is no toggle + // button and the test is ignored + + // Toggle expand state + // Toggle expand state + boolean doOpen = !group.isExpanded(); + startGroupAnimation(group, doOpen); + group._setExpanded(doOpen, false); + + // Deselect items if group is collapsed + if (!isGroupExpanded(group)) { + group.deselectAll(); + } + // Notify listeners + gallery.notifyTreeListeners(group, isGroupExpanded(group)); + + // Update library + if (!animation) { + gallery.updateStructuralValues(null, false); + gallery.updateScrollBarsProperties(); + gallery.redraw(); + } + + } else { + // Click on the title bar : Select all children. Only work + // if multiple items can be selected (SWT.MULTI) + if (isGroupExpanded(group) + && (this.getGallery().getStyle() & SWT.MULTI) > 0) { + + // Cancel previous selection + if ((e.stateMask & SWT.MOD1) == 0) { + gallery.deselectAll(); + } + + // Select all and notify + group.selectAll(); + gallery.notifySelectionListeners(group, + gallery.indexOf(group), false); + gallery.redraw(); + } + } + // Event was handled at the group level, stop further + // processing. + return false; + } + } + + // Mouse down event was not handled at the group level, continue with + // standard mouse down event processing. + return true; + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#getSize( + * org.eclipse.nebula.widgets.gallery.GalleryItem) + */ + public Rectangle getSize(GalleryItem item) { + // If the item is not a group, get its parent + GalleryItem group = item.getParentItem(); + if (group == null) { + group = item; + } + + return super.getSize(item, getGroupOffset(group)); + } + + /** + * Get group title text color. + * + * @return current color. + */ + public Color getTitleForeground() { + return titleForeground; + } + + /** + * Change group title text color. + * + * @param titleColor + * Color or null to revert to default. + */ + public void setTitleForeground(Color titleColor) { + if (titleColor == null) { + if (gallery == null) { + throw new IllegalArgumentException( + "Please associate this renderer with a Gallery before trying to reset foreground defaults"); //$NON-NLS-1$ + } + titleForeground = gallery.getDisplay() + .getSystemColor(SWT.COLOR_TITLE_FOREGROUND); + } else { + this.titleForeground = titleColor; + } + } + + public Color getTitleBackground() { + return titleBackground; + } + + public void setTitleBackground(Color titleBackground) { + this.titleBackgroundGradient = false; + this.titleBackground = titleBackground; + } + + public void setTitleBackgroundGradient(Color gradientBackground, + Color gradientForeground) { + this.titleBackgroundGradient = true; + + if (gradientBackground != null && gradientForeground != null) { + this.titleBackground = gradientBackground; + this.titleBackground2 = gradientForeground; + } else { + if (gallery == null) { + throw new IllegalArgumentException( + "Please associate this renderer with a Gallery before trying to reset background defaults"); //$NON-NLS-1$ + } + + // Default gradient Background + this.titleBackground = gallery.getDisplay() + .getSystemColor(SWT.COLOR_TITLE_BACKGROUND); + this.titleBackground2 = gallery.getDisplay() + .getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT); + } + } + + /** + * Returns the font used for drawing the group title or null if + * system font is used. + * + * @return the font + */ + public Font getFont() { + return font; + } + + /** + * Set the font for drawing the group title or null to use system + * font. + * + * @param font + * the font to set + */ + public void setFont(Font font) { + if (this.font != font) { + this.font = font; + if (getGallery() != null) + getGallery().redraw(); + } + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#drawItem + * (org.eclipse.swt.graphics.GC, int, boolean, + * org.eclipse.nebula.widgets.gallery.GalleryItem, int) + */ + protected void drawItem(GC gc, int index, boolean selected, + GalleryItem parent, int offsetY) { + + if (fill) { + Item item = parent.getItem(index); + + // No item ? return + if (item == null) + return; + + GalleryItem gItem = (GalleryItem) item; + + Rectangle area = gallery.getClientArea(); + + gItem.x = area.x; + gItem.y = area.y + gallery.translate; + + gItem.height = area.height; + gItem.width = area.width; + + gallery.sendPaintItemEvent(item, index, gc, area.x, area.y, + area.width, area.height); + + if (gallery.getItemRenderer() != null) { + gallery.getItemRenderer().setSelected(selected); + gallery.getItemRenderer().draw(gc, gItem, index, area.x, area.y, + area.width, area.height); + } + + return; + } + + super.drawItem(gc, index, selected, parent, offsetY); + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer# + * getScrollBarIncrement() + */ + public int getScrollBarIncrement() { + if (fill) { + if (gallery.isVertical()) { + // Vertical fill + return gallery.getClientArea().height; + } + + // Horizontal fill + return gallery.getClientArea().width; + } + + // Standard behavior + return super.getScrollBarIncrement(); + } + + /** + * @see #setFillIfSingleColumn(boolean) + * @return + */ + public boolean isFillIfSingleColumn() { + return fillIfSingleColumn; + } + + /** + *

+ * Experimental feature. + *

+ *

+ * If set to true, this will enable a special behavior when the items are so + * large that only one can fit in the client area. In this case, items are + * always resized and centered to fit best in the client area. + *

+ *

+ * See bug 266613 : https://bugs.eclipse.org/266613 + *

+ * + * @param fillIfSingle + */ + public void setFillIfSingleColumn(boolean fillIfSingle) { + this.fillIfSingleColumn = fillIfSingle; + } + + /** + * @see #setMaxImageWidth(int) + * @return + */ + public int getMaxImageWidth() { + return maxImageWidth; + } + + /** + * Set the maximum width for a group image in the title bar. + * + * @see GalleryItem#setImage(Image) + * + * @param imageWidth + */ + public void setMaxImageWidth(int imageWidth) { + this.maxImageWidth = imageWidth; + } + + /** + * @see #setMaxImageHeight(int) + * @return + */ + public int getMaxImageHeight() { + return maxImageHeight; + } + + /** + * Set the maximum height for a group image in the title bar. + * + * @see GalleryItem#setImage(Image) + * + * @param imageHeight + */ + public void setMaxImageHeight(int imageHeight) { + this.maxImageHeight = imageHeight; + } + + /** + * @see #setAnimation(boolean) + * @return + */ + public boolean isAnimation() { + return animation; + } + + /** + * Enable animation for group expand/collapse. + * + * @see #setAnimationLength(int) + * @see #setAnimationOpenMovement(IMovement) + * + * @param animation + */ + public void setAnimation(boolean animation) { + this.animation = animation; + } + + /** + * @see #setAnimationLength(int) + * @return + */ + public int getAnimationLength() { + return animationLength; + } + + /** + * Set the length of the animation + * + * @see #setAnimation(boolean) + * @see #setAnimationOpenMovement(IMovement) + * + * @param animationLength + */ + public void setAnimationLength(int animationLength) { + this.animationLength = animationLength; + } + + /** + * Get the current movement used for animation + * + * @see #setAnimationOpenMovement(IMovement) + * + * @return + */ + public IMovement getAnimationOpenMovement() { + return animationOpenMovement; + } + + /** + * @see #setAnimationCloseMovement(IMovement) + * @return + */ + public IMovement getAnimationCloseMovement() { + return animationCloseMovement; + } + + /** + * + * Set the movement used for open animation. + * + * @see #setAnimation(boolean) + * @see #setAnimationLength(int) + * + * @param animationMovement + */ + public void setAnimationOpenMovement(IMovement animationMovement) { + this.animationOpenMovement = animationMovement; + } + + /** + * + * Set the movement used for close animation. + * + * @see #setAnimation(boolean) + * @see #setAnimationLength(int) + * @param animationMovement + */ + public void setAnimationCloseMovement(IMovement animationMovement) { + this.animationCloseMovement = animationMovement; + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer# + * isGroupExpanded (org.eclipse.nebula.widgets.gallery.GalleryItem) + */ + protected boolean isGroupExpanded(GalleryItem item) { + + if (animation) { + if (item.getData( + DefaultGalleryGroupRenderer.DATA_ANIMATION) != null) + return true; + } + return super.isGroupExpanded(item); + } + + public boolean isTitleBackgroundGradient() { + return titleBackgroundGradient; + } + + public Color getTitleBackground2() { + return titleBackground2; + } + +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/DefaultGalleryItemRenderer.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/DefaultGalleryItemRenderer.java index cb5508696..7ba277b88 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/DefaultGalleryItemRenderer.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/DefaultGalleryItemRenderer.java @@ -1,393 +1,393 @@ -/******************************************************************************* - * Copyright (c) 2006-2007 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - * Richard Michalsky - bugs 195415, 195443 - *******************************************************************************/ -package org.eclipse.nebula.widgets.gallery; - -import java.util.ArrayList; -import java.util.Iterator; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -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.Display; - -/** - *

- * Default item renderer used by the Gallery widget. Supports single line text, - * image, drop shadows and decorators. - *

- *

- * Decorator images can be set with {@link GalleryItem#setData(String, Object)} - * by using the following keys : - *

- *
    - *
  • org.eclipse.nebula.widget.gallery.bottomLeftOverlay
  • - *
  • org.eclipse.nebula.widget.gallery.bottomRightOverlay
  • - *
  • org.eclipse.nebula.widget.gallery.topLeftOverlay
  • - *
  • org.eclipse.nebula.widget.gallery.topRightOverlay
  • - *
- *

- * Supported types are org.eclipse.swt.Image for one single decorator and - * org.eclipse.swt.Image[] for multiple decorators. - *

- *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. - *

- * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - * @contributor Richard Michalsky (bugs 195415, 195443) - * @contributor Peter Centgraf (bugs 212071, 212073) - */ -public class DefaultGalleryItemRenderer extends AbstractGalleryItemRenderer { - - /** - * Stores colors used in drop shadows - */ - protected ArrayList dropShadowsColors = new ArrayList<>(); - - // Renderer parameters - boolean dropShadows = false; - - int dropShadowsSize = 0; - - int dropShadowsAlphaStep = 20; - - Color selectionForegroundColor; - - Color selectionBackgroundColor; - - Color foregroundColor, backgroundColor; - - boolean showLabels = true; - - boolean showRoundedSelectionCorners = true; - - int selectionRadius = 15; - - // Vars used during drawing (optimization) - private boolean _drawBackground = false; - private Color _drawBackgroundColor = null; - private Image _drawImage = null; - private Color _drawForegroundColor = null; - - /** - * Returns current label state : enabled or disabled - * - * @return true if labels are enabled. - * @see DefaultGalleryItemRenderer#setShowLabels(boolean) - * - */ - public boolean isShowLabels() { - return showLabels; - } - - /** - * Enables / disables labels at the bottom of each item. - * - * @param showLabels - * @see DefaultGalleryItemRenderer#isShowLabels() - * - */ - public void setShowLabels(boolean showLabels) { - this.showLabels = showLabels; - } - - public DefaultGalleryItemRenderer() { - // Set defaults - foregroundColor = Display.getDefault() - .getSystemColor(SWT.COLOR_LIST_FOREGROUND); - backgroundColor = Display.getDefault() - .getSystemColor(SWT.COLOR_LIST_BACKGROUND); - - selectionForegroundColor = Display.getDefault() - .getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); - selectionBackgroundColor = Display.getDefault() - .getSystemColor(SWT.COLOR_LIST_SELECTION); - - // Create drop shadows - createColors(); - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer#draw(org - * .eclipse.swt.graphics.GC, - * org.eclipse.nebula.widgets.gallery.GalleryItem, int, int, int, int, - * int) - */ - public void draw(GC gc, GalleryItem item, int index, int x, int y, - int width, int height) { - _drawImage = item.getImage(); - _drawForegroundColor = getForeground(item); - - // Set up the GC - gc.setFont(getFont(item)); - - // Create some room for the label. - int useableHeight = height; - int fontHeight = 0; - if (item.getText() != null && !EMPTY_STRING.equals(item.getText()) - && this.showLabels) { - fontHeight = gc.getFontMetrics().getHeight(); - useableHeight -= fontHeight + 2; - } - - int imageWidth = 0; - int imageHeight = 0; - int xShift = 0; - int yShift = 0; - Point size = null; - - if (_drawImage != null) { - Rectangle itemImageBounds = _drawImage.getBounds(); - imageWidth = itemImageBounds.width; - imageHeight = itemImageBounds.height; - - size = RendererHelper.getBestSize(imageWidth, imageHeight, - width - 8 - 2 * this.dropShadowsSize, - useableHeight - 8 - 2 * this.dropShadowsSize); - - xShift = RendererHelper.getShift(width, size.x); - yShift = RendererHelper.getShift(useableHeight, size.y); - - if (dropShadows) { - Color c = null; - for (int i = this.dropShadowsSize - 1; i >= 0; i--) { - c = (Color) dropShadowsColors.get(i); - gc.setForeground(c); - - gc.drawLine(x + width + i - xShift - 1, - y + dropShadowsSize + yShift, - x + width + i - xShift - 1, - y + useableHeight + i - yShift); - gc.drawLine(x + xShift + dropShadowsSize, - y + useableHeight + i - yShift - 1, - x + width + i - xShift, - y - 1 + useableHeight + i - yShift); - } - } - } - - // Draw background (rounded rectangles) - - // Checks if background has to be drawn - _drawBackground = selected; - _drawBackgroundColor = null; - if (!_drawBackground && item.getBackground(true) != null) { - _drawBackgroundColor = getBackground(item); - - if (!RendererHelper.isColorsEquals(_drawBackgroundColor, - galleryBackgroundColor)) { - _drawBackground = true; - } - } - - if (_drawBackground) { - // Set colors - if (selected) { - gc.setBackground(selectionBackgroundColor); - gc.setForeground(selectionBackgroundColor); - } else if (_drawBackgroundColor != null) { - gc.setBackground(_drawBackgroundColor); - } - - // Draw - if (showRoundedSelectionCorners) { - gc.fillRoundRectangle(x, y, width, useableHeight, - selectionRadius, selectionRadius); - } else { - gc.fillRectangle(x, y, width, height); - } - - if (item.getText() != null && !EMPTY_STRING.equals(item.getText()) - && showLabels) { - gc.fillRoundRectangle(x, y + height - fontHeight, width, - fontHeight, selectionRadius, selectionRadius); - } - } - - // Draw image - if (_drawImage != null && size != null) { - if (size.x > 0 && size.y > 0) { - gc.drawImage(_drawImage, 0, 0, imageWidth, imageHeight, - x + xShift, y + yShift, size.x, size.y); - drawAllOverlays(gc, item, x, y, size, xShift, yShift); - } - - } - - // Draw label - if (item.getText() != null && !EMPTY_STRING.equals(item.getText()) - && showLabels) { - // Set colors - if (selected) { - // Selected : use selection colors. - gc.setForeground(selectionForegroundColor); - gc.setBackground(selectionBackgroundColor); - } else { - // Not selected, use item values or defaults. - - // Background - if (_drawBackgroundColor != null) { - gc.setBackground(_drawBackgroundColor); - } else { - gc.setBackground(backgroundColor); - } - - // Foreground - if (_drawForegroundColor != null) { - gc.setForeground(_drawForegroundColor); - } else { - gc.setForeground(foregroundColor); - } - } - - // Create label - String text = RendererHelper.createLabel(item.getText(), gc, - width - 10); - - // Center text - int textWidth = gc.textExtent(text).x; - int textxShift = RendererHelper.getShift(width, textWidth); - - // Draw - gc.drawText(text, x + textxShift, y + height - fontHeight, true); - } - } - - public void setDropShadowsSize(int dropShadowsSize) { - this.dropShadowsSize = dropShadowsSize; - this.dropShadowsAlphaStep = (dropShadowsSize == 0) ? 0 - : (200 / dropShadowsSize); - - freeDropShadowsColors(); - createColors(); - // TODO: force redraw - - } - - private void createColors() { - if (dropShadowsSize > 0) { - int step = 125 / dropShadowsSize; - // Create new colors - for (int i = dropShadowsSize - 1; i >= 0; i--) { - int value = 255 - i * step; - Color c = new Color(Display.getDefault(), value, value, value); - dropShadowsColors.add(c); - } - } - } - - private void freeDropShadowsColors() { - // Free colors : - { - Iterator i = this.dropShadowsColors.iterator(); - while (i.hasNext()) { - Color c = i.next(); - if (c != null && !c.isDisposed()) - c.dispose(); - } - } - } - - public boolean isDropShadows() { - return dropShadows; - } - - public void setDropShadows(boolean dropShadows) { - this.dropShadows = dropShadows; - } - - public int getDropShadowsSize() { - return dropShadowsSize; - } - - /** - * Returns the font used for drawing all item labels or null if - * system font is used. - * - * @return the font - * @see {@link Gallery#getFont()} for setting font for a specific - * GalleryItem. - */ - public Font getFont() { - if (gallery != null) { - return gallery.getFont(); - } - return null; - } - - /** - * Set the font for drawing all item labels or null to use system - * font. - * - * @param font - * the font to set - * @see {@link Gallery#setFont(Font)} for setting font for a specific - * GalleryItem. - */ - public void setFont(Font font) { - if (gallery != null) { - gallery.setFont(font); - } - } - - public void dispose() { - freeDropShadowsColors(); - } - - public Color getForegroundColor() { - return foregroundColor; - } - - public void setForegroundColor(Color foregroundColor) { - this.foregroundColor = foregroundColor; - } - - public Color getSelectionForegroundColor() { - return selectionForegroundColor; - } - - public void setSelectionForegroundColor(Color selectionForegroundColor) { - this.selectionForegroundColor = selectionForegroundColor; - } - - public Color getSelectionBackgroundColor() { - return selectionBackgroundColor; - } - - public void setSelectionBackgroundColor(Color selectionBackgroundColor) { - this.selectionBackgroundColor = selectionBackgroundColor; - } - - public Color getBackgroundColor() { - return backgroundColor; - } - - public void setBackgroundColor(Color backgroundColor) { - this.backgroundColor = backgroundColor; - } - - public boolean isShowRoundedSelectionCorners() { - return this.showRoundedSelectionCorners; - } - - public void setShowRoundedSelectionCorners( - boolean showRoundedSelectionCorners) { - this.showRoundedSelectionCorners = showRoundedSelectionCorners; - } -} +/******************************************************************************* + * Copyright (c) 2006-2007 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + * Richard Michalsky - bugs 195415, 195443 + *******************************************************************************/ +package org.eclipse.nebula.widgets.gallery; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +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.Display; + +/** + *

+ * Default item renderer used by the Gallery widget. Supports single line text, + * image, drop shadows and decorators. + *

+ *

+ * Decorator images can be set with {@link GalleryItem#setData(String, Object)} + * by using the following keys : + *

+ *
    + *
  • org.eclipse.nebula.widget.gallery.bottomLeftOverlay
  • + *
  • org.eclipse.nebula.widget.gallery.bottomRightOverlay
  • + *
  • org.eclipse.nebula.widget.gallery.topLeftOverlay
  • + *
  • org.eclipse.nebula.widget.gallery.topRightOverlay
  • + *
+ *

+ * Supported types are org.eclipse.swt.Image for one single decorator and + * org.eclipse.swt.Image[] for multiple decorators. + *

+ *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. + *

+ * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + * @contributor Richard Michalsky (bugs 195415, 195443) + * @contributor Peter Centgraf (bugs 212071, 212073) + */ +public class DefaultGalleryItemRenderer extends AbstractGalleryItemRenderer { + + /** + * Stores colors used in drop shadows + */ + protected ArrayList dropShadowsColors = new ArrayList<>(); + + // Renderer parameters + boolean dropShadows = false; + + int dropShadowsSize = 0; + + int dropShadowsAlphaStep = 20; + + Color selectionForegroundColor; + + Color selectionBackgroundColor; + + Color foregroundColor, backgroundColor; + + boolean showLabels = true; + + boolean showRoundedSelectionCorners = true; + + int selectionRadius = 15; + + // Vars used during drawing (optimization) + private boolean _drawBackground = false; + private Color _drawBackgroundColor = null; + private Image _drawImage = null; + private Color _drawForegroundColor = null; + + /** + * Returns current label state : enabled or disabled + * + * @return true if labels are enabled. + * @see DefaultGalleryItemRenderer#setShowLabels(boolean) + * + */ + public boolean isShowLabels() { + return showLabels; + } + + /** + * Enables / disables labels at the bottom of each item. + * + * @param showLabels + * @see DefaultGalleryItemRenderer#isShowLabels() + * + */ + public void setShowLabels(boolean showLabels) { + this.showLabels = showLabels; + } + + public DefaultGalleryItemRenderer() { + // Set defaults + foregroundColor = Display.getDefault() + .getSystemColor(SWT.COLOR_LIST_FOREGROUND); + backgroundColor = Display.getDefault() + .getSystemColor(SWT.COLOR_LIST_BACKGROUND); + + selectionForegroundColor = Display.getDefault() + .getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); + selectionBackgroundColor = Display.getDefault() + .getSystemColor(SWT.COLOR_LIST_SELECTION); + + // Create drop shadows + createColors(); + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer#draw(org + * .eclipse.swt.graphics.GC, + * org.eclipse.nebula.widgets.gallery.GalleryItem, int, int, int, int, + * int) + */ + public void draw(GC gc, GalleryItem item, int index, int x, int y, + int width, int height) { + _drawImage = item.getImage(); + _drawForegroundColor = getForeground(item); + + // Set up the GC + gc.setFont(getFont(item)); + + // Create some room for the label. + int useableHeight = height; + int fontHeight = 0; + if (item.getText() != null && !EMPTY_STRING.equals(item.getText()) + && this.showLabels) { + fontHeight = gc.getFontMetrics().getHeight(); + useableHeight -= fontHeight + 2; + } + + int imageWidth = 0; + int imageHeight = 0; + int xShift = 0; + int yShift = 0; + Point size = null; + + if (_drawImage != null) { + Rectangle itemImageBounds = _drawImage.getBounds(); + imageWidth = itemImageBounds.width; + imageHeight = itemImageBounds.height; + + size = RendererHelper.getBestSize(imageWidth, imageHeight, + width - 8 - 2 * this.dropShadowsSize, + useableHeight - 8 - 2 * this.dropShadowsSize); + + xShift = RendererHelper.getShift(width, size.x); + yShift = RendererHelper.getShift(useableHeight, size.y); + + if (dropShadows) { + Color c = null; + for (int i = this.dropShadowsSize - 1; i >= 0; i--) { + c = (Color) dropShadowsColors.get(i); + gc.setForeground(c); + + gc.drawLine(x + width + i - xShift - 1, + y + dropShadowsSize + yShift, + x + width + i - xShift - 1, + y + useableHeight + i - yShift); + gc.drawLine(x + xShift + dropShadowsSize, + y + useableHeight + i - yShift - 1, + x + width + i - xShift, + y - 1 + useableHeight + i - yShift); + } + } + } + + // Draw background (rounded rectangles) + + // Checks if background has to be drawn + _drawBackground = selected; + _drawBackgroundColor = null; + if (!_drawBackground && item.getBackground(true) != null) { + _drawBackgroundColor = getBackground(item); + + if (!RendererHelper.isColorsEquals(_drawBackgroundColor, + galleryBackgroundColor)) { + _drawBackground = true; + } + } + + if (_drawBackground) { + // Set colors + if (selected) { + gc.setBackground(selectionBackgroundColor); + gc.setForeground(selectionBackgroundColor); + } else if (_drawBackgroundColor != null) { + gc.setBackground(_drawBackgroundColor); + } + + // Draw + if (showRoundedSelectionCorners) { + gc.fillRoundRectangle(x, y, width, useableHeight, + selectionRadius, selectionRadius); + } else { + gc.fillRectangle(x, y, width, height); + } + + if (item.getText() != null && !EMPTY_STRING.equals(item.getText()) + && showLabels) { + gc.fillRoundRectangle(x, y + height - fontHeight, width, + fontHeight, selectionRadius, selectionRadius); + } + } + + // Draw image + if (_drawImage != null && size != null) { + if (size.x > 0 && size.y > 0) { + gc.drawImage(_drawImage, 0, 0, imageWidth, imageHeight, + x + xShift, y + yShift, size.x, size.y); + drawAllOverlays(gc, item, x, y, size, xShift, yShift); + } + + } + + // Draw label + if (item.getText() != null && !EMPTY_STRING.equals(item.getText()) + && showLabels) { + // Set colors + if (selected) { + // Selected : use selection colors. + gc.setForeground(selectionForegroundColor); + gc.setBackground(selectionBackgroundColor); + } else { + // Not selected, use item values or defaults. + + // Background + if (_drawBackgroundColor != null) { + gc.setBackground(_drawBackgroundColor); + } else { + gc.setBackground(backgroundColor); + } + + // Foreground + if (_drawForegroundColor != null) { + gc.setForeground(_drawForegroundColor); + } else { + gc.setForeground(foregroundColor); + } + } + + // Create label + String text = RendererHelper.createLabel(item.getText(), gc, + width - 10); + + // Center text + int textWidth = gc.textExtent(text).x; + int textxShift = RendererHelper.getShift(width, textWidth); + + // Draw + gc.drawText(text, x + textxShift, y + height - fontHeight, true); + } + } + + public void setDropShadowsSize(int dropShadowsSize) { + this.dropShadowsSize = dropShadowsSize; + this.dropShadowsAlphaStep = (dropShadowsSize == 0) ? 0 + : (200 / dropShadowsSize); + + freeDropShadowsColors(); + createColors(); + // TODO: force redraw + + } + + private void createColors() { + if (dropShadowsSize > 0) { + int step = 125 / dropShadowsSize; + // Create new colors + for (int i = dropShadowsSize - 1; i >= 0; i--) { + int value = 255 - i * step; + Color c = new Color(Display.getDefault(), value, value, value); + dropShadowsColors.add(c); + } + } + } + + private void freeDropShadowsColors() { + // Free colors : + { + Iterator i = this.dropShadowsColors.iterator(); + while (i.hasNext()) { + Color c = i.next(); + if (c != null && !c.isDisposed()) + c.dispose(); + } + } + } + + public boolean isDropShadows() { + return dropShadows; + } + + public void setDropShadows(boolean dropShadows) { + this.dropShadows = dropShadows; + } + + public int getDropShadowsSize() { + return dropShadowsSize; + } + + /** + * Returns the font used for drawing all item labels or null if + * system font is used. + * + * @return the font + * @see {@link Gallery#getFont()} for setting font for a specific + * GalleryItem. + */ + public Font getFont() { + if (gallery != null) { + return gallery.getFont(); + } + return null; + } + + /** + * Set the font for drawing all item labels or null to use system + * font. + * + * @param font + * the font to set + * @see {@link Gallery#setFont(Font)} for setting font for a specific + * GalleryItem. + */ + public void setFont(Font font) { + if (gallery != null) { + gallery.setFont(font); + } + } + + public void dispose() { + freeDropShadowsColors(); + } + + public Color getForegroundColor() { + return foregroundColor; + } + + public void setForegroundColor(Color foregroundColor) { + this.foregroundColor = foregroundColor; + } + + public Color getSelectionForegroundColor() { + return selectionForegroundColor; + } + + public void setSelectionForegroundColor(Color selectionForegroundColor) { + this.selectionForegroundColor = selectionForegroundColor; + } + + public Color getSelectionBackgroundColor() { + return selectionBackgroundColor; + } + + public void setSelectionBackgroundColor(Color selectionBackgroundColor) { + this.selectionBackgroundColor = selectionBackgroundColor; + } + + public Color getBackgroundColor() { + return backgroundColor; + } + + public void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public boolean isShowRoundedSelectionCorners() { + return this.showRoundedSelectionCorners; + } + + public void setShowRoundedSelectionCorners( + boolean showRoundedSelectionCorners) { + this.showRoundedSelectionCorners = showRoundedSelectionCorners; + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/Gallery.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/Gallery.java index b7409320e..f0a04cea7 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/Gallery.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/Gallery.java @@ -1,2558 +1,2558 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - * Tom Schindl (tom.schindl@bestsolution.at) - fix for bug 174933 - *******************************************************************************/ - -package org.eclipse.nebula.widgets.gallery; - -import java.lang.reflect.Array; -import java.util.ArrayList; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TreeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.ScrollBar; -import org.eclipse.swt.widgets.TypedListener; - -/** - *

- * SWT Widget that displays an image gallery
- * see http://www.eclipse.org/nebula/widgets/gallery/gallery.php
- * This widget requires jdk-1.8+ - *

- *

- * Style VIRTUAL is used to create a Gallery whose - * GalleryItems are to be populated by the client on an on-demand - * basis instead of up-front. This can provide significant performance - * improvements for galleries that are very large or for which - * GalleryItem population is expensive (for example, retrieving - * values from an external source). - *

- *

- * Here is an example of using a Gallery with style - * VIRTUAL:

- * final Gallery gallery = new Gallery(parent, SWT.VIRTUAL | V_SCROLL | SWT.BORDER);
- * gallery.setGroupRenderer(new DefaultGalleryGroupRenderer());
- * gallery.setItemRenderer(new DefaultGalleryItemRenderer());
- * gallery.setItemCount(1000000);
- * gallery.addListener(SWT.SetData, new Listener() {
- * 	public void handleEvent(Event event) {
- * 		GalleryItem item = (GalleryItem) event.item;
- * 		int index = gallery.indexOf(item);
- * 		item.setText("Item " + index);
- * 		System.out.println(item.getText());
- * 	}
- * });
- * 
- *

- *

- *

- *
Styles:
- *
SINGLE, MULTI, VIRTUAL, V_SCROLL, H_SCROLL
- *
- *

- *

- * Note: Only one of the styles SINGLE and MULTI may be specified. - *

- *

- * Note: Only one of the styles V_SCROLL and H_SCROLL may be specified. - *

- *

- *

- *
Events:
- *
Selection, DefaultSelection, SetData, PaintItem
- *
- *

- *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. - *

- * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - * @contributor Peter Centgraf (bugs 212071, 212073) - * @contributor Robert Handschmann (bug 215817) - * @contributor Berthold Daum (bug 306144 - selection tuning) - */ - -public class Gallery extends Canvas { - - private static final String BUG_PLATFORM_LINUX_GTK_174932 = "gtk"; //$NON-NLS-1$ - - /** - * Used to enable debug logging in the Gallery widget. - */ - protected static boolean DEBUG = false; - - GalleryItem[] items = null; - - private GalleryItem[] selection = null; - - /** - * Selection bit flags. Each 'int' contains flags for 32 items. - */ - protected int[] selectionFlags = null; - - /** - * Virtual mode flag. - */ - boolean virtual = false; - - /** - * Ultra virtual : non visible groups are not initialized. - */ - boolean virtualGroups = false; - boolean virtualGroupsCompatibilityMode = false; - int virtualGroupDefaultItemCount = 10; - - /** - * Scrolling direction flag. True : V_SCROLL, false : H_SCROLL. - */ - boolean vertical = true; - - /** - * Multi-selection flag - */ - boolean multi = false; - - /** - * Image quality : interpolation - */ - int interpolation = SWT.HIGH; - - /** - * Image quality : antialias - */ - int antialias = SWT.ON; - - // Internals - - private int gHeight = 0; - - private int gWidth = 0; - - int lastIndexOf = 0; - - /** - * Keeps track of the last selected item. This is necessary to support - * "Shift+Mouse button" where we have to select all items between the - * previous and the current item and keyboard navigation. - */ - protected GalleryItem lastSingleClick = null; - - /** - * Current translation (scroll bar position). Can be used by renderer during - * paint. - */ - protected int translate = 0; - - /** - * Low quality on user action : decrease drawing quality on scrolling or - * resize. (faster) - */ - boolean lowQualityOnUserAction = false; - protected int lastTranslateValue = 0; - protected int lastControlWidth = 0; - protected int lastControlHeight = 0; - protected int lastContentHeight = 0; - protected int lastContentWidth = 0; - protected int higherQualityDelay = 500; - - /** - * Keep track of processing the current mouse event. - */ - private boolean mouseClickHandled = false; - - /** - * Background color, if Control#getBackground() is not used. - * - * @see Gallery#useControlColors - */ - private Color backgroundColor; - - /** - * Foreground color, if Control#getForeground() is not used. - * - * @see Gallery#useControlColors - */ - private Color foregroundColor; - - /** - * If set to true, the gallery will get colors from parent Control. This may - * generate more objects and slightly slow down the application. See Bug - * 279822 : https://bugs.eclipse.org/bugs/show_bug.cgi?id=279822 - */ - private boolean useControlColors = false; - - AbstractGalleryItemRenderer itemRenderer; - - AbstractGalleryGroupRenderer groupRenderer; - - /** - * Return the number of root-level items in the receiver. Does not include - * children. - * - * @return - */ - public int getItemCount() { - checkWidget(); - - if (items == null) - return 0; - - return items.length; - } - - /** - * Sets the number of root-level items contained in the receiver. Only work - * in VIRTUAL mode. - * - * @return - */ - public void setItemCount(int count) { - checkWidget(); - - if (DEBUG) - System.out.println("setCount" + count); //$NON-NLS-1$ - - if (count == 0) { - // No items - items = null; - } else { - // At least one item, create a new array and copy data from the - // old one. - GalleryItem[] newItems = new GalleryItem[count]; - if (items != null) { - System.arraycopy(items, 0, newItems, 0, - Math.min(count, items.length)); - } - items = newItems; - } - - updateStructuralValues(null, false); - this.updateScrollBarsProperties(); - redraw(); - - } - - /** - * Get current item renderer - * - * @return - */ - public AbstractGalleryItemRenderer getItemRenderer() { - checkWidget(); - return itemRenderer; - } - - /** - * Set item receiver. Usually, this does not trigger gallery update. redraw - * must be called right after setGroupRenderer to reflect this change. - * - * @param itemRenderer - */ - public void setItemRenderer(AbstractGalleryItemRenderer itemRenderer) { - checkWidget(); - this.itemRenderer = itemRenderer; - - if (this.itemRenderer != null) - this.itemRenderer.setGallery(this); - - redraw(); - } - - /** - * Adds the listener to the collection of listeners who will be notified - * when the receiver's selection changes, by sending it one of the messages - * defined in the SelectionListener interface. - *

- * When widgetSelected is called, the item field of the event - * object is valid. - *

- * - * @param listener - * the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(SelectionListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - - TypedListener typedListener = new TypedListener(listener); - addListener(SWT.Selection, typedListener); - addListener(SWT.DefaultSelection, typedListener); - } - - /** - * Removes the listener from the collection of listeners who will be - * notified when the receiver's selection changes. - * - * @param listener - * the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener(SelectionListener) - */ - public void removeSelectionListener(SelectionListener listener) { - checkWidget(); - removeListener(SWT.Selection, listener); - removeListener(SWT.DefaultSelection, listener); - } - - /** - * Removes the listener from the collection of listeners who will be - * notified when items in the receiver are expanded or collapsed. - * - * @param listener - */ - public void removeTreeListener(SelectionListener listener) { - checkWidget(); - removeListener(SWT.Expand, listener); - } - - /** - * Adds the listener to the collection of listeners who will be notified - * when an item in the receiver is expanded or collapsed by sending it one - * of the messages defined in the TreeListener interface. - * - * @param listener - */ - public void addTreeListener(TreeListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - addListener(SWT.Expand, new TypedListener(listener)); - } - - /** - * Send SWT.PaintItem for one item. - * - * @param item - * @param index - * @param gc - * @param x - * @param y - */ - protected void sendPaintItemEvent(Item item, int index, GC gc, int x, int y, - int width, int height) { - - Event e = new Event(); - e.item = item; - e.type = SWT.PaintItem; - e.index = index; - // TODO: Does clipping need to be set ? - // gc.setClipping(x, y, width, height); - e.gc = gc; - e.x = x; - e.y = y; - e.width = width; - e.height = height; - this.notifyListeners(SWT.PaintItem, e); - } - - /** - * #see {@link #setLowQualityOnUserAction(boolean)} - * - * @return - */ - public boolean isLowQualityOnUserAction() { - return lowQualityOnUserAction; - } - - /** - * If set to true, the gallery will disable antialiasing and interpolation - * while the user is resizing or scrolling the gallery. This enables faster - * redraws at the cost of lower image quality. When every redraw is finished - * a last one will be issued using the default (higher) quality. - * - * @see #setHigherQualityDelay(int) - * @param lowQualityOnUserAction - */ - public void setLowQualityOnUserAction(boolean lowQualityOnUserAction) { - this.lowQualityOnUserAction = lowQualityOnUserAction; - } - - /** - * @see #setHigherQualityDelay(int) - * @return - */ - public int getHigherQualityDelay() { - return higherQualityDelay; - } - - /** - * Set the delay after the last user action before the redraw at higher - * quality is triggered - * - * @see #setLowQualityOnUserAction(boolean) - * @param higherQualityDelay - */ - public void setHigherQualityDelay(int higherQualityDelay) { - this.higherQualityDelay = higherQualityDelay; - } - - /** - * @see #setInterpolation(int) - * @return - */ - public int getInterpolation() { - return interpolation; - } - - /** - * Sets the gallery's interpolation setting to the parameter, which must be - * one of SWT.DEFAULT, SWT.NONE, - * SWT.LOW or SWT.HIGH. - * - * @param interpolation - */ - public void setInterpolation(int interpolation) { - this.interpolation = interpolation; - } - - /** - * @see #setAntialias(int) - * @return - */ - public int getAntialias() { - return antialias; - } - - /** - * - * Sets the gallery's anti-aliasing value to the parameter, which must be - * one of SWT.DEFAULT, SWT.OFF or - * SWT.ON. - * - * @param antialias - */ - public void setAntialias(int antialias) { - this.antialias = antialias; - } - - /** - * Send a selection event for a gallery item - * - * @param item - */ - protected void notifySelectionListeners(GalleryItem item, int index, - boolean isDefault) { - - Event e = new Event(); - e.widget = this; - e.item = item; - if (item != null) { - e.data = item.getData(); - } - // TODO: report index - // e.index = index; - try { - if (isDefault) { - notifyListeners(SWT.DefaultSelection, e); - } else { - notifyListeners(SWT.Selection, e); - } - } catch (RuntimeException ex) { - ex.printStackTrace(); - } - } - - /** - * Send an Expand event for a GalleryItem - * - * @param item - * @param index - */ - protected void notifyTreeListeners(GalleryItem item, boolean state) { - - Event e = new Event(); - e.widget = this; - e.item = item; - if (item != null) { - e.data = item.getData(); - } - // TODO: report index - // e.index = index; - try { - notifyListeners(SWT.Expand, e); - } catch (RuntimeException ex) { - ex.printStackTrace(); - } - } - - /** - * Create a Gallery - * - * - * @param parent - * @param style - * - SWT.VIRTUAL switches in virtual mode.
- * SWT.V_SCROLL add vertical slider and switches to vertical - * mode.
- * SWT.H_SCROLL add horizontal slider and switches to horizontal - * mode.
- * if both V_SCROLL and H_SCROLL are specified, the gallery is in - * vertical mode by default. Mode can be changed afterward using - * setVertical
- * SWT.MULTI allows only several items to be selected at the same - * time. - */ - public Gallery(Composite parent, int style) { - super(parent, style | SWT.DOUBLE_BUFFERED); - virtual = (style & SWT.VIRTUAL) > 0; - vertical = (style & SWT.V_SCROLL) > 0; - multi = (style & SWT.MULTI) > 0; - setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND)); - - // Add listeners : redraws, mouse and keyboard - _addDisposeListeners(); - _addResizeListeners(); - _addPaintListeners(); - _addScrollBarsListeners(); - _addMouseListeners(); - _addKeyListeners(); - - // Set defaults - _setDefaultRenderers(); - - // Layout - updateStructuralValues(null, false); - updateScrollBarsProperties(); - redraw(); - } - - private void _setDefaultRenderers() { - // Group renderer - DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer(); - gr.setMinMargin(2); - gr.setItemHeight(56); - gr.setItemWidth(72); - gr.setAutoMargin(true); - gr.setGallery(this); - this.groupRenderer = gr; - - // Item renderer - this.itemRenderer = new DefaultGalleryItemRenderer(); - itemRenderer.setGallery(this); - } - - /** - * Add internal dispose listeners to this gallery. - */ - private void _addDisposeListeners() { - this.addListener(SWT.Dispose, event -> onDispose()); - } - - /** - * Add internal paint listeners to this gallery. - */ - private void _addPaintListeners() { - addListener(SWT.Paint, event -> onPaint(event.gc)); - } - - /** - * Add internal resize listeners to this gallery. - */ - private void _addResizeListeners() { - addListener(SWT.Resize, event -> { - updateStructuralValues(null, true); - updateScrollBarsProperties(); - redraw(); - }); - } - - /** - * Add internal scrollbars listeners to this gallery. - */ - private void _addScrollBarsListeners() { - // Vertical bar - ScrollBar verticalBar = getVerticalBar(); - if (verticalBar != null) { - verticalBar.addListener(SWT.Selection, event -> { - if (vertical) - scrollVertical(); - }); - } - - // Horizontal bar - - ScrollBar horizontalBar = getHorizontalBar(); - if (horizontalBar != null) { - horizontalBar.addListener(SWT.Selection, event -> { - if (!vertical) - scrollHorizontal(); - }); - } - - } - - private void _addKeyListeners() { - this.addListener(SWT.KeyDown, e -> { - switch (e.keyCode) { - case SWT.ARROW_LEFT: - case SWT.ARROW_RIGHT: - case SWT.ARROW_UP: - case SWT.ARROW_DOWN: - case SWT.PAGE_UP: - case SWT.PAGE_DOWN: - case SWT.HOME: - case SWT.END: - GalleryItem newItem = groupRenderer.getNextItem(lastSingleClick, - e.keyCode); - - if (newItem != null) { - _deselectAll(false); - setSelected(newItem, true, true); - lastSingleClick = newItem; - _showItem(newItem); - redraw(); - } - - break; - case SWT.CR: - GalleryItem[] selection = getSelection(); - GalleryItem item = null; - if (selection != null && selection.length > 0) { - item = selection[0]; - } - - notifySelectionListeners(item, 0, true); - break; - } - }); - } - - /** - * Scroll the Gallery in order to make 'item' visible. - * - * @param item - * Item to show - */ - public void showItem(GalleryItem item) { - this.checkWidget(); - this._showItem(item); - } - - void _showItem(GalleryItem item) { - int y; - int height; - Rectangle rect = groupRenderer.getSize(item); - if (rect == null) { - return; - } - - if (vertical) { - y = rect.y; - height = rect.height; - if (y < translate) { - translate = y; - } else if (translate + this.getClientArea().height < y + height) { - translate = y + height - this.getClientArea().height; - } - - } else { - y = rect.x; - height = rect.width; - - if (y < translate) { - translate = y; - } else if (translate + this.getClientArea().width < y + height) { - translate = y + height - this.getClientArea().width; - } - } - - this.updateScrollBarsProperties(); - redraw(); - - } - - /** - * Add internal mouse listeners to this gallery. - */ - private void _addMouseListeners() { - addListener(SWT.MouseDoubleClick, event -> onMouseDoubleClick(event)); - addListener(SWT.MouseDown, event -> onMouseDown(event)); - addListener(SWT.MouseUp, event -> onMouseUp(event)); - } - - private void select(int from, int to) { - for (int i = from; i <= to; i++) { - GalleryItem item = getItem(i); - this._addSelection(item); - item._selectAll(); - - } - } - - private void select(GalleryItem from, GalleryItem to) { - GalleryItem fromParent = from.getParentItem(); - GalleryItem toParent = to.getParentItem(); - - if (fromParent == toParent) { - - if (fromParent == null) { - int fromIndex = indexOf(from); - int toIndex = indexOf(to); - select(fromIndex, toIndex); - } else { - int fromIndex = fromParent.indexOf(from); - int toIndex = toParent.indexOf(to); - fromParent.select(fromIndex, toIndex); - } - } else { - int fromParentIndex = indexOf(fromParent); - int toParentIndex = indexOf(toParent); - int fromIndex = fromParent.indexOf(from); - int toIndex = toParent.indexOf(to); - - fromParent.select(fromIndex, fromParent.getItemCount() - 1); - for (int i = fromParentIndex + 1; i < toParentIndex; i++) { - getItem(i)._selectAll(); - } - toParent.select(0, toIndex); - - } - this.notifySelectionListeners(to, indexOf(to), false); - redraw(); - } - - private boolean getOrder(GalleryItem before, GalleryItem after) { - - if (before == null || after == null) - return true; - - GalleryItem newParent = before.getParentItem(); - GalleryItem oldParent = after.getParentItem(); - - int beforeParentIndex = indexOf(newParent); - int afterParentIndex = indexOf(oldParent); - - if (newParent == oldParent) { - int newParentIndex; - int oldParentIndex; - if (newParent == null) { - newParentIndex = indexOf(before); - oldParentIndex = indexOf(after); - - } else { - newParentIndex = newParent.indexOf(before); - oldParentIndex = newParent.indexOf(after); - } - return (newParentIndex < oldParentIndex); - } - - return beforeParentIndex < afterParentIndex; - } - - /** - * Toggle item selection status - * - * @param item - * Item which state is to be changed. - * @param selected - * true is the item is now selected, false if it is now - * unselected. - * @param notifyListeners - * If true, a selection event will be sent to all the current - * selection listeners. - * - */ - protected void setSelected(GalleryItem item, boolean selected, - boolean notifyListeners) { - if (selected) { - if (!isSelected(item)) { - _addSelection(item); - - } - - } else { - if (isSelected(item)) { - _removeSelection(item); - } - } - - // Notify listeners if necessary. - if (notifyListeners) { - - GalleryItem notifiedItem = null; - - if (item != null && selected) { - notifiedItem = item; - } else { - if (selection != null && selection.length > 0) { - notifiedItem = selection[selection.length - 1]; - } - } - - int index = -1; - if (notifiedItem != null) { - index = indexOf(notifiedItem); - } - - notifySelectionListeners(notifiedItem, index, false); - } - - } - - protected void _addSelection(GalleryItem item) { - - if (item == null) - return; - - if (this.isSelected(item)) - return; - - // Deselect all items is multi selection is disabled - if (!multi) { - _deselectAll(false); - } - - if (item.getParentItem() != null) { - item.getParentItem()._addSelection(item); - } else { - int index = indexOf(item); - - // Divide position by 32 to get selection bloc for this item. - int n = index >> 5; - if (selectionFlags == null) { - // Create selectionFlag array - // Add 31 before dividing by 32 to ensure at least one 'int' is - // created if size < 32. - selectionFlags = new int[(items.length + 31) >> 5]; - } else if (n >= selectionFlags.length) { - // Expand selectionArray - int[] oldFlags = selectionFlags; - selectionFlags = new int[n + 1]; - System.arraycopy(oldFlags, 0, selectionFlags, 0, - oldFlags.length); - } - - // Get flag position in the 32 bit block and ensure is selected. - selectionFlags[n] |= 1 << (index & 0x1f); - - } - - if (selection == null) { - selection = new GalleryItem[1]; - } else { - GalleryItem[] oldSelection = selection; - selection = new GalleryItem[oldSelection.length + 1]; - System.arraycopy(oldSelection, 0, selection, 0, - oldSelection.length); - } - selection[selection.length - 1] = item; - - } - - private void _removeSelection(GalleryItem item) { - - if (item.getParentItem() == null) { - int index = _indexOf(item); - selectionFlags[index >> 5] &= ~(1 << (index & 0x1f)); - } else - _removeSelection(item.getParentItem(), item); - - int index = _arrayIndexOf(selection, item); - if (index == -1) - return; - - selection = (GalleryItem[]) _arrayRemoveItem(selection, index); - - } - - protected void _removeSelection(GalleryItem parent, GalleryItem item) { - int index = _indexOf(parent, item); - parent.selectionFlags[index >> 5] &= ~(1 << (index & 0x1f)); - } - - protected boolean isSelected(GalleryItem item) { - - if (item == null) - return false; - - if (item.getParentItem() != null) { - return item.getParentItem().isSelected(item); - } - - if (selectionFlags == null) - return false; - - int index = indexOf(item); - int n = index >> 5; - if (n >= selectionFlags.length) - return false; - int flags = selectionFlags[n]; - return flags != 0 && (flags & 1 << (index & 0x1f)) != 0; - - } - - /** - * Deselects all items. - */ - public void deselectAll() { - checkWidget(); - _deselectAll(false); - - redraw(); - } - - /** - * Deselects all items and send selection event depending on parameter. - * - * @param notifyListeners - * If true, a selection event will be sent to all the current - * selection listeners. - */ - protected void _deselectAll(boolean notifyListeners) { - - if (DEBUG) - System.out.println("clear"); //$NON-NLS-1$ - - this.selection = null; - // Deselect groups - // We could set selectionFlags to null, but we rather set all values to - // 0 to redure garbage collection. On each iteration, we deselect 32 - // items. - if (selectionFlags != null) - for (int i = 0; i < selectionFlags.length; i++) - selectionFlags[i] = 0; - - if (items == null) - return; - for (int i = 0; i < items.length; i++) { - if (items[i] != null) - items[i]._deselectAll(); - } - - // Notify listeners if necessary. - if (notifyListeners) - notifySelectionListeners(null, -1, false); - } - - void onMouseDoubleClick(Event e) { - if (DEBUG) - System.out.println("Mouse Double Click"); //$NON-NLS-1$ - - GalleryItem item = getItem(new Point(e.x, e.y)); - if (item != null) { - notifySelectionListeners(item, 0, true); - } - mouseClickHandled = true; - } - - void onMouseUp(Event e) { - if (DEBUG) - System.out.println("onMouseUp"); //$NON-NLS-1$ - - if (mouseClickHandled) { - if (DEBUG) { - System.out.println("onMouseUp : mouse event already handled"); //$NON-NLS-1$ - } - return; - } - - if (e.button == 1) { - GalleryItem item = getItem(new Point(e.x, e.y)); - if (item == null) - return; - - if ((e.stateMask & SWT.MOD1) > 0) { - onMouseHandleLeftMod1(e, item, false, true); - } else if ((e.stateMask & SWT.SHIFT) > 0) { - onMouseHandleLeftShift(e, item, false, true); - } else { - onMouseHandleLeft(e, item, false, true); - } - } - } - - /** - * Clean up the Gallery and renderers on dispose. - */ - void onDispose() { - // Remove items if not Virtual. - if (!virtual) - removeAll(); - - // Dispose renderers - if (itemRenderer != null) - itemRenderer.dispose(); - - if (groupRenderer != null) - groupRenderer.dispose(); - - } - - void onMouseDown(Event e) { - if (DEBUG) - System.out.println("Mouse down "); //$NON-NLS-1$ - - mouseClickHandled = false; - - if (!_mouseDown(e)) { - // Stop handling as requested by the group renderer - mouseClickHandled = true; - return; - } - - GalleryItem item = getItem(new Point(e.x, e.y)); - - if (e.button == 1) { - - if (item == null) { - _deselectAll(true); - redraw(); - mouseClickHandled = true; - lastSingleClick = null; - } else { - if ((e.stateMask & SWT.MOD1) > 0) { - onMouseHandleLeftMod1(e, item, true, false); - } else if ((e.stateMask & SWT.SHIFT) > 0) { - onMouseHandleLeftShift(e, item, true, false); - } else { - onMouseHandleLeft(e, item, true, false); - } - } - } else if (e.button == 3) { - onMouseHandleRight(e, item, true, false); - } - } - - private void onMouseHandleLeftMod1(Event e, GalleryItem item, boolean down, - boolean up) { - if (up) { - // if (lastSingleClick != null) { - if (item != null) { - if (DEBUG) - System.out.println("setSelected : inverse"); //$NON-NLS-1$ - setSelected(item, !isSelected(item), true); - lastSingleClick = item; - redraw(); - } - // } - } - } - - private void onMouseHandleLeftShift(Event e, GalleryItem item, boolean down, - boolean up) { - if (up) { - if (lastSingleClick != null) { - _deselectAll(false); - - if (getOrder(item, lastSingleClick)) - select(item, lastSingleClick); - else - select(lastSingleClick, item); - } - } - } - - void onMouseHandleLeft(Event e, GalleryItem item, boolean down, - boolean up) { - if (down) { - if (!isSelected(item)) { - _deselectAll(false); - - if (DEBUG) - System.out.println("setSelected"); //$NON-NLS-1$ - setSelected(item, true, true); - - lastSingleClick = item; - redraw(); - mouseClickHandled = true; - } - } else if (up) { - if (item == null) { - _deselectAll(true); - } else { - if (DEBUG) - System.out.println("setSelected"); //$NON-NLS-1$ - - _deselectAll(false); - setSelected(item, true, lastSingleClick != item); - lastSingleClick = item; - } - redraw(); - } - } - - /** - * Handle right click. - * - * @param e - * @param item - * : The item which is under the cursor or null - * @param down - * @param up - */ - void onMouseHandleRight(Event e, GalleryItem item, boolean down, - boolean up) { - if (down) { - if (DEBUG) - System.out.println("right click"); //$NON-NLS-1$ - - if (item != null && !isSelected(item)) { - _deselectAll(false); - setSelected(item, true, true); - redraw(); - mouseClickHandled = true; - } - } - - } - - void onPaint(GC gc) { - if (DEBUG) - System.out.println("paint"); //$NON-NLS-1$ - - boolean lowQualityPaint = lowQualityOnUserAction - && (translate != lastTranslateValue - || (lastControlWidth != getSize().x - || lastControlHeight != getSize().y - || lastContentHeight != this.gHeight - || lastContentWidth != this.gWidth)); - try { - // Linux-GTK Bug 174932 - if (!SWT.getPlatform().equals(BUG_PLATFORM_LINUX_GTK_174932)) { - gc.setAdvanced(true); - } - - if (gc.getAdvanced()) { - if (lowQualityPaint) { - gc.setAntialias(SWT.OFF); - gc.setInterpolation(SWT.OFF); - } else { - gc.setAntialias(antialias); - gc.setInterpolation(interpolation); - } - } - // End of Bug 174932 - - Rectangle clipping = gc.getClipping(); - - gc.setBackground(this.getBackground()); - drawBackground(gc, clipping.x, clipping.y, clipping.width, - clipping.height); - - int[] indexes = getVisibleItems(clipping); - - if (indexes != null && indexes.length > 0) { - - // Call preDraw for optimization - if (groupRenderer != null) - groupRenderer.preDraw(gc); - if (itemRenderer != null) - itemRenderer.preDraw(gc); - - for (int i = indexes.length - 1; i >= 0; i--) { - if (DEBUG) - System.out.println("Drawing group " + indexes[i]); //$NON-NLS-1$ - - _drawGroup(gc, indexes[i]); - } - - // Call postDraw for optimization / cleanup - if (groupRenderer != null) - groupRenderer.postDraw(gc); - if (itemRenderer != null) - itemRenderer.postDraw(gc); - } - } catch (Exception e) { - // We can't let onPaint throw an exception because unexpected - // results may occur in SWT. - e.printStackTrace(); - } - - // When lowQualityOnUserAction is enabled, keep last state and wait - // before updating with a higher quality - if (lowQualityOnUserAction) { - lastTranslateValue = translate; - lastControlWidth = getSize().x; - lastControlHeight = getSize().y; - lastContentHeight = gHeight; - lastContentWidth = gWidth; - - if (lowQualityPaint) { - // Calling timerExec with the same object just delays the - // execution (doesn't run twice) - Display.getCurrent().timerExec(higherQualityDelay, redrawTimer); - } - } - } - - Runnable redrawTimer = () -> { - if (!isDisposed()) { - redraw(); - } - }; - - private int[] getVisibleItems(Rectangle clipping) { - - if (items == null) - return null; - - int start = vertical ? (clipping.y + translate) - : (clipping.x + translate); - - int end = vertical ? (clipping.y + clipping.height + translate) - : (clipping.x + clipping.width + translate); - - ArrayList al = new ArrayList<>(); - int index = 0; - GalleryItem item = null; - while (index < items.length) { - if (virtualGroups) { - item = _getItem(index, false); - } else { - item = _getItem(index); - } - if ((vertical ? item.y : item.x) > end) - break; - - if ((vertical ? (item.y + item.height) - : (item.x + item.width)) >= start) - al.add(new Integer(index)); - - index++; - } - - int[] result = new int[al.size()]; - - for (int i = 0; i < al.size(); i++) - result[i] = ((Integer) al.get(i)).intValue(); - - return result; - } - - /** - * Refresh item by firering SWT.SetData. - *

- * Currently not implemented. - *

- * - * @param index - */ - public void refresh(int index) { - checkWidget(); - if (index < getItemCount()) { - // TODO: refresh - } - } - - /** - * Redraw the item given as parameter. - * - * @param item - */ - public void redraw(GalleryItem item) { - checkWidget(); - - // Redraw only the item's bounds - Rectangle bounds = item.getBounds(); - redraw(bounds.x, bounds.y, bounds.width, bounds.height, true); - } - - /** - * Handle the drawing of root items - * - * @param gc - * @param index - */ - private void _drawGroup(GC gc, int index) { - GalleryItem item = null; - - if (virtualGroups) { - // Ultra virtual : when a group is about to be drawn, initialize it - // and update gallery layout according to the new size - item = _getItem(index, false); - if (item.isUltraLazyDummy()) { - boolean updateLocation = (vertical && item.y < translate) - || (!vertical && item.x < translate); - int oldSize = item.height; - item = _getItem(index, true); - - // Compatibility mode : ensure all previous items are already - // initialized - if (virtualGroupsCompatibilityMode) { - for (int i = 0; i < index; i++) { - _getItem(i); - } - } - - updateStructuralValues(item, false); - - if (DEBUG) { - System.out.println("old" + oldSize + " new " + item.height //$NON-NLS-1$//$NON-NLS-2$ - + " translate " + translate); //$NON-NLS-1$ - } - - if (updateLocation) { - translate += (item.height - oldSize); - if (DEBUG) { - System.out.println("updated to : " + translate); //$NON-NLS-1$ - } - } - this.updateScrollBarsProperties(); - redraw(); - } - } else { - // Default behavior : get the item with no special handling. - item = getItem(index); - } - - if (item == null) - return; - - // update item attributes - this.groupRenderer.setExpanded(item.isExpanded()); - - // Drawing area - int x = this.vertical ? item.x : item.x - this.translate; - int y = this.vertical ? item.y - translate : item.y; - - Rectangle clipping = gc.getClipping(); - Rectangle previousClipping = new Rectangle(clipping.x, clipping.y, - clipping.width, clipping.height); - - clipping.intersect(new Rectangle(x, y, item.width, item.height)); - gc.setClipping(clipping); - // Draw group - this.groupRenderer.draw(gc, item, x, y, clipping.x, clipping.y, - clipping.width, clipping.height); - - gc.setClipping(previousClipping); - } - - /** - * If table is virtual and item at pos i has not been set, call the callback - * listener to set its value. - * - * @return - */ - private void updateItem(GalleryItem parentItem, int i, boolean create) { - if (virtual) { - - GalleryItem galleryItem; - if (parentItem == null) { - // Parent is the Gallery widget - galleryItem = items[i]; - - if (galleryItem == null || (virtualGroups - && galleryItem.isUltraLazyDummy() && create)) { - - if (DEBUG) { - System.out.println("Virtual/creating item "); //$NON-NLS-1$ - } - - galleryItem = new GalleryItem(this, SWT.NONE, i, false); - items[i] = galleryItem; - - if (virtualGroups && !create) { - galleryItem.setItemCount(virtualGroupDefaultItemCount); - galleryItem.setUltraLazyDummy(true); - galleryItem.setExpanded(true); - } else { - setData(galleryItem, i); - } - } - } else { - // Parent is another GalleryItem - galleryItem = parentItem.items[i]; - if (galleryItem == null) { - if (DEBUG) { - System.out.println("Virtual/creating item "); //$NON-NLS-1$ - } - - galleryItem = new GalleryItem(parentItem, SWT.NONE, i, - false); - parentItem.items[i] = galleryItem; - setData(galleryItem, i); - } - } - } - - } - - /** - * Sends SWT.SetData event. Used if SWT.VIRTUAL - * - * @param galleryItem - * @param index - */ - protected void setData(GalleryItem galleryItem, int index) { - Item item = galleryItem; - Event e = new Event(); - e.item = item; - e.type = SWT.SetData; - e.index = index; - this.notifyListeners(SWT.SetData, e); - } - - /** - * Recalculate structural values using the group renderer
- * Gallery and item size will be updated. - * - * @param keepLocation - * if true, the current scrollbars position ratio is saved and - * restored even if the gallery size has changed. (Visible items - * stay visible) - * @deprecated Use {@link #updateStructuralValues(GalleryItem,boolean)} - * instead - */ - protected void updateStructuralValues(boolean keepLocation) { - updateStructuralValues(null, keepLocation); - } - - /** - * Recalculate structural values using the group renderer
- * Gallery and item size will be updated. - * - * @param changedGroup - * the group that was modified since the last layout. If the - * group renderer or more that one group have changed, use null - * as parameter (full update) - * @param keepLocation - * if true, the current scrollbars position ratio is saved and - * restored even if the gallery size has changed. (Visible items - * stay visible) - */ - protected void updateStructuralValues(GalleryItem changedGroup, - boolean keepLocation) { - - if (DEBUG) { - System.out.println("Client Area : " + this.getClientArea().x + " " //$NON-NLS-1$//$NON-NLS-2$ - + this.getClientArea().y + " " + this.getClientArea().width //$NON-NLS-1$ - + " " + this.getClientArea().height); //$NON-NLS-1$ - } - - Rectangle area = this.getClientArea(); - float pos = 0; - - if (vertical) { - if (gHeight > 0 && keepLocation) - pos = (float) (translate + 0.5 * area.height) / gHeight; - - gWidth = area.width; - gHeight = calculateSize(changedGroup); - - if (keepLocation) - translate = (int) (gHeight * pos - 0.5 * area.height); - - } else { - if (gWidth > 0 && keepLocation) - pos = (float) (translate + 0.5 * area.width) / gWidth; - - gWidth = calculateSize(changedGroup); - gHeight = area.height; - - if (keepLocation) - translate = (int) (gWidth * pos - 0.5 * area.width); - } - - validateTranslation(); - - if (DEBUG) { - System.out.println("Content Size : " + gWidth + " " + gHeight); //$NON-NLS-1$//$NON-NLS-2$ - } - - } - - /** - * Calculate full height (or width) of the Gallery. The group renderer is - * used to calculate the size of each group. - * - * @return - */ - private int calculateSize(GalleryItem onlyUpdateGroup) { - - if (groupRenderer == null) - return 0; - - groupRenderer.preLayout(null); - - int currentHeight = 0; - - int mainItemCount = getItemCount(); - - for (int i = 0; i < mainItemCount; i++) { - GalleryItem item = null; - if (virtualGroups) { - item = this._getItem(i, false); - } else { - item = this._getItem(i); - } - - if (onlyUpdateGroup != null && !onlyUpdateGroup.equals(item)) { - // Item has not changed : no layout. - if (vertical) { - item.y = currentHeight; - item.x = getClientArea().x; - currentHeight += item.height; - } else { - item.y = getClientArea().y; - item.x = currentHeight; - currentHeight += item.width; - } - } else { - this.groupRenderer.setExpanded(item.isExpanded()); - // TODO: Not used ATM - // int groupItemCount = item.getItemCount(); - if (vertical) { - item.y = currentHeight; - item.x = getClientArea().x; - item.width = getClientArea().width; - item.height = -1; - this.groupRenderer.layout(null, item); - currentHeight += item.height; - } else { - item.y = getClientArea().y; - item.x = currentHeight; - item.width = -1; - item.height = getClientArea().height; - this.groupRenderer.layout(null, item); - currentHeight += item.width; - } - } - - } - - groupRenderer.postLayout(null); - - return currentHeight; - } - - /** - * Move the scrollbar to reflect the current visible items position.
- * The bar which is moved depends of the current gallery scrolling : - * vertical or horizontal. - * - */ - protected void updateScrollBarsProperties() { - - if (vertical) { - updateScrollBarProperties(getVerticalBar(), getClientArea().height, - gHeight); - } else { - updateScrollBarProperties(getHorizontalBar(), getClientArea().width, - gWidth); - } - - } - - /** - * Move the scrollbar to reflect the current visible items position. - * - * @param bar - * - the scroll bar to move - * @param clientSize - * - Client (visible) area size - * @param totalSize - * - Total Size - */ - private void updateScrollBarProperties(ScrollBar bar, int clientSize, - int totalSize) { - if (bar == null) - return; - - bar.setMinimum(0); - bar.setPageIncrement(clientSize); - bar.setMaximum(totalSize); - bar.setThumb(clientSize); - - // Let the group renderer use a custom increment value. - if (groupRenderer != null) - bar.setIncrement(groupRenderer.getScrollBarIncrement()); - - if (totalSize > clientSize) { - if (DEBUG) - System.out.println("Enabling scrollbar"); //$NON-NLS-1$ - - bar.setEnabled(true); - bar.setVisible(true); - bar.setSelection(translate); - - // Ensure that translate has a valid value. - validateTranslation(); - } else { - if (DEBUG) - System.out.println("Disabling scrollbar"); //$NON-NLS-1$ - - bar.setEnabled(false); - bar.setVisible(false); - bar.setSelection(0); - translate = 0; - } - - } - - /** - * Check the current translation value. Must be > 0 and < gallery - * size.
- * Invalid values are fixed. - */ - private void validateTranslation() { - Rectangle area = this.getClientArea(); - // Ensure that translate has a valid value. - int totalSize = 0; - int clientSize = 0; - - // Fix negative values - if (translate < 0) - translate = 0; - - // Get size depending on vertical setting. - if (vertical) { - totalSize = gHeight; - clientSize = area.height; - } else { - totalSize = gWidth; - clientSize = area.width; - } - - if (totalSize > clientSize) { - // Fix translate too big. - if (translate + clientSize > totalSize) { - translate = totalSize - clientSize; - } - } else { - translate = 0; - } - - } - - protected void scrollVertical() { - int areaHeight = getClientArea().height; - - if (gHeight > areaHeight) { - // image is higher than client area - ScrollBar bar = getVerticalBar(); - scroll(0, translate - bar.getSelection(), 0, 0, - getClientArea().width, areaHeight, false); - translate = bar.getSelection(); - } else { - translate = 0; - } - } - - protected void scrollHorizontal() { - - int areaWidth = getClientArea().width; - if (gWidth > areaWidth) { - // image is higher than client area - ScrollBar bar = getHorizontalBar(); - scroll(translate - bar.getSelection(), 0, 0, 0, areaWidth, - getClientArea().height, false); - translate = bar.getSelection(); - } else { - translate = 0; - } - - } - - protected void addItem(GalleryItem item, int position) { - if (position != -1 && (position < 0 || position > getItemCount())) { - throw new IllegalArgumentException("ERROR_INVALID_RANGE "); //$NON-NLS-1$ - } - _addItem(item, position); - } - - private void _addItem(GalleryItem item, int position) { - // Insert item - items = (GalleryItem[]) _arrayAddItem(items, item, position); - - // Update Gallery - updateStructuralValues(null, false); - updateScrollBarsProperties(); - } - - /** - * Get the item at index.
- * If SWT.VIRTUAL is used and the item has not been used yet, the item is - * created and a SWT.SetData event is fired. - * - * @param index - * index of the item. - * @return the GalleryItem or null if index is out of bounds - */ - public GalleryItem getItem(int index) { - checkWidget(); - return _getItem(index); - } - - /** - * This method is used by items to implement getItem( index ) - * - * @param parent - * @param index - * @return - */ - protected GalleryItem _getItem(GalleryItem parent, int index) { - - if (index < parent.getItemCount()) { - // Refresh item if it is not set yet - updateItem(parent, index, true); - - if (parent.items == null) { - return null; - } else if (index < parent.items.length) { - return parent.items[index]; - } - } - - return null; - } - - /** - * Get the item at index.
- * If SWT.VIRTUAL is used and the item has not been used yet, the item is - * created and a SWT.SetData is fired.
- * - * This is the internal implementation of this method : checkWidget() is not - * used. - * - * @param index - * @return The item at 'index' (not null) - */ - protected GalleryItem _getItem(int index) { - return _getItem(index, true); - } - - /** - * Get the item at 'index'.
- * If SWT.VIRTUAL is used, 'create' is true and the item has not been used - * yet, the item is created and a SWT.SetData is fired.
- * - * @param index - * @param create - * @return The item at 'index' or null if there was no item and 'create' was - * false. - */ - protected GalleryItem _getItem(int index, boolean create) { - - if (index < getItemCount()) { - updateItem(null, index, create); - if (index < items.length) { - return items[index]; - } - } - - return null; - } - - /** - * Forward the mouseDown event to the corresponding group according to the - * mouse position. - * - * @param event - * The original MouseEvent - * @return true if Gallery should continue standard mouse click handling - */ - protected boolean _mouseDown(Event event) { - - if (DEBUG) - System.out.println("getitem " + event.x + " " + event.y); //$NON-NLS-1$//$NON-NLS-2$ - - GalleryItem group = this._getGroup(new Point(event.x, event.y)); - if (group != null) { - int pos = vertical ? (event.y + translate) : (event.x + translate); - - try { - return groupRenderer.mouseDown(group, event, new Point( - vertical ? event.x : pos, vertical ? pos : event.y)); - } catch (Exception e) { - // We can't let 3rd party groupRenderer#mouseDown throw an - // exception because unexpected results may occur in SWT. - e.printStackTrace(); - } - } - - return true; - } - - /** - * Get item at pixel position - * - * @param coords - * @return GalleryItem or null - */ - public GalleryItem getItem(Point coords) { - checkWidget(); - - if (DEBUG) - System.out.println("getitem " + coords.x + " " + coords.y); //$NON-NLS-1$ //$NON-NLS-2$ - - int pos = vertical ? (coords.y + translate) : (coords.x + translate); - - GalleryItem group = this._getGroup(coords); - if (group != null) - return groupRenderer.getItem(group, new Point( - vertical ? coords.x : pos, vertical ? pos : coords.y)); - - return null; - } - - /** - * Get group at pixel position - * - * @param coords - * @return GalleryItem or null - */ - private GalleryItem _getGroup(Point coords) { - // If there is no item in the gallery, return asap - if (items == null) - return null; - - int pos = vertical ? (coords.y + translate) : (coords.x + translate); - - int index = 0; - GalleryItem item = null; - while (index < items.length) { - item = getItem(index); - - if ((vertical ? item.y : item.x) > pos) - break; - - if ((vertical ? (item.y + item.height) - : (item.x + item.width)) >= pos) - return item; - - index++; - } - - return null; - } - - /** - *

- * Get group at pixel position (relative to client area). - *

- *

- * This is an experimental API which is exposing an internal method, it may - * become deprecated at some point. - *

- * - * @param coords - * @return - */ - public GalleryItem getGroup(Point coords) { - checkWidget(); - return _getGroup(coords); - } - - /** - * Clear all Gallery items.
- * - * - * If the Gallery is virtual, the item count is not reseted and all items - * will be created again at their first use.
- * - * @param all - * If true, all children will be cleared. Only groups are cleared - * otherwise. - */ - public void clearAll(boolean all) { - checkWidget(); - - if (items == null) - return; - - if (virtual) { - items = new GalleryItem[items.length]; - } else { - for (int i = 0; i < items.length; i++) { - if (items[i] != null) { - if (all) { - items[i].clearAll(true); - } else { - items[i].clear(); - } - } - } - } - - // TODO: I'm clearing selection here - // but we have to check that Table has the same behavior - this._deselectAll(false); - - updateStructuralValues(null, false); - updateScrollBarsProperties(); - redraw(); - - } - - /** - * Clear all GalleryGroups - */ - public void clearAll() { - clearAll(false); - } - - /** - * Clear one item.
- * - * @param index - */ - public void clear(int index) { - clear(index, false); - } - - /** - * Clear one item and all its children if 'all' is true - * - * @param index - * @param all - */ - public void clear(int index, boolean all) { - checkWidget(); - - // Item is already cleared, return immediately. - if (items[index] == null) - return; - - if (virtual) { - // Clear item - items[index] = null; - - // In virtual mode, clearing an item can change its content, so - // force content update - updateStructuralValues(null, false); - updateScrollBarsProperties(); - } else { - // Reset item - items[index].clear(); - if (all) { - items[index].clearAll(true); - } - } - - redraw(); - } - - /** - * Returns the index of a GalleryItem. - * - * @param parentItem - * @param item - * @return - */ - public int indexOf(GalleryItem item) { - checkWidget(); - if (item == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - // SWT.error throws an exception - } - - if (item.getParentItem() == null) { - return _indexOf(item); - } - - return _indexOf(item.getParentItem(), item); - } - - /** - * Returns the index of a GalleryItem when it is a root Item - * - * @param parentItem - * @param item - * @return - */ - protected int _indexOf(GalleryItem item) { - int itemCount = getItemCount(); - if (item == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (1 <= lastIndexOf && lastIndexOf < itemCount - 1) { - if (items[lastIndexOf] == item) - return lastIndexOf; - if (items[lastIndexOf + 1] == item) - return ++lastIndexOf; - if (items[lastIndexOf - 1] == item) - return --lastIndexOf; - } - if (lastIndexOf < itemCount / 2) { - for (int i = 0; i < itemCount; i++) { - if (items[i] == item) - return lastIndexOf = i; - } - } else { - for (int i = itemCount - 1; i >= 0; --i) { - if (items[i] == item) - return lastIndexOf = i; - } - } - return -1; - } - - /** - * Returns the index of a GalleryItem when it is not a root Item - * - * @param parentItem - * @param item - * @return - */ - protected int _indexOf(GalleryItem parentItem, GalleryItem item) { - int itemCount = parentItem.getItemCount(); - if (item == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (1 <= parentItem.lastIndexOf - && parentItem.lastIndexOf < itemCount - 1) { - if (parentItem.items[parentItem.lastIndexOf] == item) - return parentItem.lastIndexOf; - if (parentItem.items[parentItem.lastIndexOf + 1] == item) - return ++parentItem.lastIndexOf; - if (parentItem.items[parentItem.lastIndexOf - 1] == item) - return --parentItem.lastIndexOf; - } - if (parentItem.lastIndexOf < itemCount / 2) { - for (int i = 0; i < itemCount; i++) { - if (parentItem.items[i] == item) - return parentItem.lastIndexOf = i; - } - } else { - for (int i = itemCount - 1; i >= 0; --i) { - if (parentItem.items[i] == item) - return parentItem.lastIndexOf = i; - } - } - return -1; - } - - public GalleryItem[] getItems() { - checkWidget(); - if (items == null) - return new GalleryItem[0]; - - GalleryItem[] itemsLocal = new GalleryItem[this.items.length]; - System.arraycopy(items, 0, itemsLocal, 0, this.items.length); - - return itemsLocal; - } - - /** - * @see Gallery#setUseControlColors(boolean) - * @return true if Gallery uses parent colors. - */ - public boolean isUseControlColors() { - return useControlColors; - } - - /** - * Set useControlColors to true in order to get colors from parent Control - * (SWT default). This may generate more objects on painting and slightly - * slow down the application. See Bug 279822 : - * https://bugs.eclipse.org/bugs/show_bug.cgi?id=279822 - * - * If enabled, you'll get new Color objects each time you call getXXXColor() - * on Gallery or GalleryItem. - * - * Default is false : colors are stored locally in Gallery, and you'll get - * the same object each time you call getXXXColor() on Gallery - * orGalleryItem. The Gallery may not catch color changes on parent control. - * - * @param useControlColors - */ - public void setUseControlColors(boolean useControlColors) { - this.useControlColors = useControlColors; - } - - /** - * @see org.eclipse.swt.widgets.Control#getBackground() - */ - public Color getBackground() { - return getBackground(false); - } - - /** - * Returns the receiver's background color. - * - * @param galleryOnly - * If TRUE, does not try to parent widget or Display defaults to - * guess the real background color. Note : FALSE is the default - * behavior. - * - * @return The background color or null if galleryOnly was used and the - * gallery has not foreground color set. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - */ - public Color getBackground(boolean galleryOnly) { - if (galleryOnly) { - return this.backgroundColor; - } - - if (useControlColors) { - return super.getBackground(); - } - - return backgroundColor != null ? backgroundColor - : getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); - } - - /** - * @see org.eclipse.swt.widgets.Control#getForeground() - */ - public Color getForeground() { - return getForeground(false); - } - - /** - * Returns the receiver's foreground color. - * - * @param galleryOnly - * If TRUE, does not try to parent widget or Display defaults to - * guess the real foreground color. Note : FALSE is the default - * behavior. - * - * @return The foreground color or null if galleryOnly was used and the - * gallery has not foreground color set. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - */ - public Color getForeground(boolean galleryOnly) { - - if (galleryOnly) { - return this.foregroundColor; - } - - if (useControlColors) { - return super.getForeground(); - } - - return foregroundColor != null ? foregroundColor - : getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND); - } - - /** - * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics - * .Color) - */ - public void setBackground(Color color) { - // Cache color locally - if (!useControlColors) { - this.backgroundColor = color; - } - - // Always call Control#setBackground(); Additionally, this will trigger - // a redraw. - super.setBackground(color); - } - - /** - * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics - * .Color) - */ - public void setForeground(Color color) { - // Cache color locally - if (!useControlColors) { - this.foregroundColor = color; - } - - // Always call Control#setForeground(); Additionally, this will trigger - // a redraw. - super.setForeground(color); - } - - /** - * Checks if the Gallery was created with SWT.V_SCROLL (ie has a vertical - * scroll bar). - * - * @return true if the gallery has the SWT.V_SCROLL style. - */ - public boolean isVertical() { - checkWidget(); - return vertical; - } - - /** - * @deprecated - * @param vertical - */ - public void setVertical(boolean vertical) { - checkWidget(); - this.vertical = vertical; - this.updateStructuralValues(null, true); - redraw(); - } - - public AbstractGalleryGroupRenderer getGroupRenderer() { - return groupRenderer; - } - - public void setGroupRenderer(AbstractGalleryGroupRenderer groupRenderer) { - this.groupRenderer = groupRenderer; - - if (this.groupRenderer != null) { - this.groupRenderer.setGallery(this); - } - - this.updateStructuralValues(null, true); - this.updateScrollBarsProperties(); - this.redraw(); - } - - public GalleryItem[] getSelection() { - if (selection == null) { - return new GalleryItem[0]; - } - - return selection; - } - - public int getSelectionCount() { - if (selection == null) - return 0; - - return selection.length; - } - - /** - * Selects all of the items in the receiver. - */ - public void selectAll() { - checkWidget(); - _selectAll(); - redraw(); - } - - protected void _selectAll() { - select(0, this.getItemCount() - 1); - } - - public void setSelection(GalleryItem[] items) { - checkWidget(); - _deselectAll(false); - for (int i = 0; i < items.length; i++) { - this.setSelected(items[i], true, false); - - // Ensure item is visible - _showItem(items[i]); - - // Simulate mouse click to enable keyboard navigation - lastSingleClick = items[i]; - } - redraw(); - } - - public void removeAll() { - checkWidget(); - - if (items != null) { - // Clear items - - GalleryItem[] tmpArray = new GalleryItem[items.length]; - System.arraycopy(items, 0, tmpArray, 0, items.length); - - for (int i = 0; i < tmpArray.length; i++) { - - // Dispose items if not virtual - // if (!virtual) { - if (tmpArray[i] != null) { - tmpArray[i]._dispose(); - } - // } - } - } - } - - public void remove(int index) { - checkWidget(); - _remove(index); - - updateStructuralValues(null, false); - updateScrollBarsProperties(); - redraw(); - } - - public void remove(GalleryItem item) { - if (item.getParentItem() == null) { - remove(indexOf(item)); - } else { - item.getParentItem().remove(item); - } - } - - protected void _remove(int index) { - if (isSelected(items[index])) { - setSelected(items[index], false, false); - } - - this.items = (GalleryItem[]) this._arrayRemoveItem(this.items, index); - } - - protected void _remove(GalleryItem parent, int index) { - if (isSelected(parent.items[index])) { - setSelected(parent.items[index], false, false); - } - - parent.items = (GalleryItem[]) this._arrayRemoveItem(parent.items, - index); - } - - protected Object[] _arrayRemoveItem(Object[] array, int index) { - - if (array == null) - return null; - - if (array.length == 1 && index == 0) - return null; - - Object[] newArray = (Object[]) Array.newInstance( - array.getClass().getComponentType(), array.length - 1); - - if (index > 0) - System.arraycopy(array, 0, newArray, 0, index); - - if (index + 1 < array.length) - System.arraycopy(array, index + 1, newArray, index, - newArray.length - index); - - return newArray; - } - - /** - * Adds an item to an array. - * - * @param array - * @param object - * @param index - * : if index == -1, item is added at the end of the array. - * @return - */ - protected Object[] _arrayAddItem(Object[] array, Object object, int index) { - - // Get current array length - int length = 0; - if (array != null) - length = array.length; - - // Create new array - Object[] newArray = (Object[]) Array.newInstance(object.getClass(), - length + 1); - - if (array != null) - System.arraycopy(array, 0, newArray, 0, length); - - if (index != -1) { - // Move all items - for (int i = newArray.length - 2; i >= index; i--) { - if (i >= 0) { - newArray[i + 1] = newArray[i]; - } - } - - // Insert item at index - newArray[index] = object; - - } else { - // Insert item at the end - newArray[newArray.length - 1] = object; - } - - return newArray; - } - - protected int _arrayIndexOf(int[] array, int value) { - if (array == null) - return -1; - - for (int i = array.length - 1; i >= 0; --i) { - if (array[i] == value) { - return i; - - } - } - return -1; - } - - protected int _arrayIndexOf(Object[] array, Object value) { - if (array == null) - return -1; - - for (int i = array.length - 1; i >= 0; --i) { - if (array[i] == value) { - return i; - - } - } - return -1; - } - - protected int[] _arrayRemoveItem(int[] array, int index) { - - if (array == null) - return null; - - if (array.length == 1 && index == 0) - return null; - - int[] newArray = new int[array.length - 1]; - - if (index > 0) - System.arraycopy(array, 0, newArray, 0, index); - - if (index + 1 < array.length) - System.arraycopy(array, index + 1, newArray, index, - newArray.length - index); - - return newArray; - } - - public void _setGalleryItems(GalleryItem[] items) { - this.items = items; - } - - /** - * @see #setVirtualGroups(boolean) - * - * @return - */ - public boolean isVirtualGroups() { - return virtualGroups; - } - - /** - * Enable virtual groups - * - *

- * When a gallery has the SWT.VIRTUAL flag, only items are initialized on - * display. All groups need to be initialized from the beginning to - * calculate the total size of the content. - *

- * - *

- * Virtual groups enable creating groups AND items lazily at the cost of a - * poor approximation of the total size of the content. - *

- * - *

- * While a group isn't initialized, the item count defined as default item - * count is used. - *

- * - *

- * When a group comes into view, it is initialized using the setData event, - * and the size of the gallery content is updated to match the real value. - *

- * - *

- * From the developer point of view, virtual groups uses exactly the same - * code as the standard virtual mode of SWT. - *

- * - *

- * This mode can create visual glitches with code that automatically scrolls - * the widget such as SAT Smooth Scrolling. In that case, you can enable the - * compatibility mode which is little less lazy that the default virtual - * groups, but still better than the standard virtual mode - *

- * - * @see #setVirtualGroupDefaultItemCount(int) - * @see #setVirtualGroupsCompatibilityMode(boolean) - * - * @param virtualGroups - */ - public void setVirtualGroups(boolean virtualGroups) { - this.virtualGroups = virtualGroups; - } - - /** - * @see #setVirtualGroupDefaultItemCount(int) - * @return - */ - public int getVirtualGroupDefaultItemCount() { - return virtualGroupDefaultItemCount; - } - - /** - * @see #setVirtualGroupsCompatibilityMode(boolean) - * @return - */ - public boolean isVirtualGroupsCompatibilityMode() { - return virtualGroupsCompatibilityMode; - } - - /** - * Enable the compatibility workaround for problems with the ultra virtual - * mode. - * - * @see #setVirtualGroups(boolean) - * @param compatibilityMode - */ - public void setVirtualGroupsCompatibilityMode(boolean compatibilityMode) { - this.virtualGroupsCompatibilityMode = compatibilityMode; - } - - /** - * Set the item count used when a group is not yet initialized (with virtual - * groups). Since the virtual groups make the size of the gallery change - * while scrolling, a fine tuned item count can improve the accuracy of the - * slider. - * - * @see #setVirtualGroups(boolean) - * - * @param defaultItemCount - */ - public void setVirtualGroupDefaultItemCount(int defaultItemCount) { - this.virtualGroupDefaultItemCount = defaultItemCount; - } -} +/******************************************************************************* + * Copyright (c) 2006-2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + * Tom Schindl (tom.schindl@bestsolution.at) - fix for bug 174933 + *******************************************************************************/ + +package org.eclipse.nebula.widgets.gallery; + +import java.lang.reflect.Array; +import java.util.ArrayList; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TreeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.TypedListener; + +/** + *

+ * SWT Widget that displays an image gallery
+ * see http://www.eclipse.org/nebula/widgets/gallery/gallery.php
+ * This widget requires jdk-1.8+ + *

+ *

+ * Style VIRTUAL is used to create a Gallery whose + * GalleryItems are to be populated by the client on an on-demand + * basis instead of up-front. This can provide significant performance + * improvements for galleries that are very large or for which + * GalleryItem population is expensive (for example, retrieving + * values from an external source). + *

+ *

+ * Here is an example of using a Gallery with style + * VIRTUAL:

+ * final Gallery gallery = new Gallery(parent, SWT.VIRTUAL | V_SCROLL | SWT.BORDER);
+ * gallery.setGroupRenderer(new DefaultGalleryGroupRenderer());
+ * gallery.setItemRenderer(new DefaultGalleryItemRenderer());
+ * gallery.setItemCount(1000000);
+ * gallery.addListener(SWT.SetData, new Listener() {
+ * 	public void handleEvent(Event event) {
+ * 		GalleryItem item = (GalleryItem) event.item;
+ * 		int index = gallery.indexOf(item);
+ * 		item.setText("Item " + index);
+ * 		System.out.println(item.getText());
+ * 	}
+ * });
+ * 
+ *

+ *

+ *

+ *
Styles:
+ *
SINGLE, MULTI, VIRTUAL, V_SCROLL, H_SCROLL
+ *
+ *

+ *

+ * Note: Only one of the styles SINGLE and MULTI may be specified. + *

+ *

+ * Note: Only one of the styles V_SCROLL and H_SCROLL may be specified. + *

+ *

+ *

+ *
Events:
+ *
Selection, DefaultSelection, SetData, PaintItem
+ *
+ *

+ *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. + *

+ * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + * @contributor Peter Centgraf (bugs 212071, 212073) + * @contributor Robert Handschmann (bug 215817) + * @contributor Berthold Daum (bug 306144 - selection tuning) + */ + +public class Gallery extends Canvas { + + private static final String BUG_PLATFORM_LINUX_GTK_174932 = "gtk"; //$NON-NLS-1$ + + /** + * Used to enable debug logging in the Gallery widget. + */ + protected static boolean DEBUG = false; + + GalleryItem[] items = null; + + private GalleryItem[] selection = null; + + /** + * Selection bit flags. Each 'int' contains flags for 32 items. + */ + protected int[] selectionFlags = null; + + /** + * Virtual mode flag. + */ + boolean virtual = false; + + /** + * Ultra virtual : non visible groups are not initialized. + */ + boolean virtualGroups = false; + boolean virtualGroupsCompatibilityMode = false; + int virtualGroupDefaultItemCount = 10; + + /** + * Scrolling direction flag. True : V_SCROLL, false : H_SCROLL. + */ + boolean vertical = true; + + /** + * Multi-selection flag + */ + boolean multi = false; + + /** + * Image quality : interpolation + */ + int interpolation = SWT.HIGH; + + /** + * Image quality : antialias + */ + int antialias = SWT.ON; + + // Internals + + private int gHeight = 0; + + private int gWidth = 0; + + int lastIndexOf = 0; + + /** + * Keeps track of the last selected item. This is necessary to support + * "Shift+Mouse button" where we have to select all items between the + * previous and the current item and keyboard navigation. + */ + protected GalleryItem lastSingleClick = null; + + /** + * Current translation (scroll bar position). Can be used by renderer during + * paint. + */ + protected int translate = 0; + + /** + * Low quality on user action : decrease drawing quality on scrolling or + * resize. (faster) + */ + boolean lowQualityOnUserAction = false; + protected int lastTranslateValue = 0; + protected int lastControlWidth = 0; + protected int lastControlHeight = 0; + protected int lastContentHeight = 0; + protected int lastContentWidth = 0; + protected int higherQualityDelay = 500; + + /** + * Keep track of processing the current mouse event. + */ + private boolean mouseClickHandled = false; + + /** + * Background color, if Control#getBackground() is not used. + * + * @see Gallery#useControlColors + */ + private Color backgroundColor; + + /** + * Foreground color, if Control#getForeground() is not used. + * + * @see Gallery#useControlColors + */ + private Color foregroundColor; + + /** + * If set to true, the gallery will get colors from parent Control. This may + * generate more objects and slightly slow down the application. See Bug + * 279822 : https://bugs.eclipse.org/bugs/show_bug.cgi?id=279822 + */ + private boolean useControlColors = false; + + AbstractGalleryItemRenderer itemRenderer; + + AbstractGalleryGroupRenderer groupRenderer; + + /** + * Return the number of root-level items in the receiver. Does not include + * children. + * + * @return + */ + public int getItemCount() { + checkWidget(); + + if (items == null) + return 0; + + return items.length; + } + + /** + * Sets the number of root-level items contained in the receiver. Only work + * in VIRTUAL mode. + * + * @return + */ + public void setItemCount(int count) { + checkWidget(); + + if (DEBUG) + System.out.println("setCount" + count); //$NON-NLS-1$ + + if (count == 0) { + // No items + items = null; + } else { + // At least one item, create a new array and copy data from the + // old one. + GalleryItem[] newItems = new GalleryItem[count]; + if (items != null) { + System.arraycopy(items, 0, newItems, 0, + Math.min(count, items.length)); + } + items = newItems; + } + + updateStructuralValues(null, false); + this.updateScrollBarsProperties(); + redraw(); + + } + + /** + * Get current item renderer + * + * @return + */ + public AbstractGalleryItemRenderer getItemRenderer() { + checkWidget(); + return itemRenderer; + } + + /** + * Set item receiver. Usually, this does not trigger gallery update. redraw + * must be called right after setGroupRenderer to reflect this change. + * + * @param itemRenderer + */ + public void setItemRenderer(AbstractGalleryItemRenderer itemRenderer) { + checkWidget(); + this.itemRenderer = itemRenderer; + + if (this.itemRenderer != null) + this.itemRenderer.setGallery(this); + + redraw(); + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the receiver's selection changes, by sending it one of the messages + * defined in the SelectionListener interface. + *

+ * When widgetSelected is called, the item field of the event + * object is valid. + *

+ * + * @param listener + * the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(SelectionListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + + TypedListener typedListener = new TypedListener(listener); + addListener(SWT.Selection, typedListener); + addListener(SWT.DefaultSelection, typedListener); + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the receiver's selection changes. + * + * @param listener + * the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener(SelectionListener) + */ + public void removeSelectionListener(SelectionListener listener) { + checkWidget(); + removeListener(SWT.Selection, listener); + removeListener(SWT.DefaultSelection, listener); + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when items in the receiver are expanded or collapsed. + * + * @param listener + */ + public void removeTreeListener(SelectionListener listener) { + checkWidget(); + removeListener(SWT.Expand, listener); + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when an item in the receiver is expanded or collapsed by sending it one + * of the messages defined in the TreeListener interface. + * + * @param listener + */ + public void addTreeListener(TreeListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + addListener(SWT.Expand, new TypedListener(listener)); + } + + /** + * Send SWT.PaintItem for one item. + * + * @param item + * @param index + * @param gc + * @param x + * @param y + */ + protected void sendPaintItemEvent(Item item, int index, GC gc, int x, int y, + int width, int height) { + + Event e = new Event(); + e.item = item; + e.type = SWT.PaintItem; + e.index = index; + // TODO: Does clipping need to be set ? + // gc.setClipping(x, y, width, height); + e.gc = gc; + e.x = x; + e.y = y; + e.width = width; + e.height = height; + this.notifyListeners(SWT.PaintItem, e); + } + + /** + * #see {@link #setLowQualityOnUserAction(boolean)} + * + * @return + */ + public boolean isLowQualityOnUserAction() { + return lowQualityOnUserAction; + } + + /** + * If set to true, the gallery will disable antialiasing and interpolation + * while the user is resizing or scrolling the gallery. This enables faster + * redraws at the cost of lower image quality. When every redraw is finished + * a last one will be issued using the default (higher) quality. + * + * @see #setHigherQualityDelay(int) + * @param lowQualityOnUserAction + */ + public void setLowQualityOnUserAction(boolean lowQualityOnUserAction) { + this.lowQualityOnUserAction = lowQualityOnUserAction; + } + + /** + * @see #setHigherQualityDelay(int) + * @return + */ + public int getHigherQualityDelay() { + return higherQualityDelay; + } + + /** + * Set the delay after the last user action before the redraw at higher + * quality is triggered + * + * @see #setLowQualityOnUserAction(boolean) + * @param higherQualityDelay + */ + public void setHigherQualityDelay(int higherQualityDelay) { + this.higherQualityDelay = higherQualityDelay; + } + + /** + * @see #setInterpolation(int) + * @return + */ + public int getInterpolation() { + return interpolation; + } + + /** + * Sets the gallery's interpolation setting to the parameter, which must be + * one of SWT.DEFAULT, SWT.NONE, + * SWT.LOW or SWT.HIGH. + * + * @param interpolation + */ + public void setInterpolation(int interpolation) { + this.interpolation = interpolation; + } + + /** + * @see #setAntialias(int) + * @return + */ + public int getAntialias() { + return antialias; + } + + /** + * + * Sets the gallery's anti-aliasing value to the parameter, which must be + * one of SWT.DEFAULT, SWT.OFF or + * SWT.ON. + * + * @param antialias + */ + public void setAntialias(int antialias) { + this.antialias = antialias; + } + + /** + * Send a selection event for a gallery item + * + * @param item + */ + protected void notifySelectionListeners(GalleryItem item, int index, + boolean isDefault) { + + Event e = new Event(); + e.widget = this; + e.item = item; + if (item != null) { + e.data = item.getData(); + } + // TODO: report index + // e.index = index; + try { + if (isDefault) { + notifyListeners(SWT.DefaultSelection, e); + } else { + notifyListeners(SWT.Selection, e); + } + } catch (RuntimeException ex) { + ex.printStackTrace(); + } + } + + /** + * Send an Expand event for a GalleryItem + * + * @param item + * @param index + */ + protected void notifyTreeListeners(GalleryItem item, boolean state) { + + Event e = new Event(); + e.widget = this; + e.item = item; + if (item != null) { + e.data = item.getData(); + } + // TODO: report index + // e.index = index; + try { + notifyListeners(SWT.Expand, e); + } catch (RuntimeException ex) { + ex.printStackTrace(); + } + } + + /** + * Create a Gallery + * + * + * @param parent + * @param style + * - SWT.VIRTUAL switches in virtual mode.
+ * SWT.V_SCROLL add vertical slider and switches to vertical + * mode.
+ * SWT.H_SCROLL add horizontal slider and switches to horizontal + * mode.
+ * if both V_SCROLL and H_SCROLL are specified, the gallery is in + * vertical mode by default. Mode can be changed afterward using + * setVertical
+ * SWT.MULTI allows only several items to be selected at the same + * time. + */ + public Gallery(Composite parent, int style) { + super(parent, style | SWT.DOUBLE_BUFFERED); + virtual = (style & SWT.VIRTUAL) > 0; + vertical = (style & SWT.V_SCROLL) > 0; + multi = (style & SWT.MULTI) > 0; + setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND)); + + // Add listeners : redraws, mouse and keyboard + _addDisposeListeners(); + _addResizeListeners(); + _addPaintListeners(); + _addScrollBarsListeners(); + _addMouseListeners(); + _addKeyListeners(); + + // Set defaults + _setDefaultRenderers(); + + // Layout + updateStructuralValues(null, false); + updateScrollBarsProperties(); + redraw(); + } + + private void _setDefaultRenderers() { + // Group renderer + DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer(); + gr.setMinMargin(2); + gr.setItemHeight(56); + gr.setItemWidth(72); + gr.setAutoMargin(true); + gr.setGallery(this); + this.groupRenderer = gr; + + // Item renderer + this.itemRenderer = new DefaultGalleryItemRenderer(); + itemRenderer.setGallery(this); + } + + /** + * Add internal dispose listeners to this gallery. + */ + private void _addDisposeListeners() { + this.addListener(SWT.Dispose, event -> onDispose()); + } + + /** + * Add internal paint listeners to this gallery. + */ + private void _addPaintListeners() { + addListener(SWT.Paint, event -> onPaint(event.gc)); + } + + /** + * Add internal resize listeners to this gallery. + */ + private void _addResizeListeners() { + addListener(SWT.Resize, event -> { + updateStructuralValues(null, true); + updateScrollBarsProperties(); + redraw(); + }); + } + + /** + * Add internal scrollbars listeners to this gallery. + */ + private void _addScrollBarsListeners() { + // Vertical bar + ScrollBar verticalBar = getVerticalBar(); + if (verticalBar != null) { + verticalBar.addListener(SWT.Selection, event -> { + if (vertical) + scrollVertical(); + }); + } + + // Horizontal bar + + ScrollBar horizontalBar = getHorizontalBar(); + if (horizontalBar != null) { + horizontalBar.addListener(SWT.Selection, event -> { + if (!vertical) + scrollHorizontal(); + }); + } + + } + + private void _addKeyListeners() { + this.addListener(SWT.KeyDown, e -> { + switch (e.keyCode) { + case SWT.ARROW_LEFT: + case SWT.ARROW_RIGHT: + case SWT.ARROW_UP: + case SWT.ARROW_DOWN: + case SWT.PAGE_UP: + case SWT.PAGE_DOWN: + case SWT.HOME: + case SWT.END: + GalleryItem newItem = groupRenderer.getNextItem(lastSingleClick, + e.keyCode); + + if (newItem != null) { + _deselectAll(false); + setSelected(newItem, true, true); + lastSingleClick = newItem; + _showItem(newItem); + redraw(); + } + + break; + case SWT.CR: + GalleryItem[] selection = getSelection(); + GalleryItem item = null; + if (selection != null && selection.length > 0) { + item = selection[0]; + } + + notifySelectionListeners(item, 0, true); + break; + } + }); + } + + /** + * Scroll the Gallery in order to make 'item' visible. + * + * @param item + * Item to show + */ + public void showItem(GalleryItem item) { + this.checkWidget(); + this._showItem(item); + } + + void _showItem(GalleryItem item) { + int y; + int height; + Rectangle rect = groupRenderer.getSize(item); + if (rect == null) { + return; + } + + if (vertical) { + y = rect.y; + height = rect.height; + if (y < translate) { + translate = y; + } else if (translate + this.getClientArea().height < y + height) { + translate = y + height - this.getClientArea().height; + } + + } else { + y = rect.x; + height = rect.width; + + if (y < translate) { + translate = y; + } else if (translate + this.getClientArea().width < y + height) { + translate = y + height - this.getClientArea().width; + } + } + + this.updateScrollBarsProperties(); + redraw(); + + } + + /** + * Add internal mouse listeners to this gallery. + */ + private void _addMouseListeners() { + addListener(SWT.MouseDoubleClick, event -> onMouseDoubleClick(event)); + addListener(SWT.MouseDown, event -> onMouseDown(event)); + addListener(SWT.MouseUp, event -> onMouseUp(event)); + } + + private void select(int from, int to) { + for (int i = from; i <= to; i++) { + GalleryItem item = getItem(i); + this._addSelection(item); + item._selectAll(); + + } + } + + private void select(GalleryItem from, GalleryItem to) { + GalleryItem fromParent = from.getParentItem(); + GalleryItem toParent = to.getParentItem(); + + if (fromParent == toParent) { + + if (fromParent == null) { + int fromIndex = indexOf(from); + int toIndex = indexOf(to); + select(fromIndex, toIndex); + } else { + int fromIndex = fromParent.indexOf(from); + int toIndex = toParent.indexOf(to); + fromParent.select(fromIndex, toIndex); + } + } else { + int fromParentIndex = indexOf(fromParent); + int toParentIndex = indexOf(toParent); + int fromIndex = fromParent.indexOf(from); + int toIndex = toParent.indexOf(to); + + fromParent.select(fromIndex, fromParent.getItemCount() - 1); + for (int i = fromParentIndex + 1; i < toParentIndex; i++) { + getItem(i)._selectAll(); + } + toParent.select(0, toIndex); + + } + this.notifySelectionListeners(to, indexOf(to), false); + redraw(); + } + + private boolean getOrder(GalleryItem before, GalleryItem after) { + + if (before == null || after == null) + return true; + + GalleryItem newParent = before.getParentItem(); + GalleryItem oldParent = after.getParentItem(); + + int beforeParentIndex = indexOf(newParent); + int afterParentIndex = indexOf(oldParent); + + if (newParent == oldParent) { + int newParentIndex; + int oldParentIndex; + if (newParent == null) { + newParentIndex = indexOf(before); + oldParentIndex = indexOf(after); + + } else { + newParentIndex = newParent.indexOf(before); + oldParentIndex = newParent.indexOf(after); + } + return (newParentIndex < oldParentIndex); + } + + return beforeParentIndex < afterParentIndex; + } + + /** + * Toggle item selection status + * + * @param item + * Item which state is to be changed. + * @param selected + * true is the item is now selected, false if it is now + * unselected. + * @param notifyListeners + * If true, a selection event will be sent to all the current + * selection listeners. + * + */ + protected void setSelected(GalleryItem item, boolean selected, + boolean notifyListeners) { + if (selected) { + if (!isSelected(item)) { + _addSelection(item); + + } + + } else { + if (isSelected(item)) { + _removeSelection(item); + } + } + + // Notify listeners if necessary. + if (notifyListeners) { + + GalleryItem notifiedItem = null; + + if (item != null && selected) { + notifiedItem = item; + } else { + if (selection != null && selection.length > 0) { + notifiedItem = selection[selection.length - 1]; + } + } + + int index = -1; + if (notifiedItem != null) { + index = indexOf(notifiedItem); + } + + notifySelectionListeners(notifiedItem, index, false); + } + + } + + protected void _addSelection(GalleryItem item) { + + if (item == null) + return; + + if (this.isSelected(item)) + return; + + // Deselect all items is multi selection is disabled + if (!multi) { + _deselectAll(false); + } + + if (item.getParentItem() != null) { + item.getParentItem()._addSelection(item); + } else { + int index = indexOf(item); + + // Divide position by 32 to get selection bloc for this item. + int n = index >> 5; + if (selectionFlags == null) { + // Create selectionFlag array + // Add 31 before dividing by 32 to ensure at least one 'int' is + // created if size < 32. + selectionFlags = new int[(items.length + 31) >> 5]; + } else if (n >= selectionFlags.length) { + // Expand selectionArray + int[] oldFlags = selectionFlags; + selectionFlags = new int[n + 1]; + System.arraycopy(oldFlags, 0, selectionFlags, 0, + oldFlags.length); + } + + // Get flag position in the 32 bit block and ensure is selected. + selectionFlags[n] |= 1 << (index & 0x1f); + + } + + if (selection == null) { + selection = new GalleryItem[1]; + } else { + GalleryItem[] oldSelection = selection; + selection = new GalleryItem[oldSelection.length + 1]; + System.arraycopy(oldSelection, 0, selection, 0, + oldSelection.length); + } + selection[selection.length - 1] = item; + + } + + private void _removeSelection(GalleryItem item) { + + if (item.getParentItem() == null) { + int index = _indexOf(item); + selectionFlags[index >> 5] &= ~(1 << (index & 0x1f)); + } else + _removeSelection(item.getParentItem(), item); + + int index = _arrayIndexOf(selection, item); + if (index == -1) + return; + + selection = (GalleryItem[]) _arrayRemoveItem(selection, index); + + } + + protected void _removeSelection(GalleryItem parent, GalleryItem item) { + int index = _indexOf(parent, item); + parent.selectionFlags[index >> 5] &= ~(1 << (index & 0x1f)); + } + + protected boolean isSelected(GalleryItem item) { + + if (item == null) + return false; + + if (item.getParentItem() != null) { + return item.getParentItem().isSelected(item); + } + + if (selectionFlags == null) + return false; + + int index = indexOf(item); + int n = index >> 5; + if (n >= selectionFlags.length) + return false; + int flags = selectionFlags[n]; + return flags != 0 && (flags & 1 << (index & 0x1f)) != 0; + + } + + /** + * Deselects all items. + */ + public void deselectAll() { + checkWidget(); + _deselectAll(false); + + redraw(); + } + + /** + * Deselects all items and send selection event depending on parameter. + * + * @param notifyListeners + * If true, a selection event will be sent to all the current + * selection listeners. + */ + protected void _deselectAll(boolean notifyListeners) { + + if (DEBUG) + System.out.println("clear"); //$NON-NLS-1$ + + this.selection = null; + // Deselect groups + // We could set selectionFlags to null, but we rather set all values to + // 0 to redure garbage collection. On each iteration, we deselect 32 + // items. + if (selectionFlags != null) + for (int i = 0; i < selectionFlags.length; i++) + selectionFlags[i] = 0; + + if (items == null) + return; + for (int i = 0; i < items.length; i++) { + if (items[i] != null) + items[i]._deselectAll(); + } + + // Notify listeners if necessary. + if (notifyListeners) + notifySelectionListeners(null, -1, false); + } + + void onMouseDoubleClick(Event e) { + if (DEBUG) + System.out.println("Mouse Double Click"); //$NON-NLS-1$ + + GalleryItem item = getItem(new Point(e.x, e.y)); + if (item != null) { + notifySelectionListeners(item, 0, true); + } + mouseClickHandled = true; + } + + void onMouseUp(Event e) { + if (DEBUG) + System.out.println("onMouseUp"); //$NON-NLS-1$ + + if (mouseClickHandled) { + if (DEBUG) { + System.out.println("onMouseUp : mouse event already handled"); //$NON-NLS-1$ + } + return; + } + + if (e.button == 1) { + GalleryItem item = getItem(new Point(e.x, e.y)); + if (item == null) + return; + + if ((e.stateMask & SWT.MOD1) > 0) { + onMouseHandleLeftMod1(e, item, false, true); + } else if ((e.stateMask & SWT.SHIFT) > 0) { + onMouseHandleLeftShift(e, item, false, true); + } else { + onMouseHandleLeft(e, item, false, true); + } + } + } + + /** + * Clean up the Gallery and renderers on dispose. + */ + void onDispose() { + // Remove items if not Virtual. + if (!virtual) + removeAll(); + + // Dispose renderers + if (itemRenderer != null) + itemRenderer.dispose(); + + if (groupRenderer != null) + groupRenderer.dispose(); + + } + + void onMouseDown(Event e) { + if (DEBUG) + System.out.println("Mouse down "); //$NON-NLS-1$ + + mouseClickHandled = false; + + if (!_mouseDown(e)) { + // Stop handling as requested by the group renderer + mouseClickHandled = true; + return; + } + + GalleryItem item = getItem(new Point(e.x, e.y)); + + if (e.button == 1) { + + if (item == null) { + _deselectAll(true); + redraw(); + mouseClickHandled = true; + lastSingleClick = null; + } else { + if ((e.stateMask & SWT.MOD1) > 0) { + onMouseHandleLeftMod1(e, item, true, false); + } else if ((e.stateMask & SWT.SHIFT) > 0) { + onMouseHandleLeftShift(e, item, true, false); + } else { + onMouseHandleLeft(e, item, true, false); + } + } + } else if (e.button == 3) { + onMouseHandleRight(e, item, true, false); + } + } + + private void onMouseHandleLeftMod1(Event e, GalleryItem item, boolean down, + boolean up) { + if (up) { + // if (lastSingleClick != null) { + if (item != null) { + if (DEBUG) + System.out.println("setSelected : inverse"); //$NON-NLS-1$ + setSelected(item, !isSelected(item), true); + lastSingleClick = item; + redraw(); + } + // } + } + } + + private void onMouseHandleLeftShift(Event e, GalleryItem item, boolean down, + boolean up) { + if (up) { + if (lastSingleClick != null) { + _deselectAll(false); + + if (getOrder(item, lastSingleClick)) + select(item, lastSingleClick); + else + select(lastSingleClick, item); + } + } + } + + void onMouseHandleLeft(Event e, GalleryItem item, boolean down, + boolean up) { + if (down) { + if (!isSelected(item)) { + _deselectAll(false); + + if (DEBUG) + System.out.println("setSelected"); //$NON-NLS-1$ + setSelected(item, true, true); + + lastSingleClick = item; + redraw(); + mouseClickHandled = true; + } + } else if (up) { + if (item == null) { + _deselectAll(true); + } else { + if (DEBUG) + System.out.println("setSelected"); //$NON-NLS-1$ + + _deselectAll(false); + setSelected(item, true, lastSingleClick != item); + lastSingleClick = item; + } + redraw(); + } + } + + /** + * Handle right click. + * + * @param e + * @param item + * : The item which is under the cursor or null + * @param down + * @param up + */ + void onMouseHandleRight(Event e, GalleryItem item, boolean down, + boolean up) { + if (down) { + if (DEBUG) + System.out.println("right click"); //$NON-NLS-1$ + + if (item != null && !isSelected(item)) { + _deselectAll(false); + setSelected(item, true, true); + redraw(); + mouseClickHandled = true; + } + } + + } + + void onPaint(GC gc) { + if (DEBUG) + System.out.println("paint"); //$NON-NLS-1$ + + boolean lowQualityPaint = lowQualityOnUserAction + && (translate != lastTranslateValue + || (lastControlWidth != getSize().x + || lastControlHeight != getSize().y + || lastContentHeight != this.gHeight + || lastContentWidth != this.gWidth)); + try { + // Linux-GTK Bug 174932 + if (!SWT.getPlatform().equals(BUG_PLATFORM_LINUX_GTK_174932)) { + gc.setAdvanced(true); + } + + if (gc.getAdvanced()) { + if (lowQualityPaint) { + gc.setAntialias(SWT.OFF); + gc.setInterpolation(SWT.OFF); + } else { + gc.setAntialias(antialias); + gc.setInterpolation(interpolation); + } + } + // End of Bug 174932 + + Rectangle clipping = gc.getClipping(); + + gc.setBackground(this.getBackground()); + drawBackground(gc, clipping.x, clipping.y, clipping.width, + clipping.height); + + int[] indexes = getVisibleItems(clipping); + + if (indexes != null && indexes.length > 0) { + + // Call preDraw for optimization + if (groupRenderer != null) + groupRenderer.preDraw(gc); + if (itemRenderer != null) + itemRenderer.preDraw(gc); + + for (int i = indexes.length - 1; i >= 0; i--) { + if (DEBUG) + System.out.println("Drawing group " + indexes[i]); //$NON-NLS-1$ + + _drawGroup(gc, indexes[i]); + } + + // Call postDraw for optimization / cleanup + if (groupRenderer != null) + groupRenderer.postDraw(gc); + if (itemRenderer != null) + itemRenderer.postDraw(gc); + } + } catch (Exception e) { + // We can't let onPaint throw an exception because unexpected + // results may occur in SWT. + e.printStackTrace(); + } + + // When lowQualityOnUserAction is enabled, keep last state and wait + // before updating with a higher quality + if (lowQualityOnUserAction) { + lastTranslateValue = translate; + lastControlWidth = getSize().x; + lastControlHeight = getSize().y; + lastContentHeight = gHeight; + lastContentWidth = gWidth; + + if (lowQualityPaint) { + // Calling timerExec with the same object just delays the + // execution (doesn't run twice) + Display.getCurrent().timerExec(higherQualityDelay, redrawTimer); + } + } + } + + Runnable redrawTimer = () -> { + if (!isDisposed()) { + redraw(); + } + }; + + private int[] getVisibleItems(Rectangle clipping) { + + if (items == null) + return null; + + int start = vertical ? (clipping.y + translate) + : (clipping.x + translate); + + int end = vertical ? (clipping.y + clipping.height + translate) + : (clipping.x + clipping.width + translate); + + ArrayList al = new ArrayList<>(); + int index = 0; + GalleryItem item = null; + while (index < items.length) { + if (virtualGroups) { + item = _getItem(index, false); + } else { + item = _getItem(index); + } + if ((vertical ? item.y : item.x) > end) + break; + + if ((vertical ? (item.y + item.height) + : (item.x + item.width)) >= start) + al.add(new Integer(index)); + + index++; + } + + int[] result = new int[al.size()]; + + for (int i = 0; i < al.size(); i++) + result[i] = ((Integer) al.get(i)).intValue(); + + return result; + } + + /** + * Refresh item by firering SWT.SetData. + *

+ * Currently not implemented. + *

+ * + * @param index + */ + public void refresh(int index) { + checkWidget(); + if (index < getItemCount()) { + // TODO: refresh + } + } + + /** + * Redraw the item given as parameter. + * + * @param item + */ + public void redraw(GalleryItem item) { + checkWidget(); + + // Redraw only the item's bounds + Rectangle bounds = item.getBounds(); + redraw(bounds.x, bounds.y, bounds.width, bounds.height, true); + } + + /** + * Handle the drawing of root items + * + * @param gc + * @param index + */ + private void _drawGroup(GC gc, int index) { + GalleryItem item = null; + + if (virtualGroups) { + // Ultra virtual : when a group is about to be drawn, initialize it + // and update gallery layout according to the new size + item = _getItem(index, false); + if (item.isUltraLazyDummy()) { + boolean updateLocation = (vertical && item.y < translate) + || (!vertical && item.x < translate); + int oldSize = item.height; + item = _getItem(index, true); + + // Compatibility mode : ensure all previous items are already + // initialized + if (virtualGroupsCompatibilityMode) { + for (int i = 0; i < index; i++) { + _getItem(i); + } + } + + updateStructuralValues(item, false); + + if (DEBUG) { + System.out.println("old" + oldSize + " new " + item.height //$NON-NLS-1$//$NON-NLS-2$ + + " translate " + translate); //$NON-NLS-1$ + } + + if (updateLocation) { + translate += (item.height - oldSize); + if (DEBUG) { + System.out.println("updated to : " + translate); //$NON-NLS-1$ + } + } + this.updateScrollBarsProperties(); + redraw(); + } + } else { + // Default behavior : get the item with no special handling. + item = getItem(index); + } + + if (item == null) + return; + + // update item attributes + this.groupRenderer.setExpanded(item.isExpanded()); + + // Drawing area + int x = this.vertical ? item.x : item.x - this.translate; + int y = this.vertical ? item.y - translate : item.y; + + Rectangle clipping = gc.getClipping(); + Rectangle previousClipping = new Rectangle(clipping.x, clipping.y, + clipping.width, clipping.height); + + clipping.intersect(new Rectangle(x, y, item.width, item.height)); + gc.setClipping(clipping); + // Draw group + this.groupRenderer.draw(gc, item, x, y, clipping.x, clipping.y, + clipping.width, clipping.height); + + gc.setClipping(previousClipping); + } + + /** + * If table is virtual and item at pos i has not been set, call the callback + * listener to set its value. + * + * @return + */ + private void updateItem(GalleryItem parentItem, int i, boolean create) { + if (virtual) { + + GalleryItem galleryItem; + if (parentItem == null) { + // Parent is the Gallery widget + galleryItem = items[i]; + + if (galleryItem == null || (virtualGroups + && galleryItem.isUltraLazyDummy() && create)) { + + if (DEBUG) { + System.out.println("Virtual/creating item "); //$NON-NLS-1$ + } + + galleryItem = new GalleryItem(this, SWT.NONE, i, false); + items[i] = galleryItem; + + if (virtualGroups && !create) { + galleryItem.setItemCount(virtualGroupDefaultItemCount); + galleryItem.setUltraLazyDummy(true); + galleryItem.setExpanded(true); + } else { + setData(galleryItem, i); + } + } + } else { + // Parent is another GalleryItem + galleryItem = parentItem.items[i]; + if (galleryItem == null) { + if (DEBUG) { + System.out.println("Virtual/creating item "); //$NON-NLS-1$ + } + + galleryItem = new GalleryItem(parentItem, SWT.NONE, i, + false); + parentItem.items[i] = galleryItem; + setData(galleryItem, i); + } + } + } + + } + + /** + * Sends SWT.SetData event. Used if SWT.VIRTUAL + * + * @param galleryItem + * @param index + */ + protected void setData(GalleryItem galleryItem, int index) { + Item item = galleryItem; + Event e = new Event(); + e.item = item; + e.type = SWT.SetData; + e.index = index; + this.notifyListeners(SWT.SetData, e); + } + + /** + * Recalculate structural values using the group renderer
+ * Gallery and item size will be updated. + * + * @param keepLocation + * if true, the current scrollbars position ratio is saved and + * restored even if the gallery size has changed. (Visible items + * stay visible) + * @deprecated Use {@link #updateStructuralValues(GalleryItem,boolean)} + * instead + */ + protected void updateStructuralValues(boolean keepLocation) { + updateStructuralValues(null, keepLocation); + } + + /** + * Recalculate structural values using the group renderer
+ * Gallery and item size will be updated. + * + * @param changedGroup + * the group that was modified since the last layout. If the + * group renderer or more that one group have changed, use null + * as parameter (full update) + * @param keepLocation + * if true, the current scrollbars position ratio is saved and + * restored even if the gallery size has changed. (Visible items + * stay visible) + */ + protected void updateStructuralValues(GalleryItem changedGroup, + boolean keepLocation) { + + if (DEBUG) { + System.out.println("Client Area : " + this.getClientArea().x + " " //$NON-NLS-1$//$NON-NLS-2$ + + this.getClientArea().y + " " + this.getClientArea().width //$NON-NLS-1$ + + " " + this.getClientArea().height); //$NON-NLS-1$ + } + + Rectangle area = this.getClientArea(); + float pos = 0; + + if (vertical) { + if (gHeight > 0 && keepLocation) + pos = (float) (translate + 0.5 * area.height) / gHeight; + + gWidth = area.width; + gHeight = calculateSize(changedGroup); + + if (keepLocation) + translate = (int) (gHeight * pos - 0.5 * area.height); + + } else { + if (gWidth > 0 && keepLocation) + pos = (float) (translate + 0.5 * area.width) / gWidth; + + gWidth = calculateSize(changedGroup); + gHeight = area.height; + + if (keepLocation) + translate = (int) (gWidth * pos - 0.5 * area.width); + } + + validateTranslation(); + + if (DEBUG) { + System.out.println("Content Size : " + gWidth + " " + gHeight); //$NON-NLS-1$//$NON-NLS-2$ + } + + } + + /** + * Calculate full height (or width) of the Gallery. The group renderer is + * used to calculate the size of each group. + * + * @return + */ + private int calculateSize(GalleryItem onlyUpdateGroup) { + + if (groupRenderer == null) + return 0; + + groupRenderer.preLayout(null); + + int currentHeight = 0; + + int mainItemCount = getItemCount(); + + for (int i = 0; i < mainItemCount; i++) { + GalleryItem item = null; + if (virtualGroups) { + item = this._getItem(i, false); + } else { + item = this._getItem(i); + } + + if (onlyUpdateGroup != null && !onlyUpdateGroup.equals(item)) { + // Item has not changed : no layout. + if (vertical) { + item.y = currentHeight; + item.x = getClientArea().x; + currentHeight += item.height; + } else { + item.y = getClientArea().y; + item.x = currentHeight; + currentHeight += item.width; + } + } else { + this.groupRenderer.setExpanded(item.isExpanded()); + // TODO: Not used ATM + // int groupItemCount = item.getItemCount(); + if (vertical) { + item.y = currentHeight; + item.x = getClientArea().x; + item.width = getClientArea().width; + item.height = -1; + this.groupRenderer.layout(null, item); + currentHeight += item.height; + } else { + item.y = getClientArea().y; + item.x = currentHeight; + item.width = -1; + item.height = getClientArea().height; + this.groupRenderer.layout(null, item); + currentHeight += item.width; + } + } + + } + + groupRenderer.postLayout(null); + + return currentHeight; + } + + /** + * Move the scrollbar to reflect the current visible items position.
+ * The bar which is moved depends of the current gallery scrolling : + * vertical or horizontal. + * + */ + protected void updateScrollBarsProperties() { + + if (vertical) { + updateScrollBarProperties(getVerticalBar(), getClientArea().height, + gHeight); + } else { + updateScrollBarProperties(getHorizontalBar(), getClientArea().width, + gWidth); + } + + } + + /** + * Move the scrollbar to reflect the current visible items position. + * + * @param bar + * - the scroll bar to move + * @param clientSize + * - Client (visible) area size + * @param totalSize + * - Total Size + */ + private void updateScrollBarProperties(ScrollBar bar, int clientSize, + int totalSize) { + if (bar == null) + return; + + bar.setMinimum(0); + bar.setPageIncrement(clientSize); + bar.setMaximum(totalSize); + bar.setThumb(clientSize); + + // Let the group renderer use a custom increment value. + if (groupRenderer != null) + bar.setIncrement(groupRenderer.getScrollBarIncrement()); + + if (totalSize > clientSize) { + if (DEBUG) + System.out.println("Enabling scrollbar"); //$NON-NLS-1$ + + bar.setEnabled(true); + bar.setVisible(true); + bar.setSelection(translate); + + // Ensure that translate has a valid value. + validateTranslation(); + } else { + if (DEBUG) + System.out.println("Disabling scrollbar"); //$NON-NLS-1$ + + bar.setEnabled(false); + bar.setVisible(false); + bar.setSelection(0); + translate = 0; + } + + } + + /** + * Check the current translation value. Must be > 0 and < gallery + * size.
+ * Invalid values are fixed. + */ + private void validateTranslation() { + Rectangle area = this.getClientArea(); + // Ensure that translate has a valid value. + int totalSize = 0; + int clientSize = 0; + + // Fix negative values + if (translate < 0) + translate = 0; + + // Get size depending on vertical setting. + if (vertical) { + totalSize = gHeight; + clientSize = area.height; + } else { + totalSize = gWidth; + clientSize = area.width; + } + + if (totalSize > clientSize) { + // Fix translate too big. + if (translate + clientSize > totalSize) { + translate = totalSize - clientSize; + } + } else { + translate = 0; + } + + } + + protected void scrollVertical() { + int areaHeight = getClientArea().height; + + if (gHeight > areaHeight) { + // image is higher than client area + ScrollBar bar = getVerticalBar(); + scroll(0, translate - bar.getSelection(), 0, 0, + getClientArea().width, areaHeight, false); + translate = bar.getSelection(); + } else { + translate = 0; + } + } + + protected void scrollHorizontal() { + + int areaWidth = getClientArea().width; + if (gWidth > areaWidth) { + // image is higher than client area + ScrollBar bar = getHorizontalBar(); + scroll(translate - bar.getSelection(), 0, 0, 0, areaWidth, + getClientArea().height, false); + translate = bar.getSelection(); + } else { + translate = 0; + } + + } + + protected void addItem(GalleryItem item, int position) { + if (position != -1 && (position < 0 || position > getItemCount())) { + throw new IllegalArgumentException("ERROR_INVALID_RANGE "); //$NON-NLS-1$ + } + _addItem(item, position); + } + + private void _addItem(GalleryItem item, int position) { + // Insert item + items = (GalleryItem[]) _arrayAddItem(items, item, position); + + // Update Gallery + updateStructuralValues(null, false); + updateScrollBarsProperties(); + } + + /** + * Get the item at index.
+ * If SWT.VIRTUAL is used and the item has not been used yet, the item is + * created and a SWT.SetData event is fired. + * + * @param index + * index of the item. + * @return the GalleryItem or null if index is out of bounds + */ + public GalleryItem getItem(int index) { + checkWidget(); + return _getItem(index); + } + + /** + * This method is used by items to implement getItem( index ) + * + * @param parent + * @param index + * @return + */ + protected GalleryItem _getItem(GalleryItem parent, int index) { + + if (index < parent.getItemCount()) { + // Refresh item if it is not set yet + updateItem(parent, index, true); + + if (parent.items == null) { + return null; + } else if (index < parent.items.length) { + return parent.items[index]; + } + } + + return null; + } + + /** + * Get the item at index.
+ * If SWT.VIRTUAL is used and the item has not been used yet, the item is + * created and a SWT.SetData is fired.
+ * + * This is the internal implementation of this method : checkWidget() is not + * used. + * + * @param index + * @return The item at 'index' (not null) + */ + protected GalleryItem _getItem(int index) { + return _getItem(index, true); + } + + /** + * Get the item at 'index'.
+ * If SWT.VIRTUAL is used, 'create' is true and the item has not been used + * yet, the item is created and a SWT.SetData is fired.
+ * + * @param index + * @param create + * @return The item at 'index' or null if there was no item and 'create' was + * false. + */ + protected GalleryItem _getItem(int index, boolean create) { + + if (index < getItemCount()) { + updateItem(null, index, create); + if (index < items.length) { + return items[index]; + } + } + + return null; + } + + /** + * Forward the mouseDown event to the corresponding group according to the + * mouse position. + * + * @param event + * The original MouseEvent + * @return true if Gallery should continue standard mouse click handling + */ + protected boolean _mouseDown(Event event) { + + if (DEBUG) + System.out.println("getitem " + event.x + " " + event.y); //$NON-NLS-1$//$NON-NLS-2$ + + GalleryItem group = this._getGroup(new Point(event.x, event.y)); + if (group != null) { + int pos = vertical ? (event.y + translate) : (event.x + translate); + + try { + return groupRenderer.mouseDown(group, event, new Point( + vertical ? event.x : pos, vertical ? pos : event.y)); + } catch (Exception e) { + // We can't let 3rd party groupRenderer#mouseDown throw an + // exception because unexpected results may occur in SWT. + e.printStackTrace(); + } + } + + return true; + } + + /** + * Get item at pixel position + * + * @param coords + * @return GalleryItem or null + */ + public GalleryItem getItem(Point coords) { + checkWidget(); + + if (DEBUG) + System.out.println("getitem " + coords.x + " " + coords.y); //$NON-NLS-1$ //$NON-NLS-2$ + + int pos = vertical ? (coords.y + translate) : (coords.x + translate); + + GalleryItem group = this._getGroup(coords); + if (group != null) + return groupRenderer.getItem(group, new Point( + vertical ? coords.x : pos, vertical ? pos : coords.y)); + + return null; + } + + /** + * Get group at pixel position + * + * @param coords + * @return GalleryItem or null + */ + private GalleryItem _getGroup(Point coords) { + // If there is no item in the gallery, return asap + if (items == null) + return null; + + int pos = vertical ? (coords.y + translate) : (coords.x + translate); + + int index = 0; + GalleryItem item = null; + while (index < items.length) { + item = getItem(index); + + if ((vertical ? item.y : item.x) > pos) + break; + + if ((vertical ? (item.y + item.height) + : (item.x + item.width)) >= pos) + return item; + + index++; + } + + return null; + } + + /** + *

+ * Get group at pixel position (relative to client area). + *

+ *

+ * This is an experimental API which is exposing an internal method, it may + * become deprecated at some point. + *

+ * + * @param coords + * @return + */ + public GalleryItem getGroup(Point coords) { + checkWidget(); + return _getGroup(coords); + } + + /** + * Clear all Gallery items.
+ * + * + * If the Gallery is virtual, the item count is not reseted and all items + * will be created again at their first use.
+ * + * @param all + * If true, all children will be cleared. Only groups are cleared + * otherwise. + */ + public void clearAll(boolean all) { + checkWidget(); + + if (items == null) + return; + + if (virtual) { + items = new GalleryItem[items.length]; + } else { + for (int i = 0; i < items.length; i++) { + if (items[i] != null) { + if (all) { + items[i].clearAll(true); + } else { + items[i].clear(); + } + } + } + } + + // TODO: I'm clearing selection here + // but we have to check that Table has the same behavior + this._deselectAll(false); + + updateStructuralValues(null, false); + updateScrollBarsProperties(); + redraw(); + + } + + /** + * Clear all GalleryGroups + */ + public void clearAll() { + clearAll(false); + } + + /** + * Clear one item.
+ * + * @param index + */ + public void clear(int index) { + clear(index, false); + } + + /** + * Clear one item and all its children if 'all' is true + * + * @param index + * @param all + */ + public void clear(int index, boolean all) { + checkWidget(); + + // Item is already cleared, return immediately. + if (items[index] == null) + return; + + if (virtual) { + // Clear item + items[index] = null; + + // In virtual mode, clearing an item can change its content, so + // force content update + updateStructuralValues(null, false); + updateScrollBarsProperties(); + } else { + // Reset item + items[index].clear(); + if (all) { + items[index].clearAll(true); + } + } + + redraw(); + } + + /** + * Returns the index of a GalleryItem. + * + * @param parentItem + * @param item + * @return + */ + public int indexOf(GalleryItem item) { + checkWidget(); + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + // SWT.error throws an exception + } + + if (item.getParentItem() == null) { + return _indexOf(item); + } + + return _indexOf(item.getParentItem(), item); + } + + /** + * Returns the index of a GalleryItem when it is a root Item + * + * @param parentItem + * @param item + * @return + */ + protected int _indexOf(GalleryItem item) { + int itemCount = getItemCount(); + if (item == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (1 <= lastIndexOf && lastIndexOf < itemCount - 1) { + if (items[lastIndexOf] == item) + return lastIndexOf; + if (items[lastIndexOf + 1] == item) + return ++lastIndexOf; + if (items[lastIndexOf - 1] == item) + return --lastIndexOf; + } + if (lastIndexOf < itemCount / 2) { + for (int i = 0; i < itemCount; i++) { + if (items[i] == item) + return lastIndexOf = i; + } + } else { + for (int i = itemCount - 1; i >= 0; --i) { + if (items[i] == item) + return lastIndexOf = i; + } + } + return -1; + } + + /** + * Returns the index of a GalleryItem when it is not a root Item + * + * @param parentItem + * @param item + * @return + */ + protected int _indexOf(GalleryItem parentItem, GalleryItem item) { + int itemCount = parentItem.getItemCount(); + if (item == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (1 <= parentItem.lastIndexOf + && parentItem.lastIndexOf < itemCount - 1) { + if (parentItem.items[parentItem.lastIndexOf] == item) + return parentItem.lastIndexOf; + if (parentItem.items[parentItem.lastIndexOf + 1] == item) + return ++parentItem.lastIndexOf; + if (parentItem.items[parentItem.lastIndexOf - 1] == item) + return --parentItem.lastIndexOf; + } + if (parentItem.lastIndexOf < itemCount / 2) { + for (int i = 0; i < itemCount; i++) { + if (parentItem.items[i] == item) + return parentItem.lastIndexOf = i; + } + } else { + for (int i = itemCount - 1; i >= 0; --i) { + if (parentItem.items[i] == item) + return parentItem.lastIndexOf = i; + } + } + return -1; + } + + public GalleryItem[] getItems() { + checkWidget(); + if (items == null) + return new GalleryItem[0]; + + GalleryItem[] itemsLocal = new GalleryItem[this.items.length]; + System.arraycopy(items, 0, itemsLocal, 0, this.items.length); + + return itemsLocal; + } + + /** + * @see Gallery#setUseControlColors(boolean) + * @return true if Gallery uses parent colors. + */ + public boolean isUseControlColors() { + return useControlColors; + } + + /** + * Set useControlColors to true in order to get colors from parent Control + * (SWT default). This may generate more objects on painting and slightly + * slow down the application. See Bug 279822 : + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=279822 + * + * If enabled, you'll get new Color objects each time you call getXXXColor() + * on Gallery or GalleryItem. + * + * Default is false : colors are stored locally in Gallery, and you'll get + * the same object each time you call getXXXColor() on Gallery + * orGalleryItem. The Gallery may not catch color changes on parent control. + * + * @param useControlColors + */ + public void setUseControlColors(boolean useControlColors) { + this.useControlColors = useControlColors; + } + + /** + * @see org.eclipse.swt.widgets.Control#getBackground() + */ + public Color getBackground() { + return getBackground(false); + } + + /** + * Returns the receiver's background color. + * + * @param galleryOnly + * If TRUE, does not try to parent widget or Display defaults to + * guess the real background color. Note : FALSE is the default + * behavior. + * + * @return The background color or null if galleryOnly was used and the + * gallery has not foreground color set. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + */ + public Color getBackground(boolean galleryOnly) { + if (galleryOnly) { + return this.backgroundColor; + } + + if (useControlColors) { + return super.getBackground(); + } + + return backgroundColor != null ? backgroundColor + : getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + } + + /** + * @see org.eclipse.swt.widgets.Control#getForeground() + */ + public Color getForeground() { + return getForeground(false); + } + + /** + * Returns the receiver's foreground color. + * + * @param galleryOnly + * If TRUE, does not try to parent widget or Display defaults to + * guess the real foreground color. Note : FALSE is the default + * behavior. + * + * @return The foreground color or null if galleryOnly was used and the + * gallery has not foreground color set. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + */ + public Color getForeground(boolean galleryOnly) { + + if (galleryOnly) { + return this.foregroundColor; + } + + if (useControlColors) { + return super.getForeground(); + } + + return foregroundColor != null ? foregroundColor + : getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND); + } + + /** + * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics + * .Color) + */ + public void setBackground(Color color) { + // Cache color locally + if (!useControlColors) { + this.backgroundColor = color; + } + + // Always call Control#setBackground(); Additionally, this will trigger + // a redraw. + super.setBackground(color); + } + + /** + * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics + * .Color) + */ + public void setForeground(Color color) { + // Cache color locally + if (!useControlColors) { + this.foregroundColor = color; + } + + // Always call Control#setForeground(); Additionally, this will trigger + // a redraw. + super.setForeground(color); + } + + /** + * Checks if the Gallery was created with SWT.V_SCROLL (ie has a vertical + * scroll bar). + * + * @return true if the gallery has the SWT.V_SCROLL style. + */ + public boolean isVertical() { + checkWidget(); + return vertical; + } + + /** + * @deprecated + * @param vertical + */ + public void setVertical(boolean vertical) { + checkWidget(); + this.vertical = vertical; + this.updateStructuralValues(null, true); + redraw(); + } + + public AbstractGalleryGroupRenderer getGroupRenderer() { + return groupRenderer; + } + + public void setGroupRenderer(AbstractGalleryGroupRenderer groupRenderer) { + this.groupRenderer = groupRenderer; + + if (this.groupRenderer != null) { + this.groupRenderer.setGallery(this); + } + + this.updateStructuralValues(null, true); + this.updateScrollBarsProperties(); + this.redraw(); + } + + public GalleryItem[] getSelection() { + if (selection == null) { + return new GalleryItem[0]; + } + + return selection; + } + + public int getSelectionCount() { + if (selection == null) + return 0; + + return selection.length; + } + + /** + * Selects all of the items in the receiver. + */ + public void selectAll() { + checkWidget(); + _selectAll(); + redraw(); + } + + protected void _selectAll() { + select(0, this.getItemCount() - 1); + } + + public void setSelection(GalleryItem[] items) { + checkWidget(); + _deselectAll(false); + for (int i = 0; i < items.length; i++) { + this.setSelected(items[i], true, false); + + // Ensure item is visible + _showItem(items[i]); + + // Simulate mouse click to enable keyboard navigation + lastSingleClick = items[i]; + } + redraw(); + } + + public void removeAll() { + checkWidget(); + + if (items != null) { + // Clear items + + GalleryItem[] tmpArray = new GalleryItem[items.length]; + System.arraycopy(items, 0, tmpArray, 0, items.length); + + for (int i = 0; i < tmpArray.length; i++) { + + // Dispose items if not virtual + // if (!virtual) { + if (tmpArray[i] != null) { + tmpArray[i]._dispose(); + } + // } + } + } + } + + public void remove(int index) { + checkWidget(); + _remove(index); + + updateStructuralValues(null, false); + updateScrollBarsProperties(); + redraw(); + } + + public void remove(GalleryItem item) { + if (item.getParentItem() == null) { + remove(indexOf(item)); + } else { + item.getParentItem().remove(item); + } + } + + protected void _remove(int index) { + if (isSelected(items[index])) { + setSelected(items[index], false, false); + } + + this.items = (GalleryItem[]) this._arrayRemoveItem(this.items, index); + } + + protected void _remove(GalleryItem parent, int index) { + if (isSelected(parent.items[index])) { + setSelected(parent.items[index], false, false); + } + + parent.items = (GalleryItem[]) this._arrayRemoveItem(parent.items, + index); + } + + protected Object[] _arrayRemoveItem(Object[] array, int index) { + + if (array == null) + return null; + + if (array.length == 1 && index == 0) + return null; + + Object[] newArray = (Object[]) Array.newInstance( + array.getClass().getComponentType(), array.length - 1); + + if (index > 0) + System.arraycopy(array, 0, newArray, 0, index); + + if (index + 1 < array.length) + System.arraycopy(array, index + 1, newArray, index, + newArray.length - index); + + return newArray; + } + + /** + * Adds an item to an array. + * + * @param array + * @param object + * @param index + * : if index == -1, item is added at the end of the array. + * @return + */ + protected Object[] _arrayAddItem(Object[] array, Object object, int index) { + + // Get current array length + int length = 0; + if (array != null) + length = array.length; + + // Create new array + Object[] newArray = (Object[]) Array.newInstance(object.getClass(), + length + 1); + + if (array != null) + System.arraycopy(array, 0, newArray, 0, length); + + if (index != -1) { + // Move all items + for (int i = newArray.length - 2; i >= index; i--) { + if (i >= 0) { + newArray[i + 1] = newArray[i]; + } + } + + // Insert item at index + newArray[index] = object; + + } else { + // Insert item at the end + newArray[newArray.length - 1] = object; + } + + return newArray; + } + + protected int _arrayIndexOf(int[] array, int value) { + if (array == null) + return -1; + + for (int i = array.length - 1; i >= 0; --i) { + if (array[i] == value) { + return i; + + } + } + return -1; + } + + protected int _arrayIndexOf(Object[] array, Object value) { + if (array == null) + return -1; + + for (int i = array.length - 1; i >= 0; --i) { + if (array[i] == value) { + return i; + + } + } + return -1; + } + + protected int[] _arrayRemoveItem(int[] array, int index) { + + if (array == null) + return null; + + if (array.length == 1 && index == 0) + return null; + + int[] newArray = new int[array.length - 1]; + + if (index > 0) + System.arraycopy(array, 0, newArray, 0, index); + + if (index + 1 < array.length) + System.arraycopy(array, index + 1, newArray, index, + newArray.length - index); + + return newArray; + } + + public void _setGalleryItems(GalleryItem[] items) { + this.items = items; + } + + /** + * @see #setVirtualGroups(boolean) + * + * @return + */ + public boolean isVirtualGroups() { + return virtualGroups; + } + + /** + * Enable virtual groups + * + *

+ * When a gallery has the SWT.VIRTUAL flag, only items are initialized on + * display. All groups need to be initialized from the beginning to + * calculate the total size of the content. + *

+ * + *

+ * Virtual groups enable creating groups AND items lazily at the cost of a + * poor approximation of the total size of the content. + *

+ * + *

+ * While a group isn't initialized, the item count defined as default item + * count is used. + *

+ * + *

+ * When a group comes into view, it is initialized using the setData event, + * and the size of the gallery content is updated to match the real value. + *

+ * + *

+ * From the developer point of view, virtual groups uses exactly the same + * code as the standard virtual mode of SWT. + *

+ * + *

+ * This mode can create visual glitches with code that automatically scrolls + * the widget such as SAT Smooth Scrolling. In that case, you can enable the + * compatibility mode which is little less lazy that the default virtual + * groups, but still better than the standard virtual mode + *

+ * + * @see #setVirtualGroupDefaultItemCount(int) + * @see #setVirtualGroupsCompatibilityMode(boolean) + * + * @param virtualGroups + */ + public void setVirtualGroups(boolean virtualGroups) { + this.virtualGroups = virtualGroups; + } + + /** + * @see #setVirtualGroupDefaultItemCount(int) + * @return + */ + public int getVirtualGroupDefaultItemCount() { + return virtualGroupDefaultItemCount; + } + + /** + * @see #setVirtualGroupsCompatibilityMode(boolean) + * @return + */ + public boolean isVirtualGroupsCompatibilityMode() { + return virtualGroupsCompatibilityMode; + } + + /** + * Enable the compatibility workaround for problems with the ultra virtual + * mode. + * + * @see #setVirtualGroups(boolean) + * @param compatibilityMode + */ + public void setVirtualGroupsCompatibilityMode(boolean compatibilityMode) { + this.virtualGroupsCompatibilityMode = compatibilityMode; + } + + /** + * Set the item count used when a group is not yet initialized (with virtual + * groups). Since the virtual groups make the size of the gallery change + * while scrolling, a fine tuned item count can improve the accuracy of the + * slider. + * + * @see #setVirtualGroups(boolean) + * + * @param defaultItemCount + */ + public void setVirtualGroupDefaultItemCount(int defaultItemCount) { + this.virtualGroupDefaultItemCount = defaultItemCount; + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/GalleryDragSourceEffect.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/GalleryDragSourceEffect.java index 3435b32cf..99a9da5c4 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/GalleryDragSourceEffect.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/GalleryDragSourceEffect.java @@ -1,60 +1,60 @@ -/******************************************************************************* - * Copyright (c) 2006-2007 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.gallery; - -import org.eclipse.swt.dnd.DragSourceEffect; -import org.eclipse.swt.dnd.DragSourceEvent; -import org.eclipse.swt.graphics.Image; - -/** - *

- * Visual effect for drag and drop operators on GalleryItem. This effect has to - * be set in - * {@link org.eclipse.swt.dnd.DragSource#setDragSourceEffect(DragSourceEffect)} - *

- * - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. - *

- * - * @see org.eclipse.swt.dnd.DragSource#setDragSourceEffect(DragSourceEffect) - * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - */ -public class GalleryDragSourceEffect extends DragSourceEffect { - Gallery g = null; - - /** - * Creates the drag source effect. - * - * @param gallery - */ - public GalleryDragSourceEffect(Gallery gallery) { - super(gallery); - g = gallery; - } - - /** - * @seeorg.eclipse.swt.dnd.DragSourceAdapter#dragStart(org.eclipse.swt.dnd. DragSourceEvent) - */ - public void dragStart(DragSourceEvent event) { - GalleryItem[] selection = g.getSelection(); - if (selection != null && selection.length > 0) { - Image img = selection[0].getImage(); - if (img != null) { - event.image = img; - } - } - } -} +/******************************************************************************* + * Copyright (c) 2006-2007 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.gallery; + +import org.eclipse.swt.dnd.DragSourceEffect; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.graphics.Image; + +/** + *

+ * Visual effect for drag and drop operators on GalleryItem. This effect has to + * be set in + * {@link org.eclipse.swt.dnd.DragSource#setDragSourceEffect(DragSourceEffect)} + *

+ * + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. + *

+ * + * @see org.eclipse.swt.dnd.DragSource#setDragSourceEffect(DragSourceEffect) + * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + */ +public class GalleryDragSourceEffect extends DragSourceEffect { + Gallery g = null; + + /** + * Creates the drag source effect. + * + * @param gallery + */ + public GalleryDragSourceEffect(Gallery gallery) { + super(gallery); + g = gallery; + } + + /** + * @seeorg.eclipse.swt.dnd.DragSourceAdapter#dragStart(org.eclipse.swt.dnd. DragSourceEvent) + */ + public void dragStart(DragSourceEvent event) { + GalleryItem[] selection = g.getSelection(); + if (selection != null && selection.length > 0) { + Image img = selection[0].getImage(); + if (img != null) { + event.image = img; + } + } + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/GalleryGroupResizeEffect.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/GalleryGroupResizeEffect.java index e996ab009..924b76ae1 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/GalleryGroupResizeEffect.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/GalleryGroupResizeEffect.java @@ -1,82 +1,82 @@ -/******************************************************************************* - * Copyright (c) 2006-2009 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.gallery; - -import org.eclipse.nebula.animation.AnimationRunner; -import org.eclipse.nebula.animation.effects.AbstractEffect; -import org.eclipse.nebula.animation.movement.IMovement; - -/** - *

- * Animation used internally on collapse / expand events. Should not be used - * directly. - *

- *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. - *

- * - * @see AnimationRunner#runEffect(org.eclipse.nebula.animation.effects.IEffect) - * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - */ -public class GalleryGroupResizeEffect extends AbstractEffect { - - int src, dest, diff; - GalleryItem item = null; - - /** - * Set up a new resize effect on a gallery item. - * - * - * @param item - * @param src - * @param dest - * @param lengthMilli - * @param movement - * @param onStop - * @param onCancel - */ - public GalleryGroupResizeEffect(GalleryItem item, int src, int dest, - long lengthMilli, IMovement movement, Runnable onStop, - Runnable onCancel) { - super(lengthMilli, movement, onStop, onCancel); - - this.src = src; - this.dest = dest; - this.diff = dest - src; - - easingFunction.init(0, 1, (int) lengthMilli); - - this.item = item; - } - - /** - * @see org.sharemedia.ui.sat.AbstractEffect#applyEffect(long) - */ - public void applyEffect(final long currentTime) { - if (!item.isDisposed()) { - double value = src - + diff * easingFunction.getValue((int) currentTime); - - item.setData(DefaultGalleryGroupRenderer.DATA_ANIMATION, - new Double(value)); - - item.getParent().updateStructuralValues(null, false); - item.getParent().updateScrollBarsProperties(); - item.getParent().redraw(); - - } - } +/******************************************************************************* + * Copyright (c) 2006-2009 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.gallery; + +import org.eclipse.nebula.animation.AnimationRunner; +import org.eclipse.nebula.animation.effects.AbstractEffect; +import org.eclipse.nebula.animation.movement.IMovement; + +/** + *

+ * Animation used internally on collapse / expand events. Should not be used + * directly. + *

+ *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. + *

+ * + * @see AnimationRunner#runEffect(org.eclipse.nebula.animation.effects.IEffect) + * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + */ +public class GalleryGroupResizeEffect extends AbstractEffect { + + int src, dest, diff; + GalleryItem item = null; + + /** + * Set up a new resize effect on a gallery item. + * + * + * @param item + * @param src + * @param dest + * @param lengthMilli + * @param movement + * @param onStop + * @param onCancel + */ + public GalleryGroupResizeEffect(GalleryItem item, int src, int dest, + long lengthMilli, IMovement movement, Runnable onStop, + Runnable onCancel) { + super(lengthMilli, movement, onStop, onCancel); + + this.src = src; + this.dest = dest; + this.diff = dest - src; + + easingFunction.init(0, 1, (int) lengthMilli); + + this.item = item; + } + + /** + * @see org.sharemedia.ui.sat.AbstractEffect#applyEffect(long) + */ + public void applyEffect(final long currentTime) { + if (!item.isDisposed()) { + double value = src + + diff * easingFunction.getValue((int) currentTime); + + item.setData(DefaultGalleryGroupRenderer.DATA_ANIMATION, + new Double(value)); + + item.getParent().updateStructuralValues(null, false); + item.getParent().updateScrollBarsProperties(); + item.getParent().redraw(); + + } + } } \ No newline at end of file diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/ListItemRenderer.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/ListItemRenderer.java index faded4dac..f21e1911d 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/ListItemRenderer.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/ListItemRenderer.java @@ -1,405 +1,405 @@ -/******************************************************************************* - * Copyright (c) 2006-2007 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.gallery; - -import java.util.ArrayList; -import java.util.Iterator; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -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.Display; - -/** - *

- * Alternate item renderer for the Gallery widget using a list style. Supports - * multi-line text, image, drop shadows and decorators. - *

- *

- * Best with bigger width than height. - *

- *

- * Decorator images can be set with {@link GalleryItem#setData(String, Object)} - * by using the following keys : - *

- *
    - *
  • org.eclipse.nebula.widget.gallery.bottomLeftOverlay
  • - *
  • org.eclipse.nebula.widget.gallery.bottomRightOverlay
  • - *
  • org.eclipse.nebula.widget.gallery.topLeftOverlay
  • - *
  • org.eclipse.nebula.widget.gallery.topRightOverlay
  • - *
- *

- * Supported types are org.eclipse.swt.Image for one single decorator and - * org.eclipse.swt.Image[] for multiple decorators. - *

- *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. - *

- * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - * - */ - -public class ListItemRenderer extends AbstractGalleryItemRenderer { - - protected ArrayList dropShadowsColors = new ArrayList<>(); - - boolean dropShadows = false; - - int dropShadowsSize = 5; - - int dropShadowsAlphaStep = 20; - - Color selectionBackgroundColor; - - Color selectionForegroundColor; - - Color foregroundColor, backgroundColor; - - Color descriptionColor; - - Font textFont = null; - - Font descriptionFont = null; - - boolean showLabels = true; - - boolean showRoundedSelectionCorners = true; - - int selectionRadius = 15; - - public boolean isShowLabels() { - return showLabels; - } - - public void setShowLabels(boolean showLabels) { - this.showLabels = showLabels; - } - - public ListItemRenderer() { - super(); - - // Set defaults - foregroundColor = Display.getDefault() - .getSystemColor(SWT.COLOR_LIST_FOREGROUND); - backgroundColor = Display.getDefault() - .getSystemColor(SWT.COLOR_LIST_BACKGROUND); - selectionBackgroundColor = Display.getDefault() - .getSystemColor(SWT.COLOR_LIST_SELECTION); - selectionForegroundColor = Display.getDefault() - .getSystemColor(SWT.COLOR_LIST_FOREGROUND); - descriptionColor = Display.getDefault() - .getSystemColor(SWT.COLOR_DARK_GRAY); - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer#preDraw - * (org.eclipse.swt.graphics.GC) - */ - public void preDraw(GC gc) { - super.preDraw(gc); - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer#draw(org - * .eclipse.swt.graphics.GC, - * org.eclipse.nebula.widgets.gallery.GalleryItem, int, int, int, int, - * int) - */ - public void draw(GC gc, GalleryItem item, int index, int x, int y, - int width, int height) { - - Image itemImage = item.getImage(); - Color itemBackgroundColor = item.getBackground(); - Color itemForegroundColor = item.getForeground(); - - int useableHeight = height; - - int imageWidth = 0; - int imageHeight = 0; - int xShift = 0; - int yShift = 0; - Point size = null; - - if (itemImage != null) { - Rectangle itemImageBounds = itemImage.getBounds(); - imageWidth = itemImageBounds.width; - imageHeight = itemImageBounds.height; - - size = RendererHelper.getBestSize(imageWidth, imageHeight, - useableHeight - 4 - this.dropShadowsSize, - useableHeight - 4 - this.dropShadowsSize); - - xShift = ((useableHeight - size.x) >> 1) + 2; - yShift = (useableHeight - size.y) >> 1; - - if (dropShadows) { - Color c = null; - for (int i = this.dropShadowsSize - 1; i >= 0; i--) { - c = (Color) dropShadowsColors.get(i); - gc.setForeground(c); - - gc.drawLine(x + useableHeight + i - xShift - 1, - y + dropShadowsSize + yShift, - x + useableHeight + i - xShift - 1, - y + useableHeight + i - yShift); - gc.drawLine(x + xShift + dropShadowsSize, - y + useableHeight + i - yShift - 1, - x + useableHeight + i - xShift, - y - 1 + useableHeight + i - yShift); - } - } - } - - // Draw selection background (rounded rectangles) - if (selected || !RendererHelper.isColorsEquals(itemBackgroundColor, - gallery.getBackground())) { - if (selected) { - gc.setBackground(selectionBackgroundColor); - gc.setForeground(selectionBackgroundColor); - } else if (itemBackgroundColor != null) { - gc.setBackground(itemBackgroundColor); - } - - if (showRoundedSelectionCorners) - gc.fillRoundRectangle(x, y, width, useableHeight, - selectionRadius, selectionRadius); - else - gc.fillRectangle(x, y, width, useableHeight); - } - - if (itemImage != null && size != null) { - if (size.x > 0 && size.y > 0) { - gc.drawImage(itemImage, 0, 0, imageWidth, imageHeight, - x + xShift, y + yShift, size.x, size.y); - drawAllOverlays(gc, item, x, y, size, xShift, yShift); - } - } - - if (item.getText() != null && !EMPTY_STRING.equals(item.getText()) - && showLabels) { - - // Calculate font height (text and description) - gc.setFont(textFont); - String text = RendererHelper.createLabel(item.getText(), gc, - width - useableHeight - 10); - int textFontHeight = gc.getFontMetrics().getHeight(); - - String description = null; - int descriptionFontHeight = 0; - if (item.getText(1) != null - && !EMPTY_STRING.equals(item.getText(1))) { - gc.setFont(descriptionFont); - description = RendererHelper.createLabel(item.getText(1), gc, - width - useableHeight - 10); - descriptionFontHeight = gc.getFontMetrics().getHeight(); - } - - boolean displayText = false; - boolean displayDescription = false; - int remainingHeight = height - 2 - textFontHeight; - if (remainingHeight > 0) - displayText = true; - remainingHeight -= descriptionFontHeight; - if (remainingHeight > 0) - displayDescription = true; - - // Background color - gc.setBackground( - selected ? selectionBackgroundColor : backgroundColor); - - // Draw text - if (displayText) { - int transY = (height - textFontHeight - 2); - if (displayDescription) - transY -= descriptionFontHeight; - transY = transY >> 1; - - if (selected) { - gc.setForeground(this.selectionForegroundColor); - } else if (itemForegroundColor != null) { - gc.setForeground(itemForegroundColor); - } else { - gc.setForeground(this.foregroundColor); - } - - gc.setFont(textFont); - gc.drawText(text, x + useableHeight + 5, y + transY, true); - } - // Draw description - if (description != null && displayDescription) { - gc.setForeground(this.descriptionColor); - gc.setFont(descriptionFont); - gc.drawText( - description, x + useableHeight + 5, y - + ((height - descriptionFontHeight - - textFontHeight - 2) >> 1) - + textFontHeight + 1, - true); - } - } - } - - public void setDropShadowsSize(int dropShadowsSize) { - this.dropShadowsSize = dropShadowsSize; - this.dropShadowsAlphaStep = (dropShadowsSize == 0) ? 0 - : (200 / dropShadowsSize); - - freeDropShadowsColors(); - createColors(); - // TODO: force redraw - - } - - private void createColors() { - if (dropShadowsSize > 0) { - int step = 125 / dropShadowsSize; - // Create new colors - for (int i = dropShadowsSize - 1; i >= 0; i--) { - int value = 255 - i * step; - Color c = new Color(Display.getDefault(), value, value, value); - dropShadowsColors.add(c); - } - } - } - - private void freeDropShadowsColors() { - // Free colors : - { - Iterator i = this.dropShadowsColors.iterator(); - while (i.hasNext()) { - Color c = i.next(); - if (c != null && !c.isDisposed()) - c.dispose(); - } - } - } - - public boolean isDropShadows() { - return dropShadows; - } - - public void setDropShadows(boolean dropShadows) { - this.dropShadows = dropShadows; - } - - public int getDropShadowsSize() { - return dropShadowsSize; - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer#dispose() - */ - public void dispose() { - freeDropShadowsColors(); - } - - public Color getSelectionBackgroundColor() { - return selectionBackgroundColor; - } - - public void setSelectionBackgroundColor(Color selectionColor) { - this.selectionBackgroundColor = selectionColor; - } - - public Color getForegroundColor() { - return foregroundColor; - } - - public void setForegroundColor(Color foregroundColor) { - this.foregroundColor = foregroundColor; - } - - public Color getBackgroundColor() { - return backgroundColor; - } - - public void setBackgroundColor(Color backgroundColor) { - this.backgroundColor = backgroundColor; - } - - public Color getDescriptionColor() { - return descriptionColor; - } - - public void setDescriptionColor(Color descriptionColor) { - this.descriptionColor = descriptionColor; - } - - public Color getSelectionForegroundColor() { - return selectionForegroundColor; - } - - public void setSelectionForegroundColor(Color selectionForegroundColor) { - this.selectionForegroundColor = selectionForegroundColor; - } - - /** - * Returns the font used for drawing item label or null if system - * font is used. - * - * @deprecated Use {@link Gallery#setFont(Font)} or - * {@link GalleryItem#setFont(Font)} instead. - * @return the font - */ - public Font getTextFont() { - return textFont; - } - - /** - * Set the font for drawing item label or null to use system font. - * - * @deprecated Use {@link Gallery#setFont(Font)} or - * {@link GalleryItem#setFont(Font)} instead. - * @param font - * the font to set - */ - public void setTextFont(Font textFont) { - this.textFont = textFont; - } - - /** - * Returns the font used for drawing item description or null if - * system font is used. - * - * @return the font - */ - public Font getDescriptionFont() { - return descriptionFont; - } - - /** - * Set the font for drawing item description or null to use system - * font. - * - * @param font - * the font to set - */ - public void setDescriptionFont(Font descriptionFont) { - this.descriptionFont = descriptionFont; - } - - public boolean isShowRoundedSelectionCorners() { - return this.showRoundedSelectionCorners; - } - - public void setShowRoundedSelectionCorners( - boolean showRoundedSelectionCorners) { - this.showRoundedSelectionCorners = showRoundedSelectionCorners; - } -} +/******************************************************************************* + * Copyright (c) 2006-2007 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.gallery; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +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.Display; + +/** + *

+ * Alternate item renderer for the Gallery widget using a list style. Supports + * multi-line text, image, drop shadows and decorators. + *

+ *

+ * Best with bigger width than height. + *

+ *

+ * Decorator images can be set with {@link GalleryItem#setData(String, Object)} + * by using the following keys : + *

+ *
    + *
  • org.eclipse.nebula.widget.gallery.bottomLeftOverlay
  • + *
  • org.eclipse.nebula.widget.gallery.bottomRightOverlay
  • + *
  • org.eclipse.nebula.widget.gallery.topLeftOverlay
  • + *
  • org.eclipse.nebula.widget.gallery.topRightOverlay
  • + *
+ *

+ * Supported types are org.eclipse.swt.Image for one single decorator and + * org.eclipse.swt.Image[] for multiple decorators. + *

+ *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. + *

+ * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + * + */ + +public class ListItemRenderer extends AbstractGalleryItemRenderer { + + protected ArrayList dropShadowsColors = new ArrayList<>(); + + boolean dropShadows = false; + + int dropShadowsSize = 5; + + int dropShadowsAlphaStep = 20; + + Color selectionBackgroundColor; + + Color selectionForegroundColor; + + Color foregroundColor, backgroundColor; + + Color descriptionColor; + + Font textFont = null; + + Font descriptionFont = null; + + boolean showLabels = true; + + boolean showRoundedSelectionCorners = true; + + int selectionRadius = 15; + + public boolean isShowLabels() { + return showLabels; + } + + public void setShowLabels(boolean showLabels) { + this.showLabels = showLabels; + } + + public ListItemRenderer() { + super(); + + // Set defaults + foregroundColor = Display.getDefault() + .getSystemColor(SWT.COLOR_LIST_FOREGROUND); + backgroundColor = Display.getDefault() + .getSystemColor(SWT.COLOR_LIST_BACKGROUND); + selectionBackgroundColor = Display.getDefault() + .getSystemColor(SWT.COLOR_LIST_SELECTION); + selectionForegroundColor = Display.getDefault() + .getSystemColor(SWT.COLOR_LIST_FOREGROUND); + descriptionColor = Display.getDefault() + .getSystemColor(SWT.COLOR_DARK_GRAY); + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer#preDraw + * (org.eclipse.swt.graphics.GC) + */ + public void preDraw(GC gc) { + super.preDraw(gc); + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer#draw(org + * .eclipse.swt.graphics.GC, + * org.eclipse.nebula.widgets.gallery.GalleryItem, int, int, int, int, + * int) + */ + public void draw(GC gc, GalleryItem item, int index, int x, int y, + int width, int height) { + + Image itemImage = item.getImage(); + Color itemBackgroundColor = item.getBackground(); + Color itemForegroundColor = item.getForeground(); + + int useableHeight = height; + + int imageWidth = 0; + int imageHeight = 0; + int xShift = 0; + int yShift = 0; + Point size = null; + + if (itemImage != null) { + Rectangle itemImageBounds = itemImage.getBounds(); + imageWidth = itemImageBounds.width; + imageHeight = itemImageBounds.height; + + size = RendererHelper.getBestSize(imageWidth, imageHeight, + useableHeight - 4 - this.dropShadowsSize, + useableHeight - 4 - this.dropShadowsSize); + + xShift = ((useableHeight - size.x) >> 1) + 2; + yShift = (useableHeight - size.y) >> 1; + + if (dropShadows) { + Color c = null; + for (int i = this.dropShadowsSize - 1; i >= 0; i--) { + c = (Color) dropShadowsColors.get(i); + gc.setForeground(c); + + gc.drawLine(x + useableHeight + i - xShift - 1, + y + dropShadowsSize + yShift, + x + useableHeight + i - xShift - 1, + y + useableHeight + i - yShift); + gc.drawLine(x + xShift + dropShadowsSize, + y + useableHeight + i - yShift - 1, + x + useableHeight + i - xShift, + y - 1 + useableHeight + i - yShift); + } + } + } + + // Draw selection background (rounded rectangles) + if (selected || !RendererHelper.isColorsEquals(itemBackgroundColor, + gallery.getBackground())) { + if (selected) { + gc.setBackground(selectionBackgroundColor); + gc.setForeground(selectionBackgroundColor); + } else if (itemBackgroundColor != null) { + gc.setBackground(itemBackgroundColor); + } + + if (showRoundedSelectionCorners) + gc.fillRoundRectangle(x, y, width, useableHeight, + selectionRadius, selectionRadius); + else + gc.fillRectangle(x, y, width, useableHeight); + } + + if (itemImage != null && size != null) { + if (size.x > 0 && size.y > 0) { + gc.drawImage(itemImage, 0, 0, imageWidth, imageHeight, + x + xShift, y + yShift, size.x, size.y); + drawAllOverlays(gc, item, x, y, size, xShift, yShift); + } + } + + if (item.getText() != null && !EMPTY_STRING.equals(item.getText()) + && showLabels) { + + // Calculate font height (text and description) + gc.setFont(textFont); + String text = RendererHelper.createLabel(item.getText(), gc, + width - useableHeight - 10); + int textFontHeight = gc.getFontMetrics().getHeight(); + + String description = null; + int descriptionFontHeight = 0; + if (item.getText(1) != null + && !EMPTY_STRING.equals(item.getText(1))) { + gc.setFont(descriptionFont); + description = RendererHelper.createLabel(item.getText(1), gc, + width - useableHeight - 10); + descriptionFontHeight = gc.getFontMetrics().getHeight(); + } + + boolean displayText = false; + boolean displayDescription = false; + int remainingHeight = height - 2 - textFontHeight; + if (remainingHeight > 0) + displayText = true; + remainingHeight -= descriptionFontHeight; + if (remainingHeight > 0) + displayDescription = true; + + // Background color + gc.setBackground( + selected ? selectionBackgroundColor : backgroundColor); + + // Draw text + if (displayText) { + int transY = (height - textFontHeight - 2); + if (displayDescription) + transY -= descriptionFontHeight; + transY = transY >> 1; + + if (selected) { + gc.setForeground(this.selectionForegroundColor); + } else if (itemForegroundColor != null) { + gc.setForeground(itemForegroundColor); + } else { + gc.setForeground(this.foregroundColor); + } + + gc.setFont(textFont); + gc.drawText(text, x + useableHeight + 5, y + transY, true); + } + // Draw description + if (description != null && displayDescription) { + gc.setForeground(this.descriptionColor); + gc.setFont(descriptionFont); + gc.drawText( + description, x + useableHeight + 5, y + + ((height - descriptionFontHeight + - textFontHeight - 2) >> 1) + + textFontHeight + 1, + true); + } + } + } + + public void setDropShadowsSize(int dropShadowsSize) { + this.dropShadowsSize = dropShadowsSize; + this.dropShadowsAlphaStep = (dropShadowsSize == 0) ? 0 + : (200 / dropShadowsSize); + + freeDropShadowsColors(); + createColors(); + // TODO: force redraw + + } + + private void createColors() { + if (dropShadowsSize > 0) { + int step = 125 / dropShadowsSize; + // Create new colors + for (int i = dropShadowsSize - 1; i >= 0; i--) { + int value = 255 - i * step; + Color c = new Color(Display.getDefault(), value, value, value); + dropShadowsColors.add(c); + } + } + } + + private void freeDropShadowsColors() { + // Free colors : + { + Iterator i = this.dropShadowsColors.iterator(); + while (i.hasNext()) { + Color c = i.next(); + if (c != null && !c.isDisposed()) + c.dispose(); + } + } + } + + public boolean isDropShadows() { + return dropShadows; + } + + public void setDropShadows(boolean dropShadows) { + this.dropShadows = dropShadows; + } + + public int getDropShadowsSize() { + return dropShadowsSize; + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer#dispose() + */ + public void dispose() { + freeDropShadowsColors(); + } + + public Color getSelectionBackgroundColor() { + return selectionBackgroundColor; + } + + public void setSelectionBackgroundColor(Color selectionColor) { + this.selectionBackgroundColor = selectionColor; + } + + public Color getForegroundColor() { + return foregroundColor; + } + + public void setForegroundColor(Color foregroundColor) { + this.foregroundColor = foregroundColor; + } + + public Color getBackgroundColor() { + return backgroundColor; + } + + public void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public Color getDescriptionColor() { + return descriptionColor; + } + + public void setDescriptionColor(Color descriptionColor) { + this.descriptionColor = descriptionColor; + } + + public Color getSelectionForegroundColor() { + return selectionForegroundColor; + } + + public void setSelectionForegroundColor(Color selectionForegroundColor) { + this.selectionForegroundColor = selectionForegroundColor; + } + + /** + * Returns the font used for drawing item label or null if system + * font is used. + * + * @deprecated Use {@link Gallery#setFont(Font)} or + * {@link GalleryItem#setFont(Font)} instead. + * @return the font + */ + public Font getTextFont() { + return textFont; + } + + /** + * Set the font for drawing item label or null to use system font. + * + * @deprecated Use {@link Gallery#setFont(Font)} or + * {@link GalleryItem#setFont(Font)} instead. + * @param font + * the font to set + */ + public void setTextFont(Font textFont) { + this.textFont = textFont; + } + + /** + * Returns the font used for drawing item description or null if + * system font is used. + * + * @return the font + */ + public Font getDescriptionFont() { + return descriptionFont; + } + + /** + * Set the font for drawing item description or null to use system + * font. + * + * @param font + * the font to set + */ + public void setDescriptionFont(Font descriptionFont) { + this.descriptionFont = descriptionFont; + } + + public boolean isShowRoundedSelectionCorners() { + return this.showRoundedSelectionCorners; + } + + public void setShowRoundedSelectionCorners( + boolean showRoundedSelectionCorners) { + this.showRoundedSelectionCorners = showRoundedSelectionCorners; + } +} diff --git a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/NoGroupRenderer.java b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/NoGroupRenderer.java index 3889dbffa..6d9376a46 100644 --- a/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/NoGroupRenderer.java +++ b/widgets/gallery/org.eclipse.nebula.widgets.gallery/src/org/eclipse/nebula/widgets/gallery/NoGroupRenderer.java @@ -1,147 +1,147 @@ -/******************************************************************************* - * Copyright (c) 2006-2007 Nicolas Richeton. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors : - * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.gallery; - -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Event; - -/** - *

- * Alternate group renderer for the Gallery widget. This group renderer does not - * draw group titles. Only items are displayed. All groups are considered as - * expanded. - *

- *

- * The visual aspect is the same as the first version of the gallery widget. - * - *

- *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. - *

- * - * - * @author Nicolas Richeton (nicolas.richeton@gmail.com) - */ -public class NoGroupRenderer extends AbstractGridGroupRenderer { - - protected static int OFFSET = 0; - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#draw(org - * .eclipse.swt.graphics.GC, - * org.eclipse.nebula.widgets.gallery.GalleryItem, int, int, int, int, - * int, int) - */ - public void draw(GC gc, GalleryItem group, int x, int y, int clipX, - int clipY, int clipWidth, int clipHeight) { - - // Get items in the clipping area - int[] indexes = getVisibleItems(group, x, y, clipX, clipY, clipWidth, - clipHeight, OFFSET); - - if (indexes != null && indexes.length > 0) { - for (int i = indexes.length - 1; i >= 0; i--) { - // Draw item - boolean selected = group.isSelected(group.getItem(indexes[i])); - - if (Gallery.DEBUG) { - System.out.println( - "Selected : " + selected + " index : " + indexes[i] //$NON-NLS-1$//$NON-NLS-2$ - + "item : " + group.getItem(indexes[i])); //$NON-NLS-1$ - } - - drawItem(gc, indexes[i], selected, group, OFFSET); - - } - } - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#layout(org - * .eclipse.swt.graphics.GC, - * org.eclipse.nebula.widgets.gallery.GalleryItem) - */ - public void layout(GC gc, GalleryItem group) { - - int countLocal = group.getItemCount(); - - if (gallery.isVertical()) { - int sizeX = group.width; - group.height = OFFSET; - - Point l = gridLayout(sizeX, countLocal, itemWidth); - int hCount = l.x; - int vCount = l.y; - if (autoMargin) { - // Calculate best margins - margin = calculateMargins(sizeX, hCount, itemWidth); - } - - Point s = this.getSize(hCount, vCount, itemWidth, itemHeight, - minMargin, margin); - group.height += s.y; - - group.setData(H_COUNT, new Integer(hCount)); - group.setData(V_COUNT, new Integer(vCount)); - } else { - int sizeY = group.height; - group.width = OFFSET; - - Point l = gridLayout(sizeY, countLocal, itemHeight); - int vCount = l.x; - int hCount = l.y; - if (autoMargin) { - // Calculate best margins - margin = calculateMargins(sizeY, vCount, itemHeight); - } - - Point s = this.getSize(hCount, vCount, itemWidth, itemHeight, - minMargin, margin); - group.width += s.x; - - group.setData(H_COUNT, new Integer(hCount)); - group.setData(V_COUNT, new Integer(vCount)); - } - - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#getItem( - * org.eclipse.nebula.widgets.gallery.GalleryItem, - * org.eclipse.swt.graphics.Point) - */ - public GalleryItem getItem(GalleryItem group, Point coords) { - return super.getItem(group, coords, OFFSET); - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer#mouseDown(org.eclipse.nebula.widgets.gallery.GalleryItem, - * org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Point) - */ - public boolean mouseDown(GalleryItem group, Event e, Point coords) { - // This renderer does not display anything, so there is nothing to do - // here. Continue standard mouse down processing - return true; - } - - /** - * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#getSize( - * org.eclipse.nebula.widgets.gallery.GalleryItem) - */ - public Rectangle getSize(GalleryItem item) { - return super.getSize(item, OFFSET); - } -} +/******************************************************************************* + * Copyright (c) 2006-2007 Nicolas Richeton. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors : + * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.gallery; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Event; + +/** + *

+ * Alternate group renderer for the Gallery widget. This group renderer does not + * draw group titles. Only items are displayed. All groups are considered as + * expanded. + *

+ *

+ * The visual aspect is the same as the first version of the gallery widget. + * + *

+ *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. + *

+ * + * + * @author Nicolas Richeton (nicolas.richeton@gmail.com) + */ +public class NoGroupRenderer extends AbstractGridGroupRenderer { + + protected static int OFFSET = 0; + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#draw(org + * .eclipse.swt.graphics.GC, + * org.eclipse.nebula.widgets.gallery.GalleryItem, int, int, int, int, + * int, int) + */ + public void draw(GC gc, GalleryItem group, int x, int y, int clipX, + int clipY, int clipWidth, int clipHeight) { + + // Get items in the clipping area + int[] indexes = getVisibleItems(group, x, y, clipX, clipY, clipWidth, + clipHeight, OFFSET); + + if (indexes != null && indexes.length > 0) { + for (int i = indexes.length - 1; i >= 0; i--) { + // Draw item + boolean selected = group.isSelected(group.getItem(indexes[i])); + + if (Gallery.DEBUG) { + System.out.println( + "Selected : " + selected + " index : " + indexes[i] //$NON-NLS-1$//$NON-NLS-2$ + + "item : " + group.getItem(indexes[i])); //$NON-NLS-1$ + } + + drawItem(gc, indexes[i], selected, group, OFFSET); + + } + } + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#layout(org + * .eclipse.swt.graphics.GC, + * org.eclipse.nebula.widgets.gallery.GalleryItem) + */ + public void layout(GC gc, GalleryItem group) { + + int countLocal = group.getItemCount(); + + if (gallery.isVertical()) { + int sizeX = group.width; + group.height = OFFSET; + + Point l = gridLayout(sizeX, countLocal, itemWidth); + int hCount = l.x; + int vCount = l.y; + if (autoMargin) { + // Calculate best margins + margin = calculateMargins(sizeX, hCount, itemWidth); + } + + Point s = this.getSize(hCount, vCount, itemWidth, itemHeight, + minMargin, margin); + group.height += s.y; + + group.setData(H_COUNT, new Integer(hCount)); + group.setData(V_COUNT, new Integer(vCount)); + } else { + int sizeY = group.height; + group.width = OFFSET; + + Point l = gridLayout(sizeY, countLocal, itemHeight); + int vCount = l.x; + int hCount = l.y; + if (autoMargin) { + // Calculate best margins + margin = calculateMargins(sizeY, vCount, itemHeight); + } + + Point s = this.getSize(hCount, vCount, itemWidth, itemHeight, + minMargin, margin); + group.width += s.x; + + group.setData(H_COUNT, new Integer(hCount)); + group.setData(V_COUNT, new Integer(vCount)); + } + + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#getItem( + * org.eclipse.nebula.widgets.gallery.GalleryItem, + * org.eclipse.swt.graphics.Point) + */ + public GalleryItem getItem(GalleryItem group, Point coords) { + return super.getItem(group, coords, OFFSET); + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGalleryGroupRenderer#mouseDown(org.eclipse.nebula.widgets.gallery.GalleryItem, + * org.eclipse.swt.widgets.Event, org.eclipse.swt.graphics.Point) + */ + public boolean mouseDown(GalleryItem group, Event e, Point coords) { + // This renderer does not display anything, so there is nothing to do + // here. Continue standard mouse down processing + return true; + } + + /** + * @see org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer#getSize( + * org.eclipse.nebula.widgets.gallery.GalleryItem) + */ + public Rectangle getSize(GalleryItem item) { + return super.getSize(item, OFFSET); + } +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/.settings/org.eclipse.jdt.core.prefs b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/.settings/org.eclipse.jdt.core.prefs index 230c1b474..a58ebdcad 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/.settings/org.eclipse.jdt.core.prefs @@ -1,15 +1,15 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java index 94644cb48..c25ec85a4 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java @@ -1,605 +1,605 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - * ziogiannigmail.com - Bug 464509 - Minute View Implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.ganttchart; - -import java.util.Calendar; -import java.util.Locale; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; - -public abstract class AbstractSettings implements ISettings2 { - - public String getDateFormat() { - return "MM/dd/yyyy"; - } - - public String getHourDateFormat() { - return "MM/dd/yyyy HH:mm"; - } - - public String getMinuteDateFormat() { - return "MM/dd/yyyy HH:mm:ss"; - } - - public String getWeekHeaderTextDisplayFormatTop() { - return "MMM dd, ''yy"; - } - - public String getMonthHeaderTextDisplayFormatTop() { - return "MMMMM ''yy"; - } - - public String getDayHeaderTextDisplayFormatTop() { - return "MMM dd, HH:mm"; - } - - public String getMinuteHeaderTextDisplayFormatTop() { - return "MMM dd, HH:mm"; - } - - public String getYearHeaderTextDisplayFormatTop() { - return "yyyy"; - } - - public String getDayHeaderTextDisplayFormatBottom() { - return "HH:mm"; - } - - public String getMinuteHeaderTextDisplayFormatBottom() { - return "HH:mm"; - } - - public String getMonthHeaderTextDisplayFormatBottom() { - return "MMM dd"; - } - - public String getWeekHeaderTextDisplayFormatBottom() { - return "E"; - } - - public String getYearHeaderTextDisplayFormatBottom() { - return "MMM"; - } - - public Color getDefaultEventColor() { - return ColorCache.getColor(181, 180, 181); - } - - public Color getDefaultGradientEventColor() { - return ColorCache.getColor(235, 235, 235); - } - - public boolean showPropertiesMenuOption() { - return true; - } - - public boolean showDeleteMenuOption() { - return true; - } - - public boolean adjustForLetters() { - return true; - } - - public boolean enableAutoScroll() { - return true; - } - - public boolean enableResizing() { - return true; - } - - public int getArrowConnectionType() { - return CONNECTION_MS_PROJECT_STYLE; - } - - public int getDayHorizontalSpacing() { - return 3; - } - - public int getDayVerticalSpacing() { - return 3; - } - - public int getDayWidth() { - return 16; - } - - public int getEventHeight() { - return 12; - } - - public int getEventPercentageBarHeight() { - return 3; - } - - public int getHeaderMonthHeight() { - return 18; - } - - public int getHeaderDayHeight() { - return 18; - } - - public int getInitialView() { - return VIEW_WEEK; - } - - public int getInitialZoomLevel() { - return ZOOM_DAY_NORMAL; - } - - public int getMonthDayWidth() { - return 6; - } - - public int getResizeBorderSensitivity() { - return 3; - } - - public int getTextSpacerConnected() { - return 9; - } - - public int getTextSpacerNonConnected() { - return 9; - } - - public int getYearMonthDayWidth() { - return 3; - } - - public boolean moveLinkedEventsWhenEventsAreMoved() { - return true; - } - - public boolean showArrows() { - return true; - } - - public boolean showBarsIn3D() { - return true; - } - - public boolean showBoldScopeText() { - return true; - } - - public boolean showDateTips() { - return true; - } - - public boolean showPlannedDates() { - return false; - } - - public boolean showGradientEventBars() { - return true; - } - - public boolean showNumberOfDaysOnBars() { - return false; - } - - public boolean showOnlyDependenciesForSelectedItems() { - return false; - } - - public boolean showToolTips() { - return true; - } - - public int getEventSpacer() { - return 12; - } - - public boolean enableDragAndDrop() { - return true; - } - - public boolean showZoomLevelBox() { - return true; - } - - public boolean allowInfiniteHorizontalScrollBar() { - return true; - } - - public boolean showResizeDateTipOnBorders() { - return true; - } - - public boolean allowBlankAreaDragAndDropToMoveDates() { - return true; - } - - public boolean allowBlankAreaVerticalDragAndDropToMoveChart() { - return false; - } - - public boolean flipBlankAreaDragDirection() { - return true; - } - - public boolean drawSelectionMarkerAroundSelectedEvent() { - return true; - } - - public boolean allowCheckpointResizing() { - return false; - } - - public boolean showMenuItemsOnRightClick() { - return true; - } - - public int getArrowHeadEventSpacer() { - return 1; - } - - public int getArrowHeadVerticalAdjuster() { - return 0; - } - - public Calendar getStartupCalendarDate() { - return Calendar.getInstance(Locale.getDefault()); - } - - public int getCalendarStartupDateOffset() { - return -4; - } - - public boolean startCalendarOnFirstDayOfWeek() { - return false; - } - - public int getMoveAreaNegativeSensitivity() { - return 6; - } - - public boolean enableZooming() { - return true; - } - - public Image getLockImage() { - return ImageCache.getImage("icons/lock_tiny.gif"); - } - - public String getTextDisplayFormat() { - return "#name# (#pc#%)"; - } - - public int getRevisedLineSpacer() { - return 3; - } - - public Image getDefaultAdvandedTooltipHelpImage() { - return null; - } - - public Image getDefaultAdvandedTooltipImage() { - return null; - } - - public boolean roundHourlyEventsOffToNearestHour() { - return false; - } - - public String getDefaultAdvancedTooltipHelpText() { - return null; - } - - public String getDefaultAdvancedTooltipTitle() { - return "\\b\\c027050082#name#"; - } - - public String getDefaultAdvancedTooltipTextExtended() { - final StringBuffer buf = new StringBuffer(); - buf.append("\\ceRevised: #rs# - #re# (#reviseddays# day(s))\n"); - buf.append("\\c100100100Planned: #sd# - #ed# (#days# day(s))\n"); - buf.append("#pc#% complete"); - return buf.toString();// "\\ceStart Date: \\b#sd#\nEnd Date: \\b#ed#\nRevised Start: \\b#rs#\nRevised End: \\b#re#\nDay Span: \\b#days# days\nPercent Complete: \\b#pc#%"; - } - - public String getDefaultAdvancedTooltipText() { - final StringBuffer buf = new StringBuffer(); - buf.append("\\cePlanned: #sd# - #ed# (#days# day(s))\n"); - buf.append("\\c100100100#pc#% complete"); - return buf.toString(); - } - - public int getTodayLineStyle() { - return SWT.LINE_SOLID; - } - - public int getTodayLineWidth() { - return 2; - } - - public int getTodayLineVerticalOffset() { - return getHeaderMonthHeight(); - } - - public int getVerticalTickMarkOffset() { - return getHeaderMonthHeight() - 5 > 0 ? getHeaderMonthHeight() - 5 : 0; - } - - public boolean drawHeader() { - return true; - } - - public int getEventsTopSpacer() { - return 12; - } - - public int getEventsBottomSpacer() { - return 12; - } - - public int getSectionBarDividerHeight() { - return 5; - } - - public int getSectionBarWidth() { - return 20; - } - - public int getMinimumSectionHeight() { - return 80; - } - - public boolean drawFullPercentageBar() { - return true; - } - - public int getPercentageBarAlpha() { - return 255; - } - - public int getRemainderPercentageBarAlpha() { - return 70; - } - - public int getAdvancedTooltipXOffset() { - return 15; - } - - public int getDragAllModifierKey() { - return SWT.SHIFT; - } - - public int getZoomWheelModifierKey() { - return SWT.MOD1; - } - - public Locale getDefaultLocale() { - return Locale.getDefault(); - } - - public boolean getUseAdvancedTooltips() { - return true; - } - - public boolean enableLastDraw() { - return false; - } - - public boolean useSplitArrowConnections() { - return true; - } - - public int getReverseDependencyLineHorizontalSpacer() { - return 2; - } - - public boolean drawVerticalLines() { - return true; - } - - public boolean drawHorizontalLines() { - return false; - } - - public int getSectionSide() { - return SWT.LEFT; - } - - public boolean drawLockedDateMarks() { - return true; - } - - public boolean showDateTipsOnScrolling() { - return true; - } - - public boolean drawFillsToBottomWhenUsingGanttSections() { - return false; - } - - public boolean drawGanttSectionBarToBottom() { - return false; - } - - public boolean lockHeaderOnVerticalScroll() { - return false; - } - - public boolean showDefaultMenuItemsOnEventRightClick() { - return true; - } - - public boolean allowScopeMenu() { - return false; - } - - public boolean allowHeaderSelection() { - return true; - } - - public boolean zoomToMousePointerDateOnWheelZooming() { - return true; - } - - public Calendar getDDayRootCalendar() { - final Calendar mDDayCalendar = Calendar.getInstance(getDefaultLocale()); - mDDayCalendar.set(Calendar.YEAR, mDDayCalendar.get(Calendar.YEAR)); - mDDayCalendar.set(Calendar.MONTH, Calendar.JANUARY); - mDDayCalendar.set(Calendar.DATE, 1); - mDDayCalendar.set(Calendar.HOUR, 0); - mDDayCalendar.set(Calendar.MINUTE, 0); - mDDayCalendar.set(Calendar.SECOND, 0); - mDDayCalendar.set(Calendar.MILLISECOND, 0); - return mDDayCalendar; - } - - public int getDDaySplitCount() { - return 10; - } - - public boolean drawEventsDownToTheHourAndMinute() { - return false; - } - - public boolean moveAndResizeOnlyDependentEventsThatAreLaterThanLinkedMoveEvent() { - return false; - } - - public boolean forceMouseWheelVerticalScroll() { - return false; - } - - public int getSectionTextSpacer() { - return 30; - } - - public int getPhasesHeaderHeight() { - return 18; - } - - public boolean allowPhaseOverlap() { - return false; - } - - public int getVerticalEventDragging() { - return VerticalDragModes.NO_VERTICAL_DRAG; - } - - public int getVerticalDragResistance() { - return 15; - } - - public boolean onVerticalDragDropShowInsertMarker() { - return true; - } - - public boolean scaleImageToDayWidth() { - return true; - } - - public boolean allowArrowKeysToScrollChart() { - return false; - } - - public int getNumberOfDaysToAppendForEndOfDay() { - return 1; - } - - public boolean scrollChartVerticallyOnMouseWheel() { - return true; - } - - public IToolTipContentReplacer getToolTipContentReplacer() { - return null; - } - - public int getMinZoomLevel() { - return ISettings.MIN_ZOOM_LEVEL; - } - - public Calendar getPeriodStart() { - return null; - } - - public Calendar getPeriodEnd() { - return null; - } - - public boolean shiftHorizontalCenteredEventString() { - return false; - } - - public boolean enableAddEvent() { - return false; - } - - public boolean drawEventString() { - return true; - } - - public boolean alwaysDragAllEvents() { - return false; - } - - public boolean printSelectedVerticallyComplete() { - return false; - } - - public boolean printFooter() { - return true; - } - - public boolean drawSectionBar() { - return true; - } - - public boolean drawSectionDetails() { - return false; - } - - public int getSectionDetailWidth() { - return 100; - } - - public String getSectionDetailTitle() { - return "\\b\\s8\\ce#name#"; - } - - public String getSectionDetailText() { - return "\\ceEvents: #ne#"; - } - - public ISectionDetailContentReplacer getSectionDetailContentReplacer() { - return null; - } - - public boolean showSectionDetailMore() { - return false; - } - - public boolean showHolidayToolTips() { - return false; - } - - public boolean enableTodayLineUpdater() { - return true; - } - - public boolean fireEmptyEventSelection() { - return false; - } -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + * ziogiannigmail.com - Bug 464509 - Minute View Implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.ganttchart; + +import java.util.Calendar; +import java.util.Locale; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; + +public abstract class AbstractSettings implements ISettings2 { + + public String getDateFormat() { + return "MM/dd/yyyy"; + } + + public String getHourDateFormat() { + return "MM/dd/yyyy HH:mm"; + } + + public String getMinuteDateFormat() { + return "MM/dd/yyyy HH:mm:ss"; + } + + public String getWeekHeaderTextDisplayFormatTop() { + return "MMM dd, ''yy"; + } + + public String getMonthHeaderTextDisplayFormatTop() { + return "MMMMM ''yy"; + } + + public String getDayHeaderTextDisplayFormatTop() { + return "MMM dd, HH:mm"; + } + + public String getMinuteHeaderTextDisplayFormatTop() { + return "MMM dd, HH:mm"; + } + + public String getYearHeaderTextDisplayFormatTop() { + return "yyyy"; + } + + public String getDayHeaderTextDisplayFormatBottom() { + return "HH:mm"; + } + + public String getMinuteHeaderTextDisplayFormatBottom() { + return "HH:mm"; + } + + public String getMonthHeaderTextDisplayFormatBottom() { + return "MMM dd"; + } + + public String getWeekHeaderTextDisplayFormatBottom() { + return "E"; + } + + public String getYearHeaderTextDisplayFormatBottom() { + return "MMM"; + } + + public Color getDefaultEventColor() { + return ColorCache.getColor(181, 180, 181); + } + + public Color getDefaultGradientEventColor() { + return ColorCache.getColor(235, 235, 235); + } + + public boolean showPropertiesMenuOption() { + return true; + } + + public boolean showDeleteMenuOption() { + return true; + } + + public boolean adjustForLetters() { + return true; + } + + public boolean enableAutoScroll() { + return true; + } + + public boolean enableResizing() { + return true; + } + + public int getArrowConnectionType() { + return CONNECTION_MS_PROJECT_STYLE; + } + + public int getDayHorizontalSpacing() { + return 3; + } + + public int getDayVerticalSpacing() { + return 3; + } + + public int getDayWidth() { + return 16; + } + + public int getEventHeight() { + return 12; + } + + public int getEventPercentageBarHeight() { + return 3; + } + + public int getHeaderMonthHeight() { + return 18; + } + + public int getHeaderDayHeight() { + return 18; + } + + public int getInitialView() { + return VIEW_WEEK; + } + + public int getInitialZoomLevel() { + return ZOOM_DAY_NORMAL; + } + + public int getMonthDayWidth() { + return 6; + } + + public int getResizeBorderSensitivity() { + return 3; + } + + public int getTextSpacerConnected() { + return 9; + } + + public int getTextSpacerNonConnected() { + return 9; + } + + public int getYearMonthDayWidth() { + return 3; + } + + public boolean moveLinkedEventsWhenEventsAreMoved() { + return true; + } + + public boolean showArrows() { + return true; + } + + public boolean showBarsIn3D() { + return true; + } + + public boolean showBoldScopeText() { + return true; + } + + public boolean showDateTips() { + return true; + } + + public boolean showPlannedDates() { + return false; + } + + public boolean showGradientEventBars() { + return true; + } + + public boolean showNumberOfDaysOnBars() { + return false; + } + + public boolean showOnlyDependenciesForSelectedItems() { + return false; + } + + public boolean showToolTips() { + return true; + } + + public int getEventSpacer() { + return 12; + } + + public boolean enableDragAndDrop() { + return true; + } + + public boolean showZoomLevelBox() { + return true; + } + + public boolean allowInfiniteHorizontalScrollBar() { + return true; + } + + public boolean showResizeDateTipOnBorders() { + return true; + } + + public boolean allowBlankAreaDragAndDropToMoveDates() { + return true; + } + + public boolean allowBlankAreaVerticalDragAndDropToMoveChart() { + return false; + } + + public boolean flipBlankAreaDragDirection() { + return true; + } + + public boolean drawSelectionMarkerAroundSelectedEvent() { + return true; + } + + public boolean allowCheckpointResizing() { + return false; + } + + public boolean showMenuItemsOnRightClick() { + return true; + } + + public int getArrowHeadEventSpacer() { + return 1; + } + + public int getArrowHeadVerticalAdjuster() { + return 0; + } + + public Calendar getStartupCalendarDate() { + return Calendar.getInstance(Locale.getDefault()); + } + + public int getCalendarStartupDateOffset() { + return -4; + } + + public boolean startCalendarOnFirstDayOfWeek() { + return false; + } + + public int getMoveAreaNegativeSensitivity() { + return 6; + } + + public boolean enableZooming() { + return true; + } + + public Image getLockImage() { + return ImageCache.getImage("icons/lock_tiny.gif"); + } + + public String getTextDisplayFormat() { + return "#name# (#pc#%)"; + } + + public int getRevisedLineSpacer() { + return 3; + } + + public Image getDefaultAdvandedTooltipHelpImage() { + return null; + } + + public Image getDefaultAdvandedTooltipImage() { + return null; + } + + public boolean roundHourlyEventsOffToNearestHour() { + return false; + } + + public String getDefaultAdvancedTooltipHelpText() { + return null; + } + + public String getDefaultAdvancedTooltipTitle() { + return "\\b\\c027050082#name#"; + } + + public String getDefaultAdvancedTooltipTextExtended() { + final StringBuffer buf = new StringBuffer(); + buf.append("\\ceRevised: #rs# - #re# (#reviseddays# day(s))\n"); + buf.append("\\c100100100Planned: #sd# - #ed# (#days# day(s))\n"); + buf.append("#pc#% complete"); + return buf.toString();// "\\ceStart Date: \\b#sd#\nEnd Date: \\b#ed#\nRevised Start: \\b#rs#\nRevised End: \\b#re#\nDay Span: \\b#days# days\nPercent Complete: \\b#pc#%"; + } + + public String getDefaultAdvancedTooltipText() { + final StringBuffer buf = new StringBuffer(); + buf.append("\\cePlanned: #sd# - #ed# (#days# day(s))\n"); + buf.append("\\c100100100#pc#% complete"); + return buf.toString(); + } + + public int getTodayLineStyle() { + return SWT.LINE_SOLID; + } + + public int getTodayLineWidth() { + return 2; + } + + public int getTodayLineVerticalOffset() { + return getHeaderMonthHeight(); + } + + public int getVerticalTickMarkOffset() { + return getHeaderMonthHeight() - 5 > 0 ? getHeaderMonthHeight() - 5 : 0; + } + + public boolean drawHeader() { + return true; + } + + public int getEventsTopSpacer() { + return 12; + } + + public int getEventsBottomSpacer() { + return 12; + } + + public int getSectionBarDividerHeight() { + return 5; + } + + public int getSectionBarWidth() { + return 20; + } + + public int getMinimumSectionHeight() { + return 80; + } + + public boolean drawFullPercentageBar() { + return true; + } + + public int getPercentageBarAlpha() { + return 255; + } + + public int getRemainderPercentageBarAlpha() { + return 70; + } + + public int getAdvancedTooltipXOffset() { + return 15; + } + + public int getDragAllModifierKey() { + return SWT.SHIFT; + } + + public int getZoomWheelModifierKey() { + return SWT.MOD1; + } + + public Locale getDefaultLocale() { + return Locale.getDefault(); + } + + public boolean getUseAdvancedTooltips() { + return true; + } + + public boolean enableLastDraw() { + return false; + } + + public boolean useSplitArrowConnections() { + return true; + } + + public int getReverseDependencyLineHorizontalSpacer() { + return 2; + } + + public boolean drawVerticalLines() { + return true; + } + + public boolean drawHorizontalLines() { + return false; + } + + public int getSectionSide() { + return SWT.LEFT; + } + + public boolean drawLockedDateMarks() { + return true; + } + + public boolean showDateTipsOnScrolling() { + return true; + } + + public boolean drawFillsToBottomWhenUsingGanttSections() { + return false; + } + + public boolean drawGanttSectionBarToBottom() { + return false; + } + + public boolean lockHeaderOnVerticalScroll() { + return false; + } + + public boolean showDefaultMenuItemsOnEventRightClick() { + return true; + } + + public boolean allowScopeMenu() { + return false; + } + + public boolean allowHeaderSelection() { + return true; + } + + public boolean zoomToMousePointerDateOnWheelZooming() { + return true; + } + + public Calendar getDDayRootCalendar() { + final Calendar mDDayCalendar = Calendar.getInstance(getDefaultLocale()); + mDDayCalendar.set(Calendar.YEAR, mDDayCalendar.get(Calendar.YEAR)); + mDDayCalendar.set(Calendar.MONTH, Calendar.JANUARY); + mDDayCalendar.set(Calendar.DATE, 1); + mDDayCalendar.set(Calendar.HOUR, 0); + mDDayCalendar.set(Calendar.MINUTE, 0); + mDDayCalendar.set(Calendar.SECOND, 0); + mDDayCalendar.set(Calendar.MILLISECOND, 0); + return mDDayCalendar; + } + + public int getDDaySplitCount() { + return 10; + } + + public boolean drawEventsDownToTheHourAndMinute() { + return false; + } + + public boolean moveAndResizeOnlyDependentEventsThatAreLaterThanLinkedMoveEvent() { + return false; + } + + public boolean forceMouseWheelVerticalScroll() { + return false; + } + + public int getSectionTextSpacer() { + return 30; + } + + public int getPhasesHeaderHeight() { + return 18; + } + + public boolean allowPhaseOverlap() { + return false; + } + + public int getVerticalEventDragging() { + return VerticalDragModes.NO_VERTICAL_DRAG; + } + + public int getVerticalDragResistance() { + return 15; + } + + public boolean onVerticalDragDropShowInsertMarker() { + return true; + } + + public boolean scaleImageToDayWidth() { + return true; + } + + public boolean allowArrowKeysToScrollChart() { + return false; + } + + public int getNumberOfDaysToAppendForEndOfDay() { + return 1; + } + + public boolean scrollChartVerticallyOnMouseWheel() { + return true; + } + + public IToolTipContentReplacer getToolTipContentReplacer() { + return null; + } + + public int getMinZoomLevel() { + return ISettings.MIN_ZOOM_LEVEL; + } + + public Calendar getPeriodStart() { + return null; + } + + public Calendar getPeriodEnd() { + return null; + } + + public boolean shiftHorizontalCenteredEventString() { + return false; + } + + public boolean enableAddEvent() { + return false; + } + + public boolean drawEventString() { + return true; + } + + public boolean alwaysDragAllEvents() { + return false; + } + + public boolean printSelectedVerticallyComplete() { + return false; + } + + public boolean printFooter() { + return true; + } + + public boolean drawSectionBar() { + return true; + } + + public boolean drawSectionDetails() { + return false; + } + + public int getSectionDetailWidth() { + return 100; + } + + public String getSectionDetailTitle() { + return "\\b\\s8\\ce#name#"; + } + + public String getSectionDetailText() { + return "\\ceEvents: #ne#"; + } + + public ISectionDetailContentReplacer getSectionDetailContentReplacer() { + return null; + } + + public boolean showSectionDetailMore() { + return false; + } + + public boolean showHolidayToolTips() { + return false; + } + + public boolean enableTodayLineUpdater() { + return true; + } + + public boolean fireEmptyEventSelection() { + return false; + } +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/CompoundViewPortHandler.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/CompoundViewPortHandler.java index 28f0e312c..620fc22f6 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/CompoundViewPortHandler.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/CompoundViewPortHandler.java @@ -1,107 +1,107 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - * ziogiannigmail.com - Bug 464509 - Minute View Implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -import java.util.ArrayList; -import java.util.List; - - -public class CompoundViewPortHandler implements IViewPortHandler2 { - - private List handler = new ArrayList(); - - public void addHandler(IViewPortHandler handler) { - this.handler.add(handler); - } - - public void removeHandler(IViewPortHandler handler) { - this.handler.remove(handler); - } - - public void scrollingLeft(int diffCount) { - for (IViewPortHandler vph : this.handler) { - vph.scrollingLeft(diffCount); - } - } - - public void scrollingRight(int diffCount) { - for (IViewPortHandler vph : this.handler) { - vph.scrollingRight(diffCount); - } - } - - public void nextMonth() { - for (IViewPortHandler vph : this.handler) { - vph.nextMonth(); - } - } - - public void prevMonth() { - for (IViewPortHandler vph : this.handler) { - vph.prevMonth(); - } - } - - public void nextWeek() { - for (IViewPortHandler vph : this.handler) { - vph.nextWeek(); - } - } - - public void prevWeek() { - for (IViewPortHandler vph : this.handler) { - vph.prevWeek(); - } - } - - public void nextHour() { - for (IViewPortHandler vph : this.handler) { - vph.nextHour(); - } - } - - public void prevHour() { - for (IViewPortHandler vph : this.handler) { - vph.prevHour(); - } - } - - public void nextMinute() { - for (IViewPortHandler vph : this.handler) { - if(vph instanceof IViewPortHandler2) - ((IViewPortHandler2) vph).nextMinute(); - } - } - - public void prevMinute() { - for (IViewPortHandler vph : this.handler) { - if(vph instanceof IViewPortHandler2) - ((IViewPortHandler2) vph).prevMinute(); - } - } - - public void nextDay() { - for (IViewPortHandler vph : this.handler) { - vph.nextDay(); - } - } - - public void prevDay() { - for (IViewPortHandler vph : this.handler) { - vph.prevDay(); - } - } - -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + * ziogiannigmail.com - Bug 464509 - Minute View Implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +import java.util.ArrayList; +import java.util.List; + + +public class CompoundViewPortHandler implements IViewPortHandler2 { + + private List handler = new ArrayList(); + + public void addHandler(IViewPortHandler handler) { + this.handler.add(handler); + } + + public void removeHandler(IViewPortHandler handler) { + this.handler.remove(handler); + } + + public void scrollingLeft(int diffCount) { + for (IViewPortHandler vph : this.handler) { + vph.scrollingLeft(diffCount); + } + } + + public void scrollingRight(int diffCount) { + for (IViewPortHandler vph : this.handler) { + vph.scrollingRight(diffCount); + } + } + + public void nextMonth() { + for (IViewPortHandler vph : this.handler) { + vph.nextMonth(); + } + } + + public void prevMonth() { + for (IViewPortHandler vph : this.handler) { + vph.prevMonth(); + } + } + + public void nextWeek() { + for (IViewPortHandler vph : this.handler) { + vph.nextWeek(); + } + } + + public void prevWeek() { + for (IViewPortHandler vph : this.handler) { + vph.prevWeek(); + } + } + + public void nextHour() { + for (IViewPortHandler vph : this.handler) { + vph.nextHour(); + } + } + + public void prevHour() { + for (IViewPortHandler vph : this.handler) { + vph.prevHour(); + } + } + + public void nextMinute() { + for (IViewPortHandler vph : this.handler) { + if(vph instanceof IViewPortHandler2) + ((IViewPortHandler2) vph).nextMinute(); + } + } + + public void prevMinute() { + for (IViewPortHandler vph : this.handler) { + if(vph instanceof IViewPortHandler2) + ((IViewPortHandler2) vph).prevMinute(); + } + } + + public void nextDay() { + for (IViewPortHandler vph : this.handler) { + vph.nextDay(); + } + } + + public void prevDay() { + for (IViewPortHandler vph : this.handler) { + vph.prevDay(); + } + } + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/CompoundZoomHandler.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/CompoundZoomHandler.java index 831c68584..163896565 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/CompoundZoomHandler.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/CompoundZoomHandler.java @@ -1,63 +1,63 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.graphics.Point; - -public class CompoundZoomHandler implements IZoomHandler { - - private List handler = new ArrayList(); - - public void addHandler(IZoomHandler handler) { - this.handler.add(handler); - } - - public void removeHandler(IViewPortHandler handler) { - this.handler.remove(handler); - } - - public void zoomIn() { - for (IZoomHandler vph : this.handler) { - vph.zoomIn(); - } - } - - public void zoomIn(boolean fromMouseWheel, Point mouseLoc) { - for (IZoomHandler vph : this.handler) { - vph.zoomIn(fromMouseWheel, mouseLoc); - } - } - - public void zoomOut() { - for (IZoomHandler vph : this.handler) { - vph.zoomOut(); - } - } - - public void zoomOut(boolean fromMouseWheel, Point mouseLoc) { - for (IZoomHandler vph : this.handler) { - vph.zoomOut(fromMouseWheel, mouseLoc); - } - } - - public void resetZoom() { - for (IZoomHandler vph : this.handler) { - vph.resetZoom(); - } - } - -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.graphics.Point; + +public class CompoundZoomHandler implements IZoomHandler { + + private List handler = new ArrayList(); + + public void addHandler(IZoomHandler handler) { + this.handler.add(handler); + } + + public void removeHandler(IViewPortHandler handler) { + this.handler.remove(handler); + } + + public void zoomIn() { + for (IZoomHandler vph : this.handler) { + vph.zoomIn(); + } + } + + public void zoomIn(boolean fromMouseWheel, Point mouseLoc) { + for (IZoomHandler vph : this.handler) { + vph.zoomIn(fromMouseWheel, mouseLoc); + } + } + + public void zoomOut() { + for (IZoomHandler vph : this.handler) { + vph.zoomOut(); + } + } + + public void zoomOut(boolean fromMouseWheel, Point mouseLoc) { + for (IZoomHandler vph : this.handler) { + vph.zoomOut(fromMouseWheel, mouseLoc); + } + } + + public void resetZoom() { + for (IZoomHandler vph : this.handler) { + vph.resetZoom(); + } + } + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/DefaultEventFactory.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/DefaultEventFactory.java index f81fb5398..69a61118a 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/DefaultEventFactory.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/DefaultEventFactory.java @@ -1,38 +1,38 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -import java.util.Calendar; - -public class DefaultEventFactory implements IEventFactory { - - public GanttEvent createGanttEvent( - GanttChart parent, - GanttSection gs, - String name, - Calendar start, - Calendar end) { - - GanttEvent newEvent = new GanttEvent(parent, name, start, end, 0); - newEvent.setStatusColor(ColorCache.getColor(24, 43, 69)); - - //add event to section - if (gs != null) { - gs.addGanttEvent(newEvent); - } - - return newEvent; - } - -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +import java.util.Calendar; + +public class DefaultEventFactory implements IEventFactory { + + public GanttEvent createGanttEvent( + GanttChart parent, + GanttSection gs, + String name, + Calendar start, + Calendar end) { + + GanttEvent newEvent = new GanttEvent(parent, name, start, end, 0); + newEvent.setStatusColor(ColorCache.getColor(24, 43, 69)); + + //add event to section + if (gs != null) { + gs.addGanttEvent(newEvent); + } + + return newEvent; + } + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttConnection.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttConnection.java index 90a1188ef..7e9e37465 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttConnection.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttConnection.java @@ -1,181 +1,181 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.ganttchart; - -import org.eclipse.swt.graphics.Color; - -/** - * This class represents one connection between two events in one direction. You may create a connection by using this class, or do it the slightly easier way by calling - * {@link GanttChart#addConnection(GanttEvent, GanttEvent)} on the {@link GanttChart}. - * - */ -public class GanttConnection implements Cloneable { - - private GanttEvent _source; - private GanttEvent _target; - private Color _color; - private GanttComposite _parent; - - GanttConnection() { - super(); - } - - GanttConnection(final GanttEvent source, final GanttEvent target, final Color color) { - this(null, source, target, color); - } - - /** - * Creates a new connection between two events. - * - * @param parent Gantt Chart parent - * @param source Source event - * @param target Target event - */ - public GanttConnection(final GanttChart parent, final GanttEvent source, final GanttEvent target) { - this(parent, source, target, null); - } - - /** - * Creates a new connection between two events and gives the connecting line a specific color. - * - * @param parent Gantt Chart parent - * @param source Source event - * @param target Target event - * @param lineColor Color of line and arrowhead drawn between the events - */ - public GanttConnection(final GanttChart parent, final GanttEvent source, final GanttEvent target, final Color lineColor) { - _source = source; - _target = target; - _color = lineColor; - if (parent != null) { - _parent = parent.getGanttComposite(); - _parent.connectionAdded(this); - } - } - - /** - * Returns the source event of this connection. - * - * @return Source event - */ - public GanttEvent getSource() { - return _source; - } - - /** - * Sets the source event of this connection. - * - * @param source Source event - */ - public void setSource(final GanttEvent source) { - this._source = source; - } - - /** - * Returns the target event of this connection. - * - * @return Target event - */ - public GanttEvent getTarget() { - return _target; - } - - /** - * Sets the target event of this connection. - * - * @param target Target event - */ - public void setTarget(final GanttEvent target) { - this._target = target; - } - - /** - * Returns the color of the line drawn in the connection. - * - * @return Color - */ - public Color getColor() { - return _color; - } - - /** - * Sets the color of the line drawn in the connection. - * - * @param color Color or null for default color. - */ - public void setColor(final Color color) { - this._color = color; - } - - /** - * Disposes this connection - */ - public void dispose() { - _parent.connectionRemoved(this); - } - - - /** - * Set the parent composite - * @param _parent - */ - void setParentComposite(GanttComposite _parent) { - this._parent = _parent; - } - - /** - * Clones the GanttConnection (and adds the clone to the parent) - */ - public Object clone() throws CloneNotSupportedException { // NOPMD - final GanttConnection clone = new GanttConnection(); - clone._parent = _parent; - clone._color = _color; - clone._source = _source; - clone._target = _target; - - _parent.connectionAdded(clone); - return clone; - } - - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final GanttConnection other = (GanttConnection) obj; - if (_source == null) { - if (other._source != null) { - return false; - } - } else if (!_source.equals(other._source)) { - return false; - } - if (_target == null) { - if (other._target != null) { - return false; - } - } else if (!_target.equals(other._target)) { - return false; - } - - return true; - } - -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.ganttchart; + +import org.eclipse.swt.graphics.Color; + +/** + * This class represents one connection between two events in one direction. You may create a connection by using this class, or do it the slightly easier way by calling + * {@link GanttChart#addConnection(GanttEvent, GanttEvent)} on the {@link GanttChart}. + * + */ +public class GanttConnection implements Cloneable { + + private GanttEvent _source; + private GanttEvent _target; + private Color _color; + private GanttComposite _parent; + + GanttConnection() { + super(); + } + + GanttConnection(final GanttEvent source, final GanttEvent target, final Color color) { + this(null, source, target, color); + } + + /** + * Creates a new connection between two events. + * + * @param parent Gantt Chart parent + * @param source Source event + * @param target Target event + */ + public GanttConnection(final GanttChart parent, final GanttEvent source, final GanttEvent target) { + this(parent, source, target, null); + } + + /** + * Creates a new connection between two events and gives the connecting line a specific color. + * + * @param parent Gantt Chart parent + * @param source Source event + * @param target Target event + * @param lineColor Color of line and arrowhead drawn between the events + */ + public GanttConnection(final GanttChart parent, final GanttEvent source, final GanttEvent target, final Color lineColor) { + _source = source; + _target = target; + _color = lineColor; + if (parent != null) { + _parent = parent.getGanttComposite(); + _parent.connectionAdded(this); + } + } + + /** + * Returns the source event of this connection. + * + * @return Source event + */ + public GanttEvent getSource() { + return _source; + } + + /** + * Sets the source event of this connection. + * + * @param source Source event + */ + public void setSource(final GanttEvent source) { + this._source = source; + } + + /** + * Returns the target event of this connection. + * + * @return Target event + */ + public GanttEvent getTarget() { + return _target; + } + + /** + * Sets the target event of this connection. + * + * @param target Target event + */ + public void setTarget(final GanttEvent target) { + this._target = target; + } + + /** + * Returns the color of the line drawn in the connection. + * + * @return Color + */ + public Color getColor() { + return _color; + } + + /** + * Sets the color of the line drawn in the connection. + * + * @param color Color or null for default color. + */ + public void setColor(final Color color) { + this._color = color; + } + + /** + * Disposes this connection + */ + public void dispose() { + _parent.connectionRemoved(this); + } + + + /** + * Set the parent composite + * @param _parent + */ + void setParentComposite(GanttComposite _parent) { + this._parent = _parent; + } + + /** + * Clones the GanttConnection (and adds the clone to the parent) + */ + public Object clone() throws CloneNotSupportedException { // NOPMD + final GanttConnection clone = new GanttConnection(); + clone._parent = _parent; + clone._color = _color; + clone._source = _source; + clone._target = _target; + + _parent.connectionAdded(clone); + return clone; + } + + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final GanttConnection other = (GanttConnection) obj; + if (_source == null) { + if (other._source != null) { + return false; + } + } else if (!_source.equals(other._source)) { + return false; + } + if (_target == null) { + if (other._target != null) { + return false; + } + } else if (!_target.equals(other._target)) { + return false; + } + + return true; + } + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSection.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSection.java index 3cc71296c..fddd19a7d 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSection.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSection.java @@ -1,453 +1,453 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.ganttchart; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; - -/** - * A GanttSection is a "box" section of the chart. A section will automatically get a left-side border that shows the - * name, and the background colors drawn for that section can differ from the rest of the chart. Here's an view of it:
- *
- * ................................................
- * Header
- * ................................................
- * n
- * a      Section
- * m
- * e
- * ................................................
- *
- */ -public class GanttSection implements IFillBackgroundColors { - - private Object _data; - private String _name; - private GanttComposite _parent; - private List _ganttEvents; - // this list contains events that are being vertically DND'd across the section - // and need to be rendered but should not count as actual member-events until (if) they are dropped - private List _dndGanttEvents; - private Rectangle _bounds; - private Image _nameImage; - private Image _additionalImage; - private boolean _needsNameUpdate; - private IFillBackgroundColors _fillColorManager; - - private Color _saturdayBgColorTop; - private Color _saturdayBgColorBottom; - private Color _sundayBgColorTop; - private Color _sundayBgColorBottom; - private Color _holidayBgColorTop; - private Color _holidayBgColorBottom; - private Color _weekdayBgColorTop; - private Color _weekdayBgColorBottom; - private Color _selectedBgColorTop; - private Color _selectedBgColorBottom; - private Color _selectedBgHeaderColorTop; - private Color _selectedBgHeaderColorBottom; - - // private items - private Point _nameExtent; - - private int _textOrientation = SWT.VERTICAL; - - private boolean _inheritBackgroud; - - private GanttSection() { - this._ganttEvents = new ArrayList(); - this._dndGanttEvents = new ArrayList(); - } - - /** - * Creates a new GanttSection. - * - * @param parent GanttChart - * @param name GanttSection name - */ - public GanttSection(final GanttChart parent, final String name) { - this(); - this._name = name; - this._parent = parent.getGanttComposite(); - this._parent.addSection(this); - this._fillColorManager = parent.getColorManager(); - } - - /** - * Creates a new GanttSection with a fill manager that controls background colors. - * - * @param parent GanttChart - * @param name GanttSection name - * @param fillManager Fill manager - */ - public GanttSection(final GanttChart parent, final String name, final IFillBackgroundColors fillManager) { - this(); - this._name = name; - this._parent = parent.getGanttComposite(); - this._parent.addSection(this); - this._fillColorManager = fillManager; - } - - /** - * Adds a Gantt Chart item (GanttSection, GanttGroup) to this section. - * - * @param event Item to add - */ - public void addGanttEvent(final IGanttChartItem event) { - addGanttEvent(-1, event); - } - - /** - * Adds a Gantt Chart item at the given index. - * - * @param index Index to add item at - * @param event Item to add - */ - public void addGanttEvent(final int index, final IGanttChartItem event) { - int inx = index; - - if (!_ganttEvents.contains(event)) { - if (inx == -1) { - _ganttEvents.add(event); - } else { - if (inx > _ganttEvents.size()) { - inx = _ganttEvents.size(); - } - _ganttEvents.add(inx, event); - } - if (event instanceof GanttEvent) { - ((GanttEvent) event).setGanttSection(this); - } - - } - } - - /** - * Removes a Gantt Chart item (GanttSection, GanttGroup) from this section. - * - * @param event Item to remove - */ - public void removeGanttEvent(final IGanttChartItem event) { - _ganttEvents.remove(event); - } - - - /** - * @return the additional image - */ - public Image getAdditionalImage() { - return _additionalImage; - } - - /** - * @param _additionalImage the additional image to set - */ - public void setAdditionalImage(Image _additionalImage) { - this._additionalImage = _additionalImage; - } - - /** - * Returns a list of all IGanttChartItems (GanttEvent and GanttGroup) contained in this section. - * - * @return List of items - */ - public List getEvents() { - return _ganttEvents; - } - - /** - * Returns the currently set data object. - * - * @return Data object - */ - public Object getData() { - return _data; - } - - /** - * Sets the current data object. - * - * @param data Data object - */ - public void setData(final Object data) { - this._data = data; - } - - /** - * Sets the name of this section. This method does not force a redraw. - * - * @param name GanttSection name - */ - public void setName(final String name) { - this._name = name; - this._needsNameUpdate = true; - } - - /** - * Returns the name of this section. - * - * @return GanttSection name - */ - public String getName() { - return _name; - } - - /** - * Returns the bounds of this GanttSection - * - * @return Rectangle - */ - public Rectangle getBounds() { - return _bounds; - } - - public Color getSaturdayBackgroundColorBottom() { - return _saturdayBgColorBottom == null ? _fillColorManager.getSaturdayBackgroundColorBottom() : _saturdayBgColorBottom; - } - - public Color getSaturdayBackgroundColorTop() { - return _saturdayBgColorTop == null ? _fillColorManager.getSaturdayBackgroundColorTop() : _saturdayBgColorTop; - } - - public Color getSundayBackgroundColorBottom() { - return _sundayBgColorBottom == null ? _fillColorManager.getSundayBackgroundColorBottom() : _sundayBgColorBottom; - } - - public Color getSundayBackgroundColorTop() { - return _sundayBgColorTop == null ? _fillColorManager.getSundayBackgroundColorTop() : _sundayBgColorTop; - } - - public Color getHolidayBackgroundColorBottom() { - return _holidayBgColorBottom == null ? _fillColorManager.getHolidayBackgroundColorBottom() : _holidayBgColorBottom; - } - - public Color getHolidayBackgroundColorTop() { - return _holidayBgColorTop == null ? _fillColorManager.getHolidayBackgroundColorTop() : _holidayBgColorTop; - } - - public Color getWeekdayBackgroundColorBottom() { - return _weekdayBgColorBottom == null ? _fillColorManager.getWeekdayBackgroundColorBottom() : _weekdayBgColorBottom; - } - - public Color getWeekdayBackgroundColorTop() { - return _weekdayBgColorTop == null ? _fillColorManager.getWeekdayBackgroundColorTop() : _weekdayBgColorTop; - } - - public Color getSelectedDayColorBottom() { - return _selectedBgColorBottom == null ? _fillColorManager.getSelectedDayColorBottom() : _selectedBgColorBottom; - } - - public Color getSelectedDayColorTop() { - return _selectedBgColorTop == null ? _fillColorManager.getSelectedDayColorTop() : _selectedBgColorTop; - } - - public Color getSelectedDayHeaderColorBottom() { - return _selectedBgHeaderColorBottom == null ? _fillColorManager.getSelectedDayHeaderColorBottom() : _selectedBgHeaderColorBottom; - } - - public Color getSelectedDayHeaderColorTop() { - return _selectedBgHeaderColorTop == null ? _fillColorManager.getSelectedDayHeaderColorTop() : _selectedBgHeaderColorTop; - } - - public void setSaturdayBackgroundColorTop(final Color saturdayBackgroundColorTop) { - _saturdayBgColorTop = saturdayBackgroundColorTop; - } - - public void setSaturdayBackgroundColorBottom(final Color saturdayBackgroundColorBottom) { - _saturdayBgColorBottom = saturdayBackgroundColorBottom; - } - - public void setSundayBackgroundColorTop(final Color sundayBackgroundColorTop) { - _sundayBgColorTop = sundayBackgroundColorTop; - } - - public void setSundayBackgroundColorBottom(final Color sundayBackgroundColorBottom) { - _sundayBgColorBottom = sundayBackgroundColorBottom; - } - - public void setHolidayBackgroundColorTop(final Color holidayBackgroundColorTop) { - _holidayBgColorTop = holidayBackgroundColorTop; - } - - public void setHolidayBackgroundColorBottom(final Color holidayBackgroundColorBottom) { - _holidayBgColorBottom = holidayBackgroundColorBottom; - } - - public void setWeekdayBackgroundColorTop(final Color weekdayBackgroundColorTop) { - _weekdayBgColorTop = weekdayBackgroundColorTop; - } - - public void setWeekdayBackgroundColorBottom(final Color weekdayBackgroundColorBottom) { - _weekdayBgColorBottom = weekdayBackgroundColorBottom; - } - - public void setSelectedBackgroundColorTop(final Color selectedBackgroundColorTop) { - _selectedBgColorTop = selectedBackgroundColorTop; - } - - public void setSelectedBackgroundColorBottom(final Color selectedBackgroundColorBottom) { - _selectedBgColorBottom = selectedBackgroundColorBottom; - } - - public void setSelectedBackgroundHeaderColorTop(final Color selectedBackgroundHeaderColorTop) { - _selectedBgHeaderColorTop = selectedBackgroundHeaderColorTop; - } - - public void setSelectedBackgroundHeaderColorBottom(final Color selectedBackgroundHeaderColorBottom) { - _selectedBgHeaderColorBottom = selectedBackgroundHeaderColorBottom; - } - - /** - * Returns the text orientation of the section. Default is SWT.VERTICAL. - * - * @return Text orientation. - */ - public int getTextOrientation() { - return _textOrientation; - } - - /** - * Sets the text orientation of the section. One of SWT.HORIZONTAL or SWT.VERTICAL. Default is SWT.VERTICAL. - * - * @param textOrientation SWT.VERTICAL or SWT.HORIZONTAL - */ - public void setTextOrientation(final int textOrientation) { - _textOrientation = textOrientation; - } - - /** - * Whether this section should just inherit the background colors of the main chart. - * - * @return true if set - * @deprecated IN PROGRESS - */ - boolean isInheritBackgroud() { - return _inheritBackgroud; - } - - /** - * Sets whether this section should inherit the background colors of the main chart for drawing date fills. - * - * @param inheritBackgroud true to inherit. Default is false. - * @deprecated IN PROGRESS - */ - void setInheritBackgroud(final boolean inheritBackgroud) { - _inheritBackgroud = inheritBackgroud; - } - - /** - * Returns the parent {@link GanttComposite} - * - * @return {@link GanttComposite} - */ - public GanttComposite getParentComposite() { - return _parent; - } - - /** - * Removes this section from the chart. Do note that all belonging GanttEvents will be orphaned, so you should - * probably deal with that post disposal. - */ - public void dispose() { - _parent.removeSection(this); - _parent.redraw(); - } - - Point getNameExtent() { - return _nameExtent; - } - - void setNameExtent(final Point extent) { - this._nameExtent = extent; - } - - void setBounds(final Rectangle bounds) { - this._bounds = bounds; - } - - Image getNameImage() { - return _nameImage; - } - - void setNameImage(final Image nameImage) { - this._nameImage = nameImage; - this._needsNameUpdate = false; - } - - boolean needsNameUpdate() { - return _needsNameUpdate; - } - - void setNeedsNameUpdate(final boolean need) { - _needsNameUpdate = need; - } - - int getEventsHeight(final ISettings settings) { - if (_ganttEvents.size() == 0) { - return settings.getMinimumSectionHeight(); - } - - int height = settings.getEventsTopSpacer(); - - for (int i = 0; i < _ganttEvents.size(); i++) { - final IGanttChartItem event = (IGanttChartItem) _ganttEvents.get(i); - - if (event.isAutomaticRowHeight()) { - height += settings.getEventHeight(); - } - else { - height += event.getFixedRowHeight(); - } - - if (i != _ganttEvents.size() - 1) { - height += settings.getEventSpacer(); - } - } - - height += settings.getEventsBottomSpacer(); - - if (height < settings.getMinimumSectionHeight()) { - height = settings.getMinimumSectionHeight(); - } - - return height; - } - - void addDNDGanttEvent(final GanttEvent ge) { - if (!_dndGanttEvents.contains(ge)) { - _dndGanttEvents.add(ge); - } - } - - void clearDNDGanttEvents() { - _dndGanttEvents.clear(); - } - - List getDNDGanttEvents() { - return _dndGanttEvents; - } - - public String toString() { - return "[GanttSection: " + _name + "]"; - } - - -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.ganttchart; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; + +/** + * A GanttSection is a "box" section of the chart. A section will automatically get a left-side border that shows the + * name, and the background colors drawn for that section can differ from the rest of the chart. Here's an view of it:
+ *
+ * ................................................
+ * Header
+ * ................................................
+ * n
+ * a      Section
+ * m
+ * e
+ * ................................................
+ *
+ */ +public class GanttSection implements IFillBackgroundColors { + + private Object _data; + private String _name; + private GanttComposite _parent; + private List _ganttEvents; + // this list contains events that are being vertically DND'd across the section + // and need to be rendered but should not count as actual member-events until (if) they are dropped + private List _dndGanttEvents; + private Rectangle _bounds; + private Image _nameImage; + private Image _additionalImage; + private boolean _needsNameUpdate; + private IFillBackgroundColors _fillColorManager; + + private Color _saturdayBgColorTop; + private Color _saturdayBgColorBottom; + private Color _sundayBgColorTop; + private Color _sundayBgColorBottom; + private Color _holidayBgColorTop; + private Color _holidayBgColorBottom; + private Color _weekdayBgColorTop; + private Color _weekdayBgColorBottom; + private Color _selectedBgColorTop; + private Color _selectedBgColorBottom; + private Color _selectedBgHeaderColorTop; + private Color _selectedBgHeaderColorBottom; + + // private items + private Point _nameExtent; + + private int _textOrientation = SWT.VERTICAL; + + private boolean _inheritBackgroud; + + private GanttSection() { + this._ganttEvents = new ArrayList(); + this._dndGanttEvents = new ArrayList(); + } + + /** + * Creates a new GanttSection. + * + * @param parent GanttChart + * @param name GanttSection name + */ + public GanttSection(final GanttChart parent, final String name) { + this(); + this._name = name; + this._parent = parent.getGanttComposite(); + this._parent.addSection(this); + this._fillColorManager = parent.getColorManager(); + } + + /** + * Creates a new GanttSection with a fill manager that controls background colors. + * + * @param parent GanttChart + * @param name GanttSection name + * @param fillManager Fill manager + */ + public GanttSection(final GanttChart parent, final String name, final IFillBackgroundColors fillManager) { + this(); + this._name = name; + this._parent = parent.getGanttComposite(); + this._parent.addSection(this); + this._fillColorManager = fillManager; + } + + /** + * Adds a Gantt Chart item (GanttSection, GanttGroup) to this section. + * + * @param event Item to add + */ + public void addGanttEvent(final IGanttChartItem event) { + addGanttEvent(-1, event); + } + + /** + * Adds a Gantt Chart item at the given index. + * + * @param index Index to add item at + * @param event Item to add + */ + public void addGanttEvent(final int index, final IGanttChartItem event) { + int inx = index; + + if (!_ganttEvents.contains(event)) { + if (inx == -1) { + _ganttEvents.add(event); + } else { + if (inx > _ganttEvents.size()) { + inx = _ganttEvents.size(); + } + _ganttEvents.add(inx, event); + } + if (event instanceof GanttEvent) { + ((GanttEvent) event).setGanttSection(this); + } + + } + } + + /** + * Removes a Gantt Chart item (GanttSection, GanttGroup) from this section. + * + * @param event Item to remove + */ + public void removeGanttEvent(final IGanttChartItem event) { + _ganttEvents.remove(event); + } + + + /** + * @return the additional image + */ + public Image getAdditionalImage() { + return _additionalImage; + } + + /** + * @param _additionalImage the additional image to set + */ + public void setAdditionalImage(Image _additionalImage) { + this._additionalImage = _additionalImage; + } + + /** + * Returns a list of all IGanttChartItems (GanttEvent and GanttGroup) contained in this section. + * + * @return List of items + */ + public List getEvents() { + return _ganttEvents; + } + + /** + * Returns the currently set data object. + * + * @return Data object + */ + public Object getData() { + return _data; + } + + /** + * Sets the current data object. + * + * @param data Data object + */ + public void setData(final Object data) { + this._data = data; + } + + /** + * Sets the name of this section. This method does not force a redraw. + * + * @param name GanttSection name + */ + public void setName(final String name) { + this._name = name; + this._needsNameUpdate = true; + } + + /** + * Returns the name of this section. + * + * @return GanttSection name + */ + public String getName() { + return _name; + } + + /** + * Returns the bounds of this GanttSection + * + * @return Rectangle + */ + public Rectangle getBounds() { + return _bounds; + } + + public Color getSaturdayBackgroundColorBottom() { + return _saturdayBgColorBottom == null ? _fillColorManager.getSaturdayBackgroundColorBottom() : _saturdayBgColorBottom; + } + + public Color getSaturdayBackgroundColorTop() { + return _saturdayBgColorTop == null ? _fillColorManager.getSaturdayBackgroundColorTop() : _saturdayBgColorTop; + } + + public Color getSundayBackgroundColorBottom() { + return _sundayBgColorBottom == null ? _fillColorManager.getSundayBackgroundColorBottom() : _sundayBgColorBottom; + } + + public Color getSundayBackgroundColorTop() { + return _sundayBgColorTop == null ? _fillColorManager.getSundayBackgroundColorTop() : _sundayBgColorTop; + } + + public Color getHolidayBackgroundColorBottom() { + return _holidayBgColorBottom == null ? _fillColorManager.getHolidayBackgroundColorBottom() : _holidayBgColorBottom; + } + + public Color getHolidayBackgroundColorTop() { + return _holidayBgColorTop == null ? _fillColorManager.getHolidayBackgroundColorTop() : _holidayBgColorTop; + } + + public Color getWeekdayBackgroundColorBottom() { + return _weekdayBgColorBottom == null ? _fillColorManager.getWeekdayBackgroundColorBottom() : _weekdayBgColorBottom; + } + + public Color getWeekdayBackgroundColorTop() { + return _weekdayBgColorTop == null ? _fillColorManager.getWeekdayBackgroundColorTop() : _weekdayBgColorTop; + } + + public Color getSelectedDayColorBottom() { + return _selectedBgColorBottom == null ? _fillColorManager.getSelectedDayColorBottom() : _selectedBgColorBottom; + } + + public Color getSelectedDayColorTop() { + return _selectedBgColorTop == null ? _fillColorManager.getSelectedDayColorTop() : _selectedBgColorTop; + } + + public Color getSelectedDayHeaderColorBottom() { + return _selectedBgHeaderColorBottom == null ? _fillColorManager.getSelectedDayHeaderColorBottom() : _selectedBgHeaderColorBottom; + } + + public Color getSelectedDayHeaderColorTop() { + return _selectedBgHeaderColorTop == null ? _fillColorManager.getSelectedDayHeaderColorTop() : _selectedBgHeaderColorTop; + } + + public void setSaturdayBackgroundColorTop(final Color saturdayBackgroundColorTop) { + _saturdayBgColorTop = saturdayBackgroundColorTop; + } + + public void setSaturdayBackgroundColorBottom(final Color saturdayBackgroundColorBottom) { + _saturdayBgColorBottom = saturdayBackgroundColorBottom; + } + + public void setSundayBackgroundColorTop(final Color sundayBackgroundColorTop) { + _sundayBgColorTop = sundayBackgroundColorTop; + } + + public void setSundayBackgroundColorBottom(final Color sundayBackgroundColorBottom) { + _sundayBgColorBottom = sundayBackgroundColorBottom; + } + + public void setHolidayBackgroundColorTop(final Color holidayBackgroundColorTop) { + _holidayBgColorTop = holidayBackgroundColorTop; + } + + public void setHolidayBackgroundColorBottom(final Color holidayBackgroundColorBottom) { + _holidayBgColorBottom = holidayBackgroundColorBottom; + } + + public void setWeekdayBackgroundColorTop(final Color weekdayBackgroundColorTop) { + _weekdayBgColorTop = weekdayBackgroundColorTop; + } + + public void setWeekdayBackgroundColorBottom(final Color weekdayBackgroundColorBottom) { + _weekdayBgColorBottom = weekdayBackgroundColorBottom; + } + + public void setSelectedBackgroundColorTop(final Color selectedBackgroundColorTop) { + _selectedBgColorTop = selectedBackgroundColorTop; + } + + public void setSelectedBackgroundColorBottom(final Color selectedBackgroundColorBottom) { + _selectedBgColorBottom = selectedBackgroundColorBottom; + } + + public void setSelectedBackgroundHeaderColorTop(final Color selectedBackgroundHeaderColorTop) { + _selectedBgHeaderColorTop = selectedBackgroundHeaderColorTop; + } + + public void setSelectedBackgroundHeaderColorBottom(final Color selectedBackgroundHeaderColorBottom) { + _selectedBgHeaderColorBottom = selectedBackgroundHeaderColorBottom; + } + + /** + * Returns the text orientation of the section. Default is SWT.VERTICAL. + * + * @return Text orientation. + */ + public int getTextOrientation() { + return _textOrientation; + } + + /** + * Sets the text orientation of the section. One of SWT.HORIZONTAL or SWT.VERTICAL. Default is SWT.VERTICAL. + * + * @param textOrientation SWT.VERTICAL or SWT.HORIZONTAL + */ + public void setTextOrientation(final int textOrientation) { + _textOrientation = textOrientation; + } + + /** + * Whether this section should just inherit the background colors of the main chart. + * + * @return true if set + * @deprecated IN PROGRESS + */ + boolean isInheritBackgroud() { + return _inheritBackgroud; + } + + /** + * Sets whether this section should inherit the background colors of the main chart for drawing date fills. + * + * @param inheritBackgroud true to inherit. Default is false. + * @deprecated IN PROGRESS + */ + void setInheritBackgroud(final boolean inheritBackgroud) { + _inheritBackgroud = inheritBackgroud; + } + + /** + * Returns the parent {@link GanttComposite} + * + * @return {@link GanttComposite} + */ + public GanttComposite getParentComposite() { + return _parent; + } + + /** + * Removes this section from the chart. Do note that all belonging GanttEvents will be orphaned, so you should + * probably deal with that post disposal. + */ + public void dispose() { + _parent.removeSection(this); + _parent.redraw(); + } + + Point getNameExtent() { + return _nameExtent; + } + + void setNameExtent(final Point extent) { + this._nameExtent = extent; + } + + void setBounds(final Rectangle bounds) { + this._bounds = bounds; + } + + Image getNameImage() { + return _nameImage; + } + + void setNameImage(final Image nameImage) { + this._nameImage = nameImage; + this._needsNameUpdate = false; + } + + boolean needsNameUpdate() { + return _needsNameUpdate; + } + + void setNeedsNameUpdate(final boolean need) { + _needsNameUpdate = need; + } + + int getEventsHeight(final ISettings settings) { + if (_ganttEvents.size() == 0) { + return settings.getMinimumSectionHeight(); + } + + int height = settings.getEventsTopSpacer(); + + for (int i = 0; i < _ganttEvents.size(); i++) { + final IGanttChartItem event = (IGanttChartItem) _ganttEvents.get(i); + + if (event.isAutomaticRowHeight()) { + height += settings.getEventHeight(); + } + else { + height += event.getFixedRowHeight(); + } + + if (i != _ganttEvents.size() - 1) { + height += settings.getEventSpacer(); + } + } + + height += settings.getEventsBottomSpacer(); + + if (height < settings.getMinimumSectionHeight()) { + height = settings.getMinimumSectionHeight(); + } + + return height; + } + + void addDNDGanttEvent(final GanttEvent ge) { + if (!_dndGanttEvents.contains(ge)) { + _dndGanttEvents.add(ge); + } + } + + void clearDNDGanttEvents() { + _dndGanttEvents.clear(); + } + + List getDNDGanttEvents() { + return _dndGanttEvents; + } + + public String toString() { + return "[GanttSection: " + _name + "]"; + } + + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSpecialDateRange.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSpecialDateRange.java index 9c8d3e718..851cbac83 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSpecialDateRange.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSpecialDateRange.java @@ -1,746 +1,746 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.ganttchart; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; - -import org.eclipse.nebula.widgets.ganttchart.utils.DateRange; -import org.eclipse.swt.graphics.Color; - -/** - * This class allows you to color a certain date range in a special background color, as well as set things such as if - * events should be allowed to be moved onto this range or not. You can also set a repeating range by setting certain - * days (Monday, Tuesday, etc) that will be repeatedly blocked.

For example, to block all events from ending up on - * weekends, you would do: - * - *

- * GanttSpecialDateRange weekends = new GanttSpecialDateRange(parentChart);
- * weekends.addRecurDay(Calendar.SATURDAY);
- * weekends.addRecurDay(Calendar.SUNDAY);
- * weekends.setAllowEventsOnDates(false);
- * 
- * - * To block a Tuesday before 8.30am and after 5.30pm, 10 times, starting Jan 1, 2009, you would do: - * - *
- * Calendar cal = Calendar.getInstance(Locale.getDefault());
- * cal.set(Calendar.YEAR, 2009);
- * cal.set(Calendar.MONTH, Calendar.JANUARY);
- * cal.set(Calendar.DATE, 1);
- * 
- * GanttSpecialDateRange blockPre = new GanttSpecialDateRange(parentChart);
- * blockPre.setStart(cal);
- * blockPre.addRecurDay(Calendar.SATURDAY);
- * blockPre.setEndHour(8);
- * blockPre.setEndMinute(29);
- * blockPre.setEndAfter(10);
- * 
- * GanttSpecialDateRange blockPost = new GanttSpecialDateRange(parentChart);
- * blockPre.setStart(cal);
- * blockPost.addRecurDay(Calendar.SATURDAY);
- * blockPost.setStartHour(17);
- * blockPost.setStartMinute(30);
- * blockPost.setEndAfter(10);
- * 
- * blockPre.setAllowEventsOnDates(false);
- * blockPost.setAllowEventsOnDates(false);
- * 
- * - * For a D-Day calendar (which does not use actual dates (at least visibily)) a typical creation may look like this: - * - *
- * Calendar start = (Calendar) _ddayRootCalendar.clone();
- * Calendar end = (Calendar) start.clone();
- * end.add(Calendar.DATE, 50);
- * GanttSpecialDateRange range = new GanttSpecialDateRange(_ganttChart, start, end);
- * // these need to be set to indicate that the range should adapt to D-Day logic 
- * range.setFrequency(GanttSpecialDateRange.REPEAT_DDAY);
- * range.setDDayRepeatInterval(10);
- * // --  
- * range.setRecurCount(50);
- * range.setBackgroundColorTop(ColorCache.getRandomColor());
- * range.setBackgroundColorBottom(ColorCache.getRandomColor());
- * 
- * - * @author cre - */ -public class GanttSpecialDateRange { - - public static final int REPEAT_DAILY = 1; - public static final int REPEAT_WEEKLY = 2; - public static final int REPEAT_MONTHLY = 3; - public static final int REPEAT_YEARLY = 4; - public static final int REPEAT_DDAY = 5; - - public static final int NO_END = -1; - - private Calendar _start; - private Calendar _end; - private Color _bgColorTop = ColorCache.getWhite(); - private Color _bgColorBottom = ColorCache.getBlack(); - private GanttChart _parentChart; - private GanttComposite _parentComposite; - private boolean _allowEventsOnDates = true; - - private int _frequency = REPEAT_WEEKLY; - private int _recurCount = 1; - private List _recurDays; - private int _startHour = 0; - private int _startMinute = 0; - private final int _startSecond = 0; - private int _endHour = 23; - private int _endMinute = 59; - private final int _endSecond = 59; - private int _endAfter = NO_END; - - private Calendar _lastActualEndDate; - - private List _cachedRanges = null; - - private int _ddayRepeatInterval = 0; - - GanttSpecialDateRange() { - this(null, null, null); - } - - /** - * Creates a new Gantt Special Date Range that indicates a certain set of dates with colors. - * - * @param parent Parent chart - */ - public GanttSpecialDateRange(final GanttChart parent) { - this(parent, null, null); - } - - /** - * Creates a new Gantt Special Date Range that indicates a certain set of dates. - * - * @param parent Parent chart - * @param start Start date - * @param end End date - */ - public GanttSpecialDateRange(final GanttChart parent, final Calendar start, final Calendar end) { - _recurDays = new ArrayList(); - _parentChart = parent; - if (parent != null) { - _parentComposite = parent.getGanttComposite(); - } - - _start = (start == null ? null : DateHelper.getNewCalendar(start)); - _end = (end == null ? null : DateHelper.getNewCalendar(end)); - - if (parent != null) { - _parentComposite.addSpecialDateRange(this); - } - updateCalculations(); - } - - /** - * Returns the start date. - * - * @return Start date - */ - public Calendar getStart() { - return _start; - } - - /** - * Sets the start date. - * - * @param start Start date - */ - public void setStart(final Calendar start) { - _start = (start == null ? null : DateHelper.getNewCalendar(start)); - - updateCalculations(); - } - - /** - * Returns the end date. - * - * @return End date - */ - public Calendar getEnd() { - return _end; - } - - /** - * Sets the end date. - * - * @param end End date - */ - public void setEnd(final Calendar end) { - _end = (end == null ? null : DateHelper.getNewCalendar(end)); - - updateCalculations(); - } - - /** - * Returns the gradient top color. - * - * @return Top color - */ - public Color getBackgroundColorTop() { - return _bgColorTop; - } - - /** - * Sets the gradient top color. - * - * @param backgroundColorTop Top color or null if none (transparent) - */ - public void setBackgroundColorTop(final Color backgroundColorTop) { - _bgColorTop = backgroundColorTop; - } - - /** - * Returns the gradient bottom color. - * - * @return Bottom color - */ - public Color getBackgroundColorBottom() { - return _bgColorBottom; - } - - /** - * Sets the gradient bottom color. - * - * @param backgroundColorBottom Bottom color or null if none (transparent) - */ - public void setBackgroundColorBottom(final Color backgroundColorBottom) { - _bgColorBottom = backgroundColorBottom; - } - - /** - * Returns the chart that this range is associated with. - * - * @return {@link GanttChart} parent - */ - public GanttChart getParentChart() { - return _parentChart; - } - - /** - * Returns the chart composite this range is associated with. - * - * @return {@link GanttComposite} parent - */ - public GanttComposite getParentComposite() { - return _parentComposite; - } - - /** - * Whether events can be resized or dropped on the date range specified in this class. Default is true. - * - * @return true if allowed - */ - public boolean isAllowEventsOnDates() { - return _allowEventsOnDates; - } - - /** - * Sets whether events can be resized or dropped on to the date range specified in this class. Default is true. - * - * @param allowEventsOnDates true if allowed - */ - public void setAllowEventsOnDates(final boolean allowEventsOnDates) { - _allowEventsOnDates = allowEventsOnDates; - } - - /** - * Adds a date that will be always used as a range date. The date is one of the Calendar dates, such as - * {@link Calendar#MONDAY}. This is purely for convenience instead of having to create multiple special date ranges - * to cover things such as weekends. Do note if you add specific hours, only the specified hour on the set days will - * be covered and not the full day itself.

If the frequency is set to {@value #REPEAT_DDAY} this method does - * nothing and you should instead be using {@link #setDDayRepeatInterval(int)} as DDay calendars has no notion of - * weekdates. - * - * @param day Calendar weekday to add - * @return true if added, false if not - */ - public boolean addRecurDay(final int day) { - if (day < Calendar.SUNDAY || day > Calendar.SATURDAY) { return false; } - - if (_recurDays.contains(new Integer(day))) { return false; } - - final boolean ret = _recurDays.add(new Integer(day)); - if (ret) { - updateCalculations(); - } - return ret; - } - - /** - * Removes a set date. - * - * @param calDate Date to remove - * @return true if removed - */ - public boolean removeRecurDay(final int calDate) { - final boolean ret = _recurDays.remove(new Integer(calDate)); - if (ret) { - updateCalculations(); - } - return ret; - } - - /** - * Returns the frequency. - * - * @return frequency - */ - public int getFrequency() { - return _frequency; - } - - /** - * Sets the repeat frequency. Options are {@link #REPEAT_DAILY}, {@link #REPEAT_MONTHLY}, {@link #REPEAT_WEEKLY}, - * {@link #REPEAT_YEARLY} or {@link #REPEAT_DDAY} for DDay calendars. - * - * @param frequency Frequency to set - */ - public void setFrequency(final int frequency) { - _frequency = frequency; - updateCalculations(); - } - - /** - * Returns the currently set DDay repeat interval. This is only used if frequency is set to {@link #REPEAT_DDAY}. - * - * @return repeat interval - */ - public int getDDayRepeatInterval() { - return _ddayRepeatInterval; - } - - /** - * Sets the custom DDay repeat interval. This is only used if frequency is set to {@link #REPEAT_DDAY}. - * - * @param interval Custom repeat interval of n DDays - */ - public void setDDayRepeatInterval(final int interval) { - _ddayRepeatInterval = interval; - } - - /** - * Returns the "recurs every" value. - * - * @return recurs every value - */ - public int getRecurCount() { - return _recurCount; - } - - /** - * How often this event re-occurs. By default it's always 1. To end after a certain number of recurrences, use - * {@link #setEndAfter(int)}. - * - * @param recurMax Recurrence frequency - */ - public void setRecurCount(final int recurMax) { - _recurCount = recurMax; - updateCalculations(); - } - - /** - * Returns the list of currently set recurring days. - * - * @return List of recurring days - */ - public List getRecurDays() { - return _recurDays; - } - - /** - * Returns the start hour. - * - * @return Start hour - */ - public int getStartHour() { - return _startHour; - } - - /** - * Sets the start hour. Hour should be in a 24h format from 0 to 23. - * - * @param startHour start hour - * @return true if set - */ - public boolean setStartHour(final int startHour) { - if (startHour < 0 || startHour > 23) { return false; } - - _startHour = startHour; - updateCalculations(); - return true; - } - - /** - * Returns the start minute. - * - * @return start minute - */ - public int getStartMinute() { - return _startMinute; - } - - /** - * Sets the start minute. Minute should be between 0 and 59. - * - * @param startMinute start minute - * @return true if set - */ - public boolean setStartMinute(final int startMinute) { - if (startMinute < 0 || startMinute > 59) { return false; - - } - - _startMinute = startMinute; - updateCalculations(); - return true; - } - - /** - * Returns the end hour. - * - * @return end hour - */ - public int getEndHour() { - return _endHour; - } - - /** - * Sets the end hour. Hour should be in a 24h format from 0 to 23. - * - * @param endHour end hour - * @return true if set - */ - public boolean setEndHour(final int endHour) { - if (endHour < 0 || endHour > 23) { return false; } - - _endHour = endHour; - updateCalculations(); - return true; - } - - /** - * Returns the end minute - * - * @return end minute - */ - public int getEndMinute() { - return _endMinute; - } - - /** - * Sets the end minute. Minute should be between 0 and 59. - * - * @param endMinute start minute - * @return true if set - */ - public boolean setEndMinute(final int endMinute) { - if (endMinute < 0 || endMinute > 59) { return false; } - - _endMinute = endMinute; - updateCalculations(); - return true; - } - - /** - * Returns the end after value that defines the number of recurring repetitions of the event. - * - * @return end after value - */ - public int getEndAfter() { - return _endAfter; - } - - /** - * Sets how many times an event should re-occur and then end. This is the end value. To set a no-end, use - * {@link #NO_END} as value. - * - * @param endAfter After how many re-occurances to stop. - */ - public void setEndAfter(final int endAfter) { - _endAfter = endAfter; - updateCalculations(); - } - - public void setParentChart(final GanttChart parentChart) { - _parentChart = parentChart; - } - - public void setParentComposite(final GanttComposite parentComposite) { - _parentComposite = parentComposite; - } - - private void updateCalculations() { - _lastActualEndDate = null; - _cachedRanges = null; - } - - /** - * Checks whether a set of dates overlap any of the dates in this range. - * - * @param start Start date - * @param end End date - * @return true if no date is overlapping the dates of this range, false otherwise - */ - public boolean canEventOccupy(final Calendar start, final Calendar end) { - if (isAllowEventsOnDates()) { - return true; - } - - // we're not in range, check this first as it's faster - if (!isVisible(start, end)) { - return true; - } - - // get all blocks that we occupy - List blocks = getBlocks(start, end); - - DateRange us = new DateRange(_start, _end); - - for (int i = 0; i < blocks.size(); i++) { - ArrayList block = (ArrayList) blocks.get(i); - - Calendar blockStart = (Calendar) block.get(0); - Calendar blockEnd = (Calendar) block.get(1); - - DateRange range = new DateRange(blockStart, blockEnd); - if (us.Overlaps(range)) { - return false; - } - } - - return true; - } - - /* - * Checks whether this range is visible in the given start/end date range - */ - boolean isVisible(final Calendar start, final Calendar end) { - if (!isUseable()) { return false; } - - // TODO: DDay calendar is fucked here - - //System.err.println(start.getTime() + " # " + end.getTime() + " --- " + _start.getTime() + " # " + _end.getTime() + " -- " + getActualEndDate().getTime() + " + " + _recurCount + " + " + _lastActualEndDate.getTime()); - - // doesn't recur on any days at all - // TODO: This should be possible to be empty, then we just use the start / end dates - if (_recurDays.isEmpty() && _frequency != REPEAT_DDAY) { return false; } - - // doesn't recur, what's the point?? - if (_recurCount <= 0) { return false; } - - // ends on specific date which is in the past - if (_end != null && _end.before(start)) { return false; } - - // same deal - final Calendar aEnd = getActualEndDate(); - //System.err.println(aEnd.getTime() + " "+ end.getTime()); - if (aEnd != null && aEnd.before(start)) { return false; } - - // now it's easy - if (_start.before(end) && aEnd.after(start)) { return true; } - - return false; - } - - Calendar getActualStartDate() { - return _start; - } - - Calendar getActualEndDate() { - if (_lastActualEndDate != null) { return _lastActualEndDate; } - if (_end != null) { - _lastActualEndDate = DateHelper.getNewCalendar(_end); - return _end; - } - - // move calendar to end recurring date - final Calendar cal = DateHelper.getNewCalendar(_start); - for (int i = 0; i < _recurCount; i++) { - switch (_frequency) { - case REPEAT_DAILY: - cal.add(Calendar.DATE, 1); - break; - case REPEAT_WEEKLY: - cal.add(Calendar.WEEK_OF_YEAR, 1); - break; - case REPEAT_MONTHLY: - cal.add(Calendar.MONTH, 1); - break; - case REPEAT_YEARLY: - cal.add(Calendar.YEAR, 1); - break; - case REPEAT_DDAY: - cal.add(Calendar.DATE, _ddayRepeatInterval); - break; - default: - break; - } - } - - // set the end day to the highest day of that week - final int d = getHighestRecurDate(); - cal.set(Calendar.DAY_OF_WEEK, d); - - cal.set(Calendar.HOUR_OF_DAY, _endHour); - cal.set(Calendar.MINUTE, _endMinute); - cal.set(Calendar.SECOND, _endSecond); - cal.set(Calendar.MILLISECOND, 999); - - _lastActualEndDate = DateHelper.getNewCalendar(cal); - - return cal; - } - - List getBlocks() { - return getBlocks(null, null); - } - - List getBlocks(final Calendar start, final Calendar end) { - // if (_cachedRanges != null) { return _cachedRanges; } - - _cachedRanges = new ArrayList(); - - final Calendar cal = DateHelper.getNewCalendar(_start); - - final Calendar ourEnd = getActualEndDate(); - - for (int i = 0; i < _recurCount; i++) { - final Calendar calEnd = DateHelper.getNewCalendar(cal); - - if (_recurDays.isEmpty() && _frequency == REPEAT_DDAY) { - cal.set(Calendar.HOUR_OF_DAY, _startHour); - cal.set(Calendar.MINUTE, _startMinute); - cal.set(Calendar.SECOND, _startSecond); - cal.set(Calendar.MILLISECOND, 0); - - calEnd.set(Calendar.HOUR_OF_DAY, _endHour); - calEnd.set(Calendar.MINUTE, _endMinute); - calEnd.set(Calendar.SECOND, _endSecond); - calEnd.set(Calendar.MILLISECOND, 999); - - if (calEnd.after(end)) { - continue; - } - - if (ourEnd != null && calEnd.after(ourEnd)) { - continue; - } - - final List foo = new ArrayList(); - foo.add(DateHelper.getNewCalendar(cal)); - foo.add(DateHelper.getNewCalendar(calEnd)); - _cachedRanges.add(foo); - - } else { - for (int x = 0; x < _recurDays.size(); x++) { - final int day = ((Integer) _recurDays.get(x)).intValue(); - - cal.set(Calendar.HOUR_OF_DAY, _startHour); - cal.set(Calendar.MINUTE, _startMinute); - cal.set(Calendar.SECOND, _startSecond); - cal.set(Calendar.MILLISECOND, 0); - cal.set(Calendar.DAY_OF_WEEK, day); - - calEnd.set(Calendar.HOUR_OF_DAY, _endHour); - calEnd.set(Calendar.MINUTE, _endMinute); - calEnd.set(Calendar.SECOND, _endSecond); - calEnd.set(Calendar.MILLISECOND, 999); - calEnd.set(Calendar.DAY_OF_WEEK, day); - - if (start != null && calEnd.before(start)) { - continue; - } - if (end != null && cal.after(end) || cal.after(ourEnd)) { - continue; - } - - final List foo = new ArrayList(); - foo.add(DateHelper.getNewCalendar(cal)); - foo.add(DateHelper.getNewCalendar(calEnd)); - _cachedRanges.add(foo); - } - } - - switch (_frequency) { - case REPEAT_DAILY: - cal.add(Calendar.DATE, 1); - break; - case REPEAT_WEEKLY: - cal.add(Calendar.WEEK_OF_YEAR, 1); - break; - case REPEAT_MONTHLY: - cal.add(Calendar.MONTH, 1); - break; - case REPEAT_YEARLY: - cal.add(Calendar.YEAR, 1); - break; - case REPEAT_DDAY: - cal.add(Calendar.DATE, _ddayRepeatInterval); - break; - default: - break; - } - } - - return _cachedRanges; - } - - int getHighestRecurDate() { - int max = 0; - for (int i = 0; i < _recurDays.size(); i++) { - final Integer day = (Integer) _recurDays.get(i); // NOPMD - max = Math.max(max, day.intValue()); - } - return max; - } - - boolean isUseable() { - if (_start == null) { return false; } - - return true; - } - - public String toString() { - String freq = ""; - switch (_frequency) { - case REPEAT_DAILY: - freq = "Daily"; - break; - case REPEAT_WEEKLY: - freq = "Weekly"; - break; - case REPEAT_MONTHLY: - freq = "Monthly"; - break; - case REPEAT_YEARLY: - freq = "Yearly"; - break; - case REPEAT_DDAY: - freq = "DDay"; - break; - default: - break; - } - - return "[GanttSpecialDateRange: "+ (_start == null ? null : _start.getTime()) + " - " + (_end == null ? null : _end.getTime()) + ". Freqency: " + freq + ". Recur Count: " + _recurCount + ". Last actual end date: " + (_lastActualEndDate == null ? null : _lastActualEndDate.getTime()) + "]"; - } - -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.ganttchart; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import org.eclipse.nebula.widgets.ganttchart.utils.DateRange; +import org.eclipse.swt.graphics.Color; + +/** + * This class allows you to color a certain date range in a special background color, as well as set things such as if + * events should be allowed to be moved onto this range or not. You can also set a repeating range by setting certain + * days (Monday, Tuesday, etc) that will be repeatedly blocked.

For example, to block all events from ending up on + * weekends, you would do: + * + *

+ * GanttSpecialDateRange weekends = new GanttSpecialDateRange(parentChart);
+ * weekends.addRecurDay(Calendar.SATURDAY);
+ * weekends.addRecurDay(Calendar.SUNDAY);
+ * weekends.setAllowEventsOnDates(false);
+ * 
+ * + * To block a Tuesday before 8.30am and after 5.30pm, 10 times, starting Jan 1, 2009, you would do: + * + *
+ * Calendar cal = Calendar.getInstance(Locale.getDefault());
+ * cal.set(Calendar.YEAR, 2009);
+ * cal.set(Calendar.MONTH, Calendar.JANUARY);
+ * cal.set(Calendar.DATE, 1);
+ * 
+ * GanttSpecialDateRange blockPre = new GanttSpecialDateRange(parentChart);
+ * blockPre.setStart(cal);
+ * blockPre.addRecurDay(Calendar.SATURDAY);
+ * blockPre.setEndHour(8);
+ * blockPre.setEndMinute(29);
+ * blockPre.setEndAfter(10);
+ * 
+ * GanttSpecialDateRange blockPost = new GanttSpecialDateRange(parentChart);
+ * blockPre.setStart(cal);
+ * blockPost.addRecurDay(Calendar.SATURDAY);
+ * blockPost.setStartHour(17);
+ * blockPost.setStartMinute(30);
+ * blockPost.setEndAfter(10);
+ * 
+ * blockPre.setAllowEventsOnDates(false);
+ * blockPost.setAllowEventsOnDates(false);
+ * 
+ * + * For a D-Day calendar (which does not use actual dates (at least visibily)) a typical creation may look like this: + * + *
+ * Calendar start = (Calendar) _ddayRootCalendar.clone();
+ * Calendar end = (Calendar) start.clone();
+ * end.add(Calendar.DATE, 50);
+ * GanttSpecialDateRange range = new GanttSpecialDateRange(_ganttChart, start, end);
+ * // these need to be set to indicate that the range should adapt to D-Day logic 
+ * range.setFrequency(GanttSpecialDateRange.REPEAT_DDAY);
+ * range.setDDayRepeatInterval(10);
+ * // --  
+ * range.setRecurCount(50);
+ * range.setBackgroundColorTop(ColorCache.getRandomColor());
+ * range.setBackgroundColorBottom(ColorCache.getRandomColor());
+ * 
+ * + * @author cre + */ +public class GanttSpecialDateRange { + + public static final int REPEAT_DAILY = 1; + public static final int REPEAT_WEEKLY = 2; + public static final int REPEAT_MONTHLY = 3; + public static final int REPEAT_YEARLY = 4; + public static final int REPEAT_DDAY = 5; + + public static final int NO_END = -1; + + private Calendar _start; + private Calendar _end; + private Color _bgColorTop = ColorCache.getWhite(); + private Color _bgColorBottom = ColorCache.getBlack(); + private GanttChart _parentChart; + private GanttComposite _parentComposite; + private boolean _allowEventsOnDates = true; + + private int _frequency = REPEAT_WEEKLY; + private int _recurCount = 1; + private List _recurDays; + private int _startHour = 0; + private int _startMinute = 0; + private final int _startSecond = 0; + private int _endHour = 23; + private int _endMinute = 59; + private final int _endSecond = 59; + private int _endAfter = NO_END; + + private Calendar _lastActualEndDate; + + private List _cachedRanges = null; + + private int _ddayRepeatInterval = 0; + + GanttSpecialDateRange() { + this(null, null, null); + } + + /** + * Creates a new Gantt Special Date Range that indicates a certain set of dates with colors. + * + * @param parent Parent chart + */ + public GanttSpecialDateRange(final GanttChart parent) { + this(parent, null, null); + } + + /** + * Creates a new Gantt Special Date Range that indicates a certain set of dates. + * + * @param parent Parent chart + * @param start Start date + * @param end End date + */ + public GanttSpecialDateRange(final GanttChart parent, final Calendar start, final Calendar end) { + _recurDays = new ArrayList(); + _parentChart = parent; + if (parent != null) { + _parentComposite = parent.getGanttComposite(); + } + + _start = (start == null ? null : DateHelper.getNewCalendar(start)); + _end = (end == null ? null : DateHelper.getNewCalendar(end)); + + if (parent != null) { + _parentComposite.addSpecialDateRange(this); + } + updateCalculations(); + } + + /** + * Returns the start date. + * + * @return Start date + */ + public Calendar getStart() { + return _start; + } + + /** + * Sets the start date. + * + * @param start Start date + */ + public void setStart(final Calendar start) { + _start = (start == null ? null : DateHelper.getNewCalendar(start)); + + updateCalculations(); + } + + /** + * Returns the end date. + * + * @return End date + */ + public Calendar getEnd() { + return _end; + } + + /** + * Sets the end date. + * + * @param end End date + */ + public void setEnd(final Calendar end) { + _end = (end == null ? null : DateHelper.getNewCalendar(end)); + + updateCalculations(); + } + + /** + * Returns the gradient top color. + * + * @return Top color + */ + public Color getBackgroundColorTop() { + return _bgColorTop; + } + + /** + * Sets the gradient top color. + * + * @param backgroundColorTop Top color or null if none (transparent) + */ + public void setBackgroundColorTop(final Color backgroundColorTop) { + _bgColorTop = backgroundColorTop; + } + + /** + * Returns the gradient bottom color. + * + * @return Bottom color + */ + public Color getBackgroundColorBottom() { + return _bgColorBottom; + } + + /** + * Sets the gradient bottom color. + * + * @param backgroundColorBottom Bottom color or null if none (transparent) + */ + public void setBackgroundColorBottom(final Color backgroundColorBottom) { + _bgColorBottom = backgroundColorBottom; + } + + /** + * Returns the chart that this range is associated with. + * + * @return {@link GanttChart} parent + */ + public GanttChart getParentChart() { + return _parentChart; + } + + /** + * Returns the chart composite this range is associated with. + * + * @return {@link GanttComposite} parent + */ + public GanttComposite getParentComposite() { + return _parentComposite; + } + + /** + * Whether events can be resized or dropped on the date range specified in this class. Default is true. + * + * @return true if allowed + */ + public boolean isAllowEventsOnDates() { + return _allowEventsOnDates; + } + + /** + * Sets whether events can be resized or dropped on to the date range specified in this class. Default is true. + * + * @param allowEventsOnDates true if allowed + */ + public void setAllowEventsOnDates(final boolean allowEventsOnDates) { + _allowEventsOnDates = allowEventsOnDates; + } + + /** + * Adds a date that will be always used as a range date. The date is one of the Calendar dates, such as + * {@link Calendar#MONDAY}. This is purely for convenience instead of having to create multiple special date ranges + * to cover things such as weekends. Do note if you add specific hours, only the specified hour on the set days will + * be covered and not the full day itself.

If the frequency is set to {@value #REPEAT_DDAY} this method does + * nothing and you should instead be using {@link #setDDayRepeatInterval(int)} as DDay calendars has no notion of + * weekdates. + * + * @param day Calendar weekday to add + * @return true if added, false if not + */ + public boolean addRecurDay(final int day) { + if (day < Calendar.SUNDAY || day > Calendar.SATURDAY) { return false; } + + if (_recurDays.contains(new Integer(day))) { return false; } + + final boolean ret = _recurDays.add(new Integer(day)); + if (ret) { + updateCalculations(); + } + return ret; + } + + /** + * Removes a set date. + * + * @param calDate Date to remove + * @return true if removed + */ + public boolean removeRecurDay(final int calDate) { + final boolean ret = _recurDays.remove(new Integer(calDate)); + if (ret) { + updateCalculations(); + } + return ret; + } + + /** + * Returns the frequency. + * + * @return frequency + */ + public int getFrequency() { + return _frequency; + } + + /** + * Sets the repeat frequency. Options are {@link #REPEAT_DAILY}, {@link #REPEAT_MONTHLY}, {@link #REPEAT_WEEKLY}, + * {@link #REPEAT_YEARLY} or {@link #REPEAT_DDAY} for DDay calendars. + * + * @param frequency Frequency to set + */ + public void setFrequency(final int frequency) { + _frequency = frequency; + updateCalculations(); + } + + /** + * Returns the currently set DDay repeat interval. This is only used if frequency is set to {@link #REPEAT_DDAY}. + * + * @return repeat interval + */ + public int getDDayRepeatInterval() { + return _ddayRepeatInterval; + } + + /** + * Sets the custom DDay repeat interval. This is only used if frequency is set to {@link #REPEAT_DDAY}. + * + * @param interval Custom repeat interval of n DDays + */ + public void setDDayRepeatInterval(final int interval) { + _ddayRepeatInterval = interval; + } + + /** + * Returns the "recurs every" value. + * + * @return recurs every value + */ + public int getRecurCount() { + return _recurCount; + } + + /** + * How often this event re-occurs. By default it's always 1. To end after a certain number of recurrences, use + * {@link #setEndAfter(int)}. + * + * @param recurMax Recurrence frequency + */ + public void setRecurCount(final int recurMax) { + _recurCount = recurMax; + updateCalculations(); + } + + /** + * Returns the list of currently set recurring days. + * + * @return List of recurring days + */ + public List getRecurDays() { + return _recurDays; + } + + /** + * Returns the start hour. + * + * @return Start hour + */ + public int getStartHour() { + return _startHour; + } + + /** + * Sets the start hour. Hour should be in a 24h format from 0 to 23. + * + * @param startHour start hour + * @return true if set + */ + public boolean setStartHour(final int startHour) { + if (startHour < 0 || startHour > 23) { return false; } + + _startHour = startHour; + updateCalculations(); + return true; + } + + /** + * Returns the start minute. + * + * @return start minute + */ + public int getStartMinute() { + return _startMinute; + } + + /** + * Sets the start minute. Minute should be between 0 and 59. + * + * @param startMinute start minute + * @return true if set + */ + public boolean setStartMinute(final int startMinute) { + if (startMinute < 0 || startMinute > 59) { return false; + + } + + _startMinute = startMinute; + updateCalculations(); + return true; + } + + /** + * Returns the end hour. + * + * @return end hour + */ + public int getEndHour() { + return _endHour; + } + + /** + * Sets the end hour. Hour should be in a 24h format from 0 to 23. + * + * @param endHour end hour + * @return true if set + */ + public boolean setEndHour(final int endHour) { + if (endHour < 0 || endHour > 23) { return false; } + + _endHour = endHour; + updateCalculations(); + return true; + } + + /** + * Returns the end minute + * + * @return end minute + */ + public int getEndMinute() { + return _endMinute; + } + + /** + * Sets the end minute. Minute should be between 0 and 59. + * + * @param endMinute start minute + * @return true if set + */ + public boolean setEndMinute(final int endMinute) { + if (endMinute < 0 || endMinute > 59) { return false; } + + _endMinute = endMinute; + updateCalculations(); + return true; + } + + /** + * Returns the end after value that defines the number of recurring repetitions of the event. + * + * @return end after value + */ + public int getEndAfter() { + return _endAfter; + } + + /** + * Sets how many times an event should re-occur and then end. This is the end value. To set a no-end, use + * {@link #NO_END} as value. + * + * @param endAfter After how many re-occurances to stop. + */ + public void setEndAfter(final int endAfter) { + _endAfter = endAfter; + updateCalculations(); + } + + public void setParentChart(final GanttChart parentChart) { + _parentChart = parentChart; + } + + public void setParentComposite(final GanttComposite parentComposite) { + _parentComposite = parentComposite; + } + + private void updateCalculations() { + _lastActualEndDate = null; + _cachedRanges = null; + } + + /** + * Checks whether a set of dates overlap any of the dates in this range. + * + * @param start Start date + * @param end End date + * @return true if no date is overlapping the dates of this range, false otherwise + */ + public boolean canEventOccupy(final Calendar start, final Calendar end) { + if (isAllowEventsOnDates()) { + return true; + } + + // we're not in range, check this first as it's faster + if (!isVisible(start, end)) { + return true; + } + + // get all blocks that we occupy + List blocks = getBlocks(start, end); + + DateRange us = new DateRange(_start, _end); + + for (int i = 0; i < blocks.size(); i++) { + ArrayList block = (ArrayList) blocks.get(i); + + Calendar blockStart = (Calendar) block.get(0); + Calendar blockEnd = (Calendar) block.get(1); + + DateRange range = new DateRange(blockStart, blockEnd); + if (us.Overlaps(range)) { + return false; + } + } + + return true; + } + + /* + * Checks whether this range is visible in the given start/end date range + */ + boolean isVisible(final Calendar start, final Calendar end) { + if (!isUseable()) { return false; } + + // TODO: DDay calendar is fucked here + + //System.err.println(start.getTime() + " # " + end.getTime() + " --- " + _start.getTime() + " # " + _end.getTime() + " -- " + getActualEndDate().getTime() + " + " + _recurCount + " + " + _lastActualEndDate.getTime()); + + // doesn't recur on any days at all + // TODO: This should be possible to be empty, then we just use the start / end dates + if (_recurDays.isEmpty() && _frequency != REPEAT_DDAY) { return false; } + + // doesn't recur, what's the point?? + if (_recurCount <= 0) { return false; } + + // ends on specific date which is in the past + if (_end != null && _end.before(start)) { return false; } + + // same deal + final Calendar aEnd = getActualEndDate(); + //System.err.println(aEnd.getTime() + " "+ end.getTime()); + if (aEnd != null && aEnd.before(start)) { return false; } + + // now it's easy + if (_start.before(end) && aEnd.after(start)) { return true; } + + return false; + } + + Calendar getActualStartDate() { + return _start; + } + + Calendar getActualEndDate() { + if (_lastActualEndDate != null) { return _lastActualEndDate; } + if (_end != null) { + _lastActualEndDate = DateHelper.getNewCalendar(_end); + return _end; + } + + // move calendar to end recurring date + final Calendar cal = DateHelper.getNewCalendar(_start); + for (int i = 0; i < _recurCount; i++) { + switch (_frequency) { + case REPEAT_DAILY: + cal.add(Calendar.DATE, 1); + break; + case REPEAT_WEEKLY: + cal.add(Calendar.WEEK_OF_YEAR, 1); + break; + case REPEAT_MONTHLY: + cal.add(Calendar.MONTH, 1); + break; + case REPEAT_YEARLY: + cal.add(Calendar.YEAR, 1); + break; + case REPEAT_DDAY: + cal.add(Calendar.DATE, _ddayRepeatInterval); + break; + default: + break; + } + } + + // set the end day to the highest day of that week + final int d = getHighestRecurDate(); + cal.set(Calendar.DAY_OF_WEEK, d); + + cal.set(Calendar.HOUR_OF_DAY, _endHour); + cal.set(Calendar.MINUTE, _endMinute); + cal.set(Calendar.SECOND, _endSecond); + cal.set(Calendar.MILLISECOND, 999); + + _lastActualEndDate = DateHelper.getNewCalendar(cal); + + return cal; + } + + List getBlocks() { + return getBlocks(null, null); + } + + List getBlocks(final Calendar start, final Calendar end) { + // if (_cachedRanges != null) { return _cachedRanges; } + + _cachedRanges = new ArrayList(); + + final Calendar cal = DateHelper.getNewCalendar(_start); + + final Calendar ourEnd = getActualEndDate(); + + for (int i = 0; i < _recurCount; i++) { + final Calendar calEnd = DateHelper.getNewCalendar(cal); + + if (_recurDays.isEmpty() && _frequency == REPEAT_DDAY) { + cal.set(Calendar.HOUR_OF_DAY, _startHour); + cal.set(Calendar.MINUTE, _startMinute); + cal.set(Calendar.SECOND, _startSecond); + cal.set(Calendar.MILLISECOND, 0); + + calEnd.set(Calendar.HOUR_OF_DAY, _endHour); + calEnd.set(Calendar.MINUTE, _endMinute); + calEnd.set(Calendar.SECOND, _endSecond); + calEnd.set(Calendar.MILLISECOND, 999); + + if (calEnd.after(end)) { + continue; + } + + if (ourEnd != null && calEnd.after(ourEnd)) { + continue; + } + + final List foo = new ArrayList(); + foo.add(DateHelper.getNewCalendar(cal)); + foo.add(DateHelper.getNewCalendar(calEnd)); + _cachedRanges.add(foo); + + } else { + for (int x = 0; x < _recurDays.size(); x++) { + final int day = ((Integer) _recurDays.get(x)).intValue(); + + cal.set(Calendar.HOUR_OF_DAY, _startHour); + cal.set(Calendar.MINUTE, _startMinute); + cal.set(Calendar.SECOND, _startSecond); + cal.set(Calendar.MILLISECOND, 0); + cal.set(Calendar.DAY_OF_WEEK, day); + + calEnd.set(Calendar.HOUR_OF_DAY, _endHour); + calEnd.set(Calendar.MINUTE, _endMinute); + calEnd.set(Calendar.SECOND, _endSecond); + calEnd.set(Calendar.MILLISECOND, 999); + calEnd.set(Calendar.DAY_OF_WEEK, day); + + if (start != null && calEnd.before(start)) { + continue; + } + if (end != null && cal.after(end) || cal.after(ourEnd)) { + continue; + } + + final List foo = new ArrayList(); + foo.add(DateHelper.getNewCalendar(cal)); + foo.add(DateHelper.getNewCalendar(calEnd)); + _cachedRanges.add(foo); + } + } + + switch (_frequency) { + case REPEAT_DAILY: + cal.add(Calendar.DATE, 1); + break; + case REPEAT_WEEKLY: + cal.add(Calendar.WEEK_OF_YEAR, 1); + break; + case REPEAT_MONTHLY: + cal.add(Calendar.MONTH, 1); + break; + case REPEAT_YEARLY: + cal.add(Calendar.YEAR, 1); + break; + case REPEAT_DDAY: + cal.add(Calendar.DATE, _ddayRepeatInterval); + break; + default: + break; + } + } + + return _cachedRanges; + } + + int getHighestRecurDate() { + int max = 0; + for (int i = 0; i < _recurDays.size(); i++) { + final Integer day = (Integer) _recurDays.get(i); // NOPMD + max = Math.max(max, day.intValue()); + } + return max; + } + + boolean isUseable() { + if (_start == null) { return false; } + + return true; + } + + public String toString() { + String freq = ""; + switch (_frequency) { + case REPEAT_DAILY: + freq = "Daily"; + break; + case REPEAT_WEEKLY: + freq = "Weekly"; + break; + case REPEAT_MONTHLY: + freq = "Monthly"; + break; + case REPEAT_YEARLY: + freq = "Yearly"; + break; + case REPEAT_DDAY: + freq = "DDay"; + break; + default: + break; + } + + return "[GanttSpecialDateRange: "+ (_start == null ? null : _start.getTime()) + " - " + (_end == null ? null : _end.getTime()) + ". Freqency: " + freq + ". Recur Count: " + _recurCount + ". Last actual end date: " + (_lastActualEndDate == null ? null : _lastActualEndDate.getTime()) + "]"; + } + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/HorizontalScrollbarHandler.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/HorizontalScrollbarHandler.java index abde9e5b9..8b6a3cc4d 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/HorizontalScrollbarHandler.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/HorizontalScrollbarHandler.java @@ -1,198 +1,198 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.ganttchart; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ScrollBar; - -class HorizontalScrollbarHandler implements Listener { - - private static final int _minScrollRange = 0; - private static final int _maxScrollRange = 500; - private static final int _center = (_maxScrollRange / 2) - 20; - - private GanttComposite _gc; - private ScrollBar _scrollBar; - private boolean _scrolling; - private int _lastScrollbarPosition; - - private boolean _infinite; - private boolean _none; - private boolean _fixed; - - private int _lastDetailEvent; - - public HorizontalScrollbarHandler(GanttComposite parent, ScrollBar scrollBar, int style) { - _gc = parent; - _scrollBar = scrollBar; - - if ((style & GanttFlags.H_SCROLL_FIXED_RANGE) != 0) { - _fixed = true; - } else if ((style & GanttFlags.H_SCROLL_INFINITE) != 0) { - _infinite = true; - } else if ((style & GanttFlags.H_SCROLL_NONE) != 0) { - _none = true; - } - - _scrollBar.addListener(SWT.Selection, this); - - if (_infinite) { - _scrollBar.setVisible(true); - _scrollBar.setMinimum(_minScrollRange); - _scrollBar.setMaximum(_maxScrollRange); - _scrollBar.setSelection(_center); - _scrollBar.setThumb(20); - return; - } - - if (_fixed) { - _scrollBar.setPageIncrement(7); - } - - _scrollBar.setMinimum(0); - _scrollBar.setIncrement(1); - - if (_none || _fixed) { - _scrollBar.setVisible(false); - } - } - - public void resetScrollPosition() { - _lastScrollbarPosition = getScrollBarPosition(); - } - - public void handleEvent(Event e) { - _scrolling = true; - - int cur = getScrollBarPosition(); - - // same as last (happens when user clicks the thumb without dragging) - if (_lastScrollbarPosition == cur) { - // if the mouse lets go of a scrollbar drag, update the scrollbars again - if (e.detail == 0 && _lastDetailEvent != 0 && _fixed) { - recalculate(); - } - - if (_infinite && e.detail == 0) { - _scrollBar.setSelection(_center); - _lastScrollbarPosition = _center; - } - - _gc.killDialogs(); - - return; - } - - _lastDetailEvent = e.detail; - - boolean left = false; - int diff = cur - _lastScrollbarPosition; - if (diff < 0) { - left = true; - diff = _lastScrollbarPosition - cur; - } - - if (e.detail == SWT.PAGE_UP || e.detail == SWT.PAGE_DOWN) { - scrollViewportByPage(scrollDirectionForEventDetail(e.detail), diff); - } else if (e.detail == SWT.ARROW_UP || e.detail == SWT.ARROW_DOWN) { - scrollViewportByOffset(scrollDirectionForEventDetail(e.detail), diff); - } else if (e.detail == SWT.DRAG) { - scrollViewportTo(left ? SWT.LEFT : SWT.RIGHT, _scrollBar.getSelection(), diff); - } - - if ((_infinite && e.detail == 0) ) { - _scrollBar.setSelection(_center); - _lastScrollbarPosition = _center; - _gc.killDialogs(); - return; - } - - _lastScrollbarPosition = getScrollBarPosition(); - - _scrolling = false; - - } - - public int getScrollBarPosition() { - return _scrollBar.getSelection(); - } - - private void scrollViewportByPage(int direction, int diff) { - scrollViewportByOffset(direction, diff); - } - - private void scrollViewportByOffset(int direction, int diff) { - if (direction == SWT.LEFT) { - _gc.getViewPortHandler().scrollingLeft(diff); - } else { - _gc.getViewPortHandler().scrollingRight(diff); - } - } - - private void scrollViewportTo(int direction, int position, int diff) { - scrollViewportByOffset(direction, diff); - } - - private int scrollDirectionForEventDetail(int eventDetail) { - return (eventDetail == SWT.PAGE_UP || eventDetail == SWT.ARROW_UP) ? SWT.LEFT : SWT.RIGHT; - } - - public boolean isScrolling() { - return _scrolling; - } - - public void recalculate() { - if (_gc.isDisposed() || !_gc.isChartReady()) { - return; - } - - // no scrollbar? nothing to recalculate - if (_none) { - return; - } - - // infinite scrollbar is reset to center - if (_infinite) { - _scrollBar.setSelection(_center); - _lastScrollbarPosition = _center; - return; - } - - // deal with fixed horizontal scrollbar - if (_fixed) { - int xStart = _gc.getXForDate(_gc.getRootStartCalendar()); - int xEnd = _gc.getXForDate(_gc.getRootEndCalendar()); - int xWidth = _gc.getVisibleBounds().width; - - if (_gc.isShowingGanttSections()) { - xWidth -= _gc.getSettings().getSectionBarWidth(); - } - - xWidth -= _gc.getVerticalBar().getSize().x; - int dayWidth = _gc.getDayWidth(); - - _scrollBar.setVisible(true); - _scrollBar.setMaximum((xEnd - xStart) / dayWidth); - _scrollBar.setThumb(xWidth / dayWidth); - _scrollBar.setSelection(-xStart / dayWidth); - - } - - _lastScrollbarPosition = _scrollBar.getSelection(); - } - +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.ganttchart; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; + +class HorizontalScrollbarHandler implements Listener { + + private static final int _minScrollRange = 0; + private static final int _maxScrollRange = 500; + private static final int _center = (_maxScrollRange / 2) - 20; + + private GanttComposite _gc; + private ScrollBar _scrollBar; + private boolean _scrolling; + private int _lastScrollbarPosition; + + private boolean _infinite; + private boolean _none; + private boolean _fixed; + + private int _lastDetailEvent; + + public HorizontalScrollbarHandler(GanttComposite parent, ScrollBar scrollBar, int style) { + _gc = parent; + _scrollBar = scrollBar; + + if ((style & GanttFlags.H_SCROLL_FIXED_RANGE) != 0) { + _fixed = true; + } else if ((style & GanttFlags.H_SCROLL_INFINITE) != 0) { + _infinite = true; + } else if ((style & GanttFlags.H_SCROLL_NONE) != 0) { + _none = true; + } + + _scrollBar.addListener(SWT.Selection, this); + + if (_infinite) { + _scrollBar.setVisible(true); + _scrollBar.setMinimum(_minScrollRange); + _scrollBar.setMaximum(_maxScrollRange); + _scrollBar.setSelection(_center); + _scrollBar.setThumb(20); + return; + } + + if (_fixed) { + _scrollBar.setPageIncrement(7); + } + + _scrollBar.setMinimum(0); + _scrollBar.setIncrement(1); + + if (_none || _fixed) { + _scrollBar.setVisible(false); + } + } + + public void resetScrollPosition() { + _lastScrollbarPosition = getScrollBarPosition(); + } + + public void handleEvent(Event e) { + _scrolling = true; + + int cur = getScrollBarPosition(); + + // same as last (happens when user clicks the thumb without dragging) + if (_lastScrollbarPosition == cur) { + // if the mouse lets go of a scrollbar drag, update the scrollbars again + if (e.detail == 0 && _lastDetailEvent != 0 && _fixed) { + recalculate(); + } + + if (_infinite && e.detail == 0) { + _scrollBar.setSelection(_center); + _lastScrollbarPosition = _center; + } + + _gc.killDialogs(); + + return; + } + + _lastDetailEvent = e.detail; + + boolean left = false; + int diff = cur - _lastScrollbarPosition; + if (diff < 0) { + left = true; + diff = _lastScrollbarPosition - cur; + } + + if (e.detail == SWT.PAGE_UP || e.detail == SWT.PAGE_DOWN) { + scrollViewportByPage(scrollDirectionForEventDetail(e.detail), diff); + } else if (e.detail == SWT.ARROW_UP || e.detail == SWT.ARROW_DOWN) { + scrollViewportByOffset(scrollDirectionForEventDetail(e.detail), diff); + } else if (e.detail == SWT.DRAG) { + scrollViewportTo(left ? SWT.LEFT : SWT.RIGHT, _scrollBar.getSelection(), diff); + } + + if ((_infinite && e.detail == 0) ) { + _scrollBar.setSelection(_center); + _lastScrollbarPosition = _center; + _gc.killDialogs(); + return; + } + + _lastScrollbarPosition = getScrollBarPosition(); + + _scrolling = false; + + } + + public int getScrollBarPosition() { + return _scrollBar.getSelection(); + } + + private void scrollViewportByPage(int direction, int diff) { + scrollViewportByOffset(direction, diff); + } + + private void scrollViewportByOffset(int direction, int diff) { + if (direction == SWT.LEFT) { + _gc.getViewPortHandler().scrollingLeft(diff); + } else { + _gc.getViewPortHandler().scrollingRight(diff); + } + } + + private void scrollViewportTo(int direction, int position, int diff) { + scrollViewportByOffset(direction, diff); + } + + private int scrollDirectionForEventDetail(int eventDetail) { + return (eventDetail == SWT.PAGE_UP || eventDetail == SWT.ARROW_UP) ? SWT.LEFT : SWT.RIGHT; + } + + public boolean isScrolling() { + return _scrolling; + } + + public void recalculate() { + if (_gc.isDisposed() || !_gc.isChartReady()) { + return; + } + + // no scrollbar? nothing to recalculate + if (_none) { + return; + } + + // infinite scrollbar is reset to center + if (_infinite) { + _scrollBar.setSelection(_center); + _lastScrollbarPosition = _center; + return; + } + + // deal with fixed horizontal scrollbar + if (_fixed) { + int xStart = _gc.getXForDate(_gc.getRootStartCalendar()); + int xEnd = _gc.getXForDate(_gc.getRootEndCalendar()); + int xWidth = _gc.getVisibleBounds().width; + + if (_gc.isShowingGanttSections()) { + xWidth -= _gc.getSettings().getSectionBarWidth(); + } + + xWidth -= _gc.getVerticalBar().getSize().x; + int dayWidth = _gc.getDayWidth(); + + _scrollBar.setVisible(true); + _scrollBar.setMaximum((xEnd - xStart) / dayWidth); + _scrollBar.setThumb(xWidth / dayWidth); + _scrollBar.setSelection(-xStart / dayWidth); + + } + + _lastScrollbarPosition = _scrollBar.getSelection(); + } + } \ No newline at end of file diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IEventFactory.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IEventFactory.java index 92a916743..b5437ed0e 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IEventFactory.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IEventFactory.java @@ -1,39 +1,39 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -import java.util.Calendar; - -public interface IEventFactory { - - /** - * Creates a new GanttEvent and adds it to the given GanttChart. - * If a GanttSection is specified, it is directly added to the - * GanttSection aswell. - * @param parent The GanttChart to add the GanttEvent to. - * @param gs The GanttSection to add the GanttEvent to. - * Can be null. - * @param name The name that should be set to the GanttEvent. - * @param start The start date of the GanttEvent. - * @param end The end date of the GanttEvent. - * @return The newly created GanttEvent that was added to the - * GanttChart. - */ - GanttEvent createGanttEvent( - GanttChart parent, - GanttSection gs, - String name, - Calendar start, - Calendar end); -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +import java.util.Calendar; + +public interface IEventFactory { + + /** + * Creates a new GanttEvent and adds it to the given GanttChart. + * If a GanttSection is specified, it is directly added to the + * GanttSection aswell. + * @param parent The GanttChart to add the GanttEvent to. + * @param gs The GanttSection to add the GanttEvent to. + * Can be null. + * @param name The name that should be set to the GanttEvent. + * @param start The start date of the GanttEvent. + * @param end The end date of the GanttEvent. + * @return The newly created GanttEvent that was added to the + * GanttChart. + */ + GanttEvent createGanttEvent( + GanttChart parent, + GanttSection gs, + String name, + Calendar start, + Calendar end); +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IEventMenuItemFactory.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IEventMenuItemFactory.java index b3527ebb3..8f388d226 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IEventMenuItemFactory.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IEventMenuItemFactory.java @@ -1,31 +1,31 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -import org.eclipse.swt.widgets.Menu; - -/** - * Interface for a factory that creates menu items in the context menu of a - * GanttEvent in the GanttChart. - */ -public interface IEventMenuItemFactory { - - /** - * Adds new custom menu items to the context menu of a GanttEvent - * in the GanttChart. - * @param menu The menu to add the custom actions to. - * @param ganttEvent The GanttEvent for which the menu is opened - */ - void addCustomMenuItems(final Menu menu, final GanttEvent ganttEvent); -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +import org.eclipse.swt.widgets.Menu; + +/** + * Interface for a factory that creates menu items in the context menu of a + * GanttEvent in the GanttChart. + */ +public interface IEventMenuItemFactory { + + /** + * Adds new custom menu items to the context menu of a GanttEvent + * in the GanttChart. + * @param menu The menu to add the custom actions to. + * @param ganttEvent The GanttEvent for which the menu is opened + */ + void addCustomMenuItems(final Menu menu, final GanttEvent ganttEvent); +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IMenuItemFactory.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IMenuItemFactory.java index 77da05eee..e7572a9fd 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IMenuItemFactory.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IMenuItemFactory.java @@ -1,31 +1,31 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -import org.eclipse.swt.widgets.Menu; - -/** - * Interface for a factory that creates menu items in the context menu of the GanttChart. - * Note that this factory will only add the menu items in case the context menu is - * NOT opened for a GanttEvent. If you want to add custom menu items for the context - * menu you need to use the IEventMenuItemFactory. - */ -public interface IMenuItemFactory { - - /** - * Adds new custom menu items to the context menu of the GanttChart. - * @param menu The menu to add the custom actions to. - */ - void addCustomMenuItems(final Menu menu); -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +import org.eclipse.swt.widgets.Menu; + +/** + * Interface for a factory that creates menu items in the context menu of the GanttChart. + * Note that this factory will only add the menu items in case the context menu is + * NOT opened for a GanttEvent. If you want to add custom menu items for the context + * menu you need to use the IEventMenuItemFactory. + */ +public interface IMenuItemFactory { + + /** + * Adds new custom menu items to the context menu of the GanttChart. + * @param menu The menu to add the custom actions to. + */ + void addCustomMenuItems(final Menu menu); +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailContentReplacer.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailContentReplacer.java index 103d87056..3826d817d 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailContentReplacer.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailContentReplacer.java @@ -1,19 +1,19 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -public interface ISectionDetailContentReplacer { - - String replaceSectionDetailPlaceHolder(GanttSection section, String sectionDetailPattern); -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +public interface ISectionDetailContentReplacer { + + String replaceSectionDetailPlaceHolder(GanttSection section, String sectionDetailPattern); +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailMoreClickListener.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailMoreClickListener.java index 37d681245..2c3455bf1 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailMoreClickListener.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailMoreClickListener.java @@ -1,30 +1,30 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -/** - * This interface is used to implement a listener that gets informed when the plus - * icon in a section detail area is clicked to show more detail information. - * Usually it is intended to open a subdialog to show more detail information. - */ -public interface ISectionDetailMoreClickListener { - - /** - * Make the advanced detail information of a GanttSection visible. - * Usually this should be done by opening a dialog that contains - * that information. - * @param section The section whos detail informations should be showed. - */ - void openAdvancedDetails(GanttSection section); -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +/** + * This interface is used to implement a listener that gets informed when the plus + * icon in a section detail area is clicked to show more detail information. + * Usually it is intended to open a subdialog to show more detail information. + */ +public interface ISectionDetailMoreClickListener { + + /** + * Make the advanced detail information of a GanttSection visible. + * Usually this should be done by opening a dialog that contains + * that information. + * @param section The section whos detail informations should be showed. + */ + void openAdvancedDetails(GanttSection section); +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java index ab39e255b..84db4d4a3 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java @@ -1,1276 +1,1276 @@ -/******************************************************************************* - * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * emil.crumhorn@gmail.com - initial API and implementation - * ziogiannigmail.com - Bug 462855 - Zoom Minimum Depth increased up to 6 levels deeper than initial implementation (-6,-5,-4,-3,-2,-1) - *******************************************************************************/ - -package org.eclipse.nebula.widgets.ganttchart; - -import java.text.DateFormat; -import java.text.DateFormatSymbols; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Locale; - -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; - -/** - * This interface lets you define various settings for the GanttChart. It's highly advisable that for implementation, {@link AbstractSettings} is extended - * and methods needed to be changed from their defaults are overridden and changed. It would be quite a hassle to implement a full ISettings interface from scratch. - * In order to preserve binary compatibility, after the MinuteView implementation, this interface has been extended by {@link ISettings2} - * Please refer both to {@link ISettings} and {@link ISettings2} for any setting change. - * - *

- * class MySettings extends AbstractSettings {
- * 	// override your methods here
- * }
- * 
- *

- * Once you've overridden the settings you wish to change, simply pass an instance of your implementation class to the constructor of GanttChart: {@link GanttChart#GanttChart(org.eclipse.swt.widgets.Composite, int, ISettings)} - * - * @author Emil Crumhorn and Giovanni Cimmino - * - */ -public interface ISettings { - - // connection types.. - // --| ---| - // | <-- type 1 |--| <-- type 2 .. "type 3" is a mix of 1 and 2 with rounded corners, Project style - // V |-> - /** - * A connecting line that starts at the right of an event and goes to the top of the connecting event - */ - static final int CONNECTION_ARROW_RIGHT_TO_TOP = 1; // TODO: Fix flawed drawing - - /** - * A connecting line that starts at the right of an event and goes to the left of the connecting event - */ - static final int CONNECTION_ARROW_RIGHT_TO_LEFT = 2; - - /** - * A MS Project style connection uses rounded corners and quite a bit of logic to make the line as nice as possible, - * and also supports reverse connection coloring. This is the suggested style and is also the default. - */ - static final int CONNECTION_MS_PROJECT_STYLE = 3; - - /** - * Birds flight path is an arrow-head-less line from the one event to another in the straightest line, also known as "how the crow flies". - */ - static final int CONNECTION_BIRDS_FLIGHT_PATH = 4; - - /** - * The default connection which is {@link #CONNECTION_ARROW_RIGHT_TO_LEFT} - */ - static final int DEFAULT_CONNECTION_ARROW = CONNECTION_ARROW_RIGHT_TO_LEFT; - - // gantt view mode - - static final int VIEW_MINUTE = 0; - static final int VIEW_DAY = 1; - static final int VIEW_WEEK = 2; - static final int VIEW_MONTH = 3; - static final int VIEW_YEAR = 4; - static final int VIEW_D_DAY = 5; - - // zoom levels - static final int MIN_ZOOM_LEVEL = -6; - static final int ZOOM_SECONDS_MAX = -6; - static final int ZOOM_SECONDS_MEDIUM = -5; - static final int ZOOM_SECONDS_NORMAL = -4; - static final int ZOOM_MINUTES_MAX = -3; - static final int ZOOM_MINUTES_MEDIUM = -2; - static final int ZOOM_MINUTES_NORMAL = -1; - static final int ZOOM_HOURS_MAX = 0; - static final int ZOOM_HOURS_MEDIUM = 1; - static final int ZOOM_HOURS_NORMAL = 2; - static final int ZOOM_DAY_MAX = 3; - static final int ZOOM_DAY_MEDIUM = 4; - static final int ZOOM_DAY_NORMAL = 5; - static final int ZOOM_MONTH_MAX = 6; - static final int ZOOM_MONTH_MEDIUM = 7; - static final int ZOOM_MONTH_NORMAL = 8; - static final int ZOOM_YEAR_MAX = 9; - static final int ZOOM_YEAR_MEDIUM = 10; - static final int ZOOM_YEAR_NORMAL = 11; - static final int ZOOM_YEAR_SMALL = 12; - static final int ZOOM_YEAR_VERY_SMALL = 13; - // static final int ZOOM_YEAR_SMALLER = 14; - // static final int ZOOM_YEAR_SMALLEST = 15; - static final int MAX_ZOOM_LEVEL = 13; - - /** - * The date format to use when displaying dates in string format. - * - * @return Date format. Default is month/day/year. - * @see DateFormat - * @see DateFormatSymbols - */ - String getDateFormat(); - - /** - * The date format to use when displaying dates in string format in the hours view. - * - * @return Date format. Default is month/day/year/ hh:mm. - * @see DateFormat - * @see DateFormatSymbols - */ - String getHourDateFormat(); - - // TODO: Move these to color manager - /** - * The default color for an event when there is none set on the event itself. - * - * @return Event color. Default is gray. - */ - Color getDefaultEventColor(); - - /** - * The default gradient color for an event (if gradients are turned on). - * - * @return Event gradient color. Default is white-ish. - */ - Color getDefaultGradientEventColor(); - - /** - * Whether to show the properties menu option in the right click menu. When clicked the event will be reported to - * IGanttEventListener. - * - * @return True if to show the menu item. Default is true. - * @see IGanttEventListener#eventPropertiesSelected(GanttEvent) - */ - boolean showPropertiesMenuOption(); - - /** - * Whether to show the delete menu option in the right click menu. When clicked the event will be reported to - * IGanttEventListener. - * - * @return True if to show the menu item. Default is true. - * @see IGanttEventListener#eventsDeleteRequest(java.util.List, org.eclipse.swt.events.MouseEvent) - */ - boolean showDeleteMenuOption(); - - /** - * What type of arrow connection to draw. There are three types: - *

    - *
  • {@link ISettings#CONNECTION_ARROW_RIGHT_TO_TOP} - Arrow line (and arrow head if turned on) will be drawn into the - * events top and bottom corners. - *
  • {@link ISettings#CONNECTION_ARROW_RIGHT_TO_LEFT} - Arrow line (and arrow head if turned on) will be drawn into the - * events middle left or right side. - *
  • {@link ISettings#CONNECTION_MS_PROJECT_STYLE} - Arrow line (and arrow head if turned on) will be drawn as - * logically as possible from above event to below. Lines are rounded in corners and arrows will go to middle to top - * of below event or to side depending on where event is situated. - *
  • {@link ISettings#CONNECTION_BIRDS_FLIGHT_PATH} - Straight "as the bird flies" line between events without any bends. - *
- * - * @return Arrow head type. Default is CONNECTION_MS_PROJECT_STYLE. - * @see #CONNECTION_MS_PROJECT_STYLE - */ - int getArrowConnectionType(); - - /** - * What view is used when the chart is initially drawn. Options are: - *
    - *
  • {@link #VIEW_DAY} - *
  • {@link #VIEW_WEEK} - *
  • {@link #VIEW_MONTH} - *
  • {@link #VIEW_YEAR} - *
  • {@link #VIEW_D_DAY} - *
- * - * @return Initial view. Default is VIEW_WEEK. - */ - int getInitialView(); - - /** - * What initial zoom level is used when the chart is initially drawn. Options are: - *
    - *
  • {@link #ZOOM_SECONDS_MAX} - *
  • {@link #ZOOM_SECONDS_MEDIUM} - *
  • {@link #ZOOM_SECONDS_NORMAL} - *
  • {@link #ZOOM_MINUTES_MAX} - *
  • {@link #ZOOM_MINUTES_MEDIUM} - *
  • {@link #ZOOM_MINUTES_NORMAL} - *
  • {@link #ZOOM_HOURS_MAX} - *
  • {@link #ZOOM_HOURS_MEDIUM} - *
  • {@link #ZOOM_HOURS_NORMAL} - *
  • {@link #ZOOM_DAY_MAX} - *
  • {@link #ZOOM_DAY_MEDIUM} - *
  • {@link #ZOOM_DAY_NORMAL} - *
  • {@link #ZOOM_MONTH_MAX} - *
  • {@link #ZOOM_MONTH_MEDIUM} - *
  • {@link #ZOOM_MONTH_NORMAL} - *
  • {@link #ZOOM_YEAR_MAX} - *
  • {@link #ZOOM_YEAR_MEDIUM} - *
  • {@link #ZOOM_YEAR_NORMAL} - *
  • {@link #ZOOM_YEAR_SMALL} - *
  • {@link #ZOOM_YEAR_VERY_SMALL} - *
- * - * @return Zoom level. Default is {@link ISettings#ZOOM_DAY_NORMAL} - * @see ISettings#ZOOM_DAY_MAX - */ - int getInitialZoomLevel(); - - /** - * If to draw arrows on connecting lines or not. - * - * @return true if to show arrowheads on connecting lines. Default is true. - */ - boolean showArrows(); - - /** - * Whether to enable auto scroll which causes the chart to scroll either left or right when events are dragged or - * resized beyond the bounds of the chart. - * - * @return true if to enable. Default is true. - */ - boolean enableAutoScroll(); - - /** - * Whether to show tooltips when mouse is lingering over events. - * - * @return true if to show tooltips. Default is true. - */ - boolean showToolTips(); - - /** - * Returns the custom tool tip generator which generates the tooltip - * out of custom data for a GanttEvent. - * - * @return - */ - IToolTipContentReplacer getToolTipContentReplacer(); - - /** - * Whether to show date tooltips when events are moved or resized. - * - * @return true if to show tooltips. Default is true. - */ - boolean showDateTips(); - - /** - * Whether to show events in 3D (meaning, a drop shadow is drawn below and to the right of the event) - * - * @return true if to show events in 3D. Default is true. - */ - boolean showBarsIn3D(); - - /** - * Whether to draw the color on the events using gradients. The colors are controlled by setting the following two - * variables on the GanttEvent. {@link GanttEvent#setGradientStatusColor(Color)} and {@link GanttEvent#setStatusColor(Color)}. - * - * @return true if to draw with gradients. Default is true. - * @see GanttEvent#setGradientStatusColor(Color) - * @see GanttEvent#setStatusColor(Color) - */ - boolean showGradientEventBars(); - - /** - * Whether to only show the dependency connections only when an event is selected, as opposed to always showing the - * lines. - * - * @return true if to show them only on selections. Default is false. - */ - boolean showOnlyDependenciesForSelectedItems(); - - /** - * Whether to show a "plaque" on the event bars that displays a number of how many days the event spans over. - * - * @return true if to show the plaque. Default is false. - */ - boolean showNumberOfDaysOnBars(); - - /** - * Whether to draw lines that show where the revised dates would have been on the chart (assuming revised dates are - * set). - * - * @return true if to draw lines for the revised dates. Default is false. - */ - boolean showPlannedDates(); - - /** - * Returns the height of the header section that displays the month names. - * - * @return Pixel value. Default is 18. - */ - int getHeaderMonthHeight(); - - /** - * Returns the height of the header section that displays the days. - * - * @return Pixel value. Default is 18. - */ - int getHeaderDayHeight(); - - /** - * Returns the width for each day that is drawn. Zoom levels use multipliers with these numbers. - * - * @return Pixel value. Default is 16. - */ - int getDayWidth(); - - /** - * Returns the width for each day that is drawn in the monthly view. Zoom levels use multipliers with these numbers. - * - * @return Pixel value. Default is 6. - */ - int getMonthDayWidth(); - - /** - * Returns the width for each day that is drawn in the yearly view. Zoom levels use multipliers with these numbers. - *

- * WARNING: Setting this value below 3 will cause an infinite loop and probable application - * crash. This happens as internal size calculations end up on 0 width (rounded) values. - * - * @return Pixel value. Default is 3. - */ - int getYearMonthDayWidth(); - - /** - * Returns the height for each event, including checkpoints. - * - * @return Pixel value. Default is 12. - */ - int getEventHeight(); - - /** - * Returns the height of the bar that is drawn inside the events that represents the percentage done. - *

- * Note: If the event height is an even number, this number does best being odd, and vice versa. - * - * @return Pixel value. Default is 3. - */ - int getEventPercentageBarHeight(); - - /** - * The percentage bar always draws as a line in the center of the event but normally it only draws the part that - * displays the % complete. If this returns true it will draw that part, but also the remainder. You can set the - * color for the remainder different than that from the actual percentage complete as well. - * - * @return true if to draw the entire bar. Default is true. - */ - boolean drawFullPercentageBar(); - - /** - * The Alpha level of the percentage complete bar. Only draws if Alpha is turned on. - * - * @return Alpha value. Default is 255. - */ - int getPercentageBarAlpha(); - - /** - * The Alpha level of the remaining percentage complete bar. Only draws if Alpha is turned on. - * - * @return Alpha value. Default is 70. - */ - int getRemainderPercentageBarAlpha(); - - /** - * Returns the number of pixels off each side of an event that is the area for which the resize cursor is shown. If - * people find it hard to grab events, increase this number. - * - * @return Pixel value. Default is 3. - */ - int getResizeBorderSensitivity(); - - /** - * Returns the number of pixels off each side of an event towards the center of it that is ignored when trying to - * move an event. This is to help resize distinguish from a move cursor and to help users find the two different - * areas. - * - * @return Pixel value. Default is 6. Remember that this value is handled in a negative calculation, but it should - * be a positive value. - */ - int getMoveAreaNegativeSensitivity(); - - /** - * Returns the space between the actual event and the text that is written after the event when the event has a - * connecting line extending from it. - * - * @return Pixel value. Default is 9. - */ - int getTextSpacerConnected(); - - /** - * Returns the space between the actual event and the text that is written after the event when the event has no - * connecting line extending from it. - * - * @return Pixel value. Default is 9. - */ - int getTextSpacerNonConnected(); - - /** - * Returns the space from the left of the border where the day letter is printed. - * - * @return Pixel value. Default is 3. - */ - int getDayVerticalSpacing(); - - /** - * Returns the spacing from the top where the day letter is printed. - * - * @return Pixel value. Default is 4. - */ - int getDayHorizontalSpacing(); - - /** - * Returns the vertical space between each event. - * - * @return Pixel value. Default is 12. - */ - int getEventSpacer(); - - /** - * Whether the name of the scope is drawn in bold or plain. - * - * @return true if bold. Default is true. - */ - boolean showBoldScopeText(); - - /** - * Letters have different width. If turned on, this will try to make all day letters appear centered, whereas if - * turned off, letter width will be ignored. - * - * @return true if to adjust for letter widths. Default is true. - */ - boolean adjustForLetters(); - - /** - * Whether event-resizing is turned on or off. - * - * @return true if turned on. If turned off, event resizing is not possible. Default is true. - */ - boolean enableResizing(); - - /** - * Whether users can hold down SHIFT (or whatever the settings say) to move an event, and all dependent - * events will move with the selected event. - * - * @return true if to move all linked events. Default is true. - * @see ISettings#getDragAllModifierKey() - */ - boolean moveLinkedEventsWhenEventsAreMoved(); - - /** - * Whether event drag-and-drop is turned on or off. - * - * @return true if turned on. If turned off, drag and drop is not possible. Default is true. - */ - boolean enableDragAndDrop(); - - /** - * Whether when a user zooms in or out (only via CTRL (or whatever the settings say) + - * Scroll Wheel) to display a box in the bottom left corner that shows the zoom level. - * - * @return true if to show a box when zooming. Default is true. - * @see ISettings#getZoomWheelModifierKey() - */ - boolean showZoomLevelBox(); - - /** - * Whether to mimic Microsoft © Project's infinite scrollbar which lets users scroll into the future or past indefinitely. If - * turned off, the scrollbar will reflect the range of the oldest event's start date, to the latest event end date. - * - * @return true if to turn on infinite scrollbar. Default is true. - */ - boolean allowInfiniteHorizontalScrollBar(); - - /** - * Whether the date tooltip box (if turned on) when resizing should hug the border of the event on the left or right - * side or if it should be simply stick somewhat to the event resize location. - * - * @return true if to stick to the resize sides. Default is true. - */ - boolean showResizeDateTipOnBorders(); - - /** - * If true, it lets the move forwards or backwards in time by clicking in a "blank" area and dragging the mouse. - * Similar to the hand tool in Photoshop or Acrobat. - * - * @return true if to allow clear-area drag. Default is true. - */ - boolean allowBlankAreaDragAndDropToMoveDates(); - - /** - * Relies on {@link #allowBlankAreaDragAndDropToMoveDates()} being true. If so, this will additionally determine if the user - * can blank-area drag the chart in a vertical manner to move the chart in that direction as well. - *

- * Holding down the shift key will double the speed of the vertical drag - * - * @return true to allow clear-area vertical drag. Default is false (as it can be confusing at first try). - */ - boolean allowBlankAreaVerticalDragAndDropToMoveChart(); - - /** - * If for some reason the drag left vs. drag right directions feel reversed, simply flip this to switch them around. - * Only active if {@link #allowBlankAreaDragAndDropToMoveDates()} is active. - * - * @return true if to flip them around. Default is false. - * @see ISettings#allowBlankAreaDragAndDropToMoveDates() - */ - boolean flipBlankAreaDragDirection(); - - /** - * If true, draws a dotted selection marker around the currently selected event to visualize the selection. - * - * @return true if to show a selection marker. Default is true. - */ - boolean drawSelectionMarkerAroundSelectedEvent(); - - /** - * Whether checkpoints can be resized (assuming resizing is on {@link ISettings#enableResizing()}). - * - * @return true if checkpoints can be resized. Default is false. - * @see ISettings#enableResizing() - */ - boolean allowCheckpointResizing(); - - /** - * Whether to show any menu items at all when right clicking an event or a chart. - * - * @return true if to show menu items on right click. Default is true. - */ - boolean showMenuItemsOnRightClick(); - - /** - * Returns the space between the head of the dependency arrowhead and the event. - * - * @return pixel space. Default is 1. - */ - int getArrowHeadEventSpacer(); - - /** - * If you for some reason wish to move the arrow head up or down vertically, setting a number here will modify the - * vertical "extra". - * - * @return pixel length. Default is 0. - */ - int getArrowHeadVerticalAdjuster(); - - /** - * Returns the position that the calendar should start on when first created. If null, the current date will be - * used. Please remember to use a Locale when you create your Calendar object, ideally the same as used in the - * settings {@link ISettings#getDefaultLocale()}. - * - * @return Calendar, or null. - */ - Calendar getStartupCalendarDate(); - - /** - * Date offset of the startup date that the calendar should start at. By default, you probably do not want this to - * be 0 as that will hug the leftmost side of the widget. It's suggested to set a negative value. - * - * @return date offset in number of days. Default is -4. - */ - int getCalendarStartupDateOffset(); - - /** - * Moves the calendar to start on the first day of the week of the either current date or the date set in - * {@link ISettings#getStartupCalendarDate()} - *

- * Please note, if the - * {@link ISettings#getCalendarStartupDateOffset()} is set to other than zero, these two methods will most likely - * clash. - *

- * This setting has no effect on D-Day charts. - * - * @return true whether calendar should start on the first day of the week. Default is false. - * @see #getCalendarStartupDateOffset() - * @see #getStartupCalendarDate() - */ - boolean startCalendarOnFirstDayOfWeek(); - - /** - * If zooming in/out should be enabled or disabled. - * - * @return true if enabled. Default is true. - */ - boolean enableZooming(); - - /** - * Returns the image used for displaying something as locked in the GANTT chart. - * - * @return Image or null. Default is the lock_tiny.gif image in the package. - */ - Image getLockImage(); - - /** - * Decides how the string behind the event is displayed. You may override this individually by setting the - * GanttEvent parameter by the same name. - *

    - *
  • #name# = Name of event - *
  • #pc# = Percentage complete - *
  • #sd# = Start date - *
  • #ed# = End date - *
  • #rs# = - * Revised start date - *
  • #re# = Revised end date - *
  • #days# = Number of days event spans over - *
  • #reviseddays# = - * Number of revised days event spans over - *
- * - * @return String format. Default is "#name# (#pc#%)" - * @see GanttEvent#setTextDisplayFormat(String) - */ - String getTextDisplayFormat(); - - /** - * The distance from the event top (and event bottom) that is used to draw the line portraying revised start and end - * dates. - * - * @return Pixel spacing. Default is 3. - */ - int getRevisedLineSpacer(); - - /** - * Whether to round off minutes on events to nearest hour. - * - * @return true if yes. Default is false. - */ - boolean roundHourlyEventsOffToNearestHour(); - - /** - * The default help image used in the advanced tooltip. Null if none. - * - * @return Image or null. Default is null. - */ - Image getDefaultAdvandedTooltipHelpImage(); - - /** - * The default image used in the advanced tooltip. Null if none. - * - * @return Image or null. Default is null. - */ - Image getDefaultAdvandedTooltipImage(); - - /** - * The default help text shown in the advanced tooltip. - * - * @return String or null. Default is null. - */ - String getDefaultAdvancedTooltipHelpText(); - - /** - * The default title text shown in the advanced tooltip. - * - * @return String or null. Default is null. - */ - String getDefaultAdvancedTooltipTitle(); - - /** - * The default extended tooltip shown in the advanced tooltip. Extended tooltips are used when the GanttEvent has - * revised dates. - * - * @return String or null. Default is a text showing the dates, revised dates and percentage complete. - */ - String getDefaultAdvancedTooltipTextExtended(); - - /** - * The default tooltip shown in the advanced tooltip. Normal tooltips are used when the GanttEvent has no revised - * dates and also for scopes, images and checkpoints. - * - * @return String or null. Default is a text showing the dates and percentage complete. - */ - String getDefaultAdvancedTooltipText(); - - /** - * The width of the line showing where today's date is. - * - * @return line width. Default is 2. - */ - int getTodayLineWidth(); - - /** - * The default line style of the line showing where today's date is. - * - * @return SWT.LINE_ style. Default is SWT.LINE_SOLID. - */ - int getTodayLineStyle(); - - /** - * The vertical offset from the top for the today line calculated from the bottom part of the header. - * - * @return Vertical offset. Default is the height of the bottom header. - */ - int getTodayLineVerticalOffset(); - - /** - * The vertical offset from top for the tick marks in the top header. - * - * @return Default is the height of the top header minus 5. - */ - int getVerticalTickMarkOffset(); - - /** - * The SimpleDateFormat of the text shown in the top header for the day view. - * - * @return {@link SimpleDateFormat} string. May not be null. - */ - String getDayHeaderTextDisplayFormatTop(); - - /** - * The SimpleDateFormat of the text shown in the top header for the week view. - * - * @return SimpleDateFormat string. May not be null. - */ - String getWeekHeaderTextDisplayFormatTop(); - - /** - * The SimpleDateFormat of the text shown in the top header for the month view. - * - * @return SimpleDateFormat string. May not be null. - */ - String getMonthHeaderTextDisplayFormatTop(); - - /** - * The SimpleDateFormat of the text shown in the top header for the year view. - * - * @return SimpleDateFormat string. May not be null. - */ - String getYearHeaderTextDisplayFormatTop(); - - /** - * The SimpleDateFormat of the text shown in the bottom header for the day view. - * - * @return SimpleDateFormat string. May not be null. - */ - String getDayHeaderTextDisplayFormatBottom(); - - /** - * The SimpleDateFormat of the text shown in the bottom header for the week view. - * - * @return SimpleDateFormat string. May not be null. - */ - String getWeekHeaderTextDisplayFormatBottom(); - - /** - * The SimpleDateFormat of the text shown in the bottom header for the month view. - * - * @return SimpleDateFormat string. May not be null. - */ - String getMonthHeaderTextDisplayFormatBottom(); - - /** - * The SimpleDateFormat of the text shown in the bottom header for the year view. - * - * @return SimpleDateFormat string. May not be null. - */ - String getYearHeaderTextDisplayFormatBottom(); - - /** - * Whether to draw the header or not. If this returns false, all header-related settings will be ignored. - * - * @return true if to draw header. Default is true. - */ - boolean drawHeader(); - - /** - * Top spacer between the top pixel and the beginning of the first event. The top pixel will be either the height of - * the header (if drawn) or 0 if the header is not drawn. - * - * @return top spacer value. Default is 12. - */ - int getEventsTopSpacer(); - - /** - * Bottom spacer between the bottom event and the section divider when using GanttSections. For non GanttSection - * usage, this setting is ignored. - * - * @return bottom spacer value. Default is 12. - */ - int getEventsBottomSpacer(); - - /** - * The height of the bar drawn between sections. - * - * @return height. Default is 5. - */ - int getSectionBarDividerHeight(); - - /** - * Width of the section bar. - * - * @return width. Default is 20. - */ - int getSectionBarWidth(); - - /** - * Minimum height of sections. Normally the minimum height is calculated by: - *

- * 1. Space the section name takes up vertically
- * 2. Space all contained events take up including various event spacers. - *

- * If the two calculations above are smaller than the value returned by this method, the height returned from this - * method will be used. - * - * @return minimum section height (larger or equals to zero). Default is 80. - */ - int getMinimumSectionHeight(); - - /** - * Advanced tooltips are shells and by default they pop up where the mouse pointer is. To not block the pointer, an - * offset is used. - * - * @return horizontal offset. Default is 15. - */ - int getAdvancedTooltipXOffset(); - - /** - * Whether to use Advanced Tooltips by default. - * - * @return True whether to use advanced tooltips. Default is true. - */ - boolean getUseAdvancedTooltips(); - - /** - * The keyboard modifier key (also known as a hint) used to determine when it's a drag-all-linked-events - * {@link ISettings#moveLinkedEventsWhenEventsAreMoved()} event or just a normal drag. - * - * @return Keyboard modifier. Default is SWT.SHIFT (the shift key) - * @see ISettings#moveLinkedEventsWhenEventsAreMoved() - */ - int getDragAllModifierKey(); - - /** - * The keyboard modifier key combined with the scroll wheel to make the chart zoom. - * - * @return Keyboard modifier. Default is SWT.MOD1 (usually the CTRL key) - */ - int getZoomWheelModifierKey(); - - /** - * Locale used for calendars and wherever needed. - * - * @return Locale. Default is Locale.getDefault(). - */ - Locale getDefaultLocale(); - - /** - * See IGanttEventListener's lastDraw(GC gc) method method info. - * - * @return true whether to enable the last draw functionality. Default is false. - * @see IGanttEventListener#lastDraw(org.eclipse.swt.graphics.GC) - */ - boolean enableLastDraw(); - - /** - * If you plan on using reverse dependencies, you may want to flag this to true. This makes normal connections draw - * the arrow to the top left corner of the target event, and if it's a reverse dependency, it draw the arrow to the - * bottom left of target events. That way any overlapping event don't have arrows drawing in the exact same spot - * which makes it much easier to view the chart. - * - * @return true to split arrows. Default is false. - */ - boolean useSplitArrowConnections(); - - /** - * If you plan on using reverse dependencies, this value will be interesting. If this value returns 0 and you have - * both a normal-direction dependency and a reverse one, their vertical lines will overlap. By setting this value to - * greater than zero that vertical line will be spaced out for reverse dependencies. The value is how much extra it - * will be spaced. - * - * @return spacer value. Default is 2. - */ - int getReverseDependencyLineHorizontalSpacer(); - - /** - * The vertical lines are the lines that divide days and weeks etc. - * - * @see GanttComposite#setDrawVerticalLinesOverride(Boolean) - * @return true if to draw vertical lines. Default is true. - */ - boolean drawVerticalLines(); - - /** - * Whether to draw horizontal lines between the events. Useful for where you have a tree/table on the left and wish - * events to be easier to see when they are lined up with the tree items. - * - * @see GanttComposite#setDrawHorizontalLinesOverride(Boolean) - * @return true to show horizontal lines. Default is false; - */ - boolean drawHorizontalLines(); - - /** - * Which side the section bar should be drawn on.
- *
- * You may use one of SWT.LEFT or SWT.RIGHT. - * - * @return section bar side. Default is SWT.LEFT. - */ - int getSectionSide(); - - /** - * When dates are locked down to a certain day, the chart will draw a special marker on the lock start and end dates - * to point out that it's locked between certain constraints. - * - * @return Whether to draw markers for date-range-locked events. Default is true. - */ - boolean drawLockedDateMarks(); - - /** - * Whether to show a date tooltip when scrolling horizontally (changing dates) and vertically. The tooltip will show - * just above the bottom horizontal toolbar. Note that if showDateTips() returns false, this tip will not show. - * - * @return true whether to show date tooltips when scrolling through dates. Default is true. - * @see #showDateTips() - */ - boolean showDateTipsOnScrolling(); - - // fix to bugzilla #236852 - /** - * Whether the GanttSection bar should draw all the way down or not. - * - * @return true to draw all the way down. Default is false. - */ - boolean drawGanttSectionBarToBottom(); - - // fix to bugzilla #236852 - /** - * Whether to draw fills and vertical lines etc to the bottom when GanttSections are used. - * - * @return true to draw everything all the way down. Default is false. - */ - boolean drawFillsToBottomWhenUsingGanttSections(); - - /** - * Whether the header should always be visible regardless of vertical scroll position. Basically a "fixed header" - * feature. - * - * @return true whether to lock the header. Default is false. - */ - boolean lockHeaderOnVerticalScroll(); - - /** - * Whether to show the default set of menu items on the right click menus of events. If false, the menu will be - * blank allowing you to set all items from scratch. - * - * @return true to show default menu items along with custom ones on right click. Default is true. - * @see #showMenuItemsOnRightClick() - * @see #showPropertiesMenuOption() - * @see #showDeleteMenuOption() - * @see GanttEvent#getMenu() - */ - boolean showDefaultMenuItemsOnEventRightClick(); - - /** - * Whether scopes can show a right click menu or not. By default scopes are non-active objects that simply draw - * according to their children. By allowing a menu to be shown on the scope you can still perform custom events if - * you so wish (such as show/hide all children). - * - * @return true to allow menus on scopes. Default is false. - * @see GanttEvent#getMenu() - * @see GanttEvent#showAllChildren() - * @see GanttEvent#hideAllChildren() - */ - boolean allowScopeMenu(); - - /** - * Whether selecting dates in the header is allowed by clicking the date. Events will be fired on selection events. - * Note that not all views have this feature, only those that actually show full dates, as that's where it makes - * most sense. - * - * @return true to allow header selection. Default is true. - */ - boolean allowHeaderSelection(); - - /** - * When you zoom in with the mouse, it can either act as a normal zoom (uses leftmost date as start date) or it can - * zoom in where the mouse pointer is at the time of the zoom in. For some the first make more sense than the other - * and vice versa. Default is that the zoom in is where the mouse pointer is (true). - */ - boolean zoomToMousePointerDateOnWheelZooming(); - - /** - * It's highly suggested you use the default implementation of this method. Basically, this method needs to return a - * zeroed-down calendar (hours, minutes etc) that will be used as the D-day root calendar. As D-days aren't dates - * (except internally), this Calendar simply needs to be any "stable" date. By default it uses January 1st, [current - * year], 0h 0m 0s 0ms. (it uses the current year as days-between calculations otherwise get very large). - * - * @return Calendar - */ - Calendar getDDayRootCalendar(); - - /** - * The value where D-days have their "weeks" so to speak, this is used to calculate the numbers shown in both - * headers, where the top header is displaying each "set" whereas the bottom one shows numbers from 0 to the number - * returned by this method. - * - * @return Split count number. Default is 10 which shows sets from 0 to 9. - */ - int getDDaySplitCount(); - - /** - * If this returns true, events are never rounded up to their nearest hour/minute when shown in the chart, but will - * always show down to the minute even in any mid-zoomed and fully-zoomed out view (this does not do anything to the - * normal minute view). Default is false. - * - * @return true to draw event location down to the hour and minute - */ - boolean drawEventsDownToTheHourAndMinute(); - - /** - * If this returns true, only linked events that come after the source drag event (time/date-wise) will be - * moved/resized (normally all linked events are moved/resized regardless of time/date). - * - * @return true to only move/resize "later" events on dependent linked event moves/resizes. Default is false. - */ - boolean moveAndResizeOnlyDependentEventsThatAreLaterThanLinkedMoveEvent(); - - /** - * In SWT 3.5 it seems the mousewheel is not interpreted the same as in previous versions. If you notice that when - * scrolling the mousewheel the chart does not actually scroll vertically, flag this to true to force it to scroll - * the chart. This is forced to true on *NIX machines (not Mac). - * - * @return true to force the mousewheel to scroll the chart. Default is false. - * @deprecated By default mousewheel now scrolls chart vertically on all platforms. To turn off, flag scrollChartVerticallyOnMouseWheel() - * @see #scrollChartVerticallyOnMouseWheel() - */ - @Deprecated - boolean forceMouseWheelVerticalScroll(); - - /** - * If the name of any section is so large that it basically defines the size of the section, this value is used to - * space out the text slightly so that the section borders don't hug the text. If you want to save on some real-estate - * set this value to 0. - * - * @return Default is 30. - */ - int getSectionTextSpacer(); - - /** - * When drawing {@link GanttPhase}s this is the header height used for displaying the names of these phases. - * - * @return Default is 18 - */ - int getPhasesHeaderHeight(); - - /** - * When phases are resized or moved, whether an overlap resize/move should be accepted or not. - * If false (default), a resize will simply stop at the next phase border, whereas a move that is dropped - * on top of a different phase will be undone (no event is fired for this). - * - * @return Default is false - */ - boolean allowPhaseOverlap(); - - /** - * What style of vertical event dragging that is enabled. For the "resistance" before a vertical drag takes - * place you can change this with {@link ISettings#getVerticalDragResistance()}. - * - * @return One of the options in {@link VerticalDragModes}. Default is {@link VerticalDragModes#NO_VERTICAL_DRAG} - */ - int getVerticalEventDragging(); - - /** - * For events that can be dragged vertically, this is the "resistance" in pixels before the event "lets go" - * of it's horizontal location. Once it's let go it will stick to the mouse cursor. - * - * @return A pixel range of resistance. Default is 15px. - */ - int getVerticalDragResistance(); - - /** - * Whether an insert marker should be shown for where the dragged event will end up when a vertical drag/drop - * is in progress. - * - * @return true to show a marker. Default is true. - */ - boolean onVerticalDragDropShowInsertMarker(); - - // bugzilla feature request #309808 - /** - * Whether to allow an image to exceed the width of one day when zooming in / out. - * - * @return true to keep within day width. Default is true. - */ - boolean scaleImageToDayWidth(); - - /** - * Whether arrow keys are enabled to scroll chart left/right/up/down. - * - * @return true to allow arrow keys to move the chart. Default is false. - */ - boolean allowArrowKeysToScrollChart(); - - /** - * Normally a day is calculated as day_starts->day_ends, which means that to make an event that starts and ends on the same day count as "anything", +1 is - * added by default to make the event actually show up on the chart. Should you for some reason need to override this, change this number to 0 or whatever you may need. - * - * @return Number of days to count for a start and end date that is the same date. Default is 1. - */ - int getNumberOfDaysToAppendForEndOfDay(); - - /** - * Whether the chart should scroll vertically when the mouse wheel is used. If you notice excessive scrolling on SWT versions earlier than 3.5, you may want to turn this off - * - * @return true to scroll chart vertically. Default is true. - */ - boolean scrollChartVerticallyOnMouseWheel(); - - /** - * Returns the minimum zoom level. - * Default should return {@link ISettings#MIN_ZOOM_LEVEL} - * - * @return - */ - int getMinZoomLevel(); - - /** - * Specify a period start. Returning another value than null will result in rendering - * an additional line to the chart indicating a period start in the gantt itself. - * - * @return - */ - Calendar getPeriodStart(); - - /** - * Specify a period end. Returning another value than null will result in rendering - * an additional line to the chart indicating a period end in the gantt itself. - * - * @return - */ - Calendar getPeriodEnd(); - - /** - * If you want to show the event String within the event rectangle by setting the horizontalTextLocation of - * the GanttEvent to SWT.CENTER, there are cases that break the visualization. If your event String is longer - * than the event in the Gantt, it will look quite strange. - *

- * If this method returns true, the AbstractPaintManager will shift the rendering of the event - * String to the right if the String length is greater than the event rectangle. - * - * @return true if the event String should be shifted, false if not - */ - boolean shiftHorizontalCenteredEventString(); - - /** - * @return true to enable the menu action for adding an event to the GanttChart, - * false if this action should not be available to the user. - */ - boolean enableAddEvent(); - - /** - * Global configuration to specify if the text of GanttEvents should be rendered or not. - * It is also possible to configure this per GanttEvent via _showText property. - * - * @return true if the event text should be rendered, false - * if not. - */ - boolean drawEventString(); - - /** - * The default behaviour in GanttChart on moving an event is that only the current dragged - * event is moved unless you press the SHIFT key. If there are more events selected, still - * only the dragged one is moved if the SHIFT key is not pressed. - * With this configuration it is possible to specify if the old default behavior should be - * used or if all currently selected events should be moved even if the SHIFT key is not pressed. - * - * @return true if all selected events should be moved by dragging on of them - * false if only the current dragged event should be moved. - */ - boolean alwaysDragAllEvents(); - - /** - * On printing a GanttChart it is possible to select to print only the selected area. - * For GanttChart this means to print the currently visible area. By default currently - * visible means vertically AND horizontally visible. This configuration allows to - * specify whether the vertical part should extend to the whole chart and only the - * horizontal area should be limited for the visible part. - * - * @return true if the printed chart should contain the whole chart - * vertically but only the horizontal visible part of the chart, - * false if only the visible part of the chart should be printed, - * horizontally AND vertically - */ - boolean printSelectedVerticallyComplete(); - - /** - * Configure whether a footer should be added to the print pages or not. - * The footer contains the page number and the date when the print was - * requested. - * - * @return true if a footer should be added to the print pages, - * false if not - */ - boolean printFooter(); - - /** - * Configure whether the section bar should be rendered. It only makes sense - * to not render the section bar if the section details are enabled. - * - * @return true if the section bar should - * be rendered, false if not - */ - boolean drawSectionBar(); - - /** - * Configure whether there should be an additional area to the section bar - * that shows additional section detail information. - * - * @return true if additional section detail information should - * be rendered, false if not - */ - boolean drawSectionDetails(); - - /** - * @return The width of the section detail area. - */ - int getSectionDetailWidth(); - - /** - * The section detail area title that should be rendered in the section detail area. - * - * @return String or null. Default is a bold black text showing the section name. - */ - String getSectionDetailTitle(); - - /** - * The detail information that should be rendered in the section detail area. - * - * @return String or null. Default is to show the number of events in that section. - */ - String getSectionDetailText(); - - /** - * Returns the custom section detail generator which generates the section detail - * out of custom data for a GanttSection. - * - * @return - */ - ISectionDetailContentReplacer getSectionDetailContentReplacer(); - - /** - * - * @return true if there should be a "more [+]" shown in the section - * detail area which allows to register a listener against to show more - * informations by e.g. opening a dialog. - */ - boolean showSectionDetailMore(); - - /** - * Configure whether a tooltip pops up when hovering the mouse over a holiday - * - * @return true to show a "holiday" popup with the configured name of the holiday, - * false if not (default) - */ - boolean showHolidayToolTips(); - - /** - * whether {@link IGanttEventListener#eventSelected(GanttEvent, java.util.List, org.eclipse.swt.events.MouseEvent)} should also - * be called on empty selection - * - * @return true to have the event fired. Default is false - */ - boolean fireEmptyEventSelection(); -} +/******************************************************************************* + * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * emil.crumhorn@gmail.com - initial API and implementation + * ziogiannigmail.com - Bug 462855 - Zoom Minimum Depth increased up to 6 levels deeper than initial implementation (-6,-5,-4,-3,-2,-1) + *******************************************************************************/ + +package org.eclipse.nebula.widgets.ganttchart; + +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; + +/** + * This interface lets you define various settings for the GanttChart. It's highly advisable that for implementation, {@link AbstractSettings} is extended + * and methods needed to be changed from their defaults are overridden and changed. It would be quite a hassle to implement a full ISettings interface from scratch. + * In order to preserve binary compatibility, after the MinuteView implementation, this interface has been extended by {@link ISettings2} + * Please refer both to {@link ISettings} and {@link ISettings2} for any setting change. + * + *

+ * class MySettings extends AbstractSettings {
+ * 	// override your methods here
+ * }
+ * 
+ *

+ * Once you've overridden the settings you wish to change, simply pass an instance of your implementation class to the constructor of GanttChart: {@link GanttChart#GanttChart(org.eclipse.swt.widgets.Composite, int, ISettings)} + * + * @author Emil Crumhorn and Giovanni Cimmino + * + */ +public interface ISettings { + + // connection types.. + // --| ---| + // | <-- type 1 |--| <-- type 2 .. "type 3" is a mix of 1 and 2 with rounded corners, Project style + // V |-> + /** + * A connecting line that starts at the right of an event and goes to the top of the connecting event + */ + static final int CONNECTION_ARROW_RIGHT_TO_TOP = 1; // TODO: Fix flawed drawing + + /** + * A connecting line that starts at the right of an event and goes to the left of the connecting event + */ + static final int CONNECTION_ARROW_RIGHT_TO_LEFT = 2; + + /** + * A MS Project style connection uses rounded corners and quite a bit of logic to make the line as nice as possible, + * and also supports reverse connection coloring. This is the suggested style and is also the default. + */ + static final int CONNECTION_MS_PROJECT_STYLE = 3; + + /** + * Birds flight path is an arrow-head-less line from the one event to another in the straightest line, also known as "how the crow flies". + */ + static final int CONNECTION_BIRDS_FLIGHT_PATH = 4; + + /** + * The default connection which is {@link #CONNECTION_ARROW_RIGHT_TO_LEFT} + */ + static final int DEFAULT_CONNECTION_ARROW = CONNECTION_ARROW_RIGHT_TO_LEFT; + + // gantt view mode + + static final int VIEW_MINUTE = 0; + static final int VIEW_DAY = 1; + static final int VIEW_WEEK = 2; + static final int VIEW_MONTH = 3; + static final int VIEW_YEAR = 4; + static final int VIEW_D_DAY = 5; + + // zoom levels + static final int MIN_ZOOM_LEVEL = -6; + static final int ZOOM_SECONDS_MAX = -6; + static final int ZOOM_SECONDS_MEDIUM = -5; + static final int ZOOM_SECONDS_NORMAL = -4; + static final int ZOOM_MINUTES_MAX = -3; + static final int ZOOM_MINUTES_MEDIUM = -2; + static final int ZOOM_MINUTES_NORMAL = -1; + static final int ZOOM_HOURS_MAX = 0; + static final int ZOOM_HOURS_MEDIUM = 1; + static final int ZOOM_HOURS_NORMAL = 2; + static final int ZOOM_DAY_MAX = 3; + static final int ZOOM_DAY_MEDIUM = 4; + static final int ZOOM_DAY_NORMAL = 5; + static final int ZOOM_MONTH_MAX = 6; + static final int ZOOM_MONTH_MEDIUM = 7; + static final int ZOOM_MONTH_NORMAL = 8; + static final int ZOOM_YEAR_MAX = 9; + static final int ZOOM_YEAR_MEDIUM = 10; + static final int ZOOM_YEAR_NORMAL = 11; + static final int ZOOM_YEAR_SMALL = 12; + static final int ZOOM_YEAR_VERY_SMALL = 13; + // static final int ZOOM_YEAR_SMALLER = 14; + // static final int ZOOM_YEAR_SMALLEST = 15; + static final int MAX_ZOOM_LEVEL = 13; + + /** + * The date format to use when displaying dates in string format. + * + * @return Date format. Default is month/day/year. + * @see DateFormat + * @see DateFormatSymbols + */ + String getDateFormat(); + + /** + * The date format to use when displaying dates in string format in the hours view. + * + * @return Date format. Default is month/day/year/ hh:mm. + * @see DateFormat + * @see DateFormatSymbols + */ + String getHourDateFormat(); + + // TODO: Move these to color manager + /** + * The default color for an event when there is none set on the event itself. + * + * @return Event color. Default is gray. + */ + Color getDefaultEventColor(); + + /** + * The default gradient color for an event (if gradients are turned on). + * + * @return Event gradient color. Default is white-ish. + */ + Color getDefaultGradientEventColor(); + + /** + * Whether to show the properties menu option in the right click menu. When clicked the event will be reported to + * IGanttEventListener. + * + * @return True if to show the menu item. Default is true. + * @see IGanttEventListener#eventPropertiesSelected(GanttEvent) + */ + boolean showPropertiesMenuOption(); + + /** + * Whether to show the delete menu option in the right click menu. When clicked the event will be reported to + * IGanttEventListener. + * + * @return True if to show the menu item. Default is true. + * @see IGanttEventListener#eventsDeleteRequest(java.util.List, org.eclipse.swt.events.MouseEvent) + */ + boolean showDeleteMenuOption(); + + /** + * What type of arrow connection to draw. There are three types: + *

    + *
  • {@link ISettings#CONNECTION_ARROW_RIGHT_TO_TOP} - Arrow line (and arrow head if turned on) will be drawn into the + * events top and bottom corners. + *
  • {@link ISettings#CONNECTION_ARROW_RIGHT_TO_LEFT} - Arrow line (and arrow head if turned on) will be drawn into the + * events middle left or right side. + *
  • {@link ISettings#CONNECTION_MS_PROJECT_STYLE} - Arrow line (and arrow head if turned on) will be drawn as + * logically as possible from above event to below. Lines are rounded in corners and arrows will go to middle to top + * of below event or to side depending on where event is situated. + *
  • {@link ISettings#CONNECTION_BIRDS_FLIGHT_PATH} - Straight "as the bird flies" line between events without any bends. + *
+ * + * @return Arrow head type. Default is CONNECTION_MS_PROJECT_STYLE. + * @see #CONNECTION_MS_PROJECT_STYLE + */ + int getArrowConnectionType(); + + /** + * What view is used when the chart is initially drawn. Options are: + *
    + *
  • {@link #VIEW_DAY} + *
  • {@link #VIEW_WEEK} + *
  • {@link #VIEW_MONTH} + *
  • {@link #VIEW_YEAR} + *
  • {@link #VIEW_D_DAY} + *
+ * + * @return Initial view. Default is VIEW_WEEK. + */ + int getInitialView(); + + /** + * What initial zoom level is used when the chart is initially drawn. Options are: + *
    + *
  • {@link #ZOOM_SECONDS_MAX} + *
  • {@link #ZOOM_SECONDS_MEDIUM} + *
  • {@link #ZOOM_SECONDS_NORMAL} + *
  • {@link #ZOOM_MINUTES_MAX} + *
  • {@link #ZOOM_MINUTES_MEDIUM} + *
  • {@link #ZOOM_MINUTES_NORMAL} + *
  • {@link #ZOOM_HOURS_MAX} + *
  • {@link #ZOOM_HOURS_MEDIUM} + *
  • {@link #ZOOM_HOURS_NORMAL} + *
  • {@link #ZOOM_DAY_MAX} + *
  • {@link #ZOOM_DAY_MEDIUM} + *
  • {@link #ZOOM_DAY_NORMAL} + *
  • {@link #ZOOM_MONTH_MAX} + *
  • {@link #ZOOM_MONTH_MEDIUM} + *
  • {@link #ZOOM_MONTH_NORMAL} + *
  • {@link #ZOOM_YEAR_MAX} + *
  • {@link #ZOOM_YEAR_MEDIUM} + *
  • {@link #ZOOM_YEAR_NORMAL} + *
  • {@link #ZOOM_YEAR_SMALL} + *
  • {@link #ZOOM_YEAR_VERY_SMALL} + *
+ * + * @return Zoom level. Default is {@link ISettings#ZOOM_DAY_NORMAL} + * @see ISettings#ZOOM_DAY_MAX + */ + int getInitialZoomLevel(); + + /** + * If to draw arrows on connecting lines or not. + * + * @return true if to show arrowheads on connecting lines. Default is true. + */ + boolean showArrows(); + + /** + * Whether to enable auto scroll which causes the chart to scroll either left or right when events are dragged or + * resized beyond the bounds of the chart. + * + * @return true if to enable. Default is true. + */ + boolean enableAutoScroll(); + + /** + * Whether to show tooltips when mouse is lingering over events. + * + * @return true if to show tooltips. Default is true. + */ + boolean showToolTips(); + + /** + * Returns the custom tool tip generator which generates the tooltip + * out of custom data for a GanttEvent. + * + * @return + */ + IToolTipContentReplacer getToolTipContentReplacer(); + + /** + * Whether to show date tooltips when events are moved or resized. + * + * @return true if to show tooltips. Default is true. + */ + boolean showDateTips(); + + /** + * Whether to show events in 3D (meaning, a drop shadow is drawn below and to the right of the event) + * + * @return true if to show events in 3D. Default is true. + */ + boolean showBarsIn3D(); + + /** + * Whether to draw the color on the events using gradients. The colors are controlled by setting the following two + * variables on the GanttEvent. {@link GanttEvent#setGradientStatusColor(Color)} and {@link GanttEvent#setStatusColor(Color)}. + * + * @return true if to draw with gradients. Default is true. + * @see GanttEvent#setGradientStatusColor(Color) + * @see GanttEvent#setStatusColor(Color) + */ + boolean showGradientEventBars(); + + /** + * Whether to only show the dependency connections only when an event is selected, as opposed to always showing the + * lines. + * + * @return true if to show them only on selections. Default is false. + */ + boolean showOnlyDependenciesForSelectedItems(); + + /** + * Whether to show a "plaque" on the event bars that displays a number of how many days the event spans over. + * + * @return true if to show the plaque. Default is false. + */ + boolean showNumberOfDaysOnBars(); + + /** + * Whether to draw lines that show where the revised dates would have been on the chart (assuming revised dates are + * set). + * + * @return true if to draw lines for the revised dates. Default is false. + */ + boolean showPlannedDates(); + + /** + * Returns the height of the header section that displays the month names. + * + * @return Pixel value. Default is 18. + */ + int getHeaderMonthHeight(); + + /** + * Returns the height of the header section that displays the days. + * + * @return Pixel value. Default is 18. + */ + int getHeaderDayHeight(); + + /** + * Returns the width for each day that is drawn. Zoom levels use multipliers with these numbers. + * + * @return Pixel value. Default is 16. + */ + int getDayWidth(); + + /** + * Returns the width for each day that is drawn in the monthly view. Zoom levels use multipliers with these numbers. + * + * @return Pixel value. Default is 6. + */ + int getMonthDayWidth(); + + /** + * Returns the width for each day that is drawn in the yearly view. Zoom levels use multipliers with these numbers. + *

+ * WARNING: Setting this value below 3 will cause an infinite loop and probable application + * crash. This happens as internal size calculations end up on 0 width (rounded) values. + * + * @return Pixel value. Default is 3. + */ + int getYearMonthDayWidth(); + + /** + * Returns the height for each event, including checkpoints. + * + * @return Pixel value. Default is 12. + */ + int getEventHeight(); + + /** + * Returns the height of the bar that is drawn inside the events that represents the percentage done. + *

+ * Note: If the event height is an even number, this number does best being odd, and vice versa. + * + * @return Pixel value. Default is 3. + */ + int getEventPercentageBarHeight(); + + /** + * The percentage bar always draws as a line in the center of the event but normally it only draws the part that + * displays the % complete. If this returns true it will draw that part, but also the remainder. You can set the + * color for the remainder different than that from the actual percentage complete as well. + * + * @return true if to draw the entire bar. Default is true. + */ + boolean drawFullPercentageBar(); + + /** + * The Alpha level of the percentage complete bar. Only draws if Alpha is turned on. + * + * @return Alpha value. Default is 255. + */ + int getPercentageBarAlpha(); + + /** + * The Alpha level of the remaining percentage complete bar. Only draws if Alpha is turned on. + * + * @return Alpha value. Default is 70. + */ + int getRemainderPercentageBarAlpha(); + + /** + * Returns the number of pixels off each side of an event that is the area for which the resize cursor is shown. If + * people find it hard to grab events, increase this number. + * + * @return Pixel value. Default is 3. + */ + int getResizeBorderSensitivity(); + + /** + * Returns the number of pixels off each side of an event towards the center of it that is ignored when trying to + * move an event. This is to help resize distinguish from a move cursor and to help users find the two different + * areas. + * + * @return Pixel value. Default is 6. Remember that this value is handled in a negative calculation, but it should + * be a positive value. + */ + int getMoveAreaNegativeSensitivity(); + + /** + * Returns the space between the actual event and the text that is written after the event when the event has a + * connecting line extending from it. + * + * @return Pixel value. Default is 9. + */ + int getTextSpacerConnected(); + + /** + * Returns the space between the actual event and the text that is written after the event when the event has no + * connecting line extending from it. + * + * @return Pixel value. Default is 9. + */ + int getTextSpacerNonConnected(); + + /** + * Returns the space from the left of the border where the day letter is printed. + * + * @return Pixel value. Default is 3. + */ + int getDayVerticalSpacing(); + + /** + * Returns the spacing from the top where the day letter is printed. + * + * @return Pixel value. Default is 4. + */ + int getDayHorizontalSpacing(); + + /** + * Returns the vertical space between each event. + * + * @return Pixel value. Default is 12. + */ + int getEventSpacer(); + + /** + * Whether the name of the scope is drawn in bold or plain. + * + * @return true if bold. Default is true. + */ + boolean showBoldScopeText(); + + /** + * Letters have different width. If turned on, this will try to make all day letters appear centered, whereas if + * turned off, letter width will be ignored. + * + * @return true if to adjust for letter widths. Default is true. + */ + boolean adjustForLetters(); + + /** + * Whether event-resizing is turned on or off. + * + * @return true if turned on. If turned off, event resizing is not possible. Default is true. + */ + boolean enableResizing(); + + /** + * Whether users can hold down SHIFT (or whatever the settings say) to move an event, and all dependent + * events will move with the selected event. + * + * @return true if to move all linked events. Default is true. + * @see ISettings#getDragAllModifierKey() + */ + boolean moveLinkedEventsWhenEventsAreMoved(); + + /** + * Whether event drag-and-drop is turned on or off. + * + * @return true if turned on. If turned off, drag and drop is not possible. Default is true. + */ + boolean enableDragAndDrop(); + + /** + * Whether when a user zooms in or out (only via CTRL (or whatever the settings say) + + * Scroll Wheel) to display a box in the bottom left corner that shows the zoom level. + * + * @return true if to show a box when zooming. Default is true. + * @see ISettings#getZoomWheelModifierKey() + */ + boolean showZoomLevelBox(); + + /** + * Whether to mimic Microsoft © Project's infinite scrollbar which lets users scroll into the future or past indefinitely. If + * turned off, the scrollbar will reflect the range of the oldest event's start date, to the latest event end date. + * + * @return true if to turn on infinite scrollbar. Default is true. + */ + boolean allowInfiniteHorizontalScrollBar(); + + /** + * Whether the date tooltip box (if turned on) when resizing should hug the border of the event on the left or right + * side or if it should be simply stick somewhat to the event resize location. + * + * @return true if to stick to the resize sides. Default is true. + */ + boolean showResizeDateTipOnBorders(); + + /** + * If true, it lets the move forwards or backwards in time by clicking in a "blank" area and dragging the mouse. + * Similar to the hand tool in Photoshop or Acrobat. + * + * @return true if to allow clear-area drag. Default is true. + */ + boolean allowBlankAreaDragAndDropToMoveDates(); + + /** + * Relies on {@link #allowBlankAreaDragAndDropToMoveDates()} being true. If so, this will additionally determine if the user + * can blank-area drag the chart in a vertical manner to move the chart in that direction as well. + *

+ * Holding down the shift key will double the speed of the vertical drag + * + * @return true to allow clear-area vertical drag. Default is false (as it can be confusing at first try). + */ + boolean allowBlankAreaVerticalDragAndDropToMoveChart(); + + /** + * If for some reason the drag left vs. drag right directions feel reversed, simply flip this to switch them around. + * Only active if {@link #allowBlankAreaDragAndDropToMoveDates()} is active. + * + * @return true if to flip them around. Default is false. + * @see ISettings#allowBlankAreaDragAndDropToMoveDates() + */ + boolean flipBlankAreaDragDirection(); + + /** + * If true, draws a dotted selection marker around the currently selected event to visualize the selection. + * + * @return true if to show a selection marker. Default is true. + */ + boolean drawSelectionMarkerAroundSelectedEvent(); + + /** + * Whether checkpoints can be resized (assuming resizing is on {@link ISettings#enableResizing()}). + * + * @return true if checkpoints can be resized. Default is false. + * @see ISettings#enableResizing() + */ + boolean allowCheckpointResizing(); + + /** + * Whether to show any menu items at all when right clicking an event or a chart. + * + * @return true if to show menu items on right click. Default is true. + */ + boolean showMenuItemsOnRightClick(); + + /** + * Returns the space between the head of the dependency arrowhead and the event. + * + * @return pixel space. Default is 1. + */ + int getArrowHeadEventSpacer(); + + /** + * If you for some reason wish to move the arrow head up or down vertically, setting a number here will modify the + * vertical "extra". + * + * @return pixel length. Default is 0. + */ + int getArrowHeadVerticalAdjuster(); + + /** + * Returns the position that the calendar should start on when first created. If null, the current date will be + * used. Please remember to use a Locale when you create your Calendar object, ideally the same as used in the + * settings {@link ISettings#getDefaultLocale()}. + * + * @return Calendar, or null. + */ + Calendar getStartupCalendarDate(); + + /** + * Date offset of the startup date that the calendar should start at. By default, you probably do not want this to + * be 0 as that will hug the leftmost side of the widget. It's suggested to set a negative value. + * + * @return date offset in number of days. Default is -4. + */ + int getCalendarStartupDateOffset(); + + /** + * Moves the calendar to start on the first day of the week of the either current date or the date set in + * {@link ISettings#getStartupCalendarDate()} + *

+ * Please note, if the + * {@link ISettings#getCalendarStartupDateOffset()} is set to other than zero, these two methods will most likely + * clash. + *

+ * This setting has no effect on D-Day charts. + * + * @return true whether calendar should start on the first day of the week. Default is false. + * @see #getCalendarStartupDateOffset() + * @see #getStartupCalendarDate() + */ + boolean startCalendarOnFirstDayOfWeek(); + + /** + * If zooming in/out should be enabled or disabled. + * + * @return true if enabled. Default is true. + */ + boolean enableZooming(); + + /** + * Returns the image used for displaying something as locked in the GANTT chart. + * + * @return Image or null. Default is the lock_tiny.gif image in the package. + */ + Image getLockImage(); + + /** + * Decides how the string behind the event is displayed. You may override this individually by setting the + * GanttEvent parameter by the same name. + *

    + *
  • #name# = Name of event + *
  • #pc# = Percentage complete + *
  • #sd# = Start date + *
  • #ed# = End date + *
  • #rs# = + * Revised start date + *
  • #re# = Revised end date + *
  • #days# = Number of days event spans over + *
  • #reviseddays# = + * Number of revised days event spans over + *
+ * + * @return String format. Default is "#name# (#pc#%)" + * @see GanttEvent#setTextDisplayFormat(String) + */ + String getTextDisplayFormat(); + + /** + * The distance from the event top (and event bottom) that is used to draw the line portraying revised start and end + * dates. + * + * @return Pixel spacing. Default is 3. + */ + int getRevisedLineSpacer(); + + /** + * Whether to round off minutes on events to nearest hour. + * + * @return true if yes. Default is false. + */ + boolean roundHourlyEventsOffToNearestHour(); + + /** + * The default help image used in the advanced tooltip. Null if none. + * + * @return Image or null. Default is null. + */ + Image getDefaultAdvandedTooltipHelpImage(); + + /** + * The default image used in the advanced tooltip. Null if none. + * + * @return Image or null. Default is null. + */ + Image getDefaultAdvandedTooltipImage(); + + /** + * The default help text shown in the advanced tooltip. + * + * @return String or null. Default is null. + */ + String getDefaultAdvancedTooltipHelpText(); + + /** + * The default title text shown in the advanced tooltip. + * + * @return String or null. Default is null. + */ + String getDefaultAdvancedTooltipTitle(); + + /** + * The default extended tooltip shown in the advanced tooltip. Extended tooltips are used when the GanttEvent has + * revised dates. + * + * @return String or null. Default is a text showing the dates, revised dates and percentage complete. + */ + String getDefaultAdvancedTooltipTextExtended(); + + /** + * The default tooltip shown in the advanced tooltip. Normal tooltips are used when the GanttEvent has no revised + * dates and also for scopes, images and checkpoints. + * + * @return String or null. Default is a text showing the dates and percentage complete. + */ + String getDefaultAdvancedTooltipText(); + + /** + * The width of the line showing where today's date is. + * + * @return line width. Default is 2. + */ + int getTodayLineWidth(); + + /** + * The default line style of the line showing where today's date is. + * + * @return SWT.LINE_ style. Default is SWT.LINE_SOLID. + */ + int getTodayLineStyle(); + + /** + * The vertical offset from the top for the today line calculated from the bottom part of the header. + * + * @return Vertical offset. Default is the height of the bottom header. + */ + int getTodayLineVerticalOffset(); + + /** + * The vertical offset from top for the tick marks in the top header. + * + * @return Default is the height of the top header minus 5. + */ + int getVerticalTickMarkOffset(); + + /** + * The SimpleDateFormat of the text shown in the top header for the day view. + * + * @return {@link SimpleDateFormat} string. May not be null. + */ + String getDayHeaderTextDisplayFormatTop(); + + /** + * The SimpleDateFormat of the text shown in the top header for the week view. + * + * @return SimpleDateFormat string. May not be null. + */ + String getWeekHeaderTextDisplayFormatTop(); + + /** + * The SimpleDateFormat of the text shown in the top header for the month view. + * + * @return SimpleDateFormat string. May not be null. + */ + String getMonthHeaderTextDisplayFormatTop(); + + /** + * The SimpleDateFormat of the text shown in the top header for the year view. + * + * @return SimpleDateFormat string. May not be null. + */ + String getYearHeaderTextDisplayFormatTop(); + + /** + * The SimpleDateFormat of the text shown in the bottom header for the day view. + * + * @return SimpleDateFormat string. May not be null. + */ + String getDayHeaderTextDisplayFormatBottom(); + + /** + * The SimpleDateFormat of the text shown in the bottom header for the week view. + * + * @return SimpleDateFormat string. May not be null. + */ + String getWeekHeaderTextDisplayFormatBottom(); + + /** + * The SimpleDateFormat of the text shown in the bottom header for the month view. + * + * @return SimpleDateFormat string. May not be null. + */ + String getMonthHeaderTextDisplayFormatBottom(); + + /** + * The SimpleDateFormat of the text shown in the bottom header for the year view. + * + * @return SimpleDateFormat string. May not be null. + */ + String getYearHeaderTextDisplayFormatBottom(); + + /** + * Whether to draw the header or not. If this returns false, all header-related settings will be ignored. + * + * @return true if to draw header. Default is true. + */ + boolean drawHeader(); + + /** + * Top spacer between the top pixel and the beginning of the first event. The top pixel will be either the height of + * the header (if drawn) or 0 if the header is not drawn. + * + * @return top spacer value. Default is 12. + */ + int getEventsTopSpacer(); + + /** + * Bottom spacer between the bottom event and the section divider when using GanttSections. For non GanttSection + * usage, this setting is ignored. + * + * @return bottom spacer value. Default is 12. + */ + int getEventsBottomSpacer(); + + /** + * The height of the bar drawn between sections. + * + * @return height. Default is 5. + */ + int getSectionBarDividerHeight(); + + /** + * Width of the section bar. + * + * @return width. Default is 20. + */ + int getSectionBarWidth(); + + /** + * Minimum height of sections. Normally the minimum height is calculated by: + *

+ * 1. Space the section name takes up vertically
+ * 2. Space all contained events take up including various event spacers. + *

+ * If the two calculations above are smaller than the value returned by this method, the height returned from this + * method will be used. + * + * @return minimum section height (larger or equals to zero). Default is 80. + */ + int getMinimumSectionHeight(); + + /** + * Advanced tooltips are shells and by default they pop up where the mouse pointer is. To not block the pointer, an + * offset is used. + * + * @return horizontal offset. Default is 15. + */ + int getAdvancedTooltipXOffset(); + + /** + * Whether to use Advanced Tooltips by default. + * + * @return True whether to use advanced tooltips. Default is true. + */ + boolean getUseAdvancedTooltips(); + + /** + * The keyboard modifier key (also known as a hint) used to determine when it's a drag-all-linked-events + * {@link ISettings#moveLinkedEventsWhenEventsAreMoved()} event or just a normal drag. + * + * @return Keyboard modifier. Default is SWT.SHIFT (the shift key) + * @see ISettings#moveLinkedEventsWhenEventsAreMoved() + */ + int getDragAllModifierKey(); + + /** + * The keyboard modifier key combined with the scroll wheel to make the chart zoom. + * + * @return Keyboard modifier. Default is SWT.MOD1 (usually the CTRL key) + */ + int getZoomWheelModifierKey(); + + /** + * Locale used for calendars and wherever needed. + * + * @return Locale. Default is Locale.getDefault(). + */ + Locale getDefaultLocale(); + + /** + * See IGanttEventListener's lastDraw(GC gc) method method info. + * + * @return true whether to enable the last draw functionality. Default is false. + * @see IGanttEventListener#lastDraw(org.eclipse.swt.graphics.GC) + */ + boolean enableLastDraw(); + + /** + * If you plan on using reverse dependencies, you may want to flag this to true. This makes normal connections draw + * the arrow to the top left corner of the target event, and if it's a reverse dependency, it draw the arrow to the + * bottom left of target events. That way any overlapping event don't have arrows drawing in the exact same spot + * which makes it much easier to view the chart. + * + * @return true to split arrows. Default is false. + */ + boolean useSplitArrowConnections(); + + /** + * If you plan on using reverse dependencies, this value will be interesting. If this value returns 0 and you have + * both a normal-direction dependency and a reverse one, their vertical lines will overlap. By setting this value to + * greater than zero that vertical line will be spaced out for reverse dependencies. The value is how much extra it + * will be spaced. + * + * @return spacer value. Default is 2. + */ + int getReverseDependencyLineHorizontalSpacer(); + + /** + * The vertical lines are the lines that divide days and weeks etc. + * + * @see GanttComposite#setDrawVerticalLinesOverride(Boolean) + * @return true if to draw vertical lines. Default is true. + */ + boolean drawVerticalLines(); + + /** + * Whether to draw horizontal lines between the events. Useful for where you have a tree/table on the left and wish + * events to be easier to see when they are lined up with the tree items. + * + * @see GanttComposite#setDrawHorizontalLinesOverride(Boolean) + * @return true to show horizontal lines. Default is false; + */ + boolean drawHorizontalLines(); + + /** + * Which side the section bar should be drawn on.
+ *
+ * You may use one of SWT.LEFT or SWT.RIGHT. + * + * @return section bar side. Default is SWT.LEFT. + */ + int getSectionSide(); + + /** + * When dates are locked down to a certain day, the chart will draw a special marker on the lock start and end dates + * to point out that it's locked between certain constraints. + * + * @return Whether to draw markers for date-range-locked events. Default is true. + */ + boolean drawLockedDateMarks(); + + /** + * Whether to show a date tooltip when scrolling horizontally (changing dates) and vertically. The tooltip will show + * just above the bottom horizontal toolbar. Note that if showDateTips() returns false, this tip will not show. + * + * @return true whether to show date tooltips when scrolling through dates. Default is true. + * @see #showDateTips() + */ + boolean showDateTipsOnScrolling(); + + // fix to bugzilla #236852 + /** + * Whether the GanttSection bar should draw all the way down or not. + * + * @return true to draw all the way down. Default is false. + */ + boolean drawGanttSectionBarToBottom(); + + // fix to bugzilla #236852 + /** + * Whether to draw fills and vertical lines etc to the bottom when GanttSections are used. + * + * @return true to draw everything all the way down. Default is false. + */ + boolean drawFillsToBottomWhenUsingGanttSections(); + + /** + * Whether the header should always be visible regardless of vertical scroll position. Basically a "fixed header" + * feature. + * + * @return true whether to lock the header. Default is false. + */ + boolean lockHeaderOnVerticalScroll(); + + /** + * Whether to show the default set of menu items on the right click menus of events. If false, the menu will be + * blank allowing you to set all items from scratch. + * + * @return true to show default menu items along with custom ones on right click. Default is true. + * @see #showMenuItemsOnRightClick() + * @see #showPropertiesMenuOption() + * @see #showDeleteMenuOption() + * @see GanttEvent#getMenu() + */ + boolean showDefaultMenuItemsOnEventRightClick(); + + /** + * Whether scopes can show a right click menu or not. By default scopes are non-active objects that simply draw + * according to their children. By allowing a menu to be shown on the scope you can still perform custom events if + * you so wish (such as show/hide all children). + * + * @return true to allow menus on scopes. Default is false. + * @see GanttEvent#getMenu() + * @see GanttEvent#showAllChildren() + * @see GanttEvent#hideAllChildren() + */ + boolean allowScopeMenu(); + + /** + * Whether selecting dates in the header is allowed by clicking the date. Events will be fired on selection events. + * Note that not all views have this feature, only those that actually show full dates, as that's where it makes + * most sense. + * + * @return true to allow header selection. Default is true. + */ + boolean allowHeaderSelection(); + + /** + * When you zoom in with the mouse, it can either act as a normal zoom (uses leftmost date as start date) or it can + * zoom in where the mouse pointer is at the time of the zoom in. For some the first make more sense than the other + * and vice versa. Default is that the zoom in is where the mouse pointer is (true). + */ + boolean zoomToMousePointerDateOnWheelZooming(); + + /** + * It's highly suggested you use the default implementation of this method. Basically, this method needs to return a + * zeroed-down calendar (hours, minutes etc) that will be used as the D-day root calendar. As D-days aren't dates + * (except internally), this Calendar simply needs to be any "stable" date. By default it uses January 1st, [current + * year], 0h 0m 0s 0ms. (it uses the current year as days-between calculations otherwise get very large). + * + * @return Calendar + */ + Calendar getDDayRootCalendar(); + + /** + * The value where D-days have their "weeks" so to speak, this is used to calculate the numbers shown in both + * headers, where the top header is displaying each "set" whereas the bottom one shows numbers from 0 to the number + * returned by this method. + * + * @return Split count number. Default is 10 which shows sets from 0 to 9. + */ + int getDDaySplitCount(); + + /** + * If this returns true, events are never rounded up to their nearest hour/minute when shown in the chart, but will + * always show down to the minute even in any mid-zoomed and fully-zoomed out view (this does not do anything to the + * normal minute view). Default is false. + * + * @return true to draw event location down to the hour and minute + */ + boolean drawEventsDownToTheHourAndMinute(); + + /** + * If this returns true, only linked events that come after the source drag event (time/date-wise) will be + * moved/resized (normally all linked events are moved/resized regardless of time/date). + * + * @return true to only move/resize "later" events on dependent linked event moves/resizes. Default is false. + */ + boolean moveAndResizeOnlyDependentEventsThatAreLaterThanLinkedMoveEvent(); + + /** + * In SWT 3.5 it seems the mousewheel is not interpreted the same as in previous versions. If you notice that when + * scrolling the mousewheel the chart does not actually scroll vertically, flag this to true to force it to scroll + * the chart. This is forced to true on *NIX machines (not Mac). + * + * @return true to force the mousewheel to scroll the chart. Default is false. + * @deprecated By default mousewheel now scrolls chart vertically on all platforms. To turn off, flag scrollChartVerticallyOnMouseWheel() + * @see #scrollChartVerticallyOnMouseWheel() + */ + @Deprecated + boolean forceMouseWheelVerticalScroll(); + + /** + * If the name of any section is so large that it basically defines the size of the section, this value is used to + * space out the text slightly so that the section borders don't hug the text. If you want to save on some real-estate + * set this value to 0. + * + * @return Default is 30. + */ + int getSectionTextSpacer(); + + /** + * When drawing {@link GanttPhase}s this is the header height used for displaying the names of these phases. + * + * @return Default is 18 + */ + int getPhasesHeaderHeight(); + + /** + * When phases are resized or moved, whether an overlap resize/move should be accepted or not. + * If false (default), a resize will simply stop at the next phase border, whereas a move that is dropped + * on top of a different phase will be undone (no event is fired for this). + * + * @return Default is false + */ + boolean allowPhaseOverlap(); + + /** + * What style of vertical event dragging that is enabled. For the "resistance" before a vertical drag takes + * place you can change this with {@link ISettings#getVerticalDragResistance()}. + * + * @return One of the options in {@link VerticalDragModes}. Default is {@link VerticalDragModes#NO_VERTICAL_DRAG} + */ + int getVerticalEventDragging(); + + /** + * For events that can be dragged vertically, this is the "resistance" in pixels before the event "lets go" + * of it's horizontal location. Once it's let go it will stick to the mouse cursor. + * + * @return A pixel range of resistance. Default is 15px. + */ + int getVerticalDragResistance(); + + /** + * Whether an insert marker should be shown for where the dragged event will end up when a vertical drag/drop + * is in progress. + * + * @return true to show a marker. Default is true. + */ + boolean onVerticalDragDropShowInsertMarker(); + + // bugzilla feature request #309808 + /** + * Whether to allow an image to exceed the width of one day when zooming in / out. + * + * @return true to keep within day width. Default is true. + */ + boolean scaleImageToDayWidth(); + + /** + * Whether arrow keys are enabled to scroll chart left/right/up/down. + * + * @return true to allow arrow keys to move the chart. Default is false. + */ + boolean allowArrowKeysToScrollChart(); + + /** + * Normally a day is calculated as day_starts->day_ends, which means that to make an event that starts and ends on the same day count as "anything", +1 is + * added by default to make the event actually show up on the chart. Should you for some reason need to override this, change this number to 0 or whatever you may need. + * + * @return Number of days to count for a start and end date that is the same date. Default is 1. + */ + int getNumberOfDaysToAppendForEndOfDay(); + + /** + * Whether the chart should scroll vertically when the mouse wheel is used. If you notice excessive scrolling on SWT versions earlier than 3.5, you may want to turn this off + * + * @return true to scroll chart vertically. Default is true. + */ + boolean scrollChartVerticallyOnMouseWheel(); + + /** + * Returns the minimum zoom level. + * Default should return {@link ISettings#MIN_ZOOM_LEVEL} + * + * @return + */ + int getMinZoomLevel(); + + /** + * Specify a period start. Returning another value than null will result in rendering + * an additional line to the chart indicating a period start in the gantt itself. + * + * @return + */ + Calendar getPeriodStart(); + + /** + * Specify a period end. Returning another value than null will result in rendering + * an additional line to the chart indicating a period end in the gantt itself. + * + * @return + */ + Calendar getPeriodEnd(); + + /** + * If you want to show the event String within the event rectangle by setting the horizontalTextLocation of + * the GanttEvent to SWT.CENTER, there are cases that break the visualization. If your event String is longer + * than the event in the Gantt, it will look quite strange. + *

+ * If this method returns true, the AbstractPaintManager will shift the rendering of the event + * String to the right if the String length is greater than the event rectangle. + * + * @return true if the event String should be shifted, false if not + */ + boolean shiftHorizontalCenteredEventString(); + + /** + * @return true to enable the menu action for adding an event to the GanttChart, + * false if this action should not be available to the user. + */ + boolean enableAddEvent(); + + /** + * Global configuration to specify if the text of GanttEvents should be rendered or not. + * It is also possible to configure this per GanttEvent via _showText property. + * + * @return true if the event text should be rendered, false + * if not. + */ + boolean drawEventString(); + + /** + * The default behaviour in GanttChart on moving an event is that only the current dragged + * event is moved unless you press the SHIFT key. If there are more events selected, still + * only the dragged one is moved if the SHIFT key is not pressed. + * With this configuration it is possible to specify if the old default behavior should be + * used or if all currently selected events should be moved even if the SHIFT key is not pressed. + * + * @return true if all selected events should be moved by dragging on of them + * false if only the current dragged event should be moved. + */ + boolean alwaysDragAllEvents(); + + /** + * On printing a GanttChart it is possible to select to print only the selected area. + * For GanttChart this means to print the currently visible area. By default currently + * visible means vertically AND horizontally visible. This configuration allows to + * specify whether the vertical part should extend to the whole chart and only the + * horizontal area should be limited for the visible part. + * + * @return true if the printed chart should contain the whole chart + * vertically but only the horizontal visible part of the chart, + * false if only the visible part of the chart should be printed, + * horizontally AND vertically + */ + boolean printSelectedVerticallyComplete(); + + /** + * Configure whether a footer should be added to the print pages or not. + * The footer contains the page number and the date when the print was + * requested. + * + * @return true if a footer should be added to the print pages, + * false if not + */ + boolean printFooter(); + + /** + * Configure whether the section bar should be rendered. It only makes sense + * to not render the section bar if the section details are enabled. + * + * @return true if the section bar should + * be rendered, false if not + */ + boolean drawSectionBar(); + + /** + * Configure whether there should be an additional area to the section bar + * that shows additional section detail information. + * + * @return true if additional section detail information should + * be rendered, false if not + */ + boolean drawSectionDetails(); + + /** + * @return The width of the section detail area. + */ + int getSectionDetailWidth(); + + /** + * The section detail area title that should be rendered in the section detail area. + * + * @return String or null. Default is a bold black text showing the section name. + */ + String getSectionDetailTitle(); + + /** + * The detail information that should be rendered in the section detail area. + * + * @return String or null. Default is to show the number of events in that section. + */ + String getSectionDetailText(); + + /** + * Returns the custom section detail generator which generates the section detail + * out of custom data for a GanttSection. + * + * @return + */ + ISectionDetailContentReplacer getSectionDetailContentReplacer(); + + /** + * + * @return true if there should be a "more [+]" shown in the section + * detail area which allows to register a listener against to show more + * informations by e.g. opening a dialog. + */ + boolean showSectionDetailMore(); + + /** + * Configure whether a tooltip pops up when hovering the mouse over a holiday + * + * @return true to show a "holiday" popup with the configured name of the holiday, + * false if not (default) + */ + boolean showHolidayToolTips(); + + /** + * whether {@link IGanttEventListener#eventSelected(GanttEvent, java.util.List, org.eclipse.swt.events.MouseEvent)} should also + * be called on empty selection + * + * @return true to have the event fired. Default is false + */ + boolean fireEmptyEventSelection(); +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings2.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings2.java index e947763ad..8d1b0fcba 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings2.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings2.java @@ -1,71 +1,71 @@ -/******************************************************************************* - * Copyright (c) 2015 Giovanni Cimmino and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * ziogiannigmail.com - Bug 464509 - Minute View Implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -import java.text.DateFormat; -import java.text.DateFormatSymbols; -import java.text.SimpleDateFormat; - -/** - * This interface is an extension of ISettings which lets you define various settings for the GanttChart. - * Its initial implementation has been defined because of MinuteView, in order to both preserve the binary code compatibility and to do not amend the pre-existent ISettings interface. - * In turn, the abstract class {@link AbstractSettings} is now implementing this interface. - * - * You can change some settings by creating your own class and overriding your desired methods, instructions as follows: - *

- * public class MySettings extends AbstractSettings {
- * 	// override your methods here
- * }
- * 
- *

- * Once you've overridden the settings you wish to change, simply pass an instance of your implementation class to the constructor of GanttChart: {@link GanttChart#GanttChart(org.eclipse.swt.widgets.Composite, int, ISettings)} - * - * @author Giovanni Cimmino - * - */ - -public interface ISettings2 extends ISettings { - - /** - * The date format to use when displaying dates in string format in the minutes view. - * - * @return Date format. Default is month/day/year/ hh:mm:ss. - * @see DateFormat - * @see DateFormatSymbols - */ - public String getMinuteDateFormat(); - - /** - * The SimpleDateFormat of the text shown in the top header for the minute view. - * - * @return {@link SimpleDateFormat} string. May not be null. - */ - public String getMinuteHeaderTextDisplayFormatTop(); - - /** - * The SimpleDateFormat of the text shown in the bottom header for the minute view. - * - * @return SimpleDateFormat string. May not be null. - */ - public String getMinuteHeaderTextDisplayFormatBottom(); - - /** - * Start the updating tread for TodayLine (red line marking current time) - * - * @return true Start Thread - * false Skip Thread - */ - public boolean enableTodayLineUpdater(); - -} +/******************************************************************************* + * Copyright (c) 2015 Giovanni Cimmino and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ziogiannigmail.com - Bug 464509 - Minute View Implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.SimpleDateFormat; + +/** + * This interface is an extension of ISettings which lets you define various settings for the GanttChart. + * Its initial implementation has been defined because of MinuteView, in order to both preserve the binary code compatibility and to do not amend the pre-existent ISettings interface. + * In turn, the abstract class {@link AbstractSettings} is now implementing this interface. + * + * You can change some settings by creating your own class and overriding your desired methods, instructions as follows: + *

+ * public class MySettings extends AbstractSettings {
+ * 	// override your methods here
+ * }
+ * 
+ *

+ * Once you've overridden the settings you wish to change, simply pass an instance of your implementation class to the constructor of GanttChart: {@link GanttChart#GanttChart(org.eclipse.swt.widgets.Composite, int, ISettings)} + * + * @author Giovanni Cimmino + * + */ + +public interface ISettings2 extends ISettings { + + /** + * The date format to use when displaying dates in string format in the minutes view. + * + * @return Date format. Default is month/day/year/ hh:mm:ss. + * @see DateFormat + * @see DateFormatSymbols + */ + public String getMinuteDateFormat(); + + /** + * The SimpleDateFormat of the text shown in the top header for the minute view. + * + * @return {@link SimpleDateFormat} string. May not be null. + */ + public String getMinuteHeaderTextDisplayFormatTop(); + + /** + * The SimpleDateFormat of the text shown in the bottom header for the minute view. + * + * @return SimpleDateFormat string. May not be null. + */ + public String getMinuteHeaderTextDisplayFormatBottom(); + + /** + * Start the updating tread for TodayLine (red line marking current time) + * + * @return true Start Thread + * false Skip Thread + */ + public boolean enableTodayLineUpdater(); + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IToolTipContentReplacer.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IToolTipContentReplacer.java index 7ef91e755..20a8ffe5e 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IToolTipContentReplacer.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IToolTipContentReplacer.java @@ -1,19 +1,19 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -public interface IToolTipContentReplacer { - - String replaceToolTipPlaceHolder(GanttEvent event, String toolTipPattern, String dateFormat); -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +public interface IToolTipContentReplacer { + + String replaceToolTipPlaceHolder(GanttEvent event, String toolTipPattern, String dateFormat); +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IViewPortHandler.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IViewPortHandler.java index bf15d5e9f..d71d74cc7 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IViewPortHandler.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IViewPortHandler.java @@ -1,61 +1,61 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -public interface IViewPortHandler { - - void scrollingLeft(final int diffCount); - - void scrollingRight(final int diffCount); - - /** - * Jumps to the next month. - */ - public void nextMonth(); - - /** - * Jumps to the previous month. - */ - public void prevMonth(); - - /** - * Jumps one week forward. - */ - public void nextWeek(); - - /** - * Jumps one week backwards. - */ - public void prevWeek(); - - /** - * Jumps to the next hour. - */ - public void nextHour(); - - /** - * Jumps to the previous hour. - */ - public void prevHour(); - - /** - * Jumps one day forward. - */ - void nextDay(); - - /** - * Jumps one day backwards. - */ - void prevDay(); -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +public interface IViewPortHandler { + + void scrollingLeft(final int diffCount); + + void scrollingRight(final int diffCount); + + /** + * Jumps to the next month. + */ + public void nextMonth(); + + /** + * Jumps to the previous month. + */ + public void prevMonth(); + + /** + * Jumps one week forward. + */ + public void nextWeek(); + + /** + * Jumps one week backwards. + */ + public void prevWeek(); + + /** + * Jumps to the next hour. + */ + public void nextHour(); + + /** + * Jumps to the previous hour. + */ + public void prevHour(); + + /** + * Jumps one day forward. + */ + void nextDay(); + + /** + * Jumps one day backwards. + */ + void prevDay(); +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IViewPortHandler2.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IViewPortHandler2.java index b8e4f5a9f..13891ea4f 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IViewPortHandler2.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IViewPortHandler2.java @@ -1,28 +1,28 @@ -/******************************************************************************* - * Copyright (c) 2015 Giovanni Cimmino and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * ziogiannigmail.com - Bug 464509 - Minute View Implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -public interface IViewPortHandler2 extends IViewPortHandler { - - /** - * Jumps to the next minute. - */ - public void nextMinute(); - - /** - * Jumps to the previous hour. - */ - public void prevMinute(); - -} +/******************************************************************************* + * Copyright (c) 2015 Giovanni Cimmino and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ziogiannigmail.com - Bug 464509 - Minute View Implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +public interface IViewPortHandler2 extends IViewPortHandler { + + /** + * Jumps to the next minute. + */ + public void nextMinute(); + + /** + * Jumps to the previous hour. + */ + public void prevMinute(); + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IZoomHandler.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IZoomHandler.java index a9608ebe7..932be16ba 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IZoomHandler.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IZoomHandler.java @@ -1,38 +1,38 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart; - -import org.eclipse.swt.graphics.Point; - -public interface IZoomHandler { - - /** - * Zooms in. If zooming is disabled, does nothing. - */ - public void zoomIn(); - - public void zoomIn(boolean fromMouseWheel, Point mouseLoc); - - /** - * Zooms out. If zooming is disabled, does nothing. - */ - public void zoomOut(); - - public void zoomOut(boolean fromMouseWheel, Point mouseLoc); - - /** - * Resets the zoom level to that set in the settings. - */ - public void resetZoom(); -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart; + +import org.eclipse.swt.graphics.Point; + +public interface IZoomHandler { + + /** + * Zooms in. If zooming is disabled, does nothing. + */ + public void zoomIn(); + + public void zoomIn(boolean fromMouseWheel, Point mouseLoc); + + /** + * Zooms out. If zooming is disabled, does nothing. + */ + public void zoomOut(); + + public void zoomOut(boolean fromMouseWheel, Point mouseLoc); + + /** + * Resets the zoom level to that set in the settings. + */ + public void resetZoom(); +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/CompoundGanttChartPrinter.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/CompoundGanttChartPrinter.java index 6fa05cc44..d04def0fa 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/CompoundGanttChartPrinter.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/CompoundGanttChartPrinter.java @@ -1,110 +1,110 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart.print; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.ganttchart.GanttChart; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.widgets.Display; - -/** - * This class is used to print multiple GanttCharts at once. - * - * @see GanttChartPrinter - */ -public class CompoundGanttChartPrinter extends GanttChartPrinter { - - private String jobName; - private final List ganttCharts = new ArrayList(); - - /** - * Creates a new CompoundGanttChartPrinter. - * Will use the print job name of the first GanttChart in the list of - * GanttCharts to print. - */ - public CompoundGanttChartPrinter() { - super(null); - } - - /** - * Creates a new CompoundGanttChartPrinter that uses the given job name as printer job name. - * @param jobName The name that will be used for the print job. - */ - public CompoundGanttChartPrinter(String jobName) { - super(null); - this.jobName = jobName; - } - - @Override - public void print() { - if (!this.ganttCharts.isEmpty()) { - final Printer printer = setupPrinter(Display.getCurrent().getActiveShell()); - if (printer == null) { - return; - } - - String name = (this.jobName != null && this.jobName.length() > 0) ? - this.jobName : this.ganttCharts.get(0).getLanguageManger().getPrintJobText(); - Display.getDefault().asyncExec(new GanttChartPrintJob( - printer, name, ganttCharts.toArray(new GanttChart[] {}))); - } - } - - @Override - protected Point getFullPageCount(Printer printer) { - Point result = new Point(0, 0); - - for (GanttChart ganttChart : this.ganttCharts) { - Image chartImage = ganttChart.getGanttComposite().getFullImage(); - Point imgPoint = PrintUtils.getPageCount(printer, chartImage); - result.x += imgPoint.x; - result.y += imgPoint.y; - chartImage.dispose(); - } - - return result; - } - - /** - * Adds the given GanttChart to the list of GanttCharts that should be - * printed by this CompoundGanttChartPrinter. - * @param ganttChart The GanttChart to add to the charts to be printed. - */ - public void addGanttChart(GanttChart ganttChart) { - this.ganttCharts.add(ganttChart); - } - - /** - * Adds the given GanttChart at the specified index to the list of GanttCharts - * that should be printed by this CompoundGanttChartPrinter. - * @param index The index at which the given GanttChart should be added. - * @param ganttChart The GanttChart to add to the charts to be printed. - */ - public void addGanttChart(int index, GanttChart ganttChart) { - this.ganttCharts.add(index, ganttChart); - } - - /** - * Removes the given GanttChart from the list of GanttCharts that should be - * printed by this CompoundGanttChartPrinter. - * @param ganttChart The GanttChart to remove from the charts to be printed. - */ - public void removeGanttChart(GanttChart ganttChart) { - this.ganttCharts.remove(ganttChart); - } -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart.print; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.ganttchart.GanttChart; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.widgets.Display; + +/** + * This class is used to print multiple GanttCharts at once. + * + * @see GanttChartPrinter + */ +public class CompoundGanttChartPrinter extends GanttChartPrinter { + + private String jobName; + private final List ganttCharts = new ArrayList(); + + /** + * Creates a new CompoundGanttChartPrinter. + * Will use the print job name of the first GanttChart in the list of + * GanttCharts to print. + */ + public CompoundGanttChartPrinter() { + super(null); + } + + /** + * Creates a new CompoundGanttChartPrinter that uses the given job name as printer job name. + * @param jobName The name that will be used for the print job. + */ + public CompoundGanttChartPrinter(String jobName) { + super(null); + this.jobName = jobName; + } + + @Override + public void print() { + if (!this.ganttCharts.isEmpty()) { + final Printer printer = setupPrinter(Display.getCurrent().getActiveShell()); + if (printer == null) { + return; + } + + String name = (this.jobName != null && this.jobName.length() > 0) ? + this.jobName : this.ganttCharts.get(0).getLanguageManger().getPrintJobText(); + Display.getDefault().asyncExec(new GanttChartPrintJob( + printer, name, ganttCharts.toArray(new GanttChart[] {}))); + } + } + + @Override + protected Point getFullPageCount(Printer printer) { + Point result = new Point(0, 0); + + for (GanttChart ganttChart : this.ganttCharts) { + Image chartImage = ganttChart.getGanttComposite().getFullImage(); + Point imgPoint = PrintUtils.getPageCount(printer, chartImage); + result.x += imgPoint.x; + result.y += imgPoint.y; + chartImage.dispose(); + } + + return result; + } + + /** + * Adds the given GanttChart to the list of GanttCharts that should be + * printed by this CompoundGanttChartPrinter. + * @param ganttChart The GanttChart to add to the charts to be printed. + */ + public void addGanttChart(GanttChart ganttChart) { + this.ganttCharts.add(ganttChart); + } + + /** + * Adds the given GanttChart at the specified index to the list of GanttCharts + * that should be printed by this CompoundGanttChartPrinter. + * @param index The index at which the given GanttChart should be added. + * @param ganttChart The GanttChart to add to the charts to be printed. + */ + public void addGanttChart(int index, GanttChart ganttChart) { + this.ganttCharts.add(index, ganttChart); + } + + /** + * Removes the given GanttChart from the list of GanttCharts that should be + * printed by this CompoundGanttChartPrinter. + * @param ganttChart The GanttChart to remove from the charts to be printed. + */ + public void removeGanttChart(GanttChart ganttChart) { + this.ganttCharts.remove(ganttChart); + } +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrintJob.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrintJob.java index 5d87071f7..9d66d4a31 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrintJob.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrintJob.java @@ -1,227 +1,227 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart.print; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.eclipse.nebula.widgets.ganttchart.GanttChart; -import org.eclipse.swt.SWT; -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.graphics.Transform; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; - -/** - * Runnable to print one ore more GanttCharts. - */ -public class GanttChartPrintJob implements Runnable { - - private final Printer printer; - - private final String jobName; - - private final GanttChart[] ganttCharts; - - private boolean disposePrinter; - - /** - * Creates a new GanttChartPrintJob that uses the given printer and print job name - * to print the specified GanttChart(s). If not changed afterwards, running this job - * will dispose the given printer when it is done. - * @param printer The printer to use. - * @param jobName The job name to use for the print job. - * @param charts The GanttCharts that should be printed. - */ - public GanttChartPrintJob(Printer printer, String jobName, GanttChart... charts) { - this(printer, jobName, true, charts); - } - - /** - * Creates a new GanttChartPrintJob that uses the given printer and print job name - * to print the specified GanttChart(s). - * @param printer The printer to use. - * @param jobName The job name to use for the print job. - * @param charts The GanttCharts that should be printed. - * @param disposePrinter Flag to configure whether the given printer should be disposed - * after the print job is done. Default is true. Only set this - * parameter to false if the printer should be reused for additional - * print jobs. You need to ensure that the printer will get disposed yourself - * in that case! - */ - public GanttChartPrintJob(Printer printer, String jobName, boolean disposePrinter, GanttChart... charts) { - this.printer = printer; - this.jobName = jobName; - this.ganttCharts = charts; - this.disposePrinter = disposePrinter; - } - - public void run() { - if (printer.startJob(jobName)) { - GC gc = new GC(printer); - - int currentPage = 1; - for (GanttChart ganttChart : this.ganttCharts) { - - Image printerImage = null; - if (printer.getPrinterData().scope == PrinterData.SELECTION) { - //the user selected to only print the selected area - //as this is quite difficult in GanttChart, we specify that - //this means to print the visible area - //but it is possible to configure via settings what "visible" - //area means: - // - really only the visible area horizontally and vertically - // - only the horizontal visible area, but vertically everything - printerImage = ganttChart.getSettings().printSelectedVerticallyComplete() ? - ganttChart.getGanttComposite().getVerticallyFullImage() : ganttChart.getGanttComposite().getImage(); - } - else { - printerImage = ganttChart.getGanttComposite().getFullImage(); - } - - final Rectangle printerClientArea = PrintUtils.computePrintArea(printer); - final Point scaleFactor = PrintUtils.computeScaleFactor(printer); - final Point pageCount = PrintUtils.getPageCount(printer, printerImage); - - // Print pages Left to Right and then Top to Down - for (int verticalPageNumber = 0; verticalPageNumber < pageCount.y; verticalPageNumber++) { - - for (int horizontalPageNumber = 0; horizontalPageNumber < pageCount.x; horizontalPageNumber++) { - - // Calculate bounds for the next page - int printerClientAreaHeight = ganttChart.getSettings().printFooter() ? - (printerClientArea.height - PrintUtils.FOOTER_HEIGHT_IN_PRINTER_DPI) : printerClientArea.height; - Rectangle printBounds = new Rectangle((printerClientArea.width / scaleFactor.x) * horizontalPageNumber, - (printerClientAreaHeight / scaleFactor.y) * verticalPageNumber, - printerClientArea.width / scaleFactor.x, - printerClientAreaHeight / scaleFactor.y); - - if (shouldPrint(printer.getPrinterData(), currentPage)) { - printer.startPage(); - - Transform printerTransform = new Transform(printer); - - // Adjust for DPI difference between display and printer - printerTransform.scale(scaleFactor.x, scaleFactor.y); - - // Adjust for margins - printerTransform.translate(printerClientArea.x / scaleFactor.x, printerClientArea.y / scaleFactor.y); - - // GanttChart will not automatically print the pages at the left margin. - // Example: page 1 will print at x = 0, page 2 at x = 100, page 3 at x = 300 - // Adjust to print from the left page margin. i.e x = 0 - printerTransform.translate(-1 * printBounds.x, -1 * printBounds.y); - gc.setTransform(printerTransform); - - int imgWidthClipping = printBounds.width; - if (((horizontalPageNumber * printBounds.width)+printBounds.width) > printerImage.getImageData().width) { - imgWidthClipping = printerImage.getImageData().width - (horizontalPageNumber * printBounds.width); - } - - int imgHeightClipping = printBounds.height; - if (((verticalPageNumber * printBounds.height)+printBounds.height) > printerImage.getImageData().height) { - imgHeightClipping = printerImage.getImageData().height - (verticalPageNumber * printBounds.height); - } - - gc.drawImage(printerImage, - horizontalPageNumber * printBounds.width, - verticalPageNumber * printBounds.height, - imgWidthClipping, imgHeightClipping, - printBounds.x, printBounds.y, imgWidthClipping, imgHeightClipping); - - if (ganttChart.getSettings().printFooter()) - printFooter(gc, ganttChart, currentPage, printBounds); - - printer.endPage(); - printerTransform.dispose(); - - } - currentPage++; - } - } - - printerImage.dispose(); - } - - printer.endJob(); - gc.dispose(); - - //only dispose the printer after the print job is done if it is configured to do so - //this configuration enables the possibility to reuse a printer for several jobs - if (disposePrinter) - printer.dispose(); - } - } - - /** - * Render the footer to a print page. - * @param gc The graphical context that is used for printing - * @param ganttChart The GanttChart which is currently printed. - * @param currentPage The number of the current page that is printed - * @param printBounds The bounds of the print area - */ - private void printFooter(GC gc, GanttChart ganttChart, int currentPage, Rectangle printBounds) { - String footerDate = new SimpleDateFormat(ganttChart.getSettings().getDateFormat()).format(new Date()); - - gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); - gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - gc.setFont(Display.getCurrent().getSystemFont()); - - gc.drawLine(printBounds.x, - printBounds.y + printBounds.height+10, - printBounds.x + printBounds.width, - printBounds.y + printBounds.height+10); - - String pageText = ganttChart.getLanguageManger().getPrintPageText() + " " + currentPage; //$NON-NLS-1$ - gc.drawString(pageText, - printBounds.x, - printBounds.y + printBounds.height + 15); - - Point dateExtend = gc.stringExtent(footerDate); - gc.drawString(footerDate, - printBounds.x + printBounds.width - dateExtend.x, - printBounds.y + printBounds.height + 15); - } - - /** - * Checks if a given page number should be printed. - * Page is allowed to print if: - * User asked to print all pages or page in a specified range - * @param printerData The printer settings made by the user. Needed to determine - * if a page should be printed dependent to the scope - * @param currentPage The page that should be checked - * @return true if the given page should be printed, - * false if not - */ - private boolean shouldPrint(PrinterData printerData, int currentPage) { - if (printerData.scope == PrinterData.PAGE_RANGE) { - return currentPage >= printerData.startPage && currentPage <= printerData.endPage; - } - return true; - } - - /** - * - * @param dispose true if the printer that is set to this GanttChartPrintJob - * should be disposed after the print job is done, false if it should - * not be disposed so the printer can be reused for additional tasks. - */ - public void setDisposePrinter(boolean dispose) { - this.disposePrinter = dispose; - } -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart.print; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.nebula.widgets.ganttchart.GanttChart; +import org.eclipse.swt.SWT; +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.graphics.Transform; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; + +/** + * Runnable to print one ore more GanttCharts. + */ +public class GanttChartPrintJob implements Runnable { + + private final Printer printer; + + private final String jobName; + + private final GanttChart[] ganttCharts; + + private boolean disposePrinter; + + /** + * Creates a new GanttChartPrintJob that uses the given printer and print job name + * to print the specified GanttChart(s). If not changed afterwards, running this job + * will dispose the given printer when it is done. + * @param printer The printer to use. + * @param jobName The job name to use for the print job. + * @param charts The GanttCharts that should be printed. + */ + public GanttChartPrintJob(Printer printer, String jobName, GanttChart... charts) { + this(printer, jobName, true, charts); + } + + /** + * Creates a new GanttChartPrintJob that uses the given printer and print job name + * to print the specified GanttChart(s). + * @param printer The printer to use. + * @param jobName The job name to use for the print job. + * @param charts The GanttCharts that should be printed. + * @param disposePrinter Flag to configure whether the given printer should be disposed + * after the print job is done. Default is true. Only set this + * parameter to false if the printer should be reused for additional + * print jobs. You need to ensure that the printer will get disposed yourself + * in that case! + */ + public GanttChartPrintJob(Printer printer, String jobName, boolean disposePrinter, GanttChart... charts) { + this.printer = printer; + this.jobName = jobName; + this.ganttCharts = charts; + this.disposePrinter = disposePrinter; + } + + public void run() { + if (printer.startJob(jobName)) { + GC gc = new GC(printer); + + int currentPage = 1; + for (GanttChart ganttChart : this.ganttCharts) { + + Image printerImage = null; + if (printer.getPrinterData().scope == PrinterData.SELECTION) { + //the user selected to only print the selected area + //as this is quite difficult in GanttChart, we specify that + //this means to print the visible area + //but it is possible to configure via settings what "visible" + //area means: + // - really only the visible area horizontally and vertically + // - only the horizontal visible area, but vertically everything + printerImage = ganttChart.getSettings().printSelectedVerticallyComplete() ? + ganttChart.getGanttComposite().getVerticallyFullImage() : ganttChart.getGanttComposite().getImage(); + } + else { + printerImage = ganttChart.getGanttComposite().getFullImage(); + } + + final Rectangle printerClientArea = PrintUtils.computePrintArea(printer); + final Point scaleFactor = PrintUtils.computeScaleFactor(printer); + final Point pageCount = PrintUtils.getPageCount(printer, printerImage); + + // Print pages Left to Right and then Top to Down + for (int verticalPageNumber = 0; verticalPageNumber < pageCount.y; verticalPageNumber++) { + + for (int horizontalPageNumber = 0; horizontalPageNumber < pageCount.x; horizontalPageNumber++) { + + // Calculate bounds for the next page + int printerClientAreaHeight = ganttChart.getSettings().printFooter() ? + (printerClientArea.height - PrintUtils.FOOTER_HEIGHT_IN_PRINTER_DPI) : printerClientArea.height; + Rectangle printBounds = new Rectangle((printerClientArea.width / scaleFactor.x) * horizontalPageNumber, + (printerClientAreaHeight / scaleFactor.y) * verticalPageNumber, + printerClientArea.width / scaleFactor.x, + printerClientAreaHeight / scaleFactor.y); + + if (shouldPrint(printer.getPrinterData(), currentPage)) { + printer.startPage(); + + Transform printerTransform = new Transform(printer); + + // Adjust for DPI difference between display and printer + printerTransform.scale(scaleFactor.x, scaleFactor.y); + + // Adjust for margins + printerTransform.translate(printerClientArea.x / scaleFactor.x, printerClientArea.y / scaleFactor.y); + + // GanttChart will not automatically print the pages at the left margin. + // Example: page 1 will print at x = 0, page 2 at x = 100, page 3 at x = 300 + // Adjust to print from the left page margin. i.e x = 0 + printerTransform.translate(-1 * printBounds.x, -1 * printBounds.y); + gc.setTransform(printerTransform); + + int imgWidthClipping = printBounds.width; + if (((horizontalPageNumber * printBounds.width)+printBounds.width) > printerImage.getImageData().width) { + imgWidthClipping = printerImage.getImageData().width - (horizontalPageNumber * printBounds.width); + } + + int imgHeightClipping = printBounds.height; + if (((verticalPageNumber * printBounds.height)+printBounds.height) > printerImage.getImageData().height) { + imgHeightClipping = printerImage.getImageData().height - (verticalPageNumber * printBounds.height); + } + + gc.drawImage(printerImage, + horizontalPageNumber * printBounds.width, + verticalPageNumber * printBounds.height, + imgWidthClipping, imgHeightClipping, + printBounds.x, printBounds.y, imgWidthClipping, imgHeightClipping); + + if (ganttChart.getSettings().printFooter()) + printFooter(gc, ganttChart, currentPage, printBounds); + + printer.endPage(); + printerTransform.dispose(); + + } + currentPage++; + } + } + + printerImage.dispose(); + } + + printer.endJob(); + gc.dispose(); + + //only dispose the printer after the print job is done if it is configured to do so + //this configuration enables the possibility to reuse a printer for several jobs + if (disposePrinter) + printer.dispose(); + } + } + + /** + * Render the footer to a print page. + * @param gc The graphical context that is used for printing + * @param ganttChart The GanttChart which is currently printed. + * @param currentPage The number of the current page that is printed + * @param printBounds The bounds of the print area + */ + private void printFooter(GC gc, GanttChart ganttChart, int currentPage, Rectangle printBounds) { + String footerDate = new SimpleDateFormat(ganttChart.getSettings().getDateFormat()).format(new Date()); + + gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + gc.setFont(Display.getCurrent().getSystemFont()); + + gc.drawLine(printBounds.x, + printBounds.y + printBounds.height+10, + printBounds.x + printBounds.width, + printBounds.y + printBounds.height+10); + + String pageText = ganttChart.getLanguageManger().getPrintPageText() + " " + currentPage; //$NON-NLS-1$ + gc.drawString(pageText, + printBounds.x, + printBounds.y + printBounds.height + 15); + + Point dateExtend = gc.stringExtent(footerDate); + gc.drawString(footerDate, + printBounds.x + printBounds.width - dateExtend.x, + printBounds.y + printBounds.height + 15); + } + + /** + * Checks if a given page number should be printed. + * Page is allowed to print if: + * User asked to print all pages or page in a specified range + * @param printerData The printer settings made by the user. Needed to determine + * if a page should be printed dependent to the scope + * @param currentPage The page that should be checked + * @return true if the given page should be printed, + * false if not + */ + private boolean shouldPrint(PrinterData printerData, int currentPage) { + if (printerData.scope == PrinterData.PAGE_RANGE) { + return currentPage >= printerData.startPage && currentPage <= printerData.endPage; + } + return true; + } + + /** + * + * @param dispose true if the printer that is set to this GanttChartPrintJob + * should be disposed after the print job is done, false if it should + * not be disposed so the printer can be reused for additional tasks. + */ + public void setDisposePrinter(boolean dispose) { + this.disposePrinter = dispose; + } +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrinter.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrinter.java index b06b1762a..2e141e4fd 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrinter.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrinter.java @@ -1,120 +1,120 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart.print; - -import org.eclipse.nebula.widgets.ganttchart.GanttChart; -import org.eclipse.nebula.widgets.ganttchart.ILanguageManager; -import org.eclipse.nebula.widgets.ganttchart.ISettings; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * This class is used to print a GanttChart. For this it will use the already existing - * functionality of rendering the GanttChart to an image. - *

- * There are some configuration parameters that have impact on: - *

    - *
  • The horizontal range to print - If everything should be printed, by default the range - * from the earliest event start date to the latest event end date (plus possible text) - * is used. But configuring a period in the ISettings will also take these values into - * account for calculating the horizontal range.
  • - *
  • The vertical range to print - If only the selected part should be printed, by default - * selection means the visible part of the chart horizontally and vertically. This behavior - * can be modified so that horizontally only the visible part of the chart will be printed - * but vertically the whole chart gets printed.
  • - *
  • The name of the print job
  • - *
  • Whether a footer should be printed or not
  • - *
  • The name of the page (can be used for localization)
  • - *
  • The format of the date in the footer
  • - *
- * - * @see ISettings#getPeriodStart() - * @see ISettings#getPeriodEnd() - * @see ISettings#printSelectedVerticallyComplete() - * @see ISettings#printFooter() - * @see ISettings#getDateFormat() - * @see ILanguageManager#getPrintJobText() - * @see ILanguageManager#getPrintPageText() - */ -public class GanttChartPrinter { - - private final GanttChart ganttChart; - - /** - * Creates a new GanttChartPrinter for the given GanttChart. - * @param ganttChart The GanttChart that should be printed by this GanttChartPrinter. - */ - public GanttChartPrinter(GanttChart ganttChart) { - this.ganttChart = ganttChart; - } - - /** - * First opens the PrintDialog so a user can adjust his print settings and will - * then print the chart based on the settings made by the user. - */ - public void print() { - final Printer printer = setupPrinter(this.ganttChart.getShell()); - if (printer == null) { - return; - } - - Display.getDefault().asyncExec(new GanttChartPrintJob( - printer, ganttChart.getLanguageManger().getPrintJobText(), ganttChart)); - } - - /** - * Opens the PrintDialog to let the user specify the printer and print configurations to use. - * @param shell The Shell which should be the parent for the PrintDialog - * @return The selected printer with the print configuration made by the user. - */ - protected Printer setupPrinter(final Shell shell) { - //Calculate the number of pages by using the full image - //This is because on setup we want to show how many pages the full print would be - Printer defaultPrinter = new Printer(); - Point pageCount = getFullPageCount(defaultPrinter); - defaultPrinter.dispose(); - - final PrintDialog printDialog = new PrintDialog(shell); - - PrinterData data = new PrinterData(); - data.orientation = PrinterData.LANDSCAPE; - data.startPage = 1; - data.endPage = pageCount.x * pageCount.y; - data.scope = PrinterData.ALL_PAGES; - printDialog.setPrinterData(data); - - PrinterData printerData = printDialog.open(); - if (printerData == null){ - return null; - } - return new Printer(printerData); - } - - /** - * Calculates the number of horizontal and vertical pages needed to print the entire chart. - * @param printer The printer that is used to determine the page count of a full print. - * @return The number of horizontal and vertical pages that will be printed. - */ - protected Point getFullPageCount(Printer printer) { - Image chartImage = this.ganttChart.getGanttComposite().getFullImage(); - Point result = PrintUtils.getPageCount(printer, chartImage); - chartImage.dispose(); - return result; - } -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart.print; + +import org.eclipse.nebula.widgets.ganttchart.GanttChart; +import org.eclipse.nebula.widgets.ganttchart.ILanguageManager; +import org.eclipse.nebula.widgets.ganttchart.ISettings; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * This class is used to print a GanttChart. For this it will use the already existing + * functionality of rendering the GanttChart to an image. + *

+ * There are some configuration parameters that have impact on: + *

    + *
  • The horizontal range to print - If everything should be printed, by default the range + * from the earliest event start date to the latest event end date (plus possible text) + * is used. But configuring a period in the ISettings will also take these values into + * account for calculating the horizontal range.
  • + *
  • The vertical range to print - If only the selected part should be printed, by default + * selection means the visible part of the chart horizontally and vertically. This behavior + * can be modified so that horizontally only the visible part of the chart will be printed + * but vertically the whole chart gets printed.
  • + *
  • The name of the print job
  • + *
  • Whether a footer should be printed or not
  • + *
  • The name of the page (can be used for localization)
  • + *
  • The format of the date in the footer
  • + *
+ * + * @see ISettings#getPeriodStart() + * @see ISettings#getPeriodEnd() + * @see ISettings#printSelectedVerticallyComplete() + * @see ISettings#printFooter() + * @see ISettings#getDateFormat() + * @see ILanguageManager#getPrintJobText() + * @see ILanguageManager#getPrintPageText() + */ +public class GanttChartPrinter { + + private final GanttChart ganttChart; + + /** + * Creates a new GanttChartPrinter for the given GanttChart. + * @param ganttChart The GanttChart that should be printed by this GanttChartPrinter. + */ + public GanttChartPrinter(GanttChart ganttChart) { + this.ganttChart = ganttChart; + } + + /** + * First opens the PrintDialog so a user can adjust his print settings and will + * then print the chart based on the settings made by the user. + */ + public void print() { + final Printer printer = setupPrinter(this.ganttChart.getShell()); + if (printer == null) { + return; + } + + Display.getDefault().asyncExec(new GanttChartPrintJob( + printer, ganttChart.getLanguageManger().getPrintJobText(), ganttChart)); + } + + /** + * Opens the PrintDialog to let the user specify the printer and print configurations to use. + * @param shell The Shell which should be the parent for the PrintDialog + * @return The selected printer with the print configuration made by the user. + */ + protected Printer setupPrinter(final Shell shell) { + //Calculate the number of pages by using the full image + //This is because on setup we want to show how many pages the full print would be + Printer defaultPrinter = new Printer(); + Point pageCount = getFullPageCount(defaultPrinter); + defaultPrinter.dispose(); + + final PrintDialog printDialog = new PrintDialog(shell); + + PrinterData data = new PrinterData(); + data.orientation = PrinterData.LANDSCAPE; + data.startPage = 1; + data.endPage = pageCount.x * pageCount.y; + data.scope = PrinterData.ALL_PAGES; + printDialog.setPrinterData(data); + + PrinterData printerData = printDialog.open(); + if (printerData == null){ + return null; + } + return new Printer(printerData); + } + + /** + * Calculates the number of horizontal and vertical pages needed to print the entire chart. + * @param printer The printer that is used to determine the page count of a full print. + * @return The number of horizontal and vertical pages that will be printed. + */ + protected Point getFullPageCount(Printer printer) { + Image chartImage = this.ganttChart.getGanttComposite().getFullImage(); + Point result = PrintUtils.getPageCount(printer, chartImage); + chartImage.dispose(); + return result; + } +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/PrintUtils.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/PrintUtils.java index 2c4f78a25..3815ccd81 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/PrintUtils.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/PrintUtils.java @@ -1,110 +1,110 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart.print; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.widgets.Display; - -/** - * Helper class for computations regarding printing of GanttCharts. - */ -public class PrintUtils { - - /** - * The height of the footer on a print page. - */ - public static final int FOOTER_HEIGHT_IN_PRINTER_DPI = 200; - - /** - * Computes the print area, including margins - * @param printer The printer that will be used to print the chart - * @return The print area - */ - public static Rectangle computePrintArea(Printer printer) { - // Get the printable area - Rectangle rect = printer.getClientArea(); - - // Compute the trim - Rectangle trim = printer.computeTrim(0, 0, 0, 0); - - // Get the printer's DPI - Point dpi = printer.getDPI(); - dpi.x = dpi.x / 2; - dpi.y = dpi.y / 2; - - // Calculate the printable area, using 1 inch margins - int left = trim.x + dpi.x; - if (left < rect.x) left = rect.x; - - int right = (rect.width + trim.x + trim.width) - dpi.x; - if (right > rect.width) right = rect.width; - - int top = trim.y + dpi.y; - if (top < rect.y) top = rect.y; - - int bottom = (rect.height + trim.y + trim.height) - dpi.y; - if (bottom > rect.height) bottom = rect.height; - - return new Rectangle(left, top, right - left, bottom - top); - } - - /** - * - * @param printer The printer that will be used to print the chart - * @return Amount to scale the screen resolution by, to match the printer - * resolution. - */ - public static Point computeScaleFactor(Printer printer) { - Point screenDPI = Display.getDefault().getDPI(); - Point printerDPI = printer.getDPI(); - - int scaleFactorX = printerDPI.x / screenDPI.x; - int scaleFactorY = printerDPI.y / screenDPI.y; - return new Point(scaleFactorX, scaleFactorY); - } - - /** - * Calculate number of horizontal and vertical pages needed - * to print the given image of the chart. - * @param printer The printer that will be used to print the chart - * @param image The image of the chart that should be printed. - * @return The number of horizontal and vertical pages that will be - * printed. - */ - public static Point getPageCount(Printer printer, Image image){ - Rectangle ganttArea = getVisibleGanttChartArea(image); - Rectangle printArea = PrintUtils.computePrintArea(printer); - Point scaleFactor = PrintUtils.computeScaleFactor(printer); - - int numOfHorizontalPages = ganttArea.width / (printArea.width / scaleFactor.x); - int numOfVerticalPages = ganttArea.height / (printArea.height / scaleFactor.y); - - // Adjusting for 0 index - return new Point(numOfHorizontalPages + 1, numOfVerticalPages + 1); - } - - /** - * - * @param image The image of the chart that should be printed. - * @return The size of the image representation of the chart that - * should be printed. - */ - public static Rectangle getVisibleGanttChartArea(Image image) { - return new Rectangle(0, 0, image.getImageData().width, image.getImageData().height); - } - -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart.print; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.widgets.Display; + +/** + * Helper class for computations regarding printing of GanttCharts. + */ +public class PrintUtils { + + /** + * The height of the footer on a print page. + */ + public static final int FOOTER_HEIGHT_IN_PRINTER_DPI = 200; + + /** + * Computes the print area, including margins + * @param printer The printer that will be used to print the chart + * @return The print area + */ + public static Rectangle computePrintArea(Printer printer) { + // Get the printable area + Rectangle rect = printer.getClientArea(); + + // Compute the trim + Rectangle trim = printer.computeTrim(0, 0, 0, 0); + + // Get the printer's DPI + Point dpi = printer.getDPI(); + dpi.x = dpi.x / 2; + dpi.y = dpi.y / 2; + + // Calculate the printable area, using 1 inch margins + int left = trim.x + dpi.x; + if (left < rect.x) left = rect.x; + + int right = (rect.width + trim.x + trim.width) - dpi.x; + if (right > rect.width) right = rect.width; + + int top = trim.y + dpi.y; + if (top < rect.y) top = rect.y; + + int bottom = (rect.height + trim.y + trim.height) - dpi.y; + if (bottom > rect.height) bottom = rect.height; + + return new Rectangle(left, top, right - left, bottom - top); + } + + /** + * + * @param printer The printer that will be used to print the chart + * @return Amount to scale the screen resolution by, to match the printer + * resolution. + */ + public static Point computeScaleFactor(Printer printer) { + Point screenDPI = Display.getDefault().getDPI(); + Point printerDPI = printer.getDPI(); + + int scaleFactorX = printerDPI.x / screenDPI.x; + int scaleFactorY = printerDPI.y / screenDPI.y; + return new Point(scaleFactorX, scaleFactorY); + } + + /** + * Calculate number of horizontal and vertical pages needed + * to print the given image of the chart. + * @param printer The printer that will be used to print the chart + * @param image The image of the chart that should be printed. + * @return The number of horizontal and vertical pages that will be + * printed. + */ + public static Point getPageCount(Printer printer, Image image){ + Rectangle ganttArea = getVisibleGanttChartArea(image); + Rectangle printArea = PrintUtils.computePrintArea(printer); + Point scaleFactor = PrintUtils.computeScaleFactor(printer); + + int numOfHorizontalPages = ganttArea.width / (printArea.width / scaleFactor.x); + int numOfVerticalPages = ganttArea.height / (printArea.height / scaleFactor.y); + + // Adjusting for 0 index + return new Point(numOfHorizontalPages + 1, numOfVerticalPages + 1); + } + + /** + * + * @param image The image of the chart that should be printed. + * @return The size of the image representation of the chart that + * should be printed. + */ + public static Rectangle getVisibleGanttChartArea(Image image) { + return new Rectangle(0, 0, image.getImageData().width, image.getImageData().height); + } + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/undoredo/commands/EventDeleteCommand.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/undoredo/commands/EventDeleteCommand.java index abf9ff907..f3eb50c0b 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/undoredo/commands/EventDeleteCommand.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/undoredo/commands/EventDeleteCommand.java @@ -1,103 +1,103 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart.undoredo.commands; - -import org.eclipse.nebula.widgets.ganttchart.GanttEvent; -import org.eclipse.nebula.widgets.ganttchart.GanttSection; -import org.eclipse.nebula.widgets.ganttchart.IGanttEventListener; -import org.eclipse.nebula.widgets.ganttchart.undoredo.commands.IUndoRedoCommand; - -/** - * Represents one GanttEvent delete action that can be undone/redone. - *

- * Note that this command is not added internally. But you are able to - * create and add this type of command within your custom - * {@link IGanttEventListener#eventsDeleteRequest(java.util.List, org.eclipse.swt.events.MouseEvent)} - */ -public class EventDeleteCommand implements IUndoRedoCommand { - - private GanttEvent _event; - private int _index; - private GanttSection _section; - - /** - * Creates a new undoable/redoable delete Event. - * - * @param event {@link GanttEvent} being deleted - * @param section {@link GanttSection} index (of all GanttSections) prior to delete - * @param index Index of event in {@link GanttSection} section prior to delete - */ - public EventDeleteCommand(final GanttEvent event, final GanttSection section, final int index) { - _event = event; - _index = index; - _section = section; - } - - public void undo() { - _event.getParentComposite().addEvent(_event, _index); - - if (_section != null) { - _section.addGanttEvent(_index, _event); - } - } - - public void redo() { - _event.getParentComposite().removeEvent(_event); - - if (_section != null) { - _section.removeGanttEvent(_event); - } - } - - public void dispose() { - } - - public GanttEvent getEvent() { - return _event; - } - - public void setEvent(final GanttEvent event) { - _event = event; - } - - public int getIndex() { - return _index; - } - - public void setIndex(final int index) { - _index = index; - } - - public GanttSection getSection() { - return _section; - } - - public void setSection(final GanttSection section) { - _section = section; - } - - @SuppressWarnings("nls") - public String toString() { - final StringBuffer buf = new StringBuffer(200); - buf.append("[EventDelete: "); - buf.append(_event); - buf.append(" was deleted from section "); - buf.append(_section); - buf.append(" at index "); - buf.append(_index); - buf.append(']'); - return buf.toString(); - } - -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart.undoredo.commands; + +import org.eclipse.nebula.widgets.ganttchart.GanttEvent; +import org.eclipse.nebula.widgets.ganttchart.GanttSection; +import org.eclipse.nebula.widgets.ganttchart.IGanttEventListener; +import org.eclipse.nebula.widgets.ganttchart.undoredo.commands.IUndoRedoCommand; + +/** + * Represents one GanttEvent delete action that can be undone/redone. + *

+ * Note that this command is not added internally. But you are able to + * create and add this type of command within your custom + * {@link IGanttEventListener#eventsDeleteRequest(java.util.List, org.eclipse.swt.events.MouseEvent)} + */ +public class EventDeleteCommand implements IUndoRedoCommand { + + private GanttEvent _event; + private int _index; + private GanttSection _section; + + /** + * Creates a new undoable/redoable delete Event. + * + * @param event {@link GanttEvent} being deleted + * @param section {@link GanttSection} index (of all GanttSections) prior to delete + * @param index Index of event in {@link GanttSection} section prior to delete + */ + public EventDeleteCommand(final GanttEvent event, final GanttSection section, final int index) { + _event = event; + _index = index; + _section = section; + } + + public void undo() { + _event.getParentComposite().addEvent(_event, _index); + + if (_section != null) { + _section.addGanttEvent(_index, _event); + } + } + + public void redo() { + _event.getParentComposite().removeEvent(_event); + + if (_section != null) { + _section.removeGanttEvent(_event); + } + } + + public void dispose() { + } + + public GanttEvent getEvent() { + return _event; + } + + public void setEvent(final GanttEvent event) { + _event = event; + } + + public int getIndex() { + return _index; + } + + public void setIndex(final int index) { + _index = index; + } + + public GanttSection getSection() { + return _section; + } + + public void setSection(final GanttSection section) { + _section = section; + } + + @SuppressWarnings("nls") + public String toString() { + final StringBuffer buf = new StringBuffer(200); + buf.append("[EventDelete: "); + buf.append(_event); + buf.append(" was deleted from section "); + buf.append(_section); + buf.append(" at index "); + buf.append(_index); + buf.append(']'); + return buf.toString(); + } + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/undoredo/commands/SectionDeleteCommand.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/undoredo/commands/SectionDeleteCommand.java index 59312ceb6..98098c2b5 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/undoredo/commands/SectionDeleteCommand.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/undoredo/commands/SectionDeleteCommand.java @@ -1,81 +1,81 @@ -/******************************************************************************* - * Copyright (c) 2013 Dirk Fauth and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Dirk Fauth - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.ganttchart.undoredo.commands; - -import org.eclipse.nebula.widgets.ganttchart.GanttSection; -import org.eclipse.nebula.widgets.ganttchart.undoredo.commands.IUndoRedoCommand; - -/** - * Represents one GanttSection delete action that can be undone/redone. - *

- * Note that this command is not added internally. This is because there is - * no code that automatically deletes sections from your GanttComposite. - * You need to create and record this command together with the code that - * removes the section from your composite. - */ -public class SectionDeleteCommand implements IUndoRedoCommand { - - private GanttSection _section; - private int _index; - - /** - * Creates a new undoable/redoable delete Event. - * - * @param section {@link GanttSection} being deleted - * @param index Index of {@link GanttSection} prior to delete - */ - public SectionDeleteCommand(final GanttSection section, final int index) { - _section = section; - _index = index; - } - - public void undo() { - _section.getParentComposite().addSection(_section, _index); - } - - public void redo() { - _section.getParentComposite().removeSection(_section); - } - - public void dispose() { - } - - public GanttSection getSection() { - return _section; - } - - public void setSection(final GanttSection section) { - _section = section; - } - - public int getIndex() { - return _index; - } - - public void setIndex(final int index) { - _index = index; - } - - @SuppressWarnings("nls") - public String toString() { - final StringBuffer buf = new StringBuffer(200); - buf.append("[SectionDelete: "); - buf.append(_section); - buf.append(" was deleted at index "); - buf.append(_index); - buf.append(']'); - return buf.toString(); - } - -} +/******************************************************************************* + * Copyright (c) 2013 Dirk Fauth and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Dirk Fauth - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.ganttchart.undoredo.commands; + +import org.eclipse.nebula.widgets.ganttchart.GanttSection; +import org.eclipse.nebula.widgets.ganttchart.undoredo.commands.IUndoRedoCommand; + +/** + * Represents one GanttSection delete action that can be undone/redone. + *

+ * Note that this command is not added internally. This is because there is + * no code that automatically deletes sections from your GanttComposite. + * You need to create and record this command together with the code that + * removes the section from your composite. + */ +public class SectionDeleteCommand implements IUndoRedoCommand { + + private GanttSection _section; + private int _index; + + /** + * Creates a new undoable/redoable delete Event. + * + * @param section {@link GanttSection} being deleted + * @param index Index of {@link GanttSection} prior to delete + */ + public SectionDeleteCommand(final GanttSection section, final int index) { + _section = section; + _index = index; + } + + public void undo() { + _section.getParentComposite().addSection(_section, _index); + } + + public void redo() { + _section.getParentComposite().removeSection(_section); + } + + public void dispose() { + } + + public GanttSection getSection() { + return _section; + } + + public void setSection(final GanttSection section) { + _section = section; + } + + public int getIndex() { + return _index; + } + + public void setIndex(final int index) { + _index = index; + } + + @SuppressWarnings("nls") + public String toString() { + final StringBuffer buf = new StringBuffer(200); + buf.append("[SectionDelete: "); + buf.append(_section); + buf.append(" was deleted at index "); + buf.append(_index); + buf.append(']'); + return buf.toString(); + } + +} diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/utils/TextPainterHelper.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/utils/TextPainterHelper.java index b1a167e5f..869fbc435 100644 --- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/utils/TextPainterHelper.java +++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/utils/TextPainterHelper.java @@ -1,238 +1,238 @@ -package org.eclipse.nebula.widgets.ganttchart.utils; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.nebula.widgets.ganttchart.ColorCache; -import org.eclipse.nebula.widgets.ganttchart.Utils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * Helper class to draw texts with markups within the GanttChart. - * Currently used for rendering tooltips and section details. - * Following markups are supported: - *

    - *
  • \\ce - render the following text in black
  • - *
  • \\c[0-9]{9} - render the following text in the specified rbg color (Note that there need to be nine digits)
  • - *
  • \\s[0-9]{1,3} - render the following text with the specified font size
  • - *
  • \\i - render the following text italic
  • - *
  • \\b - render the following text bold
  • - *
  • \\x - normalize, which means to reset the previous assigned markups and render with the default font and color
  • - *
- */ -@SuppressWarnings("nls") -public class TextPainterHelper { - - /** - * Will draw the given text to the given GC. Before drawing the containing - * markups will be interpreted to apply color and font settings. - * @param gc The GC to draw the text to - * @param text The text to draw - * @param x The x coordinate where the text should be drawed to the GC - * @param y The y coordinate where the text should be drawed to the GC - * @return The end point of the drawed text. - */ - public static Point drawText(final GC gc, final String text, final int x, final int y) { - Pattern pattern = Pattern.compile("(\\\\(ce|c[0-9]{9}|s[0-9]{1,3}|[xbi]))*[^\\\\]*"); - - try { - final Font old = gc.getFont(); - final int oldSize = (int) old.getFontData()[0].height; - - int curX = x; - boolean bold = false; - boolean italic = false; - int size = oldSize; - Color fg = ColorCache.getBlack(); - - int maxWidth = 0; - int maxHeight = 0; - - Matcher matcher = pattern.matcher(text); - - while (matcher.find()) { - String token = matcher.group(); - - if (isNormalize(token)) { - bold = false; - italic = false; - size = oldSize; - fg = ColorCache.getBlack(); - } - else { - final int newSize = getSize(token); - if (newSize != size && newSize != -1) { - size = newSize; - } - - final boolean newBold = isBold(token); - if (bold && !newBold) { - bold = true; - } - else { - bold = newBold; - } - - final boolean newItalic = isItalic(token); - if (italic && !newItalic) { - italic = true; - } - else { - italic = newItalic; - } - - final Color newColor = getColor(token); - if (newColor != null && !newColor.equals(fg)) { - fg = newColor; - } - } - - if (fg != null) { - gc.setForeground(fg); - } - - token = cleanUp(token); - - int style = SWT.NORMAL; - if (bold) { - style |= SWT.BOLD; - } - if (italic) { - style |= SWT.ITALIC; - } - - Font used = Utils.applyFontData(old, style, size); - gc.setFont(used); - - if (token.length() != 0) { - gc.drawText(token, curX, y, true); - final int extX = gc.textExtent(token).x; - final int extY = gc.textExtent(token).y; - curX += extX; - - maxWidth = Math.max(maxWidth, curX); - maxHeight = Math.max(maxHeight, extY); - } - - used.dispose(); - } - - gc.setFont(old); - return new Point(maxWidth - x, maxHeight); - } - catch (Exception err) { - SWT.error(SWT.ERROR_UNSPECIFIED, err); - } - - return null; - } - - /** - * Removes all markups out of the given string. Needed to render - * after all markups have been resolved. - * @param string The string whose markups should be removed. - * @return The given string without any further markups. - */ - public static String cleanUp(final String string) { - String str = string; - str = str.replaceAll("\\\\ce", ""); - str = str.replaceAll("\\\\c[0-9]{9}", ""); - str = str.replaceAll("\\\\s[0-9]{1,3}", ""); - str = str.replaceAll("\\\\x", ""); - str = str.replaceAll("\\\\b", ""); - str = str.replaceAll("\\\\i", ""); - return str; - } - - /** - * Checks for the existence of the normalize markup. - * The normalize markup can be used to reset all former assigned - * markups for the following text to render. - * The normalize markup is \\x - * @param str The string to check for the normalize markup - * @return true if the given string contains the - * normalize markup - */ - public static boolean isNormalize(final String str) { - return str.indexOf("\\x") > -1; - } - - /** - * Checks for the existence of the bold markup. - * The bold markup is \\b - * @param str The string to check for the bold markup - * @return true if the given string contains the - * bold markup - */ - public static boolean isBold(final String str) { - return str.indexOf("\\b") > -1; - } - - /** - * Checks for the existence of the italic markup. - * The italic markup is \\i - * @param str The string to check for the italic markup - * @return true if the given string contains the - * italic markup - */ - public static boolean isItalic(final String str) { - return str.indexOf("\\i") > -1; - } - - /** - * Gets the font size out of a size markup in the given string. - * A size markup is specified \\s[0-9]{1,3} - * @param str The string containing the size markup - * @return The font size to use for rendering - */ - public static int getSize(final String str) { - Pattern pattern = Pattern.compile("\\\\s[0-9]{1,3}"); - Matcher matcher = pattern.matcher(str); - if (matcher.find()) { - String sizeString = matcher.group(); - sizeString = sizeString.substring(2); - - try { - return Integer.parseInt(sizeString); - } catch (Exception badParse) { - SWT.error(SWT.ERROR_UNSPECIFIED, badParse); - } - } - - return -1; - } - - /** - * Gets the color for a color markup in the given string. - * A color markup is either \\ce for black or \\c[0-9]{9} - * to specify a custom color by rgb code - * @param str The string containing a color markup - * @return The Color that is specified by the color markup - */ - public static Color getColor(final String str) { - final int start = str.indexOf("\\c"); - if (start == -1) { - return null; - } - - if (str.indexOf("\\ce") != -1) { - return ColorCache.getBlack(); - } - - try { - final int red = Integer.parseInt(str.substring(start + 2, start + 5)); - final int green = Integer.parseInt(str.substring(start + 5, start + 8)); - final int blue = Integer.parseInt(str.substring(start + 8, start + 11)); - - return ColorCache.getColor(red, green, blue); - } catch (Exception err) { - SWT.error(SWT.ERROR_UNSPECIFIED, err); - } - - return ColorCache.getBlack(); - } -} +package org.eclipse.nebula.widgets.ganttchart.utils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.nebula.widgets.ganttchart.ColorCache; +import org.eclipse.nebula.widgets.ganttchart.Utils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * Helper class to draw texts with markups within the GanttChart. + * Currently used for rendering tooltips and section details. + * Following markups are supported: + *
    + *
  • \\ce - render the following text in black
  • + *
  • \\c[0-9]{9} - render the following text in the specified rbg color (Note that there need to be nine digits)
  • + *
  • \\s[0-9]{1,3} - render the following text with the specified font size
  • + *
  • \\i - render the following text italic
  • + *
  • \\b - render the following text bold
  • + *
  • \\x - normalize, which means to reset the previous assigned markups and render with the default font and color
  • + *
+ */ +@SuppressWarnings("nls") +public class TextPainterHelper { + + /** + * Will draw the given text to the given GC. Before drawing the containing + * markups will be interpreted to apply color and font settings. + * @param gc The GC to draw the text to + * @param text The text to draw + * @param x The x coordinate where the text should be drawed to the GC + * @param y The y coordinate where the text should be drawed to the GC + * @return The end point of the drawed text. + */ + public static Point drawText(final GC gc, final String text, final int x, final int y) { + Pattern pattern = Pattern.compile("(\\\\(ce|c[0-9]{9}|s[0-9]{1,3}|[xbi]))*[^\\\\]*"); + + try { + final Font old = gc.getFont(); + final int oldSize = (int) old.getFontData()[0].height; + + int curX = x; + boolean bold = false; + boolean italic = false; + int size = oldSize; + Color fg = ColorCache.getBlack(); + + int maxWidth = 0; + int maxHeight = 0; + + Matcher matcher = pattern.matcher(text); + + while (matcher.find()) { + String token = matcher.group(); + + if (isNormalize(token)) { + bold = false; + italic = false; + size = oldSize; + fg = ColorCache.getBlack(); + } + else { + final int newSize = getSize(token); + if (newSize != size && newSize != -1) { + size = newSize; + } + + final boolean newBold = isBold(token); + if (bold && !newBold) { + bold = true; + } + else { + bold = newBold; + } + + final boolean newItalic = isItalic(token); + if (italic && !newItalic) { + italic = true; + } + else { + italic = newItalic; + } + + final Color newColor = getColor(token); + if (newColor != null && !newColor.equals(fg)) { + fg = newColor; + } + } + + if (fg != null) { + gc.setForeground(fg); + } + + token = cleanUp(token); + + int style = SWT.NORMAL; + if (bold) { + style |= SWT.BOLD; + } + if (italic) { + style |= SWT.ITALIC; + } + + Font used = Utils.applyFontData(old, style, size); + gc.setFont(used); + + if (token.length() != 0) { + gc.drawText(token, curX, y, true); + final int extX = gc.textExtent(token).x; + final int extY = gc.textExtent(token).y; + curX += extX; + + maxWidth = Math.max(maxWidth, curX); + maxHeight = Math.max(maxHeight, extY); + } + + used.dispose(); + } + + gc.setFont(old); + return new Point(maxWidth - x, maxHeight); + } + catch (Exception err) { + SWT.error(SWT.ERROR_UNSPECIFIED, err); + } + + return null; + } + + /** + * Removes all markups out of the given string. Needed to render + * after all markups have been resolved. + * @param string The string whose markups should be removed. + * @return The given string without any further markups. + */ + public static String cleanUp(final String string) { + String str = string; + str = str.replaceAll("\\\\ce", ""); + str = str.replaceAll("\\\\c[0-9]{9}", ""); + str = str.replaceAll("\\\\s[0-9]{1,3}", ""); + str = str.replaceAll("\\\\x", ""); + str = str.replaceAll("\\\\b", ""); + str = str.replaceAll("\\\\i", ""); + return str; + } + + /** + * Checks for the existence of the normalize markup. + * The normalize markup can be used to reset all former assigned + * markups for the following text to render. + * The normalize markup is \\x + * @param str The string to check for the normalize markup + * @return true if the given string contains the + * normalize markup + */ + public static boolean isNormalize(final String str) { + return str.indexOf("\\x") > -1; + } + + /** + * Checks for the existence of the bold markup. + * The bold markup is \\b + * @param str The string to check for the bold markup + * @return true if the given string contains the + * bold markup + */ + public static boolean isBold(final String str) { + return str.indexOf("\\b") > -1; + } + + /** + * Checks for the existence of the italic markup. + * The italic markup is \\i + * @param str The string to check for the italic markup + * @return true if the given string contains the + * italic markup + */ + public static boolean isItalic(final String str) { + return str.indexOf("\\i") > -1; + } + + /** + * Gets the font size out of a size markup in the given string. + * A size markup is specified \\s[0-9]{1,3} + * @param str The string containing the size markup + * @return The font size to use for rendering + */ + public static int getSize(final String str) { + Pattern pattern = Pattern.compile("\\\\s[0-9]{1,3}"); + Matcher matcher = pattern.matcher(str); + if (matcher.find()) { + String sizeString = matcher.group(); + sizeString = sizeString.substring(2); + + try { + return Integer.parseInt(sizeString); + } catch (Exception badParse) { + SWT.error(SWT.ERROR_UNSPECIFIED, badParse); + } + } + + return -1; + } + + /** + * Gets the color for a color markup in the given string. + * A color markup is either \\ce for black or \\c[0-9]{9} + * to specify a custom color by rgb code + * @param str The string containing a color markup + * @return The Color that is specified by the color markup + */ + public static Color getColor(final String str) { + final int start = str.indexOf("\\c"); + if (start == -1) { + return null; + } + + if (str.indexOf("\\ce") != -1) { + return ColorCache.getBlack(); + } + + try { + final int red = Integer.parseInt(str.substring(start + 2, start + 5)); + final int green = Integer.parseInt(str.substring(start + 5, start + 8)); + final int blue = Integer.parseInt(str.substring(start + 8, start + 11)); + + return ColorCache.getColor(red, green, blue); + } catch (Exception err) { + SWT.error(SWT.ERROR_UNSPECIFIED, err); + } + + return ColorCache.getBlack(); + } +} diff --git a/widgets/geomap/org.eclipse.nebula.widgets.geomap.example/.classpath b/widgets/geomap/org.eclipse.nebula.widgets.geomap.example/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/geomap/org.eclipse.nebula.widgets.geomap.example/.classpath +++ b/widgets/geomap/org.eclipse.nebula.widgets.geomap.example/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/geomap/org.eclipse.nebula.widgets.geomap.example/.settings/org.eclipse.jdt.core.prefs b/widgets/geomap/org.eclipse.nebula.widgets.geomap.example/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/geomap/org.eclipse.nebula.widgets.geomap.example/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/geomap/org.eclipse.nebula.widgets.geomap.example/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/geomap/org.eclipse.nebula.widgets.geomap.snippets/.classpath b/widgets/geomap/org.eclipse.nebula.widgets.geomap.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/geomap/org.eclipse.nebula.widgets.geomap.snippets/.classpath +++ b/widgets/geomap/org.eclipse.nebula.widgets.geomap.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/geomap/org.eclipse.nebula.widgets.geomap.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/geomap/org.eclipse.nebula.widgets.geomap.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/geomap/org.eclipse.nebula.widgets.geomap.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/geomap/org.eclipse.nebula.widgets.geomap.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/geomap/org.eclipse.nebula.widgets.geomap.tests/.classpath b/widgets/geomap/org.eclipse.nebula.widgets.geomap.tests/.classpath index 8d0861da9..4846768a3 100644 --- a/widgets/geomap/org.eclipse.nebula.widgets.geomap.tests/.classpath +++ b/widgets/geomap/org.eclipse.nebula.widgets.geomap.tests/.classpath @@ -1,17 +1,17 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/widgets/geomap/org.eclipse.nebula.widgets.geomap.tests/.settings/org.eclipse.jdt.core.prefs b/widgets/geomap/org.eclipse.nebula.widgets.geomap.tests/.settings/org.eclipse.jdt.core.prefs index 45628c68c..e8c450c01 100644 --- a/widgets/geomap/org.eclipse.nebula.widgets.geomap.tests/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/geomap/org.eclipse.nebula.widgets.geomap.tests/.settings/org.eclipse.jdt.core.prefs @@ -1,11 +1,11 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/geomap/org.eclipse.nebula.widgets.geomap/.classpath b/widgets/geomap/org.eclipse.nebula.widgets.geomap/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/geomap/org.eclipse.nebula.widgets.geomap/.classpath +++ b/widgets/geomap/org.eclipse.nebula.widgets.geomap/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/geomap/org.eclipse.nebula.widgets.geomap/src/org/eclipse/nebula/widgets/geomap/GeoMap.java b/widgets/geomap/org.eclipse.nebula.widgets.geomap/src/org/eclipse/nebula/widgets/geomap/GeoMap.java index c3ec84433..c99f8c530 100644 --- a/widgets/geomap/org.eclipse.nebula.widgets.geomap/src/org/eclipse/nebula/widgets/geomap/GeoMap.java +++ b/widgets/geomap/org.eclipse.nebula.widgets.geomap/src/org/eclipse/nebula/widgets/geomap/GeoMap.java @@ -1,461 +1,461 @@ -/******************************************************************************* - * Copyright (c) 2008, 2012 Stepan Rutz. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Stepan Rutz - initial implementation - * Hallvard Trætteberg - further cleanup and development - *******************************************************************************/ - -package org.eclipse.nebula.widgets.geomap; - -import java.util.ArrayList; -import java.util.EventListener; -import java.util.List; - -import org.eclipse.nebula.widgets.geomap.internal.DefaultMouseHandler; -import org.eclipse.nebula.widgets.geomap.internal.GeoMapHelper; -import org.eclipse.nebula.widgets.geomap.internal.InternalGeoMap; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; - -/** - * GeoMap display tiles from openstreetmap as is. This simple minimal viewer - * supports zoom around mouse-click center and has a simple api. A number of - * tiles are cached. If you use this it will create traffic on the tileserver - * you are using. Please be conscious about this. - * - * This class is a JPanel which can be integrated into any swing app just by - * creating an instance and adding like a JLabel. - * - * The map has the size 256*1<. This measure is referred - * to as map-coordinates. Geometric locations like longitude and latitude can be - * obtained by helper methods. Note that a point in map-coordinates corresponds - * to a given geometric position but also depending on the current zoom level. - * - * You can zoomIn around current mouse position by left double click. Left right - * click zooms out. - * - *

- * Methods of interest are - *

    - *
  • {@link #setZoom(int)} which sets the map's zoom level. Values between 1 - * and 18 are allowed.
  • - *
  • {@link #setMapPosition(Point)} which sets the map's top left corner. (In - * map coordinates)
  • - *
  • {@link #setCenterPosition(Point)} which sets the map's center position. - * (In map coordinates)
  • for the given longitude and latitude. If you want - * to center the map around this geometric location you need to pass the result - * to the method - *
- *

- * - *

- * For performance tuning the two crucial parameters are the size of the tile - * cache and the number of image-loader threads. - *

- * - *

- * - *

- * License is EPL (Eclipse Public License) - * https://www.eclipse.org/legal/epl-2.0/. Contact at stepan.rutz@gmx.de - *

- * - * @author stepan.rutz - * @version $Revision$ - */ - -public class GeoMap extends InternalGeoMap { - - /** - * About message. - */ - @SuppressWarnings({ "nls" }) - public static final String ABOUT_MSG = "GeoMap - Minimal Openstreetmap/Maptile Viewer\r\n" - + "Requirements: Java + SWT. Opensource and licensed under EPL.\r\n" + "\r\n" - + "Web/Source: http://eclipse.org/nebula\r\n" - + "Written by Stephan Rutz. Maintained by the Eclipse Nebula Project.\r\n\r\n" - + "Tileserver and Nominationserver are accessed online and are part of Openstreetmap.org and not of this software.\r\n"; - - private Point mouseCoords = new Point(0, 0); - private DefaultMouseHandler defaultMouseHandler = new DefaultMouseHandler(this) { - @Override - public Point getMapSize() { - return getSize(); - } - }; - - private static final int DEFAULT_CACHE_SIZE = 256; - - /** - * Creates a new GeoMap using the default size for its internal - * cache of tiles. The map is showing the position (275091, 180145 - * at zoom level 11. In other words this constructor is best used - * only in debugging scenarios. - * - * @param parent - * SWT parent Composite - * @param style - * SWT style as in Canvas, since this class inherits - * from it. Double buffering is always enabed. - */ - public GeoMap(Composite parent, int style) { - this(parent, style, new Point(275091, 180145), 11); - } - - /** - * Creates a new GeoMap using the default size for its internal - * cache of tiles - * - * @param parent - * SWT parent Composite - * @param style - * SWT style as in Canvas, since this class inherits - * from it. Double buffering is always enabed. - * @param mapPosition - * initial mapPosition. - * @param zoom - * initial map zoom - */ - public GeoMap(Composite parent, int style, Point mapPosition, int zoom) { - this(parent, style, mapPosition, zoom, DEFAULT_CACHE_SIZE); - } - - private class MouseCoordsHandler implements MouseListener, MouseMoveListener { - - private void setMouseCoords(MouseEvent e) { - mouseCoords = new Point(e.x, e.y); - } - - @Override - public void mouseDown(MouseEvent e) { - setMouseCoords(e); - } - - @Override - public void mouseMove(MouseEvent e) { - setMouseCoords(e); - } - - @Override - public void mouseUp(MouseEvent e) { - setMouseCoords(e); - } - - @Override - public void mouseDoubleClick(MouseEvent e) { - setMouseCoords(e); - } - } - - /** - * Creates a new GeoMap using the default size for its internal - * cache of tiles - * - * @param parent - * SWT parent Composite - * @param style - * SWT style as in Canvas, since this class inherits - * from it. Double buffering is always enabed. - * @param mapPosition - * initial mapPosition. - * @param zoom - * initial map zoom - * @param cacheSize - * initial cache size, eg number of tile-images that are kept in - * cache to prevent reloading from the network. - */ - public GeoMap(Composite parent, int style, Point mapPosition, int zoom, int cacheSize) { - super(parent, style, mapPosition, zoom, cacheSize); - MouseCoordsHandler mouseCoordsHandler = new MouseCoordsHandler(); - addMouseListener(mouseCoordsHandler); - addMouseMoveListener(mouseCoordsHandler); - addMouseHandler(defaultMouseHandler); - } - - /** - * Returns the default mouse handler, so it may be configured or removed. - * - * @return the default mouse handler - */ - public DefaultMouseHandler getDefaultMouseHandler() { - return defaultMouseHandler; - } - - /** - * Adds listener to appropriate listener lists depending on the listener - * interfaces that are implemented. - * - * @param listener - * the listener - */ - public void addMouseHandler(EventListener listener) { - if (listener instanceof MouseListener) { - addMouseListener((MouseListener) listener); - } - if (listener instanceof MouseMoveListener) { - addMouseMoveListener((MouseMoveListener) listener); - } - if (listener instanceof MouseTrackListener) { - addMouseTrackListener((MouseTrackListener) listener); - } - if (listener instanceof MouseWheelListener) { - addMouseWheelListener((MouseWheelListener) listener); - } - if (listener instanceof PaintListener) { - addPaintListener((PaintListener) listener); - } - } - - /** - * Removes listener from appropriate listener lists depending on the listener - * interfaces that are implemented. - * - * @param listener - * the listener - */ - public void removeMouseHandler(EventListener listener) { - if (listener instanceof MouseListener) { - removeMouseListener((MouseListener) listener); - } - if (listener instanceof MouseMoveListener) { - removeMouseMoveListener((MouseMoveListener) listener); - } - if (listener instanceof MouseTrackListener) { - removeMouseTrackListener((MouseTrackListener) listener); - } - if (listener instanceof MouseWheelListener) { - removeMouseWheelListener((MouseWheelListener) listener); - } - if (listener instanceof PaintListener) { - removePaintListener((PaintListener) listener); - } - } - - // - - /** - * Returns the current TileServer of this GeoMap. - * - * @return the current TileServer - */ - public TileServer getTileServer() { - return geoMapHelper.getTileServer(); - } - - /** - * Sets the current TileServer of this GeoMap. Note that this will clear the map - * and reload the tiles using the new TileServer. - * - * @param tileServer - * the TileServer - */ - public void setTileServer(TileServer tileServer) { - geoMapHelper.setTileServer(tileServer); - } - - // - - private List geoMapListeners; - - /** - * Adds a GeoMapListener, that will be notified of changes to the position and - * zoom level - * - * @param listener - * the GeoMapListener - */ - public void addGeoMapListener(GeoMapListener listener) { - if (geoMapListeners == null) { - geoMapListeners = new ArrayList<>(); - } - geoMapListeners.add(listener); - } - - /** - * Removes a GeoMapListener, so it no longer will be notified of changes to the - * position and zoom level - * - * @param listener - * the GeoMapListener - */ - public void removeGeoMapListener(GeoMapListener listener) { - if (geoMapListeners != null) { - geoMapListeners.remove(listener); - } - } - - private void fireCenterChanged() { - if (geoMapListeners != null) { - for (GeoMapListener listener : geoMapListeners) { - listener.centerChanged(this); - } - } - } - - private void fireZoomChanged() { - if (geoMapListeners != null) { - for (GeoMapListener listener : geoMapListeners) { - listener.zoomChanged(this); - } - } - } - - // - - /** - * Sets the position of the upper left corner of this GeoMap, without any - * panning effect. - * - * @param mapPosition - * the new position - */ - public void setMapPosition(Point mapPosition) { - setMapPosition(mapPosition.x, mapPosition.y); - } - - /** - * Sets the position of the upper left corner of this GeoMap, without any - * panning effect. - * - * @param x - * the x-coordinate of the position - * @param y - * the y-coordinate of the position - */ - @Override - public void setMapPosition(int x, int y) { - super.setMapPosition(x, y); - fireCenterChanged(); - } - - /** - * Translates the position of the upper left corner of this GeoMap, without any - * panning effect. - * - * @param tx - * the relative distance in x-direction - * @param ty - * the relative distance in y-direction - */ - public void translateMapPosition(int tx, int ty) { - GeoMapUtil.translateMapPosition(this, tx, ty); - } - - /** - * Sets the zoom level, without any transition effect. - * - * @param zoom - * the new zoom level - */ - @Override - public void setZoom(int zoom) { - super.setZoom(zoom); - fireZoomChanged(); - } - - /** - * Zooms in, while ensuring that the pivot point remains at the same screen - * location. - * - * @param pivot - * the point that will remain at the same screen location. - */ - public void zoomIn(Point pivot) { - GeoMapUtil.zoomIn(this, pivot); - redraw(); - } - - /** - * Zooms out, while ensuring that the pivot point remains at the same screen - * location. - * - * @param pivot - * the point that will remain at the same screen location. - */ - public void zoomOut(Point pivot) { - GeoMapUtil.zoomOut(this, pivot); - redraw(); - } - - /** - * Zooms into and centers on the specified rectangle. - * - * @param rect - * the rectangle - */ - public void zoomTo(Rectangle rect) { - GeoMapUtil.zoomTo(this, getSize(), rect, -1); - redraw(); - } - - /** - * Returns the position of the center of this GeoMap. The coordinates depend on - * the zoom level. - * - * @return the position of the center of this GeoMap - */ - public Point getCenterPosition() { - org.eclipse.swt.graphics.Point size = getSize(); - Point mapPosition = getMapPosition(); - return new Point(mapPosition.x + size.x / 2, mapPosition.y + size.y / 2); - } - - /** - * Sets the position of the center of this GeoMap, without any panning effect. - * - * @param mapPosition - * the new position - */ - public void setCenterPosition(Point mapPosition) { - org.eclipse.swt.graphics.Point size = getSize(); - setMapPosition(mapPosition.x - size.x / 2, mapPosition.y - size.y / 2); - } - - /** - * Returns the map position of the mouse cursor. - * - * @return the map position of the mouse cursor - */ - public Point getCursorPosition() { - Point mapPosition = getMapPosition(); - return new Point(mapPosition.x + mouseCoords.x, // - mapPosition.y + mouseCoords.y); - } - - public Point computeSize(int wHint, int hHint, boolean changed) { - int widthHint, heightHint; - if (wHint == SWT.DEFAULT) { - widthHint = GeoMapHelper.TILE_SIZE * 3; // Arbitrary size - } else { - widthHint = wHint; - } - if (hHint == SWT.DEFAULT) { - heightHint = GeoMapHelper.TILE_SIZE * 3; // Arbitrary size - } else { - heightHint = hHint; - } - - return super.computeSize(widthHint, heightHint, changed); - } - - public Point computeSize(int wHint, int hHint) { - return computeSize(wHint, hHint, true); - } - -} +/******************************************************************************* + * Copyright (c) 2008, 2012 Stepan Rutz. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Stepan Rutz - initial implementation + * Hallvard Trætteberg - further cleanup and development + *******************************************************************************/ + +package org.eclipse.nebula.widgets.geomap; + +import java.util.ArrayList; +import java.util.EventListener; +import java.util.List; + +import org.eclipse.nebula.widgets.geomap.internal.DefaultMouseHandler; +import org.eclipse.nebula.widgets.geomap.internal.GeoMapHelper; +import org.eclipse.nebula.widgets.geomap.internal.InternalGeoMap; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + +/** + * GeoMap display tiles from openstreetmap as is. This simple minimal viewer + * supports zoom around mouse-click center and has a simple api. A number of + * tiles are cached. If you use this it will create traffic on the tileserver + * you are using. Please be conscious about this. + * + * This class is a JPanel which can be integrated into any swing app just by + * creating an instance and adding like a JLabel. + * + * The map has the size 256*1<. This measure is referred + * to as map-coordinates. Geometric locations like longitude and latitude can be + * obtained by helper methods. Note that a point in map-coordinates corresponds + * to a given geometric position but also depending on the current zoom level. + * + * You can zoomIn around current mouse position by left double click. Left right + * click zooms out. + * + *

+ * Methods of interest are + *

    + *
  • {@link #setZoom(int)} which sets the map's zoom level. Values between 1 + * and 18 are allowed.
  • + *
  • {@link #setMapPosition(Point)} which sets the map's top left corner. (In + * map coordinates)
  • + *
  • {@link #setCenterPosition(Point)} which sets the map's center position. + * (In map coordinates)
  • for the given longitude and latitude. If you want + * to center the map around this geometric location you need to pass the result + * to the method + *
+ *

+ * + *

+ * For performance tuning the two crucial parameters are the size of the tile + * cache and the number of image-loader threads. + *

+ * + *

+ * + *

+ * License is EPL (Eclipse Public License) + * https://www.eclipse.org/legal/epl-2.0/. Contact at stepan.rutz@gmx.de + *

+ * + * @author stepan.rutz + * @version $Revision$ + */ + +public class GeoMap extends InternalGeoMap { + + /** + * About message. + */ + @SuppressWarnings({ "nls" }) + public static final String ABOUT_MSG = "GeoMap - Minimal Openstreetmap/Maptile Viewer\r\n" + + "Requirements: Java + SWT. Opensource and licensed under EPL.\r\n" + "\r\n" + + "Web/Source: http://eclipse.org/nebula\r\n" + + "Written by Stephan Rutz. Maintained by the Eclipse Nebula Project.\r\n\r\n" + + "Tileserver and Nominationserver are accessed online and are part of Openstreetmap.org and not of this software.\r\n"; + + private Point mouseCoords = new Point(0, 0); + private DefaultMouseHandler defaultMouseHandler = new DefaultMouseHandler(this) { + @Override + public Point getMapSize() { + return getSize(); + } + }; + + private static final int DEFAULT_CACHE_SIZE = 256; + + /** + * Creates a new GeoMap using the default size for its internal + * cache of tiles. The map is showing the position (275091, 180145 + * at zoom level 11. In other words this constructor is best used + * only in debugging scenarios. + * + * @param parent + * SWT parent Composite + * @param style + * SWT style as in Canvas, since this class inherits + * from it. Double buffering is always enabed. + */ + public GeoMap(Composite parent, int style) { + this(parent, style, new Point(275091, 180145), 11); + } + + /** + * Creates a new GeoMap using the default size for its internal + * cache of tiles + * + * @param parent + * SWT parent Composite + * @param style + * SWT style as in Canvas, since this class inherits + * from it. Double buffering is always enabed. + * @param mapPosition + * initial mapPosition. + * @param zoom + * initial map zoom + */ + public GeoMap(Composite parent, int style, Point mapPosition, int zoom) { + this(parent, style, mapPosition, zoom, DEFAULT_CACHE_SIZE); + } + + private class MouseCoordsHandler implements MouseListener, MouseMoveListener { + + private void setMouseCoords(MouseEvent e) { + mouseCoords = new Point(e.x, e.y); + } + + @Override + public void mouseDown(MouseEvent e) { + setMouseCoords(e); + } + + @Override + public void mouseMove(MouseEvent e) { + setMouseCoords(e); + } + + @Override + public void mouseUp(MouseEvent e) { + setMouseCoords(e); + } + + @Override + public void mouseDoubleClick(MouseEvent e) { + setMouseCoords(e); + } + } + + /** + * Creates a new GeoMap using the default size for its internal + * cache of tiles + * + * @param parent + * SWT parent Composite + * @param style + * SWT style as in Canvas, since this class inherits + * from it. Double buffering is always enabed. + * @param mapPosition + * initial mapPosition. + * @param zoom + * initial map zoom + * @param cacheSize + * initial cache size, eg number of tile-images that are kept in + * cache to prevent reloading from the network. + */ + public GeoMap(Composite parent, int style, Point mapPosition, int zoom, int cacheSize) { + super(parent, style, mapPosition, zoom, cacheSize); + MouseCoordsHandler mouseCoordsHandler = new MouseCoordsHandler(); + addMouseListener(mouseCoordsHandler); + addMouseMoveListener(mouseCoordsHandler); + addMouseHandler(defaultMouseHandler); + } + + /** + * Returns the default mouse handler, so it may be configured or removed. + * + * @return the default mouse handler + */ + public DefaultMouseHandler getDefaultMouseHandler() { + return defaultMouseHandler; + } + + /** + * Adds listener to appropriate listener lists depending on the listener + * interfaces that are implemented. + * + * @param listener + * the listener + */ + public void addMouseHandler(EventListener listener) { + if (listener instanceof MouseListener) { + addMouseListener((MouseListener) listener); + } + if (listener instanceof MouseMoveListener) { + addMouseMoveListener((MouseMoveListener) listener); + } + if (listener instanceof MouseTrackListener) { + addMouseTrackListener((MouseTrackListener) listener); + } + if (listener instanceof MouseWheelListener) { + addMouseWheelListener((MouseWheelListener) listener); + } + if (listener instanceof PaintListener) { + addPaintListener((PaintListener) listener); + } + } + + /** + * Removes listener from appropriate listener lists depending on the listener + * interfaces that are implemented. + * + * @param listener + * the listener + */ + public void removeMouseHandler(EventListener listener) { + if (listener instanceof MouseListener) { + removeMouseListener((MouseListener) listener); + } + if (listener instanceof MouseMoveListener) { + removeMouseMoveListener((MouseMoveListener) listener); + } + if (listener instanceof MouseTrackListener) { + removeMouseTrackListener((MouseTrackListener) listener); + } + if (listener instanceof MouseWheelListener) { + removeMouseWheelListener((MouseWheelListener) listener); + } + if (listener instanceof PaintListener) { + removePaintListener((PaintListener) listener); + } + } + + // + + /** + * Returns the current TileServer of this GeoMap. + * + * @return the current TileServer + */ + public TileServer getTileServer() { + return geoMapHelper.getTileServer(); + } + + /** + * Sets the current TileServer of this GeoMap. Note that this will clear the map + * and reload the tiles using the new TileServer. + * + * @param tileServer + * the TileServer + */ + public void setTileServer(TileServer tileServer) { + geoMapHelper.setTileServer(tileServer); + } + + // + + private List geoMapListeners; + + /** + * Adds a GeoMapListener, that will be notified of changes to the position and + * zoom level + * + * @param listener + * the GeoMapListener + */ + public void addGeoMapListener(GeoMapListener listener) { + if (geoMapListeners == null) { + geoMapListeners = new ArrayList<>(); + } + geoMapListeners.add(listener); + } + + /** + * Removes a GeoMapListener, so it no longer will be notified of changes to the + * position and zoom level + * + * @param listener + * the GeoMapListener + */ + public void removeGeoMapListener(GeoMapListener listener) { + if (geoMapListeners != null) { + geoMapListeners.remove(listener); + } + } + + private void fireCenterChanged() { + if (geoMapListeners != null) { + for (GeoMapListener listener : geoMapListeners) { + listener.centerChanged(this); + } + } + } + + private void fireZoomChanged() { + if (geoMapListeners != null) { + for (GeoMapListener listener : geoMapListeners) { + listener.zoomChanged(this); + } + } + } + + // + + /** + * Sets the position of the upper left corner of this GeoMap, without any + * panning effect. + * + * @param mapPosition + * the new position + */ + public void setMapPosition(Point mapPosition) { + setMapPosition(mapPosition.x, mapPosition.y); + } + + /** + * Sets the position of the upper left corner of this GeoMap, without any + * panning effect. + * + * @param x + * the x-coordinate of the position + * @param y + * the y-coordinate of the position + */ + @Override + public void setMapPosition(int x, int y) { + super.setMapPosition(x, y); + fireCenterChanged(); + } + + /** + * Translates the position of the upper left corner of this GeoMap, without any + * panning effect. + * + * @param tx + * the relative distance in x-direction + * @param ty + * the relative distance in y-direction + */ + public void translateMapPosition(int tx, int ty) { + GeoMapUtil.translateMapPosition(this, tx, ty); + } + + /** + * Sets the zoom level, without any transition effect. + * + * @param zoom + * the new zoom level + */ + @Override + public void setZoom(int zoom) { + super.setZoom(zoom); + fireZoomChanged(); + } + + /** + * Zooms in, while ensuring that the pivot point remains at the same screen + * location. + * + * @param pivot + * the point that will remain at the same screen location. + */ + public void zoomIn(Point pivot) { + GeoMapUtil.zoomIn(this, pivot); + redraw(); + } + + /** + * Zooms out, while ensuring that the pivot point remains at the same screen + * location. + * + * @param pivot + * the point that will remain at the same screen location. + */ + public void zoomOut(Point pivot) { + GeoMapUtil.zoomOut(this, pivot); + redraw(); + } + + /** + * Zooms into and centers on the specified rectangle. + * + * @param rect + * the rectangle + */ + public void zoomTo(Rectangle rect) { + GeoMapUtil.zoomTo(this, getSize(), rect, -1); + redraw(); + } + + /** + * Returns the position of the center of this GeoMap. The coordinates depend on + * the zoom level. + * + * @return the position of the center of this GeoMap + */ + public Point getCenterPosition() { + org.eclipse.swt.graphics.Point size = getSize(); + Point mapPosition = getMapPosition(); + return new Point(mapPosition.x + size.x / 2, mapPosition.y + size.y / 2); + } + + /** + * Sets the position of the center of this GeoMap, without any panning effect. + * + * @param mapPosition + * the new position + */ + public void setCenterPosition(Point mapPosition) { + org.eclipse.swt.graphics.Point size = getSize(); + setMapPosition(mapPosition.x - size.x / 2, mapPosition.y - size.y / 2); + } + + /** + * Returns the map position of the mouse cursor. + * + * @return the map position of the mouse cursor + */ + public Point getCursorPosition() { + Point mapPosition = getMapPosition(); + return new Point(mapPosition.x + mouseCoords.x, // + mapPosition.y + mouseCoords.y); + } + + public Point computeSize(int wHint, int hHint, boolean changed) { + int widthHint, heightHint; + if (wHint == SWT.DEFAULT) { + widthHint = GeoMapHelper.TILE_SIZE * 3; // Arbitrary size + } else { + widthHint = wHint; + } + if (hHint == SWT.DEFAULT) { + heightHint = GeoMapHelper.TILE_SIZE * 3; // Arbitrary size + } else { + heightHint = hHint; + } + + return super.computeSize(widthHint, heightHint, changed); + } + + public Point computeSize(int wHint, int hHint) { + return computeSize(wHint, hHint, true); + } + +} diff --git a/widgets/geomap/org.eclipse.nebula.widgets.geomap/src/org/eclipse/nebula/widgets/geomap/internal/GeoMapHelper.java b/widgets/geomap/org.eclipse.nebula.widgets.geomap/src/org/eclipse/nebula/widgets/geomap/internal/GeoMapHelper.java index 251597383..8ff694d65 100644 --- a/widgets/geomap/org.eclipse.nebula.widgets.geomap/src/org/eclipse/nebula/widgets/geomap/internal/GeoMapHelper.java +++ b/widgets/geomap/org.eclipse.nebula.widgets.geomap/src/org/eclipse/nebula/widgets/geomap/internal/GeoMapHelper.java @@ -1,399 +1,399 @@ -/******************************************************************************* - * Copyright (c) 2008, 2012 Stepan Rutz. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Stepan Rutz - initial implementation - * Hallvard Trætteberg - further cleanup and development - *******************************************************************************/ - -package org.eclipse.nebula.widgets.geomap.internal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -import org.eclipse.nebula.widgets.geomap.OsmTileServer; -import org.eclipse.nebula.widgets.geomap.TileServer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -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.Display; - -/** - *

- * License is EPL (Eclipse Public License) - * http://www.eclipse.org/legal/epl-v10.html. Contact at stepan.rutz@gmx.de - *

- * - * @author stepan.rutz, hal - * @version $Revision$ - */ -public class GeoMapHelper implements GeoMapPositioned, GeoMapHelperListener { - - private final Display display; - - /** - * Initializes a new GeoMapHelper with a specific display. The - * display is used for async runnables and as device for images. - * - * @param display - * the display - */ - private GeoMapHelper(Display display) { - super(); - this.display = display; - } - - Display getDisplay() { - return display; - } - - /** - * basically not be changed, must be the same as GeoMapUtil's TILE_SIZE - */ - public static final int TILE_SIZE = 256; - - private static final int DEFAULT_NUMBER_OF_IMAGEFETCHER_THREADS = 4; - - private static final int MIN_CACHE_SIZE = 200; - - private Point mapSize = new Point(0, 0); - private Point mapPosition = new Point(0, 0); - private int zoom; - - AtomicLong zoomStamp = new AtomicLong(); - - private TileServer tileServer = OsmTileServer.TILESERVERS[0]; - private int cacheSize; - // must be readable from AsyncImage - Map cache; - - private BlockingQueue workQueue = new LinkedBlockingQueue<>(); - - private ThreadFactory threadFactory = r -> { - Thread thread = new Thread(r); - thread.setName("Async Image Loader " + thread.getId() + " " //$NON-NLS-1$ //$NON-NLS-2$ - + System.identityHashCode(thread)); - thread.setDaemon(true); - return thread; - }; - ThreadPoolExecutor executor = new ThreadPoolExecutor(DEFAULT_NUMBER_OF_IMAGEFETCHER_THREADS, 16, 2, - TimeUnit.SECONDS, workQueue, threadFactory); - private Color waitBackground, waitForeground; - - /** - * Initializes a new GeoMapHelper for a specific display, position, - * zoom level and cache size. - * - * @param display - * the Display to create images for. - * @param mapPosition - * initial mapPosition. - * @param zoom - * initial map zoom - * @param cacheSize - * initial cache size, eg number of tile-images that are kept in - * cache to prevent reloading from the network. - */ - @SuppressWarnings("serial") - public GeoMapHelper(Display display, Point mapPosition, int zoom, int cacheSize) { - this(display); - if (cacheSize < MIN_CACHE_SIZE) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, " - Cache size should be greater than " + MIN_CACHE_SIZE); //$NON-NLS-1$ - } - this.cacheSize = cacheSize; - this.cache = Collections.synchronizedMap(new LinkedHashMap(cacheSize, 0.75f, true) { - @Override - protected boolean removeEldestEntry(Map.Entry eldest) { - boolean remove = size() > GeoMapHelper.this.cacheSize; - if (remove) { - eldest.getValue().dispose(); - } - return remove; - } - - @Override - public void clear() { - for (AsyncImage image : values()) { - image.dispose(); - } - super.clear(); - } - }); - waitBackground = new Color(display, 0x88, 0x88, 0x88); - waitForeground = new Color(display, 0x77, 0x77, 0x77); - - setZoom(zoom); - setMapPosition(mapPosition.x, mapPosition.y); - } - - /** - * Points the map to the provided graphics context (GC), which could be the one - * provided in an SWT control paint request or one created for rendering an SWT - * Image - * - * @param gc - * the graphics context - * @param clip - * the area that needs updating, could be null - * @param size - * the size of the map area - */ - public void paint(GC gc, Rectangle clip, Point size) { - - long startTime = System.currentTimeMillis(); - int tileCount = 0; - - int x0 = (int) Math.floor((double) mapPosition.x / TILE_SIZE); - int y0 = (int) Math.floor((double) mapPosition.y / TILE_SIZE); - int x1 = (int) Math.ceil(((double) mapPosition.x + size.x) / TILE_SIZE); - int y1 = (int) Math.ceil(((double) mapPosition.y + size.y) / TILE_SIZE); - - int dy = y0 * TILE_SIZE - mapPosition.y; - for (int y = y0; y < y1; y++) { - int dx = x0 * TILE_SIZE - mapPosition.x; - for (int x = x0; x < x1; x++) { - if (clip == null || dx + TILE_SIZE >= clip.x && dy + TILE_SIZE >= clip.y && dx <= clip.x + clip.width - && dy <= clip.y + clip.height) { - paintTile(gc, dx, dy, x, y); - } - dx += TILE_SIZE; - tileCount++; - } - dy += TILE_SIZE; - } - - long endTime = System.currentTimeMillis(); - for (InternalGeoMapListener listener : internalGeoMapListeners) { - listener.mapPainted(tileCount, endTime - startTime); - } - for (InternalGeoMapListener listener : internalGeoMapListeners) { - listener.tileCacheUpdated(cache.size(), this.cacheSize); - } - } - - void paintTile(GC gc, int dx, int dy, int x, int y) { - boolean DRAW_IMAGES = true; - boolean DEBUG = false; - boolean DRAW_OUT_OF_BOUNDS = !false; - - boolean imageDrawn = false; - int xTileCount = 1 << zoom; - int yTileCount = 1 << zoom; - boolean tileInBounds = x >= 0 && x < xTileCount && y >= 0 && y < yTileCount; - boolean drawImage = DRAW_IMAGES && tileInBounds; - if (drawImage) { - TileRef tileRef = new TileRef(x, y, zoom); - AsyncImage image = cache.get(tileRef); - if (image == null) { - image = new AsyncImage(this, tileRef, tileServer.getTileURL(tileRef)); - cache.put(tileRef, image); - } - Image swtImage = image.getImage(getDisplay()); - if (swtImage != null) { - gc.drawImage(swtImage, dx, dy); - imageDrawn = true; - } else { - // reuse tile from lower zoom level, i.e. half the resolution - tileRef = new TileRef(x / 2, y / 2, zoom - 1); - image = cache.get(tileRef); - if (image != null) { - swtImage = image.getImage(getDisplay()); - if (swtImage != null) { - gc.drawImage(swtImage, x % 2 == 0 ? 0 : TILE_SIZE / 2, y % 2 == 0 ? 0 : TILE_SIZE / 2, - TILE_SIZE / 2, TILE_SIZE / 2, dx, dy, TILE_SIZE, TILE_SIZE); - imageDrawn = true; - } - } - } - for (InternalGeoMapListener listener : internalGeoMapListeners) { - listener.tilePainted(tileRef); - } - } - if (DEBUG && !imageDrawn && (tileInBounds || DRAW_OUT_OF_BOUNDS)) { - gc.setBackground(display.getSystemColor(tileInBounds ? SWT.COLOR_GREEN : SWT.COLOR_RED)); - gc.fillRectangle(dx + 4, dy + 4, TILE_SIZE - 8, TILE_SIZE - 8); - gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); - String s = "T " + x + ", " + y + (!tileInBounds ? " #" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - gc.drawString(s, dx + 4 + 8, dy + 4 + 12); - } else if (!DEBUG && !imageDrawn && tileInBounds) { - gc.setBackground(waitBackground); - gc.fillRectangle(dx, dy, TILE_SIZE, TILE_SIZE); - gc.setForeground(waitForeground); - for (int yl = 0; yl < TILE_SIZE; yl += 32) { - gc.drawLine(dx, dy + yl, dx + TILE_SIZE, dy + yl); - } - for (int xl = 0; xl < TILE_SIZE; xl += 32) { - gc.drawLine(dx + xl, dy, dx + xl, dy + TILE_SIZE); - } - } - } - - /** - * Dispose internal data - */ - public void dispose() { - waitBackground.dispose(); - waitForeground.dispose(); - cache.clear(); - } - - // - - /** - * Gets the tile server used for fetching tiles - * - * @return the tile server - */ - public TileServer getTileServer() { - return tileServer; - } - - /** - * Sets the tile server used for fetching tiles - * - * @param tileServer - * the new tile server to use - */ - public void setTileServer(TileServer tileServer) { - this.tileServer = tileServer; - cache.clear(); - } - - // - - /** - * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#getMapPosition() - */ - @Override - public Point getMapPosition() { - return new Point(mapPosition.x, mapPosition.y); - } - - /** - * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#setMapPosition(int, - * int) - */ - @Override - public void setMapPosition(int x, int y) { - mapPosition.x = x; - mapPosition.y = y; - } - - /** - * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#getMinZoom() - */ - @Override - public int getMinZoom() { - return getTileServer().getMinZoom(); - } - - /** - * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#getMaxZoom() - */ - @Override - public int getMaxZoom() { - return getTileServer().getMaxZoom(); - } - - /** - * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#getZoom() - */ - @Override - public int getZoom() { - return zoom; - } - - /** - * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#setZoom(int) - */ - @Override - public void setZoom(int zoom) { - zoomStamp.incrementAndGet(); - this.zoom = Math.min(tileServer.getMaxZoom(), zoom); - int size = TILE_SIZE * (1 << zoom); - mapSize.x = size; - mapSize.y = size; - } - - // - - private List geoMapHelperListeners = new ArrayList<>(); - - @Override - public void tileUpdated(TileRef tileRef) { - for (GeoMapHelperListener listener : geoMapHelperListeners) { - listener.tileUpdated(tileRef); - } - } - - /** - * Adds a GeoMapHelperListener that will be notified about tile updates - * - * @param listener - * the GeoMapHelperListener - */ - public void addGeoMapHelperListener(GeoMapHelperListener listener) { - geoMapHelperListeners.add(listener); - } - - /** - * Removes a GeoMapHelperListener - * - * @param listener - * the GeoMapHelperListener - */ - public void removeGeoMapHelperListener(GeoMapHelperListener listener) { - geoMapHelperListeners.remove(listener); - } - - // - - private List internalGeoMapListeners = new ArrayList<>(); - - /** - * Adds an InternalGeoMapListener that will be notified about painting and cache - * updates - * - * @param listener - * the InternalGeoMapListener - */ - public void addInternalGeoMapListener(InternalGeoMapListener listener) { - internalGeoMapListeners.add(listener); - } - - /** - * Removes an InternalGeoMapListener - * - * @param listener - * the InternalGeoMapListener - */ - public void removeInternalGeoMapListener(InternalGeoMapListener listener) { - internalGeoMapListeners.remove(listener); - } - - /** - * @return the number of tiles - */ - public int getNumberOfTiles() { - return Math.max(cache.size(), cacheSize); - } -} +/******************************************************************************* + * Copyright (c) 2008, 2012 Stepan Rutz. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Stepan Rutz - initial implementation + * Hallvard Trætteberg - further cleanup and development + *******************************************************************************/ + +package org.eclipse.nebula.widgets.geomap.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import org.eclipse.nebula.widgets.geomap.OsmTileServer; +import org.eclipse.nebula.widgets.geomap.TileServer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +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.Display; + +/** + *

+ * License is EPL (Eclipse Public License) + * http://www.eclipse.org/legal/epl-v10.html. Contact at stepan.rutz@gmx.de + *

+ * + * @author stepan.rutz, hal + * @version $Revision$ + */ +public class GeoMapHelper implements GeoMapPositioned, GeoMapHelperListener { + + private final Display display; + + /** + * Initializes a new GeoMapHelper with a specific display. The + * display is used for async runnables and as device for images. + * + * @param display + * the display + */ + private GeoMapHelper(Display display) { + super(); + this.display = display; + } + + Display getDisplay() { + return display; + } + + /** + * basically not be changed, must be the same as GeoMapUtil's TILE_SIZE + */ + public static final int TILE_SIZE = 256; + + private static final int DEFAULT_NUMBER_OF_IMAGEFETCHER_THREADS = 4; + + private static final int MIN_CACHE_SIZE = 200; + + private Point mapSize = new Point(0, 0); + private Point mapPosition = new Point(0, 0); + private int zoom; + + AtomicLong zoomStamp = new AtomicLong(); + + private TileServer tileServer = OsmTileServer.TILESERVERS[0]; + private int cacheSize; + // must be readable from AsyncImage + Map cache; + + private BlockingQueue workQueue = new LinkedBlockingQueue<>(); + + private ThreadFactory threadFactory = r -> { + Thread thread = new Thread(r); + thread.setName("Async Image Loader " + thread.getId() + " " //$NON-NLS-1$ //$NON-NLS-2$ + + System.identityHashCode(thread)); + thread.setDaemon(true); + return thread; + }; + ThreadPoolExecutor executor = new ThreadPoolExecutor(DEFAULT_NUMBER_OF_IMAGEFETCHER_THREADS, 16, 2, + TimeUnit.SECONDS, workQueue, threadFactory); + private Color waitBackground, waitForeground; + + /** + * Initializes a new GeoMapHelper for a specific display, position, + * zoom level and cache size. + * + * @param display + * the Display to create images for. + * @param mapPosition + * initial mapPosition. + * @param zoom + * initial map zoom + * @param cacheSize + * initial cache size, eg number of tile-images that are kept in + * cache to prevent reloading from the network. + */ + @SuppressWarnings("serial") + public GeoMapHelper(Display display, Point mapPosition, int zoom, int cacheSize) { + this(display); + if (cacheSize < MIN_CACHE_SIZE) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, " - Cache size should be greater than " + MIN_CACHE_SIZE); //$NON-NLS-1$ + } + this.cacheSize = cacheSize; + this.cache = Collections.synchronizedMap(new LinkedHashMap(cacheSize, 0.75f, true) { + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + boolean remove = size() > GeoMapHelper.this.cacheSize; + if (remove) { + eldest.getValue().dispose(); + } + return remove; + } + + @Override + public void clear() { + for (AsyncImage image : values()) { + image.dispose(); + } + super.clear(); + } + }); + waitBackground = new Color(display, 0x88, 0x88, 0x88); + waitForeground = new Color(display, 0x77, 0x77, 0x77); + + setZoom(zoom); + setMapPosition(mapPosition.x, mapPosition.y); + } + + /** + * Points the map to the provided graphics context (GC), which could be the one + * provided in an SWT control paint request or one created for rendering an SWT + * Image + * + * @param gc + * the graphics context + * @param clip + * the area that needs updating, could be null + * @param size + * the size of the map area + */ + public void paint(GC gc, Rectangle clip, Point size) { + + long startTime = System.currentTimeMillis(); + int tileCount = 0; + + int x0 = (int) Math.floor((double) mapPosition.x / TILE_SIZE); + int y0 = (int) Math.floor((double) mapPosition.y / TILE_SIZE); + int x1 = (int) Math.ceil(((double) mapPosition.x + size.x) / TILE_SIZE); + int y1 = (int) Math.ceil(((double) mapPosition.y + size.y) / TILE_SIZE); + + int dy = y0 * TILE_SIZE - mapPosition.y; + for (int y = y0; y < y1; y++) { + int dx = x0 * TILE_SIZE - mapPosition.x; + for (int x = x0; x < x1; x++) { + if (clip == null || dx + TILE_SIZE >= clip.x && dy + TILE_SIZE >= clip.y && dx <= clip.x + clip.width + && dy <= clip.y + clip.height) { + paintTile(gc, dx, dy, x, y); + } + dx += TILE_SIZE; + tileCount++; + } + dy += TILE_SIZE; + } + + long endTime = System.currentTimeMillis(); + for (InternalGeoMapListener listener : internalGeoMapListeners) { + listener.mapPainted(tileCount, endTime - startTime); + } + for (InternalGeoMapListener listener : internalGeoMapListeners) { + listener.tileCacheUpdated(cache.size(), this.cacheSize); + } + } + + void paintTile(GC gc, int dx, int dy, int x, int y) { + boolean DRAW_IMAGES = true; + boolean DEBUG = false; + boolean DRAW_OUT_OF_BOUNDS = !false; + + boolean imageDrawn = false; + int xTileCount = 1 << zoom; + int yTileCount = 1 << zoom; + boolean tileInBounds = x >= 0 && x < xTileCount && y >= 0 && y < yTileCount; + boolean drawImage = DRAW_IMAGES && tileInBounds; + if (drawImage) { + TileRef tileRef = new TileRef(x, y, zoom); + AsyncImage image = cache.get(tileRef); + if (image == null) { + image = new AsyncImage(this, tileRef, tileServer.getTileURL(tileRef)); + cache.put(tileRef, image); + } + Image swtImage = image.getImage(getDisplay()); + if (swtImage != null) { + gc.drawImage(swtImage, dx, dy); + imageDrawn = true; + } else { + // reuse tile from lower zoom level, i.e. half the resolution + tileRef = new TileRef(x / 2, y / 2, zoom - 1); + image = cache.get(tileRef); + if (image != null) { + swtImage = image.getImage(getDisplay()); + if (swtImage != null) { + gc.drawImage(swtImage, x % 2 == 0 ? 0 : TILE_SIZE / 2, y % 2 == 0 ? 0 : TILE_SIZE / 2, + TILE_SIZE / 2, TILE_SIZE / 2, dx, dy, TILE_SIZE, TILE_SIZE); + imageDrawn = true; + } + } + } + for (InternalGeoMapListener listener : internalGeoMapListeners) { + listener.tilePainted(tileRef); + } + } + if (DEBUG && !imageDrawn && (tileInBounds || DRAW_OUT_OF_BOUNDS)) { + gc.setBackground(display.getSystemColor(tileInBounds ? SWT.COLOR_GREEN : SWT.COLOR_RED)); + gc.fillRectangle(dx + 4, dy + 4, TILE_SIZE - 8, TILE_SIZE - 8); + gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); + String s = "T " + x + ", " + y + (!tileInBounds ? " #" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + gc.drawString(s, dx + 4 + 8, dy + 4 + 12); + } else if (!DEBUG && !imageDrawn && tileInBounds) { + gc.setBackground(waitBackground); + gc.fillRectangle(dx, dy, TILE_SIZE, TILE_SIZE); + gc.setForeground(waitForeground); + for (int yl = 0; yl < TILE_SIZE; yl += 32) { + gc.drawLine(dx, dy + yl, dx + TILE_SIZE, dy + yl); + } + for (int xl = 0; xl < TILE_SIZE; xl += 32) { + gc.drawLine(dx + xl, dy, dx + xl, dy + TILE_SIZE); + } + } + } + + /** + * Dispose internal data + */ + public void dispose() { + waitBackground.dispose(); + waitForeground.dispose(); + cache.clear(); + } + + // + + /** + * Gets the tile server used for fetching tiles + * + * @return the tile server + */ + public TileServer getTileServer() { + return tileServer; + } + + /** + * Sets the tile server used for fetching tiles + * + * @param tileServer + * the new tile server to use + */ + public void setTileServer(TileServer tileServer) { + this.tileServer = tileServer; + cache.clear(); + } + + // + + /** + * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#getMapPosition() + */ + @Override + public Point getMapPosition() { + return new Point(mapPosition.x, mapPosition.y); + } + + /** + * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#setMapPosition(int, + * int) + */ + @Override + public void setMapPosition(int x, int y) { + mapPosition.x = x; + mapPosition.y = y; + } + + /** + * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#getMinZoom() + */ + @Override + public int getMinZoom() { + return getTileServer().getMinZoom(); + } + + /** + * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#getMaxZoom() + */ + @Override + public int getMaxZoom() { + return getTileServer().getMaxZoom(); + } + + /** + * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#getZoom() + */ + @Override + public int getZoom() { + return zoom; + } + + /** + * @see org.eclipse.nebula.widgets.geomap.internal.GeoMapPositioned#setZoom(int) + */ + @Override + public void setZoom(int zoom) { + zoomStamp.incrementAndGet(); + this.zoom = Math.min(tileServer.getMaxZoom(), zoom); + int size = TILE_SIZE * (1 << zoom); + mapSize.x = size; + mapSize.y = size; + } + + // + + private List geoMapHelperListeners = new ArrayList<>(); + + @Override + public void tileUpdated(TileRef tileRef) { + for (GeoMapHelperListener listener : geoMapHelperListeners) { + listener.tileUpdated(tileRef); + } + } + + /** + * Adds a GeoMapHelperListener that will be notified about tile updates + * + * @param listener + * the GeoMapHelperListener + */ + public void addGeoMapHelperListener(GeoMapHelperListener listener) { + geoMapHelperListeners.add(listener); + } + + /** + * Removes a GeoMapHelperListener + * + * @param listener + * the GeoMapHelperListener + */ + public void removeGeoMapHelperListener(GeoMapHelperListener listener) { + geoMapHelperListeners.remove(listener); + } + + // + + private List internalGeoMapListeners = new ArrayList<>(); + + /** + * Adds an InternalGeoMapListener that will be notified about painting and cache + * updates + * + * @param listener + * the InternalGeoMapListener + */ + public void addInternalGeoMapListener(InternalGeoMapListener listener) { + internalGeoMapListeners.add(listener); + } + + /** + * Removes an InternalGeoMapListener + * + * @param listener + * the InternalGeoMapListener + */ + public void removeInternalGeoMapListener(InternalGeoMapListener listener) { + internalGeoMapListeners.remove(listener); + } + + /** + * @return the number of tiles + */ + public int getNumberOfTiles() { + return Math.max(cache.size(), cacheSize); + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/.project b/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/.project index e51d3aa09..585bb4b71 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/.project +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.grid.css.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.grid.css.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/feature.xml b/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/feature.xml index 6ccff87d4..7648cc34a 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/feature.xml +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/feature.xml @@ -1,34 +1,34 @@ - - - - - Grid CSS - - - - %license - - - - - - - - - - - + + + + + Grid CSS + + + + %license + + + + + + + + + + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/pom.xml b/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/pom.xml index d69d7a5e9..b61de6212 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/pom.xml +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - grid - 1.1.0-SNAPSHOT - - - org.eclipse.nebula.widgets.grid.css.feature - eclipse-feature - - Nebula Grid CSS Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + grid + 1.1.0-SNAPSHOT + + + org.eclipse.nebula.widgets.grid.css.feature + eclipse-feature + + Nebula Grid CSS Feature + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css/.classpath b/widgets/grid/org.eclipse.nebula.widgets.grid.css/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css/.classpath +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css/.project b/widgets/grid/org.eclipse.nebula.widgets.grid.css/.project index 5815863f6..6aa55fbd8 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css/.project +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.grid.css - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.grid.css + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css/.settings/org.eclipse.jdt.core.prefs b/widgets/grid/org.eclipse.nebula.widgets.grid.css/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css/META-INF/MANIFEST.MF b/widgets/grid/org.eclipse.nebula.widgets.grid.css/META-INF/MANIFEST.MF index 8cc3c56cd..86f8f717a 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css/META-INF/MANIFEST.MF +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Grid CSS -Bundle-SymbolicName: org.eclipse.nebula.widgets.grid.css;singleton:=true -Bundle-Version: 1.1.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.swt, - org.eclipse.e4.ui.services;bundle-version="0.10.0", - org.eclipse.e4.ui.css.core;bundle-version="0.10.0", - org.eclipse.e4.ui.css.swt;bundle-version="0.10.0", - org.eclipse.nebula.widgets.grid -Export-Package: org.eclipse.nebula.widgets.grid.css -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.widgets.grid.css +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Grid CSS +Bundle-SymbolicName: org.eclipse.nebula.widgets.grid.css;singleton:=true +Bundle-Version: 1.1.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.swt, + org.eclipse.e4.ui.services;bundle-version="0.10.0", + org.eclipse.e4.ui.css.core;bundle-version="0.10.0", + org.eclipse.e4.ui.css.swt;bundle-version="0.10.0", + org.eclipse.nebula.widgets.grid +Export-Package: org.eclipse.nebula.widgets.grid.css +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.widgets.grid.css diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css/build.properties b/widgets/grid/org.eclipse.nebula.widgets.grid.css/build.properties index 6f20375d6..e9863e281 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css/build.properties +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css/build.properties @@ -1,5 +1,5 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - plugin.xml +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css/plugin.xml b/widgets/grid/org.eclipse.nebula.widgets.grid.css/plugin.xml index bbae9155f..735c7ccec 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css/plugin.xml +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css/plugin.xml @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css/pom.xml b/widgets/grid/org.eclipse.nebula.widgets.grid.css/pom.xml index aed85099b..234c821e6 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css/pom.xml +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css/pom.xml @@ -1,29 +1,29 @@ - - - - 4.0.0 - - - org.eclipse.nebula - grid - 1.1.0-SNAPSHOT - - - org.eclipse.nebula.widgets.grid.css - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + grid + 1.1.0-SNAPSHOT + + + org.eclipse.nebula.widgets.grid.css + eclipse-plugin + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css/src/org/eclipse/nebula/widgets/grid/css/GridPropertyHandler.java b/widgets/grid/org.eclipse.nebula.widgets.grid.css/src/org/eclipse/nebula/widgets/grid/css/GridPropertyHandler.java index eb901e8e6..d466a3cc8 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css/src/org/eclipse/nebula/widgets/grid/css/GridPropertyHandler.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css/src/org/eclipse/nebula/widgets/grid/css/GridPropertyHandler.java @@ -1,284 +1,284 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent Caron. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent Caron - initial API and implementation - ******************************************************************************/ -package org.eclipse.nebula.widgets.grid.css; - -import org.eclipse.e4.ui.css.core.css2.CSS2FontHelper; -import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; -import org.eclipse.e4.ui.css.core.engine.CSSEngine; -import org.eclipse.e4.ui.css.core.impl.dom.Measure; -import org.eclipse.nebula.widgets.grid.Grid; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.Win7RendererSupport; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.w3c.dom.css.CSSPrimitiveValue; -import org.w3c.dom.css.CSSValue; -import org.w3c.dom.css.CSSValueList; - -@SuppressWarnings("restriction") -public class GridPropertyHandler implements ICSSPropertyHandler { - private static final String FOOTER = "footer"; - private static final String HEADER = "header"; - - /** - * @see org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler#applyCSSProperty(java.lang.Object, java.lang.String, org.w3c.dom.css.CSSValue, java.lang.String, org.eclipse.e4.ui.css.core.engine.CSSEngine) - */ - @Override - public boolean applyCSSProperty(final Object element, final String property, final CSSValue value, final String pseudo, final CSSEngine engine) throws Exception { - - final Grid grid = (Grid) ((GridElement) element).getNativeWidget(); - - // Theme - if ("grid-theme".equals(property)) { - if (value.getCssText() != null && value.getCssText().equals("win7")) { - Win7RendererSupport.create(grid).decorate(); - } - } - - // General - if ("grid-cell-header-selection-background-color".equals(property) && value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final Color newColor = (Color) engine.convert(value, Color.class, grid.getDisplay()); - grid.setCellHeaderSelectionBackground(newColor); - } - - if ("grid-header-visible".equals(property)) { - final boolean headerVisible = value == null ? false : Boolean.parseBoolean(value.getCssText()); - grid.setHeaderVisible(headerVisible); - } - - if ("grid-footer-visible".equals(property)) { - final boolean footerVisible = value == null ? false : Boolean.parseBoolean(value.getCssText()); - grid.setFooterVisible(footerVisible); - } - - // Items - if ("grid-item-height".equals(property)) { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final Measure m = (Measure) value; - final int width = Math.round(m.getFloatValue((short) 0)); - grid.setItemHeight(width); - } - } - - if ("grid-item-header-width".equals(property)) { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final Measure m = (Measure) value; - final int width = Math.round(m.getFloatValue((short) 0)); - grid.setItemHeaderWidth(width); - } - } - - // Lines - if ("grid-line-color".equals(property) && value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final Color newColor = (Color) engine.convert(value, Color.class, grid.getDisplay()); - grid.setLineColor(newColor); - } - - if ("grid-lines-visible".equals(property)) { - final boolean linesVisible = value == null ? false : Boolean.parseBoolean(value.getCssText()); - grid.setLinesVisible(linesVisible); - } - - if ("grid-tree-lines-visible".equals(property)) { - final boolean treeLinesVisible = value == null ? false : Boolean.parseBoolean(value.getCssText()); - grid.setTreeLinesVisible(treeLinesVisible); - } - - // Columns - if ("grid-columns-alignment".equals(property) && grid.getColumns() != null) { - final int alignment; - if ("left".equals(value.getCssText())) { - alignment = SWT.LEFT; - } else if ("right".equals(value.getCssText())) { - alignment = SWT.RIGHT; - } else if ("center".equals(value.getCssText())) { - alignment = SWT.CENTER; - } else { - alignment = SWT.NONE; - } - if (alignment == SWT.LEFT || alignment == SWT.CENTER || alignment == SWT.RIGHT) - for (GridColumn col : grid.getColumns()) { - col.setAlignment(alignment); - } - } - - if ("grid-columns-header-font".equals(property) && grid.getColumns() != null) { - applyCSSPropertyFont(element, grid, value, HEADER); - } - if ("grid-columns-header-font-style".equals(property) && grid.getColumns() != null) { - applyCSSPropertyStyle(element, grid, value, HEADER); - } - if ("grid-columns-header-font-size".equals(property) && grid.getColumns() != null) { - applyCSSPropertySize(element, grid, value, HEADER); - } - if ("grid-columns-header-font-weight".equals(property) && grid.getColumns() != null) { - applyCSSPropertyWeight(element, grid, value, HEADER); - } - if ("grid-columns-header-font-family".equals(property) && grid.getColumns() != null) { - applyCSSPropertyFamily(element, grid, value, HEADER); - } - - if ("grid-columns-footer-font".equals(property) && grid.getColumns() != null) { - applyCSSPropertyFont(element, grid, value, FOOTER); - } - if ("grid-columns-footer-font-style".equals(property) && grid.getColumns() != null) { - applyCSSPropertyStyle(element, grid, value, FOOTER); - } - if ("grid-columns-footer-font-size".equals(property) && grid.getColumns() != null) { - applyCSSPropertySize(element, grid, value, FOOTER); - } - if ("grid-columns-footer-font-weight".equals(property) && grid.getColumns() != null) { - applyCSSPropertyWeight(element, grid, value, FOOTER); - } - if ("grid-columns-footer-font-family".equals(property) && grid.getColumns() != null) { - applyCSSPropertyFamily(element, grid, value, FOOTER); - } - - return true; - } - - private void applyCSSPropertyFont(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { - final CSSValueList valueList = (CSSValueList) value; - final int length = valueList.getLength(); - for (int i = 0; i < length; i++) { - final CSSValue value2 = valueList.item(i); - if (value2.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final String cssProp = CSS2FontHelper.getCSSFontPropertyName((CSSPrimitiveValue) value2); - if (cssProp.equals("font-family")) { - applyCSSPropertyFamily(element, grid, value2, target); - } else if (cssProp.equals("font-size")) { - applyCSSPropertySize(element, grid, value2, target); - } else if (cssProp.equals("font-weight") && ("bold".equals(value2.getCssText()) || "bolder".equals(value2.getCssText()))) { - applyCSSPropertyWeight(element, grid, value2, target); - } else if (cssProp.equals("font-style") && ("italic".equals(value2.getCssText()) || "oblique".equals(value2.getCssText()))) { - applyCSSPropertyStyle(element, grid, value2, target); - } - } - } - } - } - - private boolean applyCSSPropertyStyle(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final FontData fd = CSSEngineHelper.getFontData(grid); - boolean modified = false; - if ("italic".equals(value.getCssText()) || "oblique".equals(value.getCssText())) { - modified = (fd.getStyle() & SWT.ITALIC) != SWT.ITALIC; - if (modified) { - fd.setStyle(fd.getStyle() | SWT.ITALIC); - } - } else { - modified = (fd.getStyle() & SWT.ITALIC) == SWT.ITALIC; - if (modified) { - fd.setStyle(fd.getStyle() | ~SWT.ITALIC); - } - } - if (modified) { - applyFont(grid, fd, target); - } - - } - return true; - } - - private void applyFont(final Grid grid, final FontData fd, String target) { - for (GridColumn column : grid.getColumns()) { - applyFont(column, fd, target); - } - } - - private void applyFont(final GridColumn column, final FontData fd, String target) { - if (target.equals(HEADER)) { - if (column.getHeaderFont() != null && !column.getHeaderFont().equals(column.getDisplay().getSystemFont())) { - column.getHeaderFont().dispose(); - } - } else { - if (column.getFooterFont() != null && !column.getFooterFont().equals(column.getDisplay().getSystemFont())) { - column.getFooterFont().dispose(); - } - } - final Font newFont = new Font(column.getDisplay(), fd); - if (target.equals(HEADER)) { - column.setHeaderFont(newFont); - } else { - column.setFooterFont(newFont); - } - - column.getParent().addListener(SWT.Dispose, e -> { - if (newFont != null && !newFont.isDisposed()) { - newFont.dispose(); - } - }); - } - - private boolean applyCSSPropertySize(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final FontData fd = CSSEngineHelper.getFontData(grid); - final Measure m = (Measure) value; - - final int newSize = Math.round(m.getFloatValue((short) 0)); - final boolean modified = fd.getHeight() != newSize; - if (modified) { - fd.setHeight(newSize); - applyFont(grid, fd, target); - } - } - - return true; - } - - private boolean applyCSSPropertyWeight(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final FontData fd = CSSEngineHelper.getFontData(grid); - boolean modified = false; - if ("bold".equals(value.getCssText()) || "bolder".equals(value.getCssText())) { - modified = (fd.getStyle() & SWT.BOLD) != SWT.BOLD; - if (modified) { - fd.setStyle(fd.getStyle() | SWT.BOLD); - } - } else { - modified = (fd.getStyle() & SWT.BOLD) == SWT.BOLD; - if (modified) { - fd.setStyle(fd.getStyle() | ~SWT.BOLD); - } - } - if (modified) { - applyFont(grid, fd, target); - } - - } - return true; - } - - private boolean applyCSSPropertyFamily(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { - if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { - final FontData fd = CSSEngineHelper.getFontData(grid); - final boolean modified = !fd.getName().equals(value.getCssText()); - if (modified) { - fd.setName(value.getCssText()); - applyFont(grid, fd, target); - } - } - return true; - } - - /** - * @see org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler#retrieveCSSProperty(java.lang.Object, java.lang.String, java.lang.String, org.eclipse.e4.ui.css.core.engine.CSSEngine) - */ - @Override - public String retrieveCSSProperty(final Object element, final String property, final String pseudo, final CSSEngine engine) throws Exception { - return null; - } +/******************************************************************************* + * Copyright (c) 2020 Laurent Caron. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent Caron - initial API and implementation + ******************************************************************************/ +package org.eclipse.nebula.widgets.grid.css; + +import org.eclipse.e4.ui.css.core.css2.CSS2FontHelper; +import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler; +import org.eclipse.e4.ui.css.core.engine.CSSEngine; +import org.eclipse.e4.ui.css.core.impl.dom.Measure; +import org.eclipse.nebula.widgets.grid.Grid; +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.nebula.widgets.grid.Win7RendererSupport; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.w3c.dom.css.CSSPrimitiveValue; +import org.w3c.dom.css.CSSValue; +import org.w3c.dom.css.CSSValueList; + +@SuppressWarnings("restriction") +public class GridPropertyHandler implements ICSSPropertyHandler { + private static final String FOOTER = "footer"; + private static final String HEADER = "header"; + + /** + * @see org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler#applyCSSProperty(java.lang.Object, java.lang.String, org.w3c.dom.css.CSSValue, java.lang.String, org.eclipse.e4.ui.css.core.engine.CSSEngine) + */ + @Override + public boolean applyCSSProperty(final Object element, final String property, final CSSValue value, final String pseudo, final CSSEngine engine) throws Exception { + + final Grid grid = (Grid) ((GridElement) element).getNativeWidget(); + + // Theme + if ("grid-theme".equals(property)) { + if (value.getCssText() != null && value.getCssText().equals("win7")) { + Win7RendererSupport.create(grid).decorate(); + } + } + + // General + if ("grid-cell-header-selection-background-color".equals(property) && value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final Color newColor = (Color) engine.convert(value, Color.class, grid.getDisplay()); + grid.setCellHeaderSelectionBackground(newColor); + } + + if ("grid-header-visible".equals(property)) { + final boolean headerVisible = value == null ? false : Boolean.parseBoolean(value.getCssText()); + grid.setHeaderVisible(headerVisible); + } + + if ("grid-footer-visible".equals(property)) { + final boolean footerVisible = value == null ? false : Boolean.parseBoolean(value.getCssText()); + grid.setFooterVisible(footerVisible); + } + + // Items + if ("grid-item-height".equals(property)) { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final Measure m = (Measure) value; + final int width = Math.round(m.getFloatValue((short) 0)); + grid.setItemHeight(width); + } + } + + if ("grid-item-header-width".equals(property)) { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final Measure m = (Measure) value; + final int width = Math.round(m.getFloatValue((short) 0)); + grid.setItemHeaderWidth(width); + } + } + + // Lines + if ("grid-line-color".equals(property) && value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final Color newColor = (Color) engine.convert(value, Color.class, grid.getDisplay()); + grid.setLineColor(newColor); + } + + if ("grid-lines-visible".equals(property)) { + final boolean linesVisible = value == null ? false : Boolean.parseBoolean(value.getCssText()); + grid.setLinesVisible(linesVisible); + } + + if ("grid-tree-lines-visible".equals(property)) { + final boolean treeLinesVisible = value == null ? false : Boolean.parseBoolean(value.getCssText()); + grid.setTreeLinesVisible(treeLinesVisible); + } + + // Columns + if ("grid-columns-alignment".equals(property) && grid.getColumns() != null) { + final int alignment; + if ("left".equals(value.getCssText())) { + alignment = SWT.LEFT; + } else if ("right".equals(value.getCssText())) { + alignment = SWT.RIGHT; + } else if ("center".equals(value.getCssText())) { + alignment = SWT.CENTER; + } else { + alignment = SWT.NONE; + } + if (alignment == SWT.LEFT || alignment == SWT.CENTER || alignment == SWT.RIGHT) + for (GridColumn col : grid.getColumns()) { + col.setAlignment(alignment); + } + } + + if ("grid-columns-header-font".equals(property) && grid.getColumns() != null) { + applyCSSPropertyFont(element, grid, value, HEADER); + } + if ("grid-columns-header-font-style".equals(property) && grid.getColumns() != null) { + applyCSSPropertyStyle(element, grid, value, HEADER); + } + if ("grid-columns-header-font-size".equals(property) && grid.getColumns() != null) { + applyCSSPropertySize(element, grid, value, HEADER); + } + if ("grid-columns-header-font-weight".equals(property) && grid.getColumns() != null) { + applyCSSPropertyWeight(element, grid, value, HEADER); + } + if ("grid-columns-header-font-family".equals(property) && grid.getColumns() != null) { + applyCSSPropertyFamily(element, grid, value, HEADER); + } + + if ("grid-columns-footer-font".equals(property) && grid.getColumns() != null) { + applyCSSPropertyFont(element, grid, value, FOOTER); + } + if ("grid-columns-footer-font-style".equals(property) && grid.getColumns() != null) { + applyCSSPropertyStyle(element, grid, value, FOOTER); + } + if ("grid-columns-footer-font-size".equals(property) && grid.getColumns() != null) { + applyCSSPropertySize(element, grid, value, FOOTER); + } + if ("grid-columns-footer-font-weight".equals(property) && grid.getColumns() != null) { + applyCSSPropertyWeight(element, grid, value, FOOTER); + } + if ("grid-columns-footer-font-family".equals(property) && grid.getColumns() != null) { + applyCSSPropertyFamily(element, grid, value, FOOTER); + } + + return true; + } + + private void applyCSSPropertyFont(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_VALUE_LIST) { + final CSSValueList valueList = (CSSValueList) value; + final int length = valueList.getLength(); + for (int i = 0; i < length; i++) { + final CSSValue value2 = valueList.item(i); + if (value2.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final String cssProp = CSS2FontHelper.getCSSFontPropertyName((CSSPrimitiveValue) value2); + if (cssProp.equals("font-family")) { + applyCSSPropertyFamily(element, grid, value2, target); + } else if (cssProp.equals("font-size")) { + applyCSSPropertySize(element, grid, value2, target); + } else if (cssProp.equals("font-weight") && ("bold".equals(value2.getCssText()) || "bolder".equals(value2.getCssText()))) { + applyCSSPropertyWeight(element, grid, value2, target); + } else if (cssProp.equals("font-style") && ("italic".equals(value2.getCssText()) || "oblique".equals(value2.getCssText()))) { + applyCSSPropertyStyle(element, grid, value2, target); + } + } + } + } + } + + private boolean applyCSSPropertyStyle(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final FontData fd = CSSEngineHelper.getFontData(grid); + boolean modified = false; + if ("italic".equals(value.getCssText()) || "oblique".equals(value.getCssText())) { + modified = (fd.getStyle() & SWT.ITALIC) != SWT.ITALIC; + if (modified) { + fd.setStyle(fd.getStyle() | SWT.ITALIC); + } + } else { + modified = (fd.getStyle() & SWT.ITALIC) == SWT.ITALIC; + if (modified) { + fd.setStyle(fd.getStyle() | ~SWT.ITALIC); + } + } + if (modified) { + applyFont(grid, fd, target); + } + + } + return true; + } + + private void applyFont(final Grid grid, final FontData fd, String target) { + for (GridColumn column : grid.getColumns()) { + applyFont(column, fd, target); + } + } + + private void applyFont(final GridColumn column, final FontData fd, String target) { + if (target.equals(HEADER)) { + if (column.getHeaderFont() != null && !column.getHeaderFont().equals(column.getDisplay().getSystemFont())) { + column.getHeaderFont().dispose(); + } + } else { + if (column.getFooterFont() != null && !column.getFooterFont().equals(column.getDisplay().getSystemFont())) { + column.getFooterFont().dispose(); + } + } + final Font newFont = new Font(column.getDisplay(), fd); + if (target.equals(HEADER)) { + column.setHeaderFont(newFont); + } else { + column.setFooterFont(newFont); + } + + column.getParent().addListener(SWT.Dispose, e -> { + if (newFont != null && !newFont.isDisposed()) { + newFont.dispose(); + } + }); + } + + private boolean applyCSSPropertySize(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final FontData fd = CSSEngineHelper.getFontData(grid); + final Measure m = (Measure) value; + + final int newSize = Math.round(m.getFloatValue((short) 0)); + final boolean modified = fd.getHeight() != newSize; + if (modified) { + fd.setHeight(newSize); + applyFont(grid, fd, target); + } + } + + return true; + } + + private boolean applyCSSPropertyWeight(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final FontData fd = CSSEngineHelper.getFontData(grid); + boolean modified = false; + if ("bold".equals(value.getCssText()) || "bolder".equals(value.getCssText())) { + modified = (fd.getStyle() & SWT.BOLD) != SWT.BOLD; + if (modified) { + fd.setStyle(fd.getStyle() | SWT.BOLD); + } + } else { + modified = (fd.getStyle() & SWT.BOLD) == SWT.BOLD; + if (modified) { + fd.setStyle(fd.getStyle() | ~SWT.BOLD); + } + } + if (modified) { + applyFont(grid, fd, target); + } + + } + return true; + } + + private boolean applyCSSPropertyFamily(final Object element, final Grid grid, final CSSValue value, String target) throws Exception { + if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { + final FontData fd = CSSEngineHelper.getFontData(grid); + final boolean modified = !fd.getName().equals(value.getCssText()); + if (modified) { + fd.setName(value.getCssText()); + applyFont(grid, fd, target); + } + } + return true; + } + + /** + * @see org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler#retrieveCSSProperty(java.lang.Object, java.lang.String, java.lang.String, org.eclipse.e4.ui.css.core.engine.CSSEngine) + */ + @Override + public String retrieveCSSProperty(final Object element, final String property, final String pseudo, final CSSEngine engine) throws Exception { + return null; + } } \ No newline at end of file diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.css/src/org/eclipse/nebula/widgets/grid/css/TestLCN.java b/widgets/grid/org.eclipse.nebula.widgets.grid.css/src/org/eclipse/nebula/widgets/grid/css/TestLCN.java index a2bbd5be3..87fadb148 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.css/src/org/eclipse/nebula/widgets/grid/css/TestLCN.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.css/src/org/eclipse/nebula/widgets/grid/css/TestLCN.java @@ -1,15 +1,15 @@ -package org.eclipse.nebula.widgets.grid.css; - -import java.io.IOException; -import java.net.URL; -import java.util.Collections; -import java.util.Enumeration; - -public class TestLCN { - - public static void main(final String[] args) throws IOException { - final Enumeration e = TestLCN.class.getClassLoader().getResources("org/w3c/dom/css/CSSPrimitiveValue.class"); - Collections.list(e).forEach(System.out::println); - } - -} +package org.eclipse.nebula.widgets.grid.css; + +import java.io.IOException; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; + +public class TestLCN { + + public static void main(final String[] args) throws IOException { + final Enumeration e = TestLCN.class.getClassLoader().getResources("org/w3c/dom/css/CSSPrimitiveValue.class"); + Collections.list(e).forEach(System.out::println); + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.classpath b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.classpath +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.project b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.project index 08e1aac79..7887b821e 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.project +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.grid.example.e4 - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.grid.example.e4 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.settings/org.eclipse.jdt.core.prefs b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/Application.e4xmi b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/Application.e4xmi index 0ac7c0650..ed0e527fe 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/Application.e4xmi +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/Application.e4xmi @@ -1,43 +1,43 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/build.properties b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/build.properties index 163f78c0c..04ab1e9b8 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/build.properties +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/build.properties @@ -1,8 +1,8 @@ -source.. = src/ -output.. = bin/ -bin.includes = plugin.xml,\ - META-INF/,\ - .,\ - icons/,\ - css/default.css,\ - Application.e4xmi +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + icons/,\ + css/default.css,\ + Application.e4xmi diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/css/default.css b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/css/default.css index edc4fc660..6593e1a5f 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/css/default.css +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/css/default.css @@ -1,22 +1,22 @@ -/* -CSS for Grid -*/ - -#two { - grid-theme: win7; -} - -#three { - grid-cell-header-selection-background-color: #ffffcc; - grid-header-visible: false; - grid-item-height: 30px; - grid-item-header-width: 150px; - grid-line-color: darkred; - grid-lines-visible: false; -} - -#four { - grid-line-color: darkred; - grid-columns-alignment: center; - grid-columns-header-font: "Comic sans MS" italic 12px; +/* +CSS for Grid +*/ + +#two { + grid-theme: win7; +} + +#three { + grid-cell-header-selection-background-color: #ffffcc; + grid-header-visible: false; + grid-item-height: 30px; + grid-item-header-width: 150px; + grid-line-color: darkred; + grid-lines-visible: false; +} + +#four { + grid-line-color: darkred; + grid-columns-alignment: center; + grid-columns-header-font: "Comic sans MS" italic 12px; } \ No newline at end of file diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/org.eclipse.nebula.widgets.grid.example.e4.product b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/org.eclipse.nebula.widgets.grid.example.e4.product index d4c104b4e..3b9531f64 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/org.eclipse.nebula.widgets.grid.example.e4.product +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/org.eclipse.nebula.widgets.grid.example.e4.product @@ -1,92 +1,92 @@ - - - - - - - - - - -clearPersistedState - - -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + -clearPersistedState + + -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/plugin.xml b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/plugin.xml index 7632325ef..db8f443e1 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/plugin.xml +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/plugin.xml @@ -1,22 +1,22 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/pom.xml b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/pom.xml index e0173b2a3..040586c9a 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/pom.xml +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - grid - 1.1.0-SNAPSHOT - - - org.eclipse.nebula.widgets.grid.example.e4 - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + grid + 1.1.0-SNAPSHOT + + + org.eclipse.nebula.widgets.grid.example.e4 + eclipse-plugin + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/src/org/eclipse/nebula/widgets/grid/example/e4/Activator.java b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/src/org/eclipse/nebula/widgets/grid/example/e4/Activator.java index 3d3d14cdb..cabdf564d 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/src/org/eclipse/nebula/widgets/grid/example/e4/Activator.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example.e4/src/org/eclipse/nebula/widgets/grid/example/e4/Activator.java @@ -1,43 +1,43 @@ -/******************************************************************************* - * Copyright (c) 2020 Laurent Caron - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent Caron - Initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid.example.e4; - -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -public class Activator implements BundleActivator { - - private static BundleContext context; - - static BundleContext getContext() { - return context; - } - - /** - * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) - */ - @Override - public void start(final BundleContext bundleContext) throws Exception { - Activator.context = bundleContext; - } - - /** - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - @Override - public void stop(final BundleContext bundleContext) throws Exception { - Activator.context = null; - } - -} +/******************************************************************************* + * Copyright (c) 2020 Laurent Caron + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent Caron - Initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid.example.e4; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /** + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(final BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /** + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(final BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example/.classpath b/widgets/grid/org.eclipse.nebula.widgets.grid.example/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example/.classpath +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.example/.settings/org.eclipse.jdt.core.prefs b/widgets/grid/org.eclipse.nebula.widgets.grid.example/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.example/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.example/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid.test/.settings/org.eclipse.jdt.core.prefs b/widgets/grid/org.eclipse.nebula.widgets.grid.test/.settings/org.eclipse.jdt.core.prefs index 210645813..5e8cee5b6 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid.test/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/grid/org.eclipse.nebula.widgets.grid.test/.settings/org.eclipse.jdt.core.prefs @@ -1,411 +1,411 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=error -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=warning -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeFieldsInNullAnalysis=disabled -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public -org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_additive_operator=50 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=82 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=82 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=82 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=82 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=50 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=52 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=51 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=52 -org.eclipse.jdt.core.formatter.alignment_for_logical_operator=50 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=50 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=82 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=82 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=84 -org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=50 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=36 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=36 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=36 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=36 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=2 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=0 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line_on_wrap -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line_on_wrap -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=next_line_on_wrap -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line_on_wrap -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line_on_wrap -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line_on_wrap -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line_on_wrap -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line_on_wrap -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line_on_wrap -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=100 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag= -org.eclipse.jdt.core.formatter.enabling_tag= -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=false -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=insert -org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=insert -org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=100 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=0 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=2 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true -org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true -org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true -org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.doc.comment.support=enabled +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=error +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeFieldsInNullAnalysis=disabled +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning +org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public +org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag +org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_additive_operator=50 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=82 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=82 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=82 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=82 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=50 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=52 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=51 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=52 +org.eclipse.jdt.core.formatter.alignment_for_logical_operator=50 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=50 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=82 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=82 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=84 +org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=50 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=36 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=36 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=36 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=36 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=2 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=0 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line_on_wrap +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line_on_wrap +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=next_line_on_wrap +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line_on_wrap +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line_on_wrap +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line_on_wrap +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line_on_wrap +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line_on_wrap +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line_on_wrap +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert +org.eclipse.jdt.core.formatter.comment.line_length=100 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag= +org.eclipse.jdt.core.formatter.enabling_tag= +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=false +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=insert +org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=insert +org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=100 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=0 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=2 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true +org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true +org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true +org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/.classpath b/widgets/grid/org.eclipse.nebula.widgets.grid/.classpath index 92e333a4b..c3ba59e4c 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/.classpath +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/.settings/org.eclipse.jdt.core.prefs b/widgets/grid/org.eclipse.nebula.widgets.grid/.settings/org.eclipse.jdt.core.prefs index cd4e9298d..b43a66d88 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/.settings/org.eclipse.jdt.core.prefs @@ -1,26 +1,26 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.doc.comment.support=enabled +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error +org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/jface/gridviewer/GridTableViewer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/jface/gridviewer/GridTableViewer.java index c82536d75..75002e87e 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/jface/gridviewer/GridTableViewer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/jface/gridviewer/GridTableViewer.java @@ -1,602 +1,602 @@ -/******************************************************************************* - * Copyright (c) 2007 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * rmcamara@us.ibm.com - initial API and implementation - * tom.schindl@bestsolution.at - various significant contributions - * mirko.paturzo@exeura.eu - improve performance - *******************************************************************************/ - -package org.eclipse.nebula.jface.gridviewer; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.jface.viewers.AbstractTableViewer; -import org.eclipse.jface.viewers.CellLabelProvider; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.ViewerCell; -import org.eclipse.jface.viewers.ViewerRow; -import org.eclipse.nebula.jface.gridviewer.internal.CellSelection; -import org.eclipse.nebula.jface.gridviewer.internal.SelectionWithFocusRow; -import org.eclipse.nebula.widgets.grid.DataVisualizer; -import org.eclipse.nebula.widgets.grid.Grid; -import org.eclipse.nebula.widgets.grid.GridItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.Widget; - -/** - * A concrete viewer based on an Grid control. - *

- * This class is not intended to be subclassed outside the viewer framework. It - * is designed to be instantiated with a pre-existing Grid control and - * configured with a domain-specific content provider, label provider, element - * filter (optional), and element sorter (optional). - *

- * Content providers for grid table viewers must not implement the {@code - * ITreeContentProvider} interface. Instead a {@link GridTreeViewer} should be - * used. - *

- * - * @author Unknown... - * @author Mirko Paturzo - * - * Mirko modified improve performace and reduce used memory fix memory - * leak and slow disposed object - */ -public class GridTableViewer extends AbstractTableViewer { - /** This viewer's grid control. */ - private final Grid grid; - - private GridViewerRow cachedRow; - - private CellLabelProvider rowHeaderLabelProvider; - - /** - * If true, this grid viewer will ensure that the grid's rows / GridItems are - * always sized to their preferred height. - */ - private boolean autoPreferredHeight = false; - - /** - * Creates a grid viewer on a newly-created grid control under the given parent. - * The grid control is created using the SWT style bits - * MULTI, H_SCROLL, V_SCROLL, and BORDER. The viewer - * has no input, no content provider, a default label provider, no sorter, and - * no filters. - * - * @param parent - * the parent control - */ - public GridTableViewer(Composite parent) { - this(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); - } - - /** - * Creates a grid viewer on a newly-created grid control under the given parent. - * The grid control is created using the given SWT style bits. The viewer has no - * input, no content provider, a default label provider, no sorter, and no - * filters. - * - * @param dataVisualizer - * @param parent - * the parent control - * @param style - * the SWT style bits used to create the grid. - */ - public GridTableViewer(DataVisualizer dataVisualizer, Composite parent, int style) { - this(new Grid(dataVisualizer, parent, style)); - } - - /** - * Creates a grid viewer on a newly-created grid control under the given parent. - * The grid control is created using the SWT style bits - * MULTI, H_SCROLL, V_SCROLL, and BORDER. The viewer - * has no input, no content provider, a default label provider, no sorter, and - * no filters. - * - * @param dataVisualizer - * @param parent - * the parent control - */ - public GridTableViewer(DataVisualizer dataVisualizer, Composite parent) { - this(dataVisualizer, parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); - } - - /** - * Creates a grid viewer on a newly-created grid control under the given parent. - * The grid control is created using the given SWT style bits. The viewer has no - * input, no content provider, a default label provider, no sorter, and no - * filters. - * - * @param parent - * the parent control - * @param style - * the SWT style bits used to create the grid. - */ - public GridTableViewer(Composite parent, int style) { - this(new Grid(parent, style)); - } - - /** - * Creates a grid viewer on the given grid control. The viewer has no input, no - * content provider, a default label provider, no sorter, and no filters. - * - * @param grid - * the grid control - */ - public GridTableViewer(Grid grid) { - this.grid = grid; - hookControl(grid); - setColumnProperties(new String[] {}); - } - - /** - * Returns the underlying Grid Control. - * - * @return grid control. - */ - public Grid getGrid() { - return grid; - } - - /** {@inheritDoc} */ - @Override - protected ViewerRow internalCreateNewRowPart(int style, int rowIndex) { - GridItem item; - - if (rowIndex >= 0) { - item = new GridItem(grid, style, rowIndex); - } else { - item = new GridItem(grid, style); - } - - return getViewerRowFromItem(item); - } - - /** {@inheritDoc} */ - @Override - protected ColumnViewerEditor createViewerEditor() { - return new GridViewerEditor(this, new ColumnViewerEditorActivationStrategy(this), ColumnViewerEditor.DEFAULT); - } - - /** {@inheritDoc} */ - @Override - protected void doClear(int index) { - grid.getDataVisualizer().clearRow(grid.getItem(index)); - } - - /** {@inheritDoc} */ - @Override - protected void doClearAll() { - grid.getDataVisualizer().clearAll(); - } - - /** - * @see org.eclipse.jface.viewers.StructuredViewer#refresh() - */ - @Override - public void refresh() { - try { - super.refresh(); - } finally { - grid.refreshData(); - } - } - - /** {@inheritDoc} */ - @Override - protected void doSetItemCount(int count) { - grid.setItemCount(count); - } - - /** {@inheritDoc} */ - @Override - protected void doDeselectAll() { - grid.deselectAll(); - } - - /** {@inheritDoc} */ - @Override - protected Widget doGetColumn(int index) { - return grid.getColumn(index); - } - - /** {@inheritDoc} */ - @Override - protected int doGetColumnCount() { - return grid.getColumnCount(); - } - - /** {@inheritDoc} */ - @Override - protected Item doGetItem(int index) { - return grid.getItem(index); - } - - /** {@inheritDoc} */ - @Override - protected int doGetItemCount() { - return grid.getItemCount(); - } - - /** {@inheritDoc} */ - @Override - protected Item[] doGetItems() { - return grid.getItems(); - } - - /** {@inheritDoc} */ - @Override - protected Item[] doGetSelection() { - return grid.getSelection(); - } - - /** {@inheritDoc} */ - @Override - protected int[] doGetSelectionIndices() { - return grid.getSelectionIndices(); - } - - /** {@inheritDoc} */ - @Override - protected int doIndexOf(Item item) { - return ((GridItem) item).getRowIndex(); - } - - /** {@inheritDoc} */ - @Override - protected void doRemove(int[] indices) { - grid.remove(indices); - } - - /** {@inheritDoc} */ - @Override - protected void doRemove(int start, int end) { - grid.remove(start, end); - } - - /** {@inheritDoc} */ - @SuppressWarnings("deprecation") - @Override - protected void doRemoveAll() { - grid.removeAll(); - } - - /** - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.AbstractTableViewer#handleDispose(org.eclipse.swt.events.DisposeEvent) - * fix crossed reference for GC - */ - @Override - protected void handleDispose(final DisposeEvent event) { - super.handleDispose(event); - - cachedRow = null; - rowHeaderLabelProvider = null; - - getGrid().setRedraw(false); - getGrid().disposeAllItems(); - getGrid().clearItems(); - } - - /** {@inheritDoc} */ - @Override - protected void doSetSelection(Item[] items) { - GridItem[] items2 = new GridItem[items.length]; - for (int i = 0; i < items.length; i++) { - items2[i] = (GridItem) items[i]; - } - grid.setSelection(items2); - grid.showSelection(); - } - - /** {@inheritDoc} */ - @Override - protected void doSetSelection(int[] indices) { - grid.setSelection(indices); - } - - /** {@inheritDoc} */ - @Override - protected void doShowItem(Item item) { - grid.showItem((GridItem) item); - } - - /** {@inheritDoc} */ - @Override - protected void doShowSelection() { - grid.showSelection(); - } - - /** {@inheritDoc} */ - @Override - protected Item getItemAt(Point point) { - return grid.getItem(point); - } - - /** {@inheritDoc} */ - @Override - public Control getControl() { - return grid; - } - - /** {@inheritDoc} */ - @Override - protected ViewerRow getViewerRowFromItem(Widget item) { - if (cachedRow == null) { - cachedRow = new GridViewerRow((GridItem) item); - } else { - cachedRow.setItem((GridItem) item); - } - - return cachedRow; - } - - /** - * {@inheritDoc} - */ - @Override - protected void doResetItem(Item item) { - GridItem gridItem = (GridItem) item; - int columnCount = Math.max(1, grid.getColumnCount()); - for (int i = 0; i < columnCount; i++) { - gridItem.setText(i, ""); //$NON-NLS-1$ - gridItem.setImage(null); - } - } - - /** - * {@inheritDoc} - */ - @Override - protected void doSelect(int[] indices) { - grid.select(indices); - } - - /** - * When set to true, this grid viewer will ensure that each of the grid's items - * is always automatically sized to its preferred height. The default is false. - *

- * Since this mechanism usually leads to a grid with rows of different heights - * and thus to a grid with decreased performance, it should only be applied if - * that is intended. To set the height of all items to a specific value, use - * {@link Grid#setItemHeight(int)} instead. - *

- * When a column with activated word wrapping is resized by dragging the column - * resizer, the items are only auto-resized properly if you use - * {@link GridViewerColumn} to create the columns. - *

- * When this method is called, existing rows are not resized to their preferred - * height. Therefore it is suggested that this method be called before rows are - * populated (i.e. before setInput). - * - * @param autoPreferredHeight - */ - public void setAutoPreferredHeight(boolean autoPreferredHeight) { - this.autoPreferredHeight = autoPreferredHeight; - } - - /** - * @return true if this grid viewer sizes its rows to their preferred height - * @see #setAutoPreferredHeight(boolean) - */ - public boolean getAutoPreferredHeight() { - return autoPreferredHeight; - } - - /** {@inheritDoc} */ - @Override - protected void doUpdateItem(Widget widget, Object element, boolean fullMap) { - super.doUpdateItem(widget, element, fullMap); - updateRowHeader(widget); - if (autoPreferredHeight && !widget.isDisposed()) - ((GridItem) widget).pack(); - } - - private void updateRowHeader(Widget widget) { - if (rowHeaderLabelProvider != null) { - ViewerCell cell = getViewerRowFromItem(widget).getCell(Integer.MAX_VALUE); - rowHeaderLabelProvider.update(cell); - } - } - - /** - * Label provider used by calculate the row header text - * - * @param rowHeaderLabelProvider - * the provider - */ - public void setRowHeaderLabelProvider(CellLabelProvider rowHeaderLabelProvider) { - this.rowHeaderLabelProvider = rowHeaderLabelProvider; - } - - /** - * Refresh row headers only - * - * @param element - * the element to start or null if all rows should be - * refreshed - */ - public void refreshRowHeaders(Object element) { - boolean refresh = element == null; - - for (int i = 0; i < getGrid().getItemCount(); i++) { - if (refresh || element.equals(getGrid().getItem(i).getData())) { - refresh = true; - updateRowHeader(getGrid().getItem(i)); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public void editElement(Object element, int column) { - try { - getControl().setRedraw(false); - Widget item = findItem(element); - if (item != null) { - ViewerRow row = getViewerRowFromItem(item); - if (row != null) { - ViewerCell cell = row.getCell(column); - if (cell != null) { - triggerEditorActivationEvent(new ColumnViewerEditorActivationEvent(cell)); - } - } - } - } finally { - getControl().setRedraw(true); - } - // } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - protected void setSelectionToWidget(ISelection selection, boolean reveal) { - if (!grid.isCellSelectionEnabled() || !(selection instanceof CellSelection)) { - super.setSelectionToWidget(selection, reveal); - Object el = null; - if (selection instanceof SelectionWithFocusRow) { - el = ((SelectionWithFocusRow) selection).getFocusElement(); - } else if (selection instanceof IStructuredSelection) { - el = ((IStructuredSelection) selection).getFirstElement(); - } - if (el != null) { - for (int i = 0; i < grid.getItemCount(); i++) { - GridItem item = grid.getItem(i); - if (item.getData() == el || el.equals(item.getData()) - || (getComparer() != null && getComparer().equals(item.getData(), el))) { - grid.setFocusItem(item); - break; - } - } - } - } else { - CellSelection cellSelection = (CellSelection) selection; - List l = cellSelection.toList(); - ArrayList pts = new ArrayList(); - - for (int i = 0; i < grid.getItemCount(); i++) { - Iterator it = l.iterator(); - Object itemObject = grid.getItem(i).getData(); - while (it.hasNext()) { - Object checkObject = it.next(); - if (itemObject == checkObject - || (getComparer() != null && getComparer().equals(itemObject, checkObject))) { - Iterator idxIt = cellSelection.getIndices(checkObject).iterator(); - while (idxIt.hasNext()) { - Integer idx = (Integer) idxIt.next(); - pts.add(new Point(idx.intValue(), i)); - } - } - } - } - Point[] tmp = new Point[pts.size()]; - pts.toArray(tmp); - grid.setCellSelection(tmp); - if (cellSelection.getFocusElement() != null) { - Object el = cellSelection.getFocusElement(); - for (int i = 0; i < grid.getItemCount(); i++) { - GridItem item = grid.getItem(i); - if (item.getData() == el || item.getData().equals(el) - || (getComparer() != null && getComparer().equals(item.getData(), el))) { - grid.setFocusItem(item); - break; - } - } - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public ISelection getSelection() { - if (grid == null || grid.isDisposed()) { - return StructuredSelection.EMPTY; - } - if (!grid.isCellSelectionEnabled()) { - IStructuredSelection selection = (IStructuredSelection) super.getSelection(); - Object el = null; - if (grid.getFocusItem() != null && !grid.getFocusItem().isDisposed()) { - el = grid.getFocusItem().getData(); - } - return new SelectionWithFocusRow(selection.toList(), el, getComparer()); - } else { - return createCellSelection(); - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private CellSelection createCellSelection() { - Point[] ps = grid.getCellSelection(); - Arrays.sort(ps, new Comparator() { - - @Override - public int compare(Object arg0, Object arg1) { - Point a = (Point) arg0; - Point b = (Point) arg1; - int rv = a.y - b.y; - - if (rv == 0) { - rv = a.x - b.x; - } - - return rv; - } - }); - - ArrayList objectList = new ArrayList(); - ArrayList indiceLists = new ArrayList(); - ArrayList indiceList = new ArrayList(); - - int curLine = -1; - - for (int i = 0; i < ps.length; i++) { - if (curLine != ps[i].y) { - curLine = ps[i].y; - indiceList = new ArrayList(); - - indiceLists.add(indiceList); - objectList.add(grid.getItem(curLine).getData()); - } - indiceList.add(new Integer(ps[i].x)); - } - - Object focusElement = null; - - if (grid.getFocusItem() != null && !grid.getFocusItem().isDisposed()) { - focusElement = grid.getFocusItem().getData(); - } - - return new CellSelection(objectList, indiceLists, focusElement, getComparer()); - } - -} +/******************************************************************************* + * Copyright (c) 2007 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * rmcamara@us.ibm.com - initial API and implementation + * tom.schindl@bestsolution.at - various significant contributions + * mirko.paturzo@exeura.eu - improve performance + *******************************************************************************/ + +package org.eclipse.nebula.jface.gridviewer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jface.viewers.AbstractTableViewer; +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.jface.viewers.ViewerRow; +import org.eclipse.nebula.jface.gridviewer.internal.CellSelection; +import org.eclipse.nebula.jface.gridviewer.internal.SelectionWithFocusRow; +import org.eclipse.nebula.widgets.grid.DataVisualizer; +import org.eclipse.nebula.widgets.grid.Grid; +import org.eclipse.nebula.widgets.grid.GridItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Widget; + +/** + * A concrete viewer based on an Grid control. + *

+ * This class is not intended to be subclassed outside the viewer framework. It + * is designed to be instantiated with a pre-existing Grid control and + * configured with a domain-specific content provider, label provider, element + * filter (optional), and element sorter (optional). + *

+ * Content providers for grid table viewers must not implement the {@code + * ITreeContentProvider} interface. Instead a {@link GridTreeViewer} should be + * used. + *

+ * + * @author Unknown... + * @author Mirko Paturzo + * + * Mirko modified improve performace and reduce used memory fix memory + * leak and slow disposed object + */ +public class GridTableViewer extends AbstractTableViewer { + /** This viewer's grid control. */ + private final Grid grid; + + private GridViewerRow cachedRow; + + private CellLabelProvider rowHeaderLabelProvider; + + /** + * If true, this grid viewer will ensure that the grid's rows / GridItems are + * always sized to their preferred height. + */ + private boolean autoPreferredHeight = false; + + /** + * Creates a grid viewer on a newly-created grid control under the given parent. + * The grid control is created using the SWT style bits + * MULTI, H_SCROLL, V_SCROLL, and BORDER. The viewer + * has no input, no content provider, a default label provider, no sorter, and + * no filters. + * + * @param parent + * the parent control + */ + public GridTableViewer(Composite parent) { + this(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + } + + /** + * Creates a grid viewer on a newly-created grid control under the given parent. + * The grid control is created using the given SWT style bits. The viewer has no + * input, no content provider, a default label provider, no sorter, and no + * filters. + * + * @param dataVisualizer + * @param parent + * the parent control + * @param style + * the SWT style bits used to create the grid. + */ + public GridTableViewer(DataVisualizer dataVisualizer, Composite parent, int style) { + this(new Grid(dataVisualizer, parent, style)); + } + + /** + * Creates a grid viewer on a newly-created grid control under the given parent. + * The grid control is created using the SWT style bits + * MULTI, H_SCROLL, V_SCROLL, and BORDER. The viewer + * has no input, no content provider, a default label provider, no sorter, and + * no filters. + * + * @param dataVisualizer + * @param parent + * the parent control + */ + public GridTableViewer(DataVisualizer dataVisualizer, Composite parent) { + this(dataVisualizer, parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + } + + /** + * Creates a grid viewer on a newly-created grid control under the given parent. + * The grid control is created using the given SWT style bits. The viewer has no + * input, no content provider, a default label provider, no sorter, and no + * filters. + * + * @param parent + * the parent control + * @param style + * the SWT style bits used to create the grid. + */ + public GridTableViewer(Composite parent, int style) { + this(new Grid(parent, style)); + } + + /** + * Creates a grid viewer on the given grid control. The viewer has no input, no + * content provider, a default label provider, no sorter, and no filters. + * + * @param grid + * the grid control + */ + public GridTableViewer(Grid grid) { + this.grid = grid; + hookControl(grid); + setColumnProperties(new String[] {}); + } + + /** + * Returns the underlying Grid Control. + * + * @return grid control. + */ + public Grid getGrid() { + return grid; + } + + /** {@inheritDoc} */ + @Override + protected ViewerRow internalCreateNewRowPart(int style, int rowIndex) { + GridItem item; + + if (rowIndex >= 0) { + item = new GridItem(grid, style, rowIndex); + } else { + item = new GridItem(grid, style); + } + + return getViewerRowFromItem(item); + } + + /** {@inheritDoc} */ + @Override + protected ColumnViewerEditor createViewerEditor() { + return new GridViewerEditor(this, new ColumnViewerEditorActivationStrategy(this), ColumnViewerEditor.DEFAULT); + } + + /** {@inheritDoc} */ + @Override + protected void doClear(int index) { + grid.getDataVisualizer().clearRow(grid.getItem(index)); + } + + /** {@inheritDoc} */ + @Override + protected void doClearAll() { + grid.getDataVisualizer().clearAll(); + } + + /** + * @see org.eclipse.jface.viewers.StructuredViewer#refresh() + */ + @Override + public void refresh() { + try { + super.refresh(); + } finally { + grid.refreshData(); + } + } + + /** {@inheritDoc} */ + @Override + protected void doSetItemCount(int count) { + grid.setItemCount(count); + } + + /** {@inheritDoc} */ + @Override + protected void doDeselectAll() { + grid.deselectAll(); + } + + /** {@inheritDoc} */ + @Override + protected Widget doGetColumn(int index) { + return grid.getColumn(index); + } + + /** {@inheritDoc} */ + @Override + protected int doGetColumnCount() { + return grid.getColumnCount(); + } + + /** {@inheritDoc} */ + @Override + protected Item doGetItem(int index) { + return grid.getItem(index); + } + + /** {@inheritDoc} */ + @Override + protected int doGetItemCount() { + return grid.getItemCount(); + } + + /** {@inheritDoc} */ + @Override + protected Item[] doGetItems() { + return grid.getItems(); + } + + /** {@inheritDoc} */ + @Override + protected Item[] doGetSelection() { + return grid.getSelection(); + } + + /** {@inheritDoc} */ + @Override + protected int[] doGetSelectionIndices() { + return grid.getSelectionIndices(); + } + + /** {@inheritDoc} */ + @Override + protected int doIndexOf(Item item) { + return ((GridItem) item).getRowIndex(); + } + + /** {@inheritDoc} */ + @Override + protected void doRemove(int[] indices) { + grid.remove(indices); + } + + /** {@inheritDoc} */ + @Override + protected void doRemove(int start, int end) { + grid.remove(start, end); + } + + /** {@inheritDoc} */ + @SuppressWarnings("deprecation") + @Override + protected void doRemoveAll() { + grid.removeAll(); + } + + /** + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.AbstractTableViewer#handleDispose(org.eclipse.swt.events.DisposeEvent) + * fix crossed reference for GC + */ + @Override + protected void handleDispose(final DisposeEvent event) { + super.handleDispose(event); + + cachedRow = null; + rowHeaderLabelProvider = null; + + getGrid().setRedraw(false); + getGrid().disposeAllItems(); + getGrid().clearItems(); + } + + /** {@inheritDoc} */ + @Override + protected void doSetSelection(Item[] items) { + GridItem[] items2 = new GridItem[items.length]; + for (int i = 0; i < items.length; i++) { + items2[i] = (GridItem) items[i]; + } + grid.setSelection(items2); + grid.showSelection(); + } + + /** {@inheritDoc} */ + @Override + protected void doSetSelection(int[] indices) { + grid.setSelection(indices); + } + + /** {@inheritDoc} */ + @Override + protected void doShowItem(Item item) { + grid.showItem((GridItem) item); + } + + /** {@inheritDoc} */ + @Override + protected void doShowSelection() { + grid.showSelection(); + } + + /** {@inheritDoc} */ + @Override + protected Item getItemAt(Point point) { + return grid.getItem(point); + } + + /** {@inheritDoc} */ + @Override + public Control getControl() { + return grid; + } + + /** {@inheritDoc} */ + @Override + protected ViewerRow getViewerRowFromItem(Widget item) { + if (cachedRow == null) { + cachedRow = new GridViewerRow((GridItem) item); + } else { + cachedRow.setItem((GridItem) item); + } + + return cachedRow; + } + + /** + * {@inheritDoc} + */ + @Override + protected void doResetItem(Item item) { + GridItem gridItem = (GridItem) item; + int columnCount = Math.max(1, grid.getColumnCount()); + for (int i = 0; i < columnCount; i++) { + gridItem.setText(i, ""); //$NON-NLS-1$ + gridItem.setImage(null); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void doSelect(int[] indices) { + grid.select(indices); + } + + /** + * When set to true, this grid viewer will ensure that each of the grid's items + * is always automatically sized to its preferred height. The default is false. + *

+ * Since this mechanism usually leads to a grid with rows of different heights + * and thus to a grid with decreased performance, it should only be applied if + * that is intended. To set the height of all items to a specific value, use + * {@link Grid#setItemHeight(int)} instead. + *

+ * When a column with activated word wrapping is resized by dragging the column + * resizer, the items are only auto-resized properly if you use + * {@link GridViewerColumn} to create the columns. + *

+ * When this method is called, existing rows are not resized to their preferred + * height. Therefore it is suggested that this method be called before rows are + * populated (i.e. before setInput). + * + * @param autoPreferredHeight + */ + public void setAutoPreferredHeight(boolean autoPreferredHeight) { + this.autoPreferredHeight = autoPreferredHeight; + } + + /** + * @return true if this grid viewer sizes its rows to their preferred height + * @see #setAutoPreferredHeight(boolean) + */ + public boolean getAutoPreferredHeight() { + return autoPreferredHeight; + } + + /** {@inheritDoc} */ + @Override + protected void doUpdateItem(Widget widget, Object element, boolean fullMap) { + super.doUpdateItem(widget, element, fullMap); + updateRowHeader(widget); + if (autoPreferredHeight && !widget.isDisposed()) + ((GridItem) widget).pack(); + } + + private void updateRowHeader(Widget widget) { + if (rowHeaderLabelProvider != null) { + ViewerCell cell = getViewerRowFromItem(widget).getCell(Integer.MAX_VALUE); + rowHeaderLabelProvider.update(cell); + } + } + + /** + * Label provider used by calculate the row header text + * + * @param rowHeaderLabelProvider + * the provider + */ + public void setRowHeaderLabelProvider(CellLabelProvider rowHeaderLabelProvider) { + this.rowHeaderLabelProvider = rowHeaderLabelProvider; + } + + /** + * Refresh row headers only + * + * @param element + * the element to start or null if all rows should be + * refreshed + */ + public void refreshRowHeaders(Object element) { + boolean refresh = element == null; + + for (int i = 0; i < getGrid().getItemCount(); i++) { + if (refresh || element.equals(getGrid().getItem(i).getData())) { + refresh = true; + updateRowHeader(getGrid().getItem(i)); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void editElement(Object element, int column) { + try { + getControl().setRedraw(false); + Widget item = findItem(element); + if (item != null) { + ViewerRow row = getViewerRowFromItem(item); + if (row != null) { + ViewerCell cell = row.getCell(column); + if (cell != null) { + triggerEditorActivationEvent(new ColumnViewerEditorActivationEvent(cell)); + } + } + } + } finally { + getControl().setRedraw(true); + } + // } + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + protected void setSelectionToWidget(ISelection selection, boolean reveal) { + if (!grid.isCellSelectionEnabled() || !(selection instanceof CellSelection)) { + super.setSelectionToWidget(selection, reveal); + Object el = null; + if (selection instanceof SelectionWithFocusRow) { + el = ((SelectionWithFocusRow) selection).getFocusElement(); + } else if (selection instanceof IStructuredSelection) { + el = ((IStructuredSelection) selection).getFirstElement(); + } + if (el != null) { + for (int i = 0; i < grid.getItemCount(); i++) { + GridItem item = grid.getItem(i); + if (item.getData() == el || el.equals(item.getData()) + || (getComparer() != null && getComparer().equals(item.getData(), el))) { + grid.setFocusItem(item); + break; + } + } + } + } else { + CellSelection cellSelection = (CellSelection) selection; + List l = cellSelection.toList(); + ArrayList pts = new ArrayList(); + + for (int i = 0; i < grid.getItemCount(); i++) { + Iterator it = l.iterator(); + Object itemObject = grid.getItem(i).getData(); + while (it.hasNext()) { + Object checkObject = it.next(); + if (itemObject == checkObject + || (getComparer() != null && getComparer().equals(itemObject, checkObject))) { + Iterator idxIt = cellSelection.getIndices(checkObject).iterator(); + while (idxIt.hasNext()) { + Integer idx = (Integer) idxIt.next(); + pts.add(new Point(idx.intValue(), i)); + } + } + } + } + Point[] tmp = new Point[pts.size()]; + pts.toArray(tmp); + grid.setCellSelection(tmp); + if (cellSelection.getFocusElement() != null) { + Object el = cellSelection.getFocusElement(); + for (int i = 0; i < grid.getItemCount(); i++) { + GridItem item = grid.getItem(i); + if (item.getData() == el || item.getData().equals(el) + || (getComparer() != null && getComparer().equals(item.getData(), el))) { + grid.setFocusItem(item); + break; + } + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public ISelection getSelection() { + if (grid == null || grid.isDisposed()) { + return StructuredSelection.EMPTY; + } + if (!grid.isCellSelectionEnabled()) { + IStructuredSelection selection = (IStructuredSelection) super.getSelection(); + Object el = null; + if (grid.getFocusItem() != null && !grid.getFocusItem().isDisposed()) { + el = grid.getFocusItem().getData(); + } + return new SelectionWithFocusRow(selection.toList(), el, getComparer()); + } else { + return createCellSelection(); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private CellSelection createCellSelection() { + Point[] ps = grid.getCellSelection(); + Arrays.sort(ps, new Comparator() { + + @Override + public int compare(Object arg0, Object arg1) { + Point a = (Point) arg0; + Point b = (Point) arg1; + int rv = a.y - b.y; + + if (rv == 0) { + rv = a.x - b.x; + } + + return rv; + } + }); + + ArrayList objectList = new ArrayList(); + ArrayList indiceLists = new ArrayList(); + ArrayList indiceList = new ArrayList(); + + int curLine = -1; + + for (int i = 0; i < ps.length; i++) { + if (curLine != ps[i].y) { + curLine = ps[i].y; + indiceList = new ArrayList(); + + indiceLists.add(indiceList); + objectList.add(grid.getItem(curLine).getData()); + } + indiceList.add(new Integer(ps[i].x)); + } + + Object focusElement = null; + + if (grid.getFocusItem() != null && !grid.getFocusItem().isDisposed()) { + focusElement = grid.getFocusItem().getData(); + } + + return new CellSelection(objectList, indiceLists, focusElement, getComparer()); + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/AbstractRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/AbstractRenderer.java index 3954aa41d..c2f93ef54 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/AbstractRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/AbstractRenderer.java @@ -1,231 +1,231 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Display; - -/** - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A PRE-RELEASE ALPHA - * VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE VERSIONS. - *

- * Base implementation of IRenderer. Provides management of a few values. - * - * @author chris.gross@us.ibm.com - */ -public abstract class AbstractRenderer implements IRenderer -{ - /** Hover state. */ - private boolean hover; - - /** Renderer has focus. */ - private boolean focus; - - /** Mouse down on the renderer area. */ - private boolean mouseDown; - - /** Selection state. */ - private boolean selected; - - /** Expansion state. */ - private boolean expanded; - - /** The bounds the renderer paints on. */ - private Rectangle bounds = new Rectangle(0, 0, 0, 0); - - /** Display used to create GC to perform painting. */ - private Display display; - - /** - * Returns the bounds. - * - * @return Rectangle describing the bounds. - */ - public Rectangle getBounds() - { - return bounds; - } - - /** - * {@inheritDoc} - */ - public void setBounds(int x, int y, int width, int height) - { - setBounds(new Rectangle(x, y, width, height)); - } - - - /** - * {@inheritDoc} - */ - public void setBounds(Rectangle bounds) - { - this.bounds = bounds; - } - - /** - * Returns the size. - * - * @return size of the renderer. - */ - public Point getSize() - { - return new Point(bounds.width, bounds.height); - } - - /** - * {@inheritDoc} - */ - public void setLocation(int x, int y) - { - setBounds(new Rectangle(x, y, bounds.width, bounds.height)); - } - - /** - * {@inheritDoc} - */ - public void setLocation(Point location) - { - setBounds(new Rectangle(location.x, location.y, bounds.width, bounds.height)); - } - - /** - * {@inheritDoc} - */ - public void setSize(int width, int height) - { - setBounds(new Rectangle(bounds.x, bounds.y, width, height)); - } - - /** - * {@inheritDoc} - */ - public void setSize(Point size) - { - setBounds(new Rectangle(bounds.x, bounds.y, size.x, size.y)); - } - - /** - * Returns a boolean value indicating if this renderer has focus. - * - * @return True/false if has focus. - */ - public boolean isFocus() - { - return focus; - } - - /** - * {@inheritDoc} - */ - public void setFocus(boolean focus) - { - this.focus = focus; - } - - /** - * Returns the hover state. - * - * @return Is the renderer in the hover state. - */ - public boolean isHover() - { - return hover; - } - - /** - * {@inheritDoc} - */ - public void setHover(boolean hover) - { - this.hover = hover; - } - - /** - * Returns the boolean value indicating if the renderer has the mouseDown - * state. - * - * @return mouse down state. - */ - public boolean isMouseDown() - { - return mouseDown; - } - - /** - * {@inheritDoc} - */ - public void setMouseDown(boolean mouseDown) - { - this.mouseDown = mouseDown; - } - - /** - * Returns the boolean state indicating if the selected state is set. - * - * @return selected state. - */ - public boolean isSelected() - { - return selected; - } - - /** - * {@inheritDoc} - */ - public void setSelected(boolean selected) - { - this.selected = selected; - } - - /** - * Returns the expansion state. - * - * @return Returns the expanded. - */ - public boolean isExpanded() - { - return expanded; - } - - /** - * Sets the expansion state of this renderer. - * - * @param expanded The expanded to set. - */ - public void setExpanded(boolean expanded) - { - this.expanded = expanded; - } - - /** - * Sets the display for the renderer. - * - * @return Returns the display. - */ - public Display getDisplay() - { - return display; - } - - /** - * {@inheritDoc} - */ - public void setDisplay(Display display) - { - this.display = display; - } -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; + +/** + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A PRE-RELEASE ALPHA + * VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE VERSIONS. + *

+ * Base implementation of IRenderer. Provides management of a few values. + * + * @author chris.gross@us.ibm.com + */ +public abstract class AbstractRenderer implements IRenderer +{ + /** Hover state. */ + private boolean hover; + + /** Renderer has focus. */ + private boolean focus; + + /** Mouse down on the renderer area. */ + private boolean mouseDown; + + /** Selection state. */ + private boolean selected; + + /** Expansion state. */ + private boolean expanded; + + /** The bounds the renderer paints on. */ + private Rectangle bounds = new Rectangle(0, 0, 0, 0); + + /** Display used to create GC to perform painting. */ + private Display display; + + /** + * Returns the bounds. + * + * @return Rectangle describing the bounds. + */ + public Rectangle getBounds() + { + return bounds; + } + + /** + * {@inheritDoc} + */ + public void setBounds(int x, int y, int width, int height) + { + setBounds(new Rectangle(x, y, width, height)); + } + + + /** + * {@inheritDoc} + */ + public void setBounds(Rectangle bounds) + { + this.bounds = bounds; + } + + /** + * Returns the size. + * + * @return size of the renderer. + */ + public Point getSize() + { + return new Point(bounds.width, bounds.height); + } + + /** + * {@inheritDoc} + */ + public void setLocation(int x, int y) + { + setBounds(new Rectangle(x, y, bounds.width, bounds.height)); + } + + /** + * {@inheritDoc} + */ + public void setLocation(Point location) + { + setBounds(new Rectangle(location.x, location.y, bounds.width, bounds.height)); + } + + /** + * {@inheritDoc} + */ + public void setSize(int width, int height) + { + setBounds(new Rectangle(bounds.x, bounds.y, width, height)); + } + + /** + * {@inheritDoc} + */ + public void setSize(Point size) + { + setBounds(new Rectangle(bounds.x, bounds.y, size.x, size.y)); + } + + /** + * Returns a boolean value indicating if this renderer has focus. + * + * @return True/false if has focus. + */ + public boolean isFocus() + { + return focus; + } + + /** + * {@inheritDoc} + */ + public void setFocus(boolean focus) + { + this.focus = focus; + } + + /** + * Returns the hover state. + * + * @return Is the renderer in the hover state. + */ + public boolean isHover() + { + return hover; + } + + /** + * {@inheritDoc} + */ + public void setHover(boolean hover) + { + this.hover = hover; + } + + /** + * Returns the boolean value indicating if the renderer has the mouseDown + * state. + * + * @return mouse down state. + */ + public boolean isMouseDown() + { + return mouseDown; + } + + /** + * {@inheritDoc} + */ + public void setMouseDown(boolean mouseDown) + { + this.mouseDown = mouseDown; + } + + /** + * Returns the boolean state indicating if the selected state is set. + * + * @return selected state. + */ + public boolean isSelected() + { + return selected; + } + + /** + * {@inheritDoc} + */ + public void setSelected(boolean selected) + { + this.selected = selected; + } + + /** + * Returns the expansion state. + * + * @return Returns the expanded. + */ + public boolean isExpanded() + { + return expanded; + } + + /** + * Sets the expansion state of this renderer. + * + * @param expanded The expanded to set. + */ + public void setExpanded(boolean expanded) + { + this.expanded = expanded; + } + + /** + * Sets the display for the renderer. + * + * @return Returns the display. + */ + public Display getDisplay() + { + return display; + } + + /** + * {@inheritDoc} + */ + public void setDisplay(Display display) + { + this.display = display; + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/AdaptedDataVisualizer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/AdaptedDataVisualizer.java index 0eda62f13..e15f2cd3d 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/AdaptedDataVisualizer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/AdaptedDataVisualizer.java @@ -1,361 +1,361 @@ -/******************************************************************************* - * Copyright (c) 2014 Mirko Paturzo (Exeura srl). - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Mirko Paturzo - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; - -/** - * A basic implementation of the DataVisualizer interface. This class can be used - * to provide general visualization values for various aspects of the GridItem like - * background, font and text. - * Scope of this implementation: reduce memory usage by avoid duplication of - * visualization data like string, fonts, and others. - * In this example, DataVisualizer is customized on Object named MyModel: LabelProvider - * is not required. - * - * - *
- * class MyOwnDataVisualizer extends AdaptedDataVisualizer {
- *		FontRegistry registry = new FontRegistry();
- *		
- *		private final MyModel models[];
- *		
- *		public MyOwnDataVisualizer(MyModel models[]) {
- *			this.models = models;
- *		}
- *		
- *		@Override
- *		public Image getImage(GridItem gridItem, int columnIndex) {
- *			return null;
- *		}
- *
- *		@Override
- *		public String getText(GridItem gridItem, int columnIndex) {
- *			return "Column " + columnIndex + " => " + models[gridItem.getRowIndex()].toString();
- *		}
- *
- *		@Override
- *		public Font getFont(GridItem gridItem, int columnIndex) {
- *			if ((models[gridItem.getRowIndex()]).counter % 2 == 0) {
- *				return registry.getBold(Display.getCurrent().getSystemFont()
- *						.getFontData()[0].getName());
- *			}
- *			return null;
- *		}
- *	}
- * 
- * - * @author Mirko Paturzo - * - */ -public class AdaptedDataVisualizer implements DataVisualizer { - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setBackground(GridItem, int, org.eclipse.swt.graphics.Color) - */ - @Override - public void setBackground(GridItem gridItem, int index, Color color) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setChecked(GridItem, int, boolean) - */ - @Override - public void setChecked(GridItem gridItem, int i, boolean checked) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setColumnSpan(GridItem, int, int) - */ - @Override - public void setColumnSpan(GridItem gridItem, int index, int span) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setRowSpan(GridItem, int, int) - */ - @Override - public void setRowSpan(GridItem gridItem, int index, int span) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setFont(GridItem, int, org.eclipse.swt.graphics.Font) - */ - @Override - public void setFont(GridItem gridItem, int index, Font font) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setForeground(GridItem, int, org.eclipse.swt.graphics.Color) - */ - @Override - public void setForeground(GridItem gridItem, int index, Color foreground) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setGrayed(GridItem, int, boolean) - */ - @Override - public void setGrayed(GridItem gridItem, int i, boolean grayed) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setImage(GridItem, int, org.eclipse.swt.graphics.Image) - */ - @Override - public void setImage(GridItem gridItem, int i, Image image) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setText(GridItem, int, java.lang.String) - */ - @Override - public void setText(GridItem gridItem, int i, String text) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setCheckable(GridItem, int, boolean) - */ - @Override - public void setCheckable(GridItem gridItem, int index, boolean checked) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setToolTipText(GridItem, int, java.lang.String) - */ - @Override - public void setToolTipText(GridItem gridItem, int index, String tooltip) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getBackground(GridItem, int) - */ - @Override - public Color getBackground(GridItem gridItem, int index) { - return getDefaultBackground(); - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getChecked(GridItem, int) - */ - @Override - public boolean getChecked(GridItem gridItem, int i) { - return false; - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getColumnSpan(GridItem, int) - */ - @Override - public int getColumnSpan(GridItem gridItem, int index) { - return 0; - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getRowSpan(GridItem, int) - */ - @Override - public int getRowSpan(GridItem gridItem, int index) { - return 0; - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getFont(GridItem, int) - */ - @Override - public Font getFont(GridItem gridItem, int index) { - return getDefaultFont(); - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getForeground(GridItem, int) - */ - @Override - public Color getForeground(GridItem gridItem, int index) { - return getDefaultForeground(); - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getGrayed(GridItem, int) - */ - @Override - public boolean getGrayed(GridItem gridItem, int index) { - return false; - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getImage(GridItem, int) - */ - @Override - public Image getImage(GridItem gridItem, int i) { - return null; - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getText(GridItem, int) - */ - @Override - public String getText(GridItem gridItem, int i) { - return null; - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getCheckable(GridItem, int) - */ - @Override - public boolean getCheckable(GridItem gridItem, int index) { - return false; - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getToolTipText(GridItem, int) - */ - @Override - public String getToolTipText(GridItem gridItem, int index) { - return null; - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#clearRow(GridItem) - */ - @Override - public void clearRow(GridItem gridItem) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#clearColumn(int) - */ - @Override - public void clearColumn(int column) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getDefaultBackground() - */ - @Override - public Color getDefaultBackground() { - return Display.getCurrent().getSystemColor(SWT.COLOR_WHITE); - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getDefaultForeground() - */ - @Override - public Color getDefaultForeground() { - return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getDefaultFont() - */ - @Override - public Font getDefaultFont() { - return null; - } - - /** (non-Javadoc) - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#addColumn(int) - */ - @Override - public void addColumn(int column) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setDefaultBackground(org.eclipse.swt.graphics.Color) - */ - @Override - public void setDefaultBackground(Color defaultBackground) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setDefaultForeground(org.eclipse.swt.graphics.Color) - */ - @Override - public void setDefaultForeground(Color defaultForeground) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setDefaultFont(org.eclipse.swt.graphics.Font) - */ - @Override - public void setDefaultFont(Font defaultFont) { - /** - * Is empty - */ - } - - /** - * @see org.eclipse.nebula.widgets.grid.DataVisualizer#clearAll() - */ - @Override - public void clearAll() - { - /** - * Is empty - */ - } - -} +/******************************************************************************* + * Copyright (c) 2014 Mirko Paturzo (Exeura srl). + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Mirko Paturzo - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +/** + * A basic implementation of the DataVisualizer interface. This class can be used + * to provide general visualization values for various aspects of the GridItem like + * background, font and text. + * Scope of this implementation: reduce memory usage by avoid duplication of + * visualization data like string, fonts, and others. + * In this example, DataVisualizer is customized on Object named MyModel: LabelProvider + * is not required. + * + * + *
+ * class MyOwnDataVisualizer extends AdaptedDataVisualizer {
+ *		FontRegistry registry = new FontRegistry();
+ *		
+ *		private final MyModel models[];
+ *		
+ *		public MyOwnDataVisualizer(MyModel models[]) {
+ *			this.models = models;
+ *		}
+ *		
+ *		@Override
+ *		public Image getImage(GridItem gridItem, int columnIndex) {
+ *			return null;
+ *		}
+ *
+ *		@Override
+ *		public String getText(GridItem gridItem, int columnIndex) {
+ *			return "Column " + columnIndex + " => " + models[gridItem.getRowIndex()].toString();
+ *		}
+ *
+ *		@Override
+ *		public Font getFont(GridItem gridItem, int columnIndex) {
+ *			if ((models[gridItem.getRowIndex()]).counter % 2 == 0) {
+ *				return registry.getBold(Display.getCurrent().getSystemFont()
+ *						.getFontData()[0].getName());
+ *			}
+ *			return null;
+ *		}
+ *	}
+ * 
+ * + * @author Mirko Paturzo + * + */ +public class AdaptedDataVisualizer implements DataVisualizer { + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setBackground(GridItem, int, org.eclipse.swt.graphics.Color) + */ + @Override + public void setBackground(GridItem gridItem, int index, Color color) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setChecked(GridItem, int, boolean) + */ + @Override + public void setChecked(GridItem gridItem, int i, boolean checked) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setColumnSpan(GridItem, int, int) + */ + @Override + public void setColumnSpan(GridItem gridItem, int index, int span) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setRowSpan(GridItem, int, int) + */ + @Override + public void setRowSpan(GridItem gridItem, int index, int span) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setFont(GridItem, int, org.eclipse.swt.graphics.Font) + */ + @Override + public void setFont(GridItem gridItem, int index, Font font) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setForeground(GridItem, int, org.eclipse.swt.graphics.Color) + */ + @Override + public void setForeground(GridItem gridItem, int index, Color foreground) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setGrayed(GridItem, int, boolean) + */ + @Override + public void setGrayed(GridItem gridItem, int i, boolean grayed) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setImage(GridItem, int, org.eclipse.swt.graphics.Image) + */ + @Override + public void setImage(GridItem gridItem, int i, Image image) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setText(GridItem, int, java.lang.String) + */ + @Override + public void setText(GridItem gridItem, int i, String text) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setCheckable(GridItem, int, boolean) + */ + @Override + public void setCheckable(GridItem gridItem, int index, boolean checked) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setToolTipText(GridItem, int, java.lang.String) + */ + @Override + public void setToolTipText(GridItem gridItem, int index, String tooltip) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getBackground(GridItem, int) + */ + @Override + public Color getBackground(GridItem gridItem, int index) { + return getDefaultBackground(); + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getChecked(GridItem, int) + */ + @Override + public boolean getChecked(GridItem gridItem, int i) { + return false; + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getColumnSpan(GridItem, int) + */ + @Override + public int getColumnSpan(GridItem gridItem, int index) { + return 0; + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getRowSpan(GridItem, int) + */ + @Override + public int getRowSpan(GridItem gridItem, int index) { + return 0; + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getFont(GridItem, int) + */ + @Override + public Font getFont(GridItem gridItem, int index) { + return getDefaultFont(); + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getForeground(GridItem, int) + */ + @Override + public Color getForeground(GridItem gridItem, int index) { + return getDefaultForeground(); + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getGrayed(GridItem, int) + */ + @Override + public boolean getGrayed(GridItem gridItem, int index) { + return false; + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getImage(GridItem, int) + */ + @Override + public Image getImage(GridItem gridItem, int i) { + return null; + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getText(GridItem, int) + */ + @Override + public String getText(GridItem gridItem, int i) { + return null; + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getCheckable(GridItem, int) + */ + @Override + public boolean getCheckable(GridItem gridItem, int index) { + return false; + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getToolTipText(GridItem, int) + */ + @Override + public String getToolTipText(GridItem gridItem, int index) { + return null; + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#clearRow(GridItem) + */ + @Override + public void clearRow(GridItem gridItem) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#clearColumn(int) + */ + @Override + public void clearColumn(int column) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getDefaultBackground() + */ + @Override + public Color getDefaultBackground() { + return Display.getCurrent().getSystemColor(SWT.COLOR_WHITE); + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getDefaultForeground() + */ + @Override + public Color getDefaultForeground() { + return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#getDefaultFont() + */ + @Override + public Font getDefaultFont() { + return null; + } + + /** (non-Javadoc) + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#addColumn(int) + */ + @Override + public void addColumn(int column) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setDefaultBackground(org.eclipse.swt.graphics.Color) + */ + @Override + public void setDefaultBackground(Color defaultBackground) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setDefaultForeground(org.eclipse.swt.graphics.Color) + */ + @Override + public void setDefaultForeground(Color defaultForeground) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#setDefaultFont(org.eclipse.swt.graphics.Font) + */ + @Override + public void setDefaultFont(Font defaultFont) { + /** + * Is empty + */ + } + + /** + * @see org.eclipse.nebula.widgets.grid.DataVisualizer#clearAll() + */ + @Override + public void clearAll() + { + /** + * Is empty + */ + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/DefaultEmptyCellRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/DefaultEmptyCellRenderer.java index 67e2a47fc..9aa5bd94e 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/DefaultEmptyCellRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/DefaultEmptyCellRenderer.java @@ -1,103 +1,103 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * The empty cell renderer. - * - * @author chris.gross@us.ibm.com - * @since 2.0.0 - */ -public class DefaultEmptyCellRenderer extends GridCellRenderer -{ - - /** - * {@inheritDoc} - */ - public void paint(GC gc, Object value) - { - - Grid table = null; - if (value instanceof Grid) - table = (Grid)value; - - GridItem item; - if (value instanceof GridItem) - { - item = (GridItem)value; - table = item.getParent(); - } - - boolean drawBackground = true; - - if (isSelected()) - { - boolean hasFocus = table.isFocusOnGrid(); - Color backgroundColor = hasFocus?getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION):getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW); - Color foregroundColor = hasFocus?getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT):getDisplay().getSystemColor(SWT.COLOR_BLACK); - gc.setBackground(backgroundColor); - gc.setForeground(foregroundColor); - } - else - { - if (table.isEnabled()) - { - drawBackground = false; - } - else - { - gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - } - gc.setForeground(table.getForeground()); - } - - if (drawBackground) - gc.fillRectangle(getBounds().x, getBounds().y, getBounds().width + 1, - getBounds().height); - - if (table.getLinesVisible()) - { - gc.setForeground(table.getLineColor()); - gc.drawLine(getBounds().x, getBounds().y + getBounds().height, getBounds().x - + getBounds().width, - getBounds().y + getBounds().height); - gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x - + getBounds().width - - 1, - getBounds().y + getBounds().height); - } - } - - /** - * {@inheritDoc} - */ - public Point computeSize(GC gc, int wHint, int hHint, Object value) - { - return new Point(wHint, hHint); - } - - /** - * {@inheritDoc} - */ - public boolean notify(int event, Point point, Object value) - { - return false; - } - -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * The empty cell renderer. + * + * @author chris.gross@us.ibm.com + * @since 2.0.0 + */ +public class DefaultEmptyCellRenderer extends GridCellRenderer +{ + + /** + * {@inheritDoc} + */ + public void paint(GC gc, Object value) + { + + Grid table = null; + if (value instanceof Grid) + table = (Grid)value; + + GridItem item; + if (value instanceof GridItem) + { + item = (GridItem)value; + table = item.getParent(); + } + + boolean drawBackground = true; + + if (isSelected()) + { + boolean hasFocus = table.isFocusOnGrid(); + Color backgroundColor = hasFocus?getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION):getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW); + Color foregroundColor = hasFocus?getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT):getDisplay().getSystemColor(SWT.COLOR_BLACK); + gc.setBackground(backgroundColor); + gc.setForeground(foregroundColor); + } + else + { + if (table.isEnabled()) + { + drawBackground = false; + } + else + { + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + } + gc.setForeground(table.getForeground()); + } + + if (drawBackground) + gc.fillRectangle(getBounds().x, getBounds().y, getBounds().width + 1, + getBounds().height); + + if (table.getLinesVisible()) + { + gc.setForeground(table.getLineColor()); + gc.drawLine(getBounds().x, getBounds().y + getBounds().height, getBounds().x + + getBounds().width, + getBounds().y + getBounds().height); + gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x + + getBounds().width + - 1, + getBounds().y + getBounds().height); + } + } + + /** + * {@inheritDoc} + */ + public Point computeSize(GC gc, int wHint, int hHint, Object value) + { + return new Point(wHint, hHint); + } + + /** + * {@inheritDoc} + */ + public boolean notify(int event, Point point, Object value) + { + return false; + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/Grid.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/Grid.java index 6bf7067f5..3eda62d86 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/Grid.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/Grid.java @@ -1,10502 +1,10502 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - * Chuck.Mastrandrea@sas.com - wordwrapping in bug 222280 - * smcduff@hotmail.com - wordwrapping in bug 222280 - * Claes Rosell - rowspan in bug 272384 - * Marco Maccaferri - fixed arrow scrolling in bug 294767 - * higerinbeijing@gmail.com . fixed selectionEvent.item in bug 286617 - * balarkrishnan@yahoo.com - fix in bug 298684 - * Enrico Schnepel - new API in 238729, bugfix in 294952, 322114 - * Benjamin Bortfeldt - new tooltip support in 300797 - * Thomas Halm - bugfix in 315397 - * Justin Dolezy - bugfix in 316598 - * Cosmin Ghita - bugfix in 323687 - * Pinard-Legry Guilhaume - bugfix in 267057 - * Thorsten Schenkel - bugfix in 356803 - * Mirko Paturzo - improvement (bugfix in 419928) - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Vector; -import java.util.function.Consumer; -import java.util.function.ToIntFunction; - -import org.eclipse.nebula.widgets.grid.internal.DefaultBottomLeftRenderer; -import org.eclipse.nebula.widgets.grid.internal.DefaultColumnGroupHeaderRenderer; -import org.eclipse.nebula.widgets.grid.internal.DefaultDropPointRenderer; -import org.eclipse.nebula.widgets.grid.internal.DefaultEmptyColumnFooterRenderer; -import org.eclipse.nebula.widgets.grid.internal.DefaultEmptyColumnHeaderRenderer; -import org.eclipse.nebula.widgets.grid.internal.DefaultEmptyRowHeaderRenderer; -import org.eclipse.nebula.widgets.grid.internal.DefaultFocusRenderer; -import org.eclipse.nebula.widgets.grid.internal.DefaultInsertMarkRenderer; -import org.eclipse.nebula.widgets.grid.internal.DefaultRowHeaderRenderer; -import org.eclipse.nebula.widgets.grid.internal.DefaultTopLeftRenderer; -import org.eclipse.nebula.widgets.grid.internal.GridToolTip; -import org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy; -import org.eclipse.nebula.widgets.grid.internal.NullScrollBarProxy; -import org.eclipse.nebula.widgets.grid.internal.ScrollBarProxyAdapter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.accessibility.ACC; -import org.eclipse.swt.accessibility.Accessible; -import org.eclipse.swt.accessibility.AccessibleAdapter; -import org.eclipse.swt.accessibility.AccessibleControlAdapter; -import org.eclipse.swt.accessibility.AccessibleControlEvent; -import org.eclipse.swt.accessibility.AccessibleEvent; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.dnd.DropTargetListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TreeEvent; -import org.eclipse.swt.events.TreeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ScrollBar; -import org.eclipse.swt.widgets.TypedListener; - -/** - * The Grid widget is a spreadsheet/table component that offers features not - * currently found in the base SWT Table. Features include cell selection, - * column grouping, column spanning, row headers, and more. - *

- * The item children that may be added to instances of this class must be of - * type {@code GridItem}. - *

- *
- *
Styles:
- *
SWT.SINGLE, SWT.MULTI, SWT.NO_FOCUS, SWT.CHECK, SWT.VIRTUAL
- *
Events:
- *
Selection, DefaultSelection
- *
- * - * @author chris.gross@us.ibm.com - * @author Mirko Paturzo - * - */ -public class Grid extends Canvas { - - /** - * Cached default font of Control.getFont. - */ - private Font defaultFont; - - // TODO: figure out better way to allow renderers to trigger events - // TODO: scroll as necessary when performing drag select (current strategy ok) - // TODO: need to refactor the way the range select remembers older selection - // TODO: remember why i decided i needed to refactor the way the range select - // remembers older selection - // TODO: need to alter how column drag selection works to allow selection of - // spanned cells - // TODO: JAVADOC! - // TODO: column freezing - - // TODO: Performance - need to cache top index - - /** - * @return {@link DataVisualizer} - */ - public DataVisualizer getDataVisualizer() { - return dataVisualizer; - } - - /** - * Object holding the visible range - */ - public static class GridVisibleRange { - private GridItem[] items = new GridItem[0]; - private GridColumn[] columns = new GridColumn[0]; - - /** - * @return the current items shown - */ - public GridItem[] getItems() { - return items; - } - - /** - * @return the current columns shown - */ - public GridColumn[] getColumns() { - return columns; - } - } - - /** - * Clear simply all GridItems - */ - public void clearItems() { - items.clear(); - rootItems.clear(); - deselectAll(); - redraw(); - } - - /** - * Accessibility default action for column headers and column group headers. - */ - private static final String ACC_COLUMN_DEFAULT_ACTION = "Click"; - - /** - * Accessibility default action for items. - */ - private static final String ACC_ITEM_DEFAULT_ACTION = "Double Click"; - - /** - * Accessibility expand action for tree items. - */ - private static final String ACC_ITEM_ACTION_EXPAND = "Expand"; - - /** - * Accessibility collapse action for tree items. - */ - private static final String ACC_ITEM_ACTION_COLLAPSE = "Collapse"; - - /** - * Accessibility name for the column group header toggle button. - */ - private static final String ACC_TOGGLE_BUTTON_NAME = "Toggle Button"; - - /** - * Alpha blending value used when drawing the dragged column header. - */ - private static final int COLUMN_DRAG_ALPHA = 128; - - /** - * Number of pixels below the header to draw the drop point. - */ - private static final int DROP_POINT_LOWER_OFFSET = 3; - - /** - * Horizontal scrolling increment, in pixels. - */ - private static final int HORZ_SCROLL_INCREMENT = 5; - - /** - * The area to the left and right of the column boundary/resizer that is still - * considered the resizer area. This prevents a user from having to be *exactly* - * over the resizer. - */ - private static final int COLUMN_RESIZER_THRESHOLD = 4; - - /** - * @see #COLUMN_RESIZER_THRESHOLD - */ - private static final int ROW_RESIZER_THRESHOLD = 3; - - /** - * The minimum width of a column header. - */ - private static final int MIN_COLUMN_HEADER_WIDTH = 20; - /** - * The minimum height of a row header. - */ - private static final int MIN_ROW_HEADER_HEIGHT = 10; - - /** - * The number used when sizing the row header (i.e. size it for '1000') - * initially. - */ - // private static final int INITIAL_ROW_HEADER_SIZING_VALUE = 1000; - - /** - * The factor to multiply the current row header sizing value by when - * determining the next sizing value. Used for performance reasons. - */ - // private static final int ROW_HEADER_SIZING_MULTIPLIER = 10; - - /** - * Tracks whether the scroll values are correct. If not they will be recomputed - * in onPaint. This allows us to get a free ride on top of the OS's paint event - * merging to assure that we don't perform this expensive operation when - * unnecessary. - */ - private boolean scrollValuesObsolete = false; - - /** - * When this variable is true, the pack is based only on the visible lines on - * the screen. - */ - private boolean visibleLinesBasedColumnPack = false; - - /** - * All items in the table, not just root items. - */ - private final List items = new ArrayList<>(); - - /** - * All root items. - */ - private final List rootItems = new ArrayList<>(); - - /** - * List of selected items. - */ - private final List selectedItems = new ArrayList<>(); - - /** - * Reference to the item in focus. - */ - private GridItem focusItem; - - private boolean cellSelectionEnabled = false; - private boolean cellDragSelectionEnabled = true; - - private final List selectedCells = new ArrayList<>(); - private final List selectedCellsBeforeRangeSelect = new ArrayList<>(); - - private boolean cellDragSelectionOccuring = false; - private boolean cellRowDragSelectionOccuring = false; - private boolean cellColumnDragSelectionOccuring = false; - private boolean cellDragCTRL = false; - private boolean followupCellSelectionEventOwed = false; - - private boolean cellSelectedOnLastMouseDown; - private boolean cellRowSelectedOnLastMouseDown; - private boolean cellColumnSelectedOnLastMouseDown; - - private GridColumn shiftSelectionAnchorColumn; - - private GridColumn focusColumn; - - private final List selectedColumns = new ArrayList<>(); - - /** - * This is the column that the user last navigated to, but may not be the - * focusColumn because that column may be spanned in the current row. This is - * only used in situations where the user has used the keyboard to navigate up - * or down in the table and the focusColumn has switched to a new column because - * the intended column (was maintained in this var) was spanned. The table will - * attempt to set focus back to the intended column during subsequent up/down - * navigations. - */ - private GridColumn intendedFocusColumn; - - /** - * List of table columns in creation/index order. - */ - private final List columns = new ArrayList<>(); - - /** - * List of the table columns in the order they are displayed. - */ - private final List displayOrderedColumns = new ArrayList<>(); - - private GridColumnGroup[] columnGroups = new GridColumnGroup[0]; - - /** - * Renderer to paint the top left area when both column and row headers are - * shown. - */ - private IRenderer topLeftRenderer = new DefaultTopLeftRenderer(); - - /** - * Renderer to paint the bottom left area when row headers and column footers - * are shown - */ - private IRenderer bottomLeftRenderer = new DefaultBottomLeftRenderer(); - - /** - * Renderer used to paint row headers. - */ - private IRenderer rowHeaderRenderer = new DefaultRowHeaderRenderer(); - - /** - * Renderer used to paint empty column headers, used when the columns don't fill - * the horz space. - */ - private IRenderer emptyColumnHeaderRenderer = new DefaultEmptyColumnHeaderRenderer(); - - /** - * Renderer used to paint empty column footers, used when the columns don't fill - * the horz space. - */ - private IRenderer emptyColumnFooterRenderer = new DefaultEmptyColumnFooterRenderer(); - - /** - * Renderer used to paint empty cells to fill horz and vert space. - */ - private GridCellRenderer emptyCellRenderer = new DefaultEmptyCellRenderer(); - - /** - * Renderer used to paint empty row headers when the rows don't fill the - * vertical space. - */ - private IRenderer emptyRowHeaderRenderer = new DefaultEmptyRowHeaderRenderer(); - - /** - * Renderers the UI affordance identifying where the dragged column will be - * dropped. - */ - private final IRenderer dropPointRenderer = new DefaultDropPointRenderer(); - - /** - * Renderer used to paint on top of an already painted row to denote focus. - */ - private IRenderer focusRenderer = new DefaultFocusRenderer(); - - /** - * Are row headers visible? - */ - private boolean rowHeaderVisible = false; - - /** - * Are column headers visible? - */ - private boolean columnHeadersVisible = false; - - /** - * Are column footers visible? - */ - private boolean columnFootersVisible = false; - - /** - * Type of selection behavior. Valid values are SWT.SINGLE and SWT.MULTI. - */ - private GridSelectionType selectionType = GridSelectionType.SINGLE; - - /** - * True if selection highlighting is enabled. - */ - private boolean selectionEnabled = true; - - /** - * Default height of items. This value is used for GridItems with a - * height of -1. - */ - private int itemHeight = 1; - - private boolean userModifiedItemHeight = false; - - /** - * Width of each row header. - */ - private int rowHeaderWidth = 0; - - /** - * The row header width is variable. The row header width gets larger as more - * rows are added to the table to ensure that the row header has enough room to - * display the longest string of numbers that display in the row header. This - * determination of how wide to make the row header is rather slow and therefore - * is only done at every 1000 items (or so). This variable remembers how many - * items were last computed and therefore when the number of items is greater - * than this value, we need to recalculate the row header width. See newItem(). - */ - // private int lastRowHeaderWidthCalculationAt = 0; - - /** - * Height of each column header. - */ - private int headerHeight = 0; - - /** - * Height of each column footer - */ - private int footerHeight = 0; - - /** - * True if mouse is hover on a column boundary and can resize the column. - */ - boolean hoveringOnColumnResizer = false; - - /** - * Reference to the column being resized. - */ - private GridColumn columnBeingResized; - - /** - * Are this Grid's rows resizeable? - */ - private boolean rowsResizeable = false; - - /** - * Is the user currently resizing a column? - */ - private boolean resizingColumn = false; - - /** - * The mouse X position when the user starts the resize. - */ - private int resizingStartX = 0; - - /** - * The width of the column when the user starts the resize. This, together with - * the resizingStartX determines the current width during resize. - */ - private int resizingColumnStartWidth = 0; - - private boolean hoveringOnRowResizer = false; - private GridItem rowBeingResized; - private boolean resizingRow = false; - private int resizingStartY; - private int resizingRowStartHeight; - - /** - * Reference to the column whose header is currently in a pushed state. - */ - private GridColumn columnBeingPushed; - - /** - * Is the user currently pushing a column header? - */ - private boolean pushingColumn = false; - - /** - * Is the user currently pushing a column header and hovering over that same - * header? - */ - private boolean pushingAndHovering = false; - - /** - * X position of the mouse when the user first pushes a column header. - */ - private int startHeaderPushX = 0; - - /** - * X position of the mouse when the user has initiated a drag. This is different - * than startHeaderPushX because the mouse is allowed some 'wiggle-room' until - * the header is put into drag mode. - */ - private int startHeaderDragX = 0; - - /** - * The current X position of the mouse during a header drag. - */ - private int currentHeaderDragX = 0; - - /** - * Are we currently dragging a column header? - */ - private boolean draggingColumn = false; - - private GridColumn dragDropBeforeColumn = null; - - private GridColumn dragDropAfterColumn = null; - - /** - * True if the current dragDropPoint is a valid drop point for the dragged - * column. This is false if the column groups are involved and a column is being - * dropped into or out of its column group. - */ - private boolean dragDropPointValid = true; - - /** - * Reference to the currently item that the mouse is currently hovering over. - */ - private GridItem hoveringItem; - - /** - * Reference to the column that the mouse is currently hovering over. Includes - * the header and all cells (all rows) in this column. - */ - private GridColumn hoveringColumn; - - private GridColumn hoveringColumnHeader; - - private GridColumnGroup hoverColumnGroupHeader; - - /** - * String-based detail of what is being hovered over in a cell. This allows a - * renderer to differentiate between hovering over different parts of the cell. - * For example, hovering over a checkbox in the cell or hovering over a tree - * node in the cell. The table does nothing with this string except to set it - * back in the renderer when its painted. The renderer sets this during its - * notify method (InternalWidget.HOVER) and the table pulls it back and - * maintains it so it can be set back when the cell is painted. The renderer - * determines what the hover detail means and how it affects painting. - */ - private String hoveringDetail = ""; - - /** - * True if the mouse is hovering of a cell's text. - */ - private boolean hoveringOverText = false; - - /** - * Are the grid lines visible? - */ - private boolean linesVisible = true; - - /** - * Are tree lines visible? - */ - private boolean treeLinesVisible = true; - - /** - * Grid line color. - */ - private Color lineColor; - - /** - * Vertical scrollbar proxy. - *

- * Note: - *

    - *
  • {@link Grid#getTopIndex()} is the only method allowed to call - * vScroll.getSelection() (except #updateScrollbars() of course)
  • - *
  • {@link Grid#setTopIndex(int)} is the only method allowed to call - * vScroll.setSelection(int)
  • - *
- */ - private IScrollBarProxy vScroll; - - /** - * Horizontal scrollbar proxy. - */ - private IScrollBarProxy hScroll; - - /** - * The number of GridItems whose visible = true. Maintained for performance - * reasons (rather than iterating over all items). - */ - private int currentVisibleItems = 0; - - /** - * Item selected when a multiple selection using shift+click first occurs. This - * item anchors all further shift+click selections. - */ - private GridItem shiftSelectionAnchorItem; - - private boolean columnScrolling = false; - - private int groupHeaderHeight; - - private Color cellHeaderSelectionBackground; - - /** - * Dispose listener. This listener is removed during the dispose event to allow - * re-firing of the event. - */ - private Listener disposeListener; - - /** - * The inplace tooltip. - */ - private GridToolTip inplaceToolTip; - - private Color backgroundColor; - - /** - * True if the widget is being disposed. When true, events are not fired. - */ - private boolean disposing = false; - - /** - * True if there is at least one tree node. This is used by accessibility and - * various places for optimization. - */ - private boolean isTree = false; - - /** - * True if there is at least one GridItem with an individual - * height. This value is only set to true in - * {@link GridItem#setHeight(int,boolean)} and it is never reset to false. - */ - boolean hasDifferingHeights = false; - - /** - * True if three is at least one cell spanning columns. This is used in various - * places for optimizatoin. - */ - private boolean hasSpanning = false; - - /** - * Index of first visible item. The value must never be read directly. It is - * cached and updated when appropriate. #getTopIndex should be called for every - * client (even internal callers). A value of -1 indicates that the value is old - * and will be recomputed. - * - * @see #bottomIndex - */ - int topIndex = -1; - /** - * Index of last visible item. The value must never be read directly. It is - * cached and updated when appropriate. #getBottomIndex() should be called for - * every client (even internal callers). A value of -1 indicates that the value - * is old and will be recomputed. - *

- * Note that the item with this index is often only partly visible; maybe only a - * single line of pixels is visible. In extreme cases, bottomIndex may be the - * same as topIndex. - * - * @see #topIndex - */ - int bottomIndex = -1; - - /** - * Index of the first visible column. A value of -1 indicates that the value is - * old and will be recomputed. - */ - int startColumnIndex = -1; - - /** - * Index of the the last visible column. A value of -1 indicates that the value - * is old and will be recomputed. - */ - int endColumnIndex = -1; - - /** - * True if the last visible item is completely visible. The value must never be - * read directly. It is cached and updated when appropriate. #isShown() should - * be called for every client (even internal callers). - * - * @see #bottomIndex - */ - private boolean bottomIndexShownCompletely = false; - - /** - * Tooltip text - overriden because we have cell specific tooltips - */ - private String toolTipText = null; - - /** - * Flag that is set to true as soon as one image is set on any one item. This is - * used to mimic Table behavior that resizes the rows on the first image added. - * See imageSetOnItem. - */ - private boolean firstImageSet = false; - - /** - * Mouse capture flag. Used for inplace tooltips. This flag must be used to - * ensure that we don't setCapture(false) in situations where we didn't do - * setCapture(true). The OS (SWT?) will automatically capture the mouse for us - * during a drag operation. - */ - private boolean inplaceTooltipCapture; - - /** - * This is the tooltip text currently used. This could be the tooltip text for - * the currently hovered cell, or the general grid tooltip. See handleCellHover. - */ - private String displayedToolTipText; - - /** - * The height of the area at the top and bottom of the visible grid area in - * which scrolling is initiated while dragging over this Grid. - */ - private static final int DRAG_SCROLL_AREA_HEIGHT = 12; - - /** - * Threshold for the selection border used for drag n drop in mode - * (!{@link #dragOnFullSelection}}. - */ - private static final int SELECTION_DRAG_BORDER_THRESHOLD = 2; - - private boolean hoveringOnSelectionDragArea = false; - - private GridItem insertMarkItem = null; - private GridColumn insertMarkColumn = null; - private boolean insertMarkBefore = false; - private final IRenderer insertMarkRenderer = new DefaultInsertMarkRenderer(); - private boolean sizeOnEveryItemImageChange; - private boolean autoHeight = false; - private boolean autoWidth = true; - private boolean wordWrapRowHeader = false; - - private final DataVisualizer dataVisualizer; - - private Listener defaultKeyListener; - - private boolean defaultKeyListenerEnabled = true; - - /** - * caching column orders improves grid rendering - */ - private int[] columnOrders; - - /** - * If true, when user types TAB the selection moved to the next line, and - * SHIFT-TAB move to the previous line - */ - private boolean moveOnTab = false; - - /** - * A range of rows in a Grid. - *

- * A row in this sense exists only for visible items (i.e. items with - * {@link GridItem#isVisible()} == true). Therefore, the items at 'startIndex' - * and 'endIndex' are always visible. - * - * @see Grid#getRowRange(int, int, boolean, boolean) - */ - private static class RowRange { - /** index of first item in range */ - public int startIndex; - /** index of last item in range */ - public int endIndex; - /** number of rows (i.e. visible items) in this range */ - public int rows; - /** - * height in pixels of this range (including horizontal separator between rows) - */ - public int height; - } - - /** - * Filters out unnecessary styles, adds mandatory styles and generally manages - * the style to pass to the super class. - * - * @param style - * user specified style. - * @return style to pass to the super class. - */ - private static int checkStyle(final int style) { - final int mask = SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE - | SWT.MULTI | SWT.NO_FOCUS | SWT.CHECK | SWT.VIRTUAL; - int newStyle = style & mask; - newStyle |= SWT.DOUBLE_BUFFERED; - return newStyle; - } - - /** - * Grid with generic DataVisualizer - * - * @param parent - * component - * @param style - * grid style - */ - public Grid(final Composite parent, final int style) { - this(new GridItemDataVisualizer(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE), - Display.getCurrent().getSystemColor(SWT.COLOR_BLACK), null), parent, style); - } - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * - * @param dataVisualizer - * manage all data of grid and its items - * @param parent - * a composite control which will be the parent of the new instance - * (cannot be null) - * @param style - * the style of control to construct - * @throws IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the parent
  • - *
- * @see SWT#SINGLE - * @see SWT#MULTI - */ - public Grid(final DataVisualizer dataVisualizer, final Composite parent, final int style) { - super(parent, checkStyle(style)); - - this.dataVisualizer = dataVisualizer; - - // initialize drag & drop support - setData("DEFAULT_DRAG_SOURCE_EFFECT", new GridDragSourceEffect(this)); - setData("DEFAULT_DROP_TARGET_EFFECT", new GridDropTargetEffect(this)); - - topLeftRenderer.setDisplay(getDisplay()); - bottomLeftRenderer.setDisplay(getDisplay()); - rowHeaderRenderer.setDisplay(getDisplay()); - emptyColumnHeaderRenderer.setDisplay(getDisplay()); - emptyColumnFooterRenderer.setDisplay(getDisplay()); - emptyCellRenderer.setDisplay(getDisplay()); - dropPointRenderer.setDisplay(getDisplay()); - focusRenderer.setDisplay(getDisplay()); - emptyRowHeaderRenderer.setDisplay(getDisplay()); - insertMarkRenderer.setDisplay(getDisplay()); - - setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND)); - setLineColor(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - - if ((style & SWT.MULTI) != 0) { - selectionType = GridSelectionType.MULTI; - } - - if (getVerticalBar() != null) { - getVerticalBar().setVisible(false); - vScroll = new ScrollBarProxyAdapter(getVerticalBar()); - } else { - vScroll = new NullScrollBarProxy(); - } - - if (getHorizontalBar() != null) { - getHorizontalBar().setVisible(false); - hScroll = new ScrollBarProxyAdapter(getHorizontalBar()); - } else { - hScroll = new NullScrollBarProxy(); - } - - scrollValuesObsolete = true; - - initListeners(); - initAccessible(); - - estimate(sizingGC -> itemHeight = sizingGC.getFontMetrics().getHeight() + 2); - - final RGB sel = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB(); - final RGB white = getDisplay().getSystemColor(SWT.COLOR_WHITE).getRGB(); - - final RGB cellSel = blend(sel, white, 50); - - cellHeaderSelectionBackground = new Color(getDisplay(), cellSel); - - setDragDetect(false); - } - - /** - * {@inheritDoc} - */ - @Override - public Color getBackground() { - checkWidget(); - if (backgroundColor == null) { - return getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); - } - return backgroundColor; - } - - /** - * {@inheritDoc} - */ - @Override - public void setBackground(final Color color) { - checkWidget(); - backgroundColor = color; - dataVisualizer.setDefaultBackground(color); - redraw(); - } - - /** - * Returns the background color of column and row headers when a cell in the row - * or header is selected. - * - * @return cell header selection background color - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public Color getCellHeaderSelectionBackground() { - checkWidget(); - return cellHeaderSelectionBackground; - } - - /** - * Sets the background color of column and row headers displayed when a cell in - * the row or header is selected. - * - * @param cellSelectionBackground - * color to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setCellHeaderSelectionBackground(final Color cellSelectionBackground) { - checkWidget(); - cellHeaderSelectionBackground = cellSelectionBackground; - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the receiver's selection changes, by sending it one of the messages defined - * in the {@code SelectionListener} interface. - *

- * Cell selection events may have Event.detail = SWT.DRAG when the - * user is drag selecting multiple cells. A follow up selection event will be - * generated when the drag is complete. - * - * @param listener - * the listener which should be notified - * @throws IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - addListener(SWT.Selection, new TypedListener(listener)); - addListener(SWT.DefaultSelection, new TypedListener(listener)); - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the receiver's items changes, by sending it one of the messages defined in - * the {@code TreeListener} interface. - * - * @param listener - * the listener which should be notified - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * @see TreeListener - * @see #removeTreeListener - * @see org.eclipse.swt.events.TreeEvent - */ - public void addTreeListener(final TreeListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - addListener(SWT.Expand, new TypedListener(listener)); - addListener(SWT.Collapse, new TypedListener(listener)); - } - - /** - * {@inheritDoc} - */ - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - checkWidget(); - - Point prefSize = null; - if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) { - prefSize = getTableSize(); - prefSize.x += 2 * getBorderWidth(); - prefSize.y += 2 * getBorderWidth(); - } - - int x = 0; - int y = 0; - - if (wHint == SWT.DEFAULT) { - x += prefSize.x; - if (getVerticalBar() != null) { - x += getVerticalBar().getSize().x; - } - } else { - x = wHint; - } - - if (hHint == SWT.DEFAULT) { - y += prefSize.y; - if (getHorizontalBar() != null) { - y += getHorizontalBar().getSize().y; - } - } else { - y = hHint; - } - - return new Point(x, y); - } - - /** - * Deselects the item at the given zero-relative index in the receiver. If the - * item at the index was already deselected, it remains deselected. Indices that - * are out of range are ignored. - *

- * If cell selection is enabled, all cells in the specified item are deselected. - * - * @param index - * the index of the item to deselect - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void deselect(final int index) { - checkWidget(); - - if (index < 0 || index > items.size() - 1) { - return; - } - - final GridItem item = items.get(index); - - if (!cellSelectionEnabled) { - if (selectedItems.contains(item)) { - selectedItems.remove(item); - } - } else { - deselectCells(getCells(item)); - } - redraw(); - } - - /** - * Deselects the items at the given zero-relative indices in the receiver. If - * the item at the given zero-relative index in the receiver is selected, it is - * deselected. If the item at the index was not selected, it remains deselected. - * The range of the indices is inclusive. Indices that are out of range are - * ignored. - *

- * If cell selection is enabled, all cells in the given range are deselected. - * - * @param start - * the start index of the items to deselect - * @param end - * the end index of the items to deselect - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void deselect(final int start, final int end) { - checkWidget(); - - for (int i = start; i <= end; i++) { - if (i < 0) { - continue; - } - if (i > items.size() - 1) { - break; - } - - final GridItem item = items.get(i); - - if (!cellSelectionEnabled) { - if (selectedItems.contains(item)) { - selectedItems.remove(item); - } - } else { - deselectCells(getCells(item)); - } - } - redraw(); - } - - /** - * Deselects the items at the given zero-relative indices in the receiver. If - * the item at the given zero-relative index in the receiver is selected, it is - * deselected. If the item at the index was not selected, it remains deselected. - * Indices that are out of range and duplicate indices are ignored. - *

- * If cell selection is enabled, all cells in the given items are deselected. - * - * @param indices - * the array of indices for the items to deselect - * @throws IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the set of indices is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void deselect(final int[] indices) { - checkWidget(); - if (indices == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - for (final int j : indices) { - if (j >= 0 && j < items.size()) { - final GridItem item = items.get(j); - - if (!cellSelectionEnabled) { - if (selectedItems.contains(item)) { - selectedItems.remove(item); - } - } else { - deselectCells(getCells(item)); - } - } - } - redraw(); - } - - /** - * Deselects all selected items in the receiver. If cell selection is enabled, - * all cells are deselected. - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void deselectAll() { - checkWidget(); - - if (!cellSelectionEnabled) { - selectedItems.clear(); - redraw(); - } else { - deselectAllCells(); - } - } - - /** - * Returns the column at the given, zero-relative index in the receiver. Throws - * an exception if the index is out of range. If no {@code GridColumn}s were - * created by the programmer, this method will throw {@code ERROR_INVALID_RANGE} - * despite the fact that a single column of data may be visible in the table. - * This occurs when the programmer uses the table like a list, adding items but - * never creating a column. - * - * @param index - * the index of the column to return - * @return the column at the given index - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the - * number of elements in the list minus 1 (inclusive)
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridColumn getColumn(final int index) { - checkWidget(); - - if (index < 0 || index > getColumnCount() - 1) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - - return columns.get(index); - } - - /** - * Returns the column at the given point in the receiver or null if no such - * column exists. The point is in the coordinate system of the receiver. - * - * @param point - * the point used to locate the column - * @return the column at the given point - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the point is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridColumn getColumn(final Point point) { - return getColumn(null, point); - } - - /** - * Returns the column at the given point and a known item in the receiver or - * null if no such column exists. The point is in the coordinate system of the - * receiver. - * - * @param item - * a known GridItem - * @param point - * the point used to locate the column - * @return the column at the given point - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the point is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - private GridColumn getColumn(GridItem item, final Point point) { - checkWidget(); - if (point == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - GridColumn overThis = null; - - int x2 = 0; - - if (rowHeaderVisible) { - if (point.x <= rowHeaderWidth) { - return null; - } - - x2 += rowHeaderWidth; - } - - x2 -= getHScrollSelectionInPixels(); - - for (final GridColumn column : displayOrderedColumns) { - if (!column.isVisible()) { - continue; - } - - if (point.x >= x2 && point.x < x2 + column.getWidth()) { - overThis = column; - break; - } - - x2 += column.getWidth(); - } - - if (overThis == null) { - return null; - } - - if (hasSpanning) { - // special logic for column spanning - if (item == null) { - item = getItem(point); - } - - if (item != null) { - final int displayColIndex = displayOrderedColumns.indexOf(overThis); - - // track back all previous columns and check their spanning - for (int i = 0; i < displayColIndex; i++) { - if (!displayOrderedColumns.get(i).isVisible()) { - continue; - } - - final int colIndex = displayOrderedColumns.get(i).index; - final int span = item.getColumnSpan(colIndex); - - if (i + span >= displayColIndex) { - overThis = displayOrderedColumns.get(i); - break; - } - } - } - } - - return overThis; - } - - /** - * Returns the number of columns contained in the receiver. If no - * {@code GridColumn}s were created by the programmer, this value is zero, - * despite the fact that visually, one column of items may be visible. This - * occurs when the programmer uses the table like a list, adding items but never - * creating a column. - * - * @return the number of columns - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getColumnCount() { - checkWidget(); - return columns.size(); - } - - /** - * Returns an array of zero-relative integers that map the creation order of the - * receiver's items to the order in which they are currently being displayed. - *

- * Specifically, the indices of the returned array represent the current visual - * order of the items, and the contents of the array represent the creation - * order of the items. - *

- *

- * Note: This is not the actual structure used by the receiver to maintain its - * list of items, so modifying the array will not affect the receiver. - *

- * - * @return the current visual order of the receiver's items - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int[] getColumnOrder() { - checkWidget(); - if (columnOrders == null) { - columnOrders = new int[columns.size()]; - int i = 0; - for (final GridColumn col : displayOrderedColumns) { - columnOrders[i] = col.index; - i++; - } - } - return columnOrders; - } - - /** - * Returns the number of column groups contained in the receiver. - * - * @return the number of column groups - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getColumnGroupCount() { - checkWidget(); - return columnGroups.length; - } - - /** - * Returns an array of {@code GridColumnGroup}s which are the column groups in - * the receiver. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * list of items, so modifying the array will not affect the receiver. - *

- * - * @return the column groups in the receiver - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridColumnGroup[] getColumnGroups() { - checkWidget(); - final GridColumnGroup[] newArray = new GridColumnGroup[columnGroups.length]; - System.arraycopy(columnGroups, 0, newArray, 0, columnGroups.length); - return newArray; - } - - /** - * Returns the column group at the given, zero-relative index in the receiver. - * Throws an exception if the index is out of range. - * - * @param index - * the index of the column group to return - * @return the column group at the given index - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the - * number of elements in the list minus 1 (inclusive)
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridColumnGroup getColumnGroup(final int index) { - checkWidget(); - - if (index < 0 || index >= columnGroups.length) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - - return columnGroups[index]; - } - - /** - * Sets the order that the items in the receiver should be displayed in to the - * given argument which is described in terms of the zero-relative ordering of - * when the items were added. - * - * @param order - * the new order to display the items - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS -if not called from the thread - * that created the receiver
  • - *
- * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item order is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the order is not the same length - * as the number of items, or if an item is listed twice, or if the - * order splits a column group
  • - *
- */ - public void setColumnOrder(final int[] order) { - checkWidget(); - - if (order == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (order.length != displayOrderedColumns.size()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - final boolean[] seen = new boolean[displayOrderedColumns.size()]; - - for (int i = 0; i < order.length; i++) { - if (order[i] < 0 || order[i] >= displayOrderedColumns.size()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - if (seen[order[i]]) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - seen[order[i]] = true; - } - - if (columnGroups.length != 0) { - GridColumnGroup currentGroup = null; - int colsInGroup = 0; - - for (final int element : order) { - final GridColumn col = getColumn(element); - - if (currentGroup != null) { - if (col.getColumnGroup() != currentGroup && colsInGroup > 0) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } else { - colsInGroup--; - if (colsInGroup <= 0) { - currentGroup = null; - } - } - } else if (col.getColumnGroup() != null) { - currentGroup = col.getColumnGroup(); - colsInGroup = currentGroup.getColumns().length - 1; - } - } - } - - final GridColumn[] cols = getColumns(); - - displayOrderedColumns.clear(); - - for (final int element : order) { - displayOrderedColumns.add(cols[element]); - } - clearDisplayOrderedCache(); - } - - /** - * This method is used for clearing columns displayed ordering cache - */ - private void clearDisplayOrderedCache() { - columnOrders = null; - } - - /** - * Returns an array of {@code GridColumn}s which are the columns in the - * receiver. If no {@code GridColumn}s were created by the programmer, the array - * is empty, despite the fact that visually, one column of items may be visible. - * This occurs when the programmer uses the table like a list, adding items but - * never creating a column. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * list of items, so modifying the array will not affect the receiver. - *

- * - * @return the items in the receiver - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridColumn[] getColumns() { - checkWidget(); - return columns.toArray(new GridColumn[columns.size()]); - } - - /** - * Returns the empty cell renderer. - * - * @return Returns the emptyCellRenderer. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridCellRenderer getEmptyCellRenderer() { - checkWidget(); - return emptyCellRenderer; - } - - /** - * Returns the empty column header renderer. - * - * @return Returns the emptyColumnHeaderRenderer. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public IRenderer getEmptyColumnHeaderRenderer() { - checkWidget(); - return emptyColumnHeaderRenderer; - } - - /** - * Returns the empty column footer renderer. - * - * @return Returns the emptyColumnFooterRenderer. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public IRenderer getEmptyColumnFooterRenderer() { - checkWidget(); - return emptyColumnFooterRenderer; - } - - /** - * Returns the empty row header renderer. - * - * @return Returns the emptyRowHeaderRenderer. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public IRenderer getEmptyRowHeaderRenderer() { - checkWidget(); - return emptyRowHeaderRenderer; - } - - /** - * Returns the externally managed horizontal scrollbar. - * - * @return the external horizontal scrollbar. - * @see #setHorizontalScrollBarProxy(IScrollBarProxy) - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - protected IScrollBarProxy getHorizontalScrollBarProxy() { - checkWidget(); - return hScroll; - } - - /** - * Returns the externally managed vertical scrollbar. - * - * @return the external vertical scrollbar. - * @see #setlVerticalScrollBarProxy(IScrollBarProxy) - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - protected IScrollBarProxy getVerticalScrollBarProxy() { - checkWidget(); - return vScroll; - } - - /** - * Gets the focus renderer. - * - * @return Returns the focusRenderer. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public IRenderer getFocusRenderer() { - checkWidget(); - return focusRenderer; - } - - /** - * Returns the height of the column headers. If this table has column groups, - * the returned value includes the height of group headers. - * - * @return height of the column header row - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getHeaderHeight() { - checkWidget(); - return headerHeight; - } - - /** - * Cached default font of Control.getFont - * - * @see org.eclipse.swt.widgets.Control#getFont() - */ - @Override - public Font getFont() { - if (defaultFont == null) { - defaultFont = super.getFont(); - } - return defaultFont; - } - - /** - * Returns the height of the column footers. - * - * @return height of the column footer row - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getFooterHeight() { - checkWidget(); - return footerHeight; - } - - /** - * Returns the height of the column group headers. - * - * @return height of column group headers - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getGroupHeaderHeight() { - checkWidget(); - return groupHeaderHeight; - } - - /** - * Returns {@code true} if the receiver's header is visible, and {@code false} - * otherwise. - * - * @return the receiver's header's visibility state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean getHeaderVisible() { - checkWidget(); - return columnHeadersVisible; - } - - /** - * Returns {@code true} if the receiver's footer is visible, and {@code false} - * otherwise - * - * @return the receiver's footer's visibility state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean getFooterVisible() { - checkWidget(); - return columnFootersVisible; - } - - /** - * Returns the item at the given, zero-relative index in the receiver. Throws an - * exception if the index is out of range. - * - * @param index - * the index of the item to return - * @return the item at the given index - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the - * number of elements in the list minus 1 (inclusive)
  • * - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridItem getItem(final int index) { - checkWidget(); - - if (index < 0 || index >= items.size()) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - - return items.get(index); - } - - /** - * Returns the item at the given point in the receiver or null if no such item - * exists. The point is in the coordinate system of the receiver. - * - * @param point - * the point used to locate the item - * @return the item at the given point - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the point is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridItem getItem(final Point point) { - checkWidget(); - - if (point == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (point.x < 0 || point.x > getClientArea().width) { - return null; - } - - final Point p = new Point(point.x, point.y); - - int y2 = 0; - - if (columnHeadersVisible) { - if (p.y <= headerHeight) { - return null; - } - y2 += headerHeight; - } - - GridItem itemToReturn = null; - - int row = getTopIndex(); - while (row < items.size() && y2 <= getClientArea().height) { - final GridItem currItem = items.get(row); - if (currItem.isVisible()) { - final int currItemHeight = currItem.getHeight(); - - if (p.y >= y2 && p.y < y2 + currItemHeight + 1) { - itemToReturn = currItem; - break; - } - - y2 += currItemHeight + 1; - } - row++; - } - - if (hasSpanning) { - if (itemToReturn != null) { - final int itemIndex = getIndexOfItem(itemToReturn); - - final GridColumn gridColumn = getColumn(itemToReturn, point); - final int displayColIndex = displayOrderedColumns.indexOf(gridColumn); - - // track back all previous columns and check their spanning - int indexNextItemToCheck = 0; - for (int i = 0; i < itemIndex; i++) { - if (i < indexNextItemToCheck) { - continue; - } - final GridItem gridItem = this.getItem(i); - if (gridItem.isVisible() == false) { - continue; - } - final int span = gridItem.getRowSpan(displayColIndex); - - if (i + span >= itemIndex) { - itemToReturn = gridItem; - break; - } - indexNextItemToCheck = i + span + 1; - } - } - } - - return itemToReturn; - } - - /** - * Returns the number of items contained in the receiver. - * - * @return the number of items - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getItemCount() { - checkWidget(); - return items.size(); - } - - /** - * Returns the default height of the items in this Grid. See - * {@link #setItemHeight(int)} for details. - * - *

- * IMPORTANT: The Grid's items need not all have the height returned by this - * method, because an item's height may have been changed by calling - * {@link GridItem#setHeight(int)}. - * - * @return default height of items - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * @see #setItemHeight(int) - */ - public int getItemHeight() { - checkWidget(); - return itemHeight; - } - - /** - * Sets the default height for this Grid's items. When this method - * is called, all existing items are resized to the specified height and items - * created afterwards will be initially sized to this height. - *

- * As long as no default height was set by the client through this method, the - * preferred height of the first item in this Grid is used as a - * default for all items (and is returned by {@link #getItemHeight()}). - * - * @param height - * default height in pixels - * @throws IllegalArgumentException - *

    - *
  • ERROR_INVALID_ARGUMENT - if the height is < 1
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * - * @see GridItem#getHeight() - * @see GridItem#setHeight(int) - */ - public void setItemHeight(final int height) { - checkWidget(); - if (height < 1) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - itemHeight = height; - userModifiedItemHeight = true; - for (final GridItem item : items) { - item.setHeight(height); - } - hasDifferingHeights = false; - setScrollValuesObsolete(); - redraw(); - } - - /** - * Returns true if the rows are resizable. - * - * @return the row resizeable state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * @see #setRowsResizeable(boolean) - */ - public boolean getRowsResizeable() { - checkWidget(); - return rowsResizeable; - } - - /** - * Sets the rows resizeable state of this Grid. The default is - * 'false'. - *

- * If a row in a Grid is resizeable, then the user can - * interactively change its height by dragging the border of the row header. - *

- * Note that for rows to be resizable the row headers must be visible. - * - * @param rowsResizeable - * true if this Grid's rows should be resizable - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * @see #setRowHeaderVisible(boolean) - */ - public void setRowsResizeable(final boolean rowsResizeable) { - checkWidget(); - this.rowsResizeable = rowsResizeable; - } - - /** - * Returns a (possibly empty) array of {@code GridItem}s which are the items in - * the receiver. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * list of items, so modifying the array will not affect the receiver. - *

- * - * @return the items in the receiver - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridItem[] getItems() { - checkWidget(); - return items.toArray(new GridItem[items.size()]); - } - - /** - * - * @param item - * @return t - */ - public int getIndexOfItem(final GridItem item) { - checkWidget(); - - return item.getRowIndex(); - } - - /** - * Returns the line color. - * - * @return Returns the lineColor. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public Color getLineColor() { - checkWidget(); - return lineColor; - } - - /** - * Returns true if the lines are visible. - * - * @return Returns the linesVisible. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean getLinesVisible() { - checkWidget(); - return linesVisible; - } - - /** - * Returns true if the tree lines are visible. - * - * @return Returns the treeLinesVisible. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean getTreeLinesVisible() { - checkWidget(); - return treeLinesVisible; - } - - /** - * Returns the next visible item in the table. - * - * @param item - * item - * @return next visible item or null - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridItem getNextVisibleItem(final GridItem item) { - checkWidget(); - - int index = item.getRowIndex(); - if (items.size() == index + 1) { - return null; - } - - GridItem nextItem = items.get(index + 1); - - while (!nextItem.isVisible()) { - index++; - if (items.size() == index + 1) { - return null; - } - - nextItem = items.get(index + 1); - } - - return nextItem; - } - - /** - * Returns the previous visible item in the table. Passing null for the item - * will return the last visible item in the table. - * - * @param item - * item or null - * @return previous visible item or if item==null last visible item - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridItem getPreviousVisibleItem(final GridItem item) { - checkWidget(); - - int index = 0; - if (item == null) { - index = items.size(); - } else { - index = item.getRowIndex(); - if (index <= 0) { - return null; - } - } - - GridItem prevItem = items.get(index - 1); - - while (!prevItem.isVisible()) { - index--; - if (index == 0) { - return null; - } - - prevItem = items.get(index - 1); - } - - return prevItem; - } - - /** - * Returns the previous visible column in the table. - * - * @param column - * column - * @return previous visible column or null - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridColumn getPreviousVisibleColumn(final GridColumn column) { - checkWidget(); - - int index = displayOrderedColumns.indexOf(column); - - if (index == 0) { - return null; - } - - index--; - - GridColumn previous = displayOrderedColumns.get(index); - - while (!previous.isVisible()) { - if (index == 0) { - return null; - } - - index--; - previous = displayOrderedColumns.get(index); - } - - return previous; - } - - /** - * Returns the next visible column in the table. - * - * @param column - * column - * @return next visible column or null - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridColumn getNextVisibleColumn(final GridColumn column) { - checkWidget(); - - int index = displayOrderedColumns.indexOf(column); - - if (index == displayOrderedColumns.size() - 1) { - return null; - } - - index++; - - GridColumn next = displayOrderedColumns.get(index); - - while (!next.isVisible()) { - if (index == displayOrderedColumns.size() - 1) { - return null; - } - - index++; - next = displayOrderedColumns.get(index); - } - - return next; - } - - /** - * Returns the number of root items contained in the receiver. - * - * @return the number of items - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getRootItemCount() { - checkWidget(); - return rootItems.size(); - } - - /** - * Returns a (possibly empty) array of {@code GridItem}s which are the root - * items in the receiver. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * list of items, so modifying the array will not affect the receiver. - *

- * - * @return the root items in the receiver - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridItem[] getRootItems() { - checkWidget(); - - return rootItems.toArray(new GridItem[rootItems.size()]); - } - - /** - * TODO: asl;fj - * - * @param index - * @return asdf - */ - public GridItem getRootItem(final int index) { - checkWidget(); - - if (index < 0 || index >= rootItems.size()) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - - return rootItems.get(index); - } - - /** - * Gets the row header renderer. - * - * @return Returns the rowHeaderRenderer. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public IRenderer getRowHeaderRenderer() { - checkWidget(); - return rowHeaderRenderer; - } - - /** - * Returns a array of {@code GridItem}s that are currently selected in the - * receiver. The order of the items is unspecified. An empty array indicates - * that no items are selected. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * selection, so modifying the array will not affect the receiver. - *

- * If cell selection is enabled, any items which contain at least one selected - * cell are returned. - * - * @return an array representing the selection - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridItem[] getSelection() { - checkWidget(); - - if (!cellSelectionEnabled) { - return selectedItems.toArray(new GridItem[selectedItems.size()]); - } else { - final Vector items = new Vector<>(); - final int itemCount = getItemCount(); - - for (final Point cell : selectedCells) { - if (cell.y >= 0 && cell.y < itemCount) { - final GridItem item = getItem(cell.y); - if (!items.contains(item)) { - items.add(item); - } - } - } - return items.toArray(new GridItem[] {}); - } - } - - /** - * Returns the number of selected items contained in the receiver. If cell - * selection is enabled, the number of items with at least one selected cell are - * returned. - * - * @return the number of selected items - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getSelectionCount() { - checkWidget(); - - if (!cellSelectionEnabled) { - return selectedItems.size(); - } else { - final Vector items = new Vector<>(); - for (final Point cell : selectedCells) { - final GridItem item = getItem(cell.y); - if (!items.contains(item)) { - items.add(item); - } - } - return items.size(); - } - } - - /** - * Returns the number of selected cells contained in the receiver. - * - * @return the number of selected cells - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getCellSelectionCount() { - checkWidget(); - return selectedCells.size(); - } - - /** - * Returns the zero-relative index of the item which is currently selected in - * the receiver, or -1 if no item is selected. If cell selection is enabled, - * returns the index of first item that contains at least one selected cell. - * - * @return the index of the selected item - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getSelectionIndex() { - checkWidget(); - - if (!cellSelectionEnabled) { - if (selectedItems.size() == 0) { - return -1; - } - - return selectedItems.get(0).getRowIndex(); - } else { - if (selectedCells.size() == 0) { - return -1; - } - - return selectedCells.get(0).y; - } - } - - /** - * Returns the zero-relative indices of the items which are currently selected - * in the receiver. The order of the indices is unspecified. The array is empty - * if no items are selected. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * selection, so modifying the array will not affect the receiver. - *

- * If cell selection is enabled, returns the indices of any items which contain - * at least one selected cell. - * - * @return the array of indices of the selected items - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int[] getSelectionIndices() { - checkWidget(); - - if (!cellSelectionEnabled) { - final int[] indices = new int[selectedItems.size()]; - int i = 0; - for (final GridItem item : selectedItems) { - indices[i] = item.getRowIndex(); - i++; - } - return indices; - } else { - final Vector selectedRows = new Vector<>(); - for (final Point cell : selectedCells) { - final GridItem item = getItem(cell.y); - if (!selectedRows.contains(item)) { - selectedRows.add(item); - } - } - final int[] indices = new int[selectedRows.size()]; - int i = 0; - for (final GridItem item : selectedRows) { - indices[i] = item.getRowIndex(); - i++; - } - return indices; - } - } - - /** - * Returns the zero-relative index of the item which is currently at the top of - * the receiver. This index can change when items are scrolled or new items are - * added or removed. - * - * @return the index of the top item - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getTopIndex() { - checkWidget(); - - if (topIndex != -1) { - return topIndex; - } - - if (!vScroll.getVisible()) { - topIndex = 0; - } else { - // figure out first visible row and last visible row - int firstVisibleIndex = vScroll.getSelection(); - - if (isTree) { - final Iterator itemsIter = items.iterator(); - int row = firstVisibleIndex + 1; - - while (row > 0 && itemsIter.hasNext()) { - final GridItem item = itemsIter.next(); - - if (item.isVisible()) { - row--; - if (row == 0) { - firstVisibleIndex = item.getRowIndex(); - } - } - } - } - - topIndex = firstVisibleIndex; - - /* - * MOPR here lies more potential for increasing performance for the case (isTree - * || hasDifferingHeights) the topIndex could be derived from the previous value - * depending on a delta of the vScroll.getSelection() instead of being - * calculated completely anew - */ - } - - return topIndex; - } - - /** - * Returns the zero-relative index of the item which is currently at the bottom - * of the receiver. This index can change when items are scrolled, expanded or - * collapsed or new items are added or removed. - *

- * Note that the item with this index is often only partly visible; maybe only a - * single line of pixels is visible. Use {@link #isShown(GridItem)} to find out. - *

- * In extreme cases, getBottomIndex() may return the same value as - * {@link #getTopIndex()}. - * - * @return the index of the bottom item - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - int getBottomIndex() { - checkWidget(); - - if (bottomIndex != -1) { - return bottomIndex; - } - - if (items.size() == 0) { - bottomIndex = 0; - } else if (getVisibleGridHeight() < 1) { - bottomIndex = getTopIndex(); - } else { - final RowRange range = getRowRange(getTopIndex(), getVisibleGridHeight(), false, false); - - bottomIndex = range.endIndex; - bottomIndexShownCompletely = range.height <= getVisibleGridHeight(); - } - - return bottomIndex; - } - - /** - * Returns a {@link RowRange} ranging from the grid item at startIndex to that - * at endIndex. - *

- * This is primarily used to measure the height in pixel of such a range and to - * count the number of visible grid items within the range. - * - * @param startIndex - * index of the first item in the range or -1 to the first visible - * item in this grid - * @param endIndex - * index of the last item in the range or -1 to use the last visible - * item in this grid - * @return - */ - private RowRange getRowRange(int startIndex, int endIndex) { - - // parameter preparation - if (startIndex == -1) { - // search frist visible item - do { - startIndex++; - } while (startIndex < items.size() && !items.get(startIndex).isVisible()); - if (startIndex == items.size()) { - return null; - } - } - if (endIndex == -1) { - // search last visible item - endIndex = items.size(); - do { - endIndex--; - } while (endIndex >= 0 && !items.get(endIndex).isVisible()); - if (endIndex == -1) { - return null; - } - } - - // fail fast - if (startIndex < 0 || endIndex < 0 || startIndex >= items.size() || endIndex >= items.size() - || endIndex < startIndex || items.get(startIndex).isVisible() == false - || items.get(endIndex).isVisible() == false) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - final RowRange range = new RowRange(); - range.startIndex = startIndex; - range.endIndex = endIndex; - - if (isTree || hasDifferingHeights) { - for (int idx = startIndex; idx <= endIndex; idx++) { - final GridItem currItem = items.get(idx); - - if (currItem.isVisible()) { - if (range.rows > 0) { - range.height++; // height of horizontal row separator - } - range.height += currItem.getHeight(); - range.rows++; - } - } - } else { - range.rows = range.endIndex - range.startIndex + 1; - range.height = (itemHeight + 1) * range.rows - 1; - } - - return range; - } - - /** - * This method can be used to build a range of grid rows that is allowed to span - * a certain height in pixels. - *

- * It returns a {@link RowRange} that contains information about the range, - * especially the index of the last element in the range (or if inverse == true, - * then the index of the first element). - *

- * Note: Even if 'forceEndCompletelyInside' is set to true, the last item will - * not lie completely within the availableHeight, if (height of item at - * startIndex < availableHeight). - * - * @param startIndex - * index of the first (if inverse==false) or last (if inverse==true) - * item in the range - * @param availableHeight - * height in pixels - * @param forceEndCompletelyInside - * if true, the last item in the range will lie completely within the - * availableHeight, otherwise it may lie partly outside this range - * @param inverse - * if true, then the first item in the range will be searched, not - * the last - * @return range of grid rows - * @see RowRange - */ - private RowRange getRowRange(int startIndex, final int availableHeight, final boolean forceEndCompletelyInside, - final boolean inverse) { - // parameter preparation - if (startIndex == -1) { - if (!inverse) { - // search frist visible item - do { - startIndex++; - } while (startIndex < items.size() && !items.get(startIndex).isVisible()); - if (startIndex == items.size()) { - return null; - } - } else { - // search last visible item - startIndex = items.size(); - do { - startIndex--; - } while (startIndex >= 0 && !items.get(startIndex).isVisible()); - if (startIndex == -1) { - return null; - } - } - } - - // fail fast - if (startIndex < 0 || startIndex >= items.size() || items.get(startIndex).isVisible() == false) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - final RowRange range = new RowRange(); - - if (availableHeight <= 0) { - // special case: empty range - range.startIndex = startIndex; - range.endIndex = startIndex; - range.rows = 0; - range.height = 0; - return range; - } - - if (isTree || hasDifferingHeights) { - int otherIndex = startIndex; // tentative end index - int consumedItems = 0; - int consumedHeight = 0; - - // consume height for startEnd (note: no separator pixel added here) - consumedItems++; - consumedHeight += items.get(otherIndex).getHeight(); - - // note: we use "+2" in next line, because we only try to add another row if - // there - // is room for the separator line + at least one pixel row for the additional - // item - while (consumedHeight + 2 <= availableHeight) { - // STEP 1: - // try to find a visible item we can add - - int nextIndex = otherIndex; - GridItem nextItem; - - do { - if (!inverse) { - nextIndex++; - } else { - nextIndex--; - } - - if (nextIndex >= 0 && nextIndex < items.size()) { - nextItem = items.get(nextIndex); - } else { - nextItem = null; - } - } while (nextItem != null && !nextItem.isVisible()); - - if (nextItem == null) { - // no visible item found - break; - } - - if (forceEndCompletelyInside) { - // must lie completely within the allowed height - if (!(consumedHeight + 1 + nextItem.getHeight() <= availableHeight)) { - break; - } - } - - // we found one !! - - // STEP 2: - // Consume height for this item - - consumedItems++; - consumedHeight += 1; // height of separator line - consumedHeight += nextItem.getHeight(); - - // STEP 3: - // make this item it the current guess for the other end - otherIndex = nextIndex; - } - - range.startIndex = !inverse ? startIndex : otherIndex; - range.endIndex = !inverse ? otherIndex : startIndex; - range.rows = consumedItems; - range.height = consumedHeight; - } else { - int availableRows = (availableHeight + 1) / (itemHeight + 1); - - if((itemHeight + 1) * range.rows - 1 + 1 < availableHeight) { - // not all available space used yet - // - so add another row if it need not be completely within availableHeight - if (!forceEndCompletelyInside) { - availableRows++; - } - } - - int otherIndex = startIndex + (availableRows - 1) * (!inverse ? 1 : -1); - if (otherIndex < 0) { - otherIndex = 0; - } - if (otherIndex >= items.size()) { - otherIndex = items.size() - 1; - } - - range.startIndex = !inverse ? startIndex : otherIndex; - range.endIndex = !inverse ? otherIndex : startIndex; - range.rows = range.endIndex - range.startIndex + 1; - range.height = (itemHeight + 1) * range.rows - 1; - } - - return range; - } - - /** - * Returns the height of the plain grid in pixels. - *

- * This includes all rows for visible items (i.e. items that return true on - * {@link GridItem#isVisible()} ; not only those currently visible on screen) - * and the 1 pixel separator between rows. - *

- * This does not include the height of the column headers. - * - * @return height of plain grid - */ - int getGridHeight() { - final RowRange range = getRowRange(-1, -1); - return range != null ? range.height : 0; - /* - * MOPR currently this method is only used in #getTableSize() ; if it will be - * used for more important things in the future (e.g. the max value for - * vScroll.setValues() when doing pixel-by-pixel vertical scrolling) then this - * value should at least be cached or even updated incrementally when grid items - * are added/removed or expaned/collapsed (similar as #currentVisibleItems). - * (this is only necessary in the case (isTree || hasDifferingHeights)) - */ - } - - /** - * Returns the height of the on-screen area that is available for showing the - * grid's rows, i.e. the client area of the scrollable minus the height of the - * column headers (if shown). - * - * @return height of visible grid in pixels - */ - int getVisibleGridHeight() { - return getClientArea().height - (columnHeadersVisible ? headerHeight : 0) - - (columnFootersVisible ? footerHeight : 0); - } - - /** - * Returns the height of the screen area that is available for showing the grid - * columns - * - * @return - */ - int getVisibleGridWidth() { - return getClientArea().width - (rowHeaderVisible ? rowHeaderWidth : 0); - } - - /** - * Gets the top left renderer. - * - * @return Returns the topLeftRenderer. - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public IRenderer getTopLeftRenderer() { - checkWidget(); - return topLeftRenderer; - } - - /** - * Gets the bottom left renderer. - * - * @return Returns the bottomLeftRenderer. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public IRenderer getBottomLeftRenderer() { - checkWidget(); - return bottomLeftRenderer; - } - - /** - * Searches the receiver's list starting at the first column (index 0) until a - * column is found that is equal to the argument, and returns the index of that - * column. If no column is found, returns -1. - * - * @param column - * the search column - * @return the index of the column - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the column is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int indexOf(final GridColumn column) { - checkWidget(); - - if (column == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (column.getParent() != this) { - return -1; - } - - return column.index; - } - - /** - * Searches the receiver's list starting at the first item (index 0) until an - * item is found that is equal to the argument, and returns the index of that - * item. If no item is found, returns -1. - * - * @param item - * the search item - * @return the index of the item - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int indexOf(final GridItem item) { - checkWidget(); - - if (item == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (item.getParent() != this) { - return -1; - } - - return items.indexOf(item); - } - - /** - * Returns {@code true} if the receiver's row header is visible, and - * {@code false} otherwise. - *

- * - * @return the receiver's row header's visibility state - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean isRowHeaderVisible() { - checkWidget(); - return rowHeaderVisible; - } - - /** - * Returns {@code true} if the item is selected, and {@code false} otherwise. - * Indices out of range are ignored. If cell selection is enabled, returns true - * if the item at the given index contains at least one selected cell. - * - * @param index - * the index of the item - * @return the visibility state of the item at the index - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean isSelected(final int index) { - checkWidget(); - - if (index < 0 || index >= items.size()) { - return false; - } - - if (!cellSelectionEnabled) { - return isSelected(items.get(index)); - } else { - for (final Point cell : selectedCells) { - if (cell.y == index) { - return true; - } - } - return false; - } - } - - /** - * Returns true if the given item is selected. If cell selection is enabled, - * returns true if the given item contains at least one selected cell. - * - * @param item - * item - * @return true if the item is selected. - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean isSelected(final GridItem item) { - checkWidget(); - if (!cellSelectionEnabled) { - return selectedItems.contains(item); - } else { - final int index = item.getRowIndex(); - if (index == -1) { - return false; - } - for (final Point cell : selectedCells) { - if (cell.y == index) { - return true; - } - } - return false; - } - } - - /** - * Returns true if the given cell is selected. - * - * @param cell - * cell - * @return true if the cell is selected. - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the cell is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean isCellSelected(final Point cell) { - checkWidget(); - - if (cell == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - return selectedCells.contains(cell); - } - - /** - * Removes the item from the receiver at the given zero-relative index. - * - * @param index - * the index for the item - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the - * number of elements in the list minus 1 (inclusive)
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void remove(final int index) { - checkWidget(); - if (index < 0 || index > items.size() - 1) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - final GridItem item = items.get(index); - item.dispose(); - redraw(); - } - - /** - * Removes the items from the receiver which are between the given zero-relative - * start and end indices (inclusive). - * - * @param start - * the start of the range - * @param end - * the end of the range - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if either the start or end are not - * between 0 and the number of elements in the list minus 1 - * (inclusive)
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void remove(final int start, final int end) { - checkWidget(); - - for (int i = end; i >= start; i--) { - if (i < 0 || i > items.size() - 1) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - final GridItem item = items.get(i); - item.dispose(); - } - redraw(); - } - - /** - * Removes the items from the receiver's list at the given zero-relative - * indices. - * - * @param indices - * the array of indices of the items - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the - * number of elements in the list minus 1 (inclusive)
  • - *
  • ERROR_NULL_ARGUMENT - if the indices array is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void remove(final int[] indices) { - checkWidget(); - - if (indices == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - final GridItem[] removeThese = new GridItem[indices.length]; - for (int i = 0; i < indices.length; i++) { - final int j = indices[i]; - if (j < items.size() && j >= 0) { - removeThese[i] = items.get(j); - } else { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - - } - for (final GridItem item : removeThese) { - item.dispose(); - } - redraw(); - } - - /** - * Removes all of the items from the receiver. - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * Call {@link Grid} disposeAllItems and clearItems.. Is faster - */ - @Deprecated - public void removeAll() { - checkWidget(); - - while (items.size() > 0) { - items.get(0).dispose(); - } - deselectAll(); - redraw(); - } - - /** - * All items needs to call the disposeOnly method - */ - public void disposeAllItems() { - checkWidget(); - - final GridItem[] items = getItems(); - for (final GridItem gridItem : items) { - gridItem.disposeOnly(); - } - clearItems(); - scrollValuesObsolete = true; - topIndex = -1; - bottomIndex = -1; - currentVisibleItems = 0; - updateColumnSelection(); - focusItem = null; - selectedItems.clear(); - redraw(); - // Need to update the scrollbars see see 375327 - updateScrollbars(); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the receiver's selection changes. - * - * @param listener - * the listener which should no longer be notified - * @see SelectionListener - * @see #addSelectionListener(SelectionListener) - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - removeListener(SWT.Selection, listener); - removeListener(SWT.DefaultSelection, listener); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the receiver's items changes. - * - * @param listener - * the listener which should no longer be notified - * @see TreeListener - * @see #addTreeListener(TreeListener) - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void removeTreeListener(final TreeListener listener) { - checkWidget(); - removeListener(SWT.Expand, listener); - removeListener(SWT.Collapse, listener); - } - - /** - * Selects the item at the given zero-relative index in the receiver. If the - * item at the index was already selected, it remains selected. Indices that are - * out of range are ignored. - *

- * If cell selection is enabled, selects all cells at the given index. - * - * @param index - * the index of the item to select - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void select(final int index) { - checkWidget(); - - if (!selectionEnabled) { - return; - } - - if (index < 0 || index >= items.size()) { - return; - } - - final GridItem item = items.get(index); - - if (!cellSelectionEnabled) { - if (selectionType == GridSelectionType.MULTI && selectedItems.contains(item)) { - return; - } - - if (selectionType == GridSelectionType.SINGLE) { - selectedItems.clear(); - } - - selectedItems.add(item); - } else { - selectCells(getCells(item)); - } - - redraw(); - } - - /** - * Selects the items in the range specified by the given zero-relative indices - * in the receiver. The range of indices is inclusive. The current selection is - * not cleared before the new items are selected. - *

- * If an item in the given range is not selected, it is selected. If an item in - * the given range was already selected, it remains selected. Indices that are - * out of range are ignored and no items will be selected if start is greater - * than end. If the receiver is single-select and there is more than one item in - * the given range, then all indices are ignored. - *

- * If cell selection is enabled, all cells within the given range are selected. - * - * @param start - * the start of the range - * @param end - * the end of the range - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * @see Grid#setSelection(int,int) - */ - public void select(final int start, final int end) { - checkWidget(); - - if (!selectionEnabled) { - return; - } - - if (selectionType == GridSelectionType.SINGLE && start != end) { - return; - } - - if (!cellSelectionEnabled) { - if (selectionType == GridSelectionType.SINGLE) { - selectedItems.clear(); - } - } - - for (int i = start; i <= end; i++) { - if (i < 0) { - continue; - } - if (i > items.size() - 1) { - break; - } - - final GridItem item = items.get(i); - - if (!cellSelectionEnabled) { - if (!selectedItems.contains(item)) { - selectedItems.add(item); - } - } else { - selectCells(getCells(item)); - } - } - - redraw(); - } - - /** - * Selects the items at the given zero-relative indices in the receiver. The - * current selection is not cleared before the new items are selected. - *

- * If the item at a given index is not selected, it is selected. If the item at - * a given index was already selected, it remains selected. Indices that are out - * of range and duplicate indices are ignored. If the receiver is single-select - * and multiple indices are specified, then all indices are ignored. - *

- * If cell selection is enabled, all cells within the given indices are - * selected. - * - * @param indices - * the array of indices for the items to select - * @throws IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the array of indices is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * @see Grid#setSelection(int[]) - */ - public void select(final int[] indices) { - checkWidget(); - - if (indices == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (!selectionEnabled) { - return; - } - - if (selectionType == GridSelectionType.SINGLE && indices.length > 1) { - return; - } - - if (!cellSelectionEnabled) { - if (selectionType == GridSelectionType.SINGLE) { - selectedItems.clear(); - } - } - - for (final int j : indices) { - if (j >= 0 && j < items.size()) { - final GridItem item = items.get(j); - - if (!cellSelectionEnabled) { - if (!selectedItems.contains(item)) { - selectedItems.add(item); - } - } else { - selectCells(getCells(item)); - } - } - } - redraw(); - } - - /** - * Selects all of the items in the receiver. - *

- * If the receiver is single-select, do nothing. If cell selection is enabled, - * all cells are selected. - * - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void selectAll() { - checkWidget(); - - if (!selectionEnabled) { - return; - } - - if (selectionType == GridSelectionType.SINGLE) { - return; - } - - if (cellSelectionEnabled) { - selectAllCells(); - return; - } - - selectedItems.clear(); - selectedItems.addAll(items); - redraw(); - } - - /** - * Sets the empty cell renderer. - * - * @param emptyCellRenderer - * The emptyCellRenderer to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setEmptyCellRenderer(final GridCellRenderer emptyCellRenderer) { - checkWidget(); - emptyCellRenderer.setDisplay(getDisplay()); - this.emptyCellRenderer = emptyCellRenderer; - } - - /** - * Sets the empty column header renderer. - * - * @param emptyColumnHeaderRenderer - * The emptyColumnHeaderRenderer to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setEmptyColumnHeaderRenderer(final IRenderer emptyColumnHeaderRenderer) { - checkWidget(); - emptyColumnHeaderRenderer.setDisplay(getDisplay()); - this.emptyColumnHeaderRenderer = emptyColumnHeaderRenderer; - } - - /** - * Sets the empty column footer renderer. - * - * @param emptyColumnFooterRenderer - * The emptyColumnFooterRenderer to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setEmptyColumnFooterRenderer(final IRenderer emptyColumnFooterRenderer) { - checkWidget(); - emptyColumnFooterRenderer.setDisplay(getDisplay()); - this.emptyColumnFooterRenderer = emptyColumnFooterRenderer; - } - - /** - * Sets the empty row header renderer. - * - * @param emptyRowHeaderRenderer - * The emptyRowHeaderRenderer to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setEmptyRowHeaderRenderer(final IRenderer emptyRowHeaderRenderer) { - checkWidget(); - emptyRowHeaderRenderer.setDisplay(getDisplay()); - this.emptyRowHeaderRenderer = emptyRowHeaderRenderer; - } - - /** - * Sets the external horizontal scrollbar. Allows the scrolling to be managed - * externally from the table. This functionality is only intended when - * SWT.H_SCROLL is not given. - *

- * Using this feature, a ScrollBar could be instantiated outside the table, - * wrapped in IScrollBar and thus be 'connected' to the table. - * - * @param scroll - * The horizontal scrollbar to set. - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - protected void setHorizontalScrollBarProxy(final IScrollBarProxy scroll) { - checkWidget(); - if (getHorizontalBar() != null) { - return; - } - hScroll = scroll; - - hScroll.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(final SelectionEvent e) { - onScrollSelection(); - } - - @Override - public void widgetDefaultSelected(final SelectionEvent e) { - } - }); - } - - /** - * Sets the external vertical scrollbar. Allows the scrolling to be managed - * externally from the table. This functionality is only intended when - * SWT.V_SCROLL is not given. - *

- * Using this feature, a ScrollBar could be instantiated outside the table, - * wrapped in IScrollBar and thus be 'connected' to the table. - * - * @param scroll - * The vertical scrollbar to set. - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - protected void setlVerticalScrollBarProxy(final IScrollBarProxy scroll) { - checkWidget(); - if (getVerticalBar() != null) { - return; - } - vScroll = scroll; - - vScroll.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(final SelectionEvent e) { - onScrollSelection(); - } - - @Override - public void widgetDefaultSelected(final SelectionEvent e) { - } - }); - } - - /** - * Sets the focus renderer. - * - * @param focusRenderer - * The focusRenderer to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setFocusRenderer(final IRenderer focusRenderer) { - checkWidget(); - this.focusRenderer = focusRenderer; - } - - /** - * Marks the receiver's header as visible if the argument is {@code true}, and - * marks it invisible otherwise. - * - * @param show - * the new visibility state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setHeaderVisible(final boolean show) { - checkWidget(); - columnHeadersVisible = show; - redraw(); - } - - /** - * Marks the receiver's footer as visible if the argument is {@code true}, and - * marks it invisible otherwise. - * - * @param show - * the new visibility state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setFooterVisible(final boolean show) { - checkWidget(); - columnFootersVisible = show; - redraw(); - } - - /** - * Sets the line color. - * - * @param lineColor - * The lineColor to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setLineColor(final Color lineColor) { - checkWidget(); - this.lineColor = lineColor; - } - - /** - * Sets the line visibility. - * - * @param linesVisible - * Te linesVisible to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setLinesVisible(final boolean linesVisible) { - checkWidget(); - this.linesVisible = linesVisible; - redraw(); - } - - /** - * Sets the tree line visibility. - * - * @param treeLinesVisible - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setTreeLinesVisible(final boolean treeLinesVisible) { - checkWidget(); - this.treeLinesVisible = treeLinesVisible; - redraw(); - } - - /** - * Sets the row header renderer. - * - * @param rowHeaderRenderer - * The rowHeaderRenderer to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setRowHeaderRenderer(final IRenderer rowHeaderRenderer) { - checkWidget(); - rowHeaderRenderer.setDisplay(getDisplay()); - this.rowHeaderRenderer = rowHeaderRenderer; - } - - /** - * Marks the receiver's row header as visible if the argument is {@code true}, - * and marks it invisible otherwise. When row headers are visible, horizontal - * scrolling is always done by column rather than by pixel. - * - * @param show - * the new visibility state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setRowHeaderVisible(final boolean show) { - setRowHeaderVisible(show, 1); - } - - /** - * Marks the receiver's row header as visible if the argument is {@code true}, - * and marks it invisible otherwise. When row headers are visible, horizontal - * scrolling is always done by column rather than by pixel. - * - * @param show - * the new visibility state - * @param minWidth - * the minimun width of the row column - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setRowHeaderVisible(final boolean show, final int minWidth) { - checkWidget(); - rowHeaderVisible = show; - setColumnScrolling(true); - - if (show && isAutoWidth()) { - computeRowHeaderWidth(minWidth); - } - - redraw(); - } - - /** - * Selects the item at the given zero-relative index in the receiver. The - * current selection is first cleared, then the new item is selected. - *

- * If cell selection is enabled, all cells within the item at the given index - * are selected. - * - * @param index - * the index of the item to select - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setSelection(final int index) { - checkWidget(); - - if (!selectionEnabled) { - return; - } - - if (index >= 0 && index < items.size()) { - if (!cellSelectionEnabled) { - selectedItems.clear(); - selectedItems.add(items.get(index)); - redraw(); - } else { - selectedCells.clear(); - selectCells(getCells(items.get(index))); - } - } - } - - /** - * Selects the items in the range specified by the given zero-relative indices - * in the receiver. The range of indices is inclusive. The current selection is - * cleared before the new items are selected. - *

- * Indices that are out of range are ignored and no items will be selected if - * start is greater than end. If the receiver is single-select and there is more - * than one item in the given range, then all indices are ignored. - *

- * If cell selection is enabled, all cells within the given range are selected. - * - * @param start - * the start index of the items to select - * @param end - * the end index of the items to select - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * @see Grid#deselectAll() - * @see Grid#select(int,int) - */ - public void setSelection(final int start, final int end) { - checkWidget(); - - if (!selectionEnabled) { - return; - } - - if (selectionType == GridSelectionType.SINGLE && start != end) { - return; - } - - if (!cellSelectionEnabled) { - selectedItems.clear(); - } else { - selectedCells.clear(); - } - - for (int i = start; i <= end; i++) { - if (i < 0) { - continue; - } - if (i > items.size() - 1) { - break; - } - - final GridItem item = items.get(i); - - if (!cellSelectionEnabled) { - selectedItems.add(item); - } else { - selectCells(getCells(item)); - } - } - redraw(); - } - - /** - * If true, column pack is based only with the visible lines (from - * topIndex to bottomIndex). false pack is in default mode. - * - * @return optimizedColumnPack value - */ - public boolean isVisibleLinesColumnPack() { - return visibleLinesBasedColumnPack; - } - - /** - * Set optimizedColumnPack to true for column pack based only with - * the visible lines. - * - * @param visibleLinesBasedColumnPack - */ - public void setVisibleLinesColumnPack(final boolean visibleLinesBasedColumnPack) { - this.visibleLinesBasedColumnPack = visibleLinesBasedColumnPack; - } - - /** - * Selects the items at the given zero-relative indices in the receiver. The - * current selection is cleared before the new items are selected. - *

- * Indices that are out of range and duplicate indices are ignored. If the - * receiver is single-select and multiple indices are specified, then all - * indices are ignored. - *

- * If cell selection is enabled, all cells within the given indices are - * selected. - * - * @param indices - * the indices of the items to select - * @throws IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the array of indices is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * @see Grid#deselectAll() - * @see Grid#select(int[]) - */ - public void setSelection(final int[] indices) { - checkWidget(); - - if (!selectionEnabled) { - return; - } - - if (selectionType == GridSelectionType.SINGLE && indices.length > 1) { - return; - } - - if (!cellSelectionEnabled) { - selectedItems.clear(); - } else { - selectedCells.clear(); - } - - for (final int j : indices) { - if (j < 0) { - continue; - } - if (j > items.size() - 1) { - break; - } - - final GridItem item = items.get(j); - - if (!cellSelectionEnabled) { - selectedItems.add(item); - } else { - selectCells(getCells(item)); - } - } - redraw(); - } - - /** - * Sets the receiver's selection to be the given array of items. The current - * selection is cleared before the new items are selected. - *

- * Items that are not in the receiver are ignored. If the receiver is - * single-select and multiple items are specified, then all items are ignored. - * If cell selection is enabled, all cells within the given items are selected. - * - * @param _items - * the array of items - * @throws IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the array of items is null
  • - *
  • ERROR_INVALID_ARGUMENT - if one of the items has been - * disposed
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- * @see Grid#deselectAll() - * @see Grid#select(int[]) - * @see Grid#setSelection(int[]) - */ - public void setSelection(final GridItem[] _items) { - checkWidget(); - - if (!selectionEnabled) { - return; - } - - if (_items == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (selectionType == GridSelectionType.SINGLE && _items.length > 1) { - return; - } - - if (!cellSelectionEnabled) { - selectedItems.clear(); - } else { - selectedCells.clear(); - } - - for (final GridItem item : _items) { - if (item == null) { - continue; - } - if (item.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - if (item.getParent() != this) { - continue; - } - - if (!cellSelectionEnabled) { - selectedItems.add(item); - } else { - selectCells(getCells(item)); - } - } - - redraw(); - } - - /** - * Sets the zero-relative index of the item which is currently at the top of the - * receiver. This index can change when items are scrolled or new items are - * added and removed. - * - * @param index - * the index of the top item - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setTopIndex(final int index) { - checkWidget(); - if (index < 0 || index >= items.size()) { - return; - } - - final GridItem item = items.get(index); - if (!item.isVisible()) { - return; - } - - if (!vScroll.getVisible()) { - return; - } - - int vScrollAmount = 0; - - for (int i = 0; i < index; i++) { - if (items.get(i).isVisible()) { - vScrollAmount++; - } - } - - vScroll.setSelection(vScrollAmount); - topIndex = -1; - bottomIndex = -1; - redraw(); - } - - /** - * Sets the top left renderer. - * - * @param topLeftRenderer - * The topLeftRenderer to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setTopLeftRenderer(final IRenderer topLeftRenderer) { - checkWidget(); - topLeftRenderer.setDisplay(getDisplay()); - this.topLeftRenderer = topLeftRenderer; - } - - /** - * Sets the bottom left renderer. - * - * @param bottomLeftRenderer - * The topLeftRenderer to set. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setBottomLeftRenderer(final IRenderer bottomLeftRenderer) { - checkWidget(); - bottomLeftRenderer.setDisplay(getDisplay()); - this.bottomLeftRenderer = bottomLeftRenderer; - } - - /** - * Shows the column. If the column is already showing in the receiver, this - * method simply returns. Otherwise, the columns are scrolled until the column - * is visible. - * - * @param col - * the column to be shown - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void showColumn(final GridColumn col) { - checkWidget(); - - if (!col.isVisible()) { - final GridColumnGroup group = col.getColumnGroup(); - group.setExpanded(!group.getExpanded()); - if (group.getExpanded()) { - group.notifyListeners(SWT.Expand, new Event()); - } else { - group.notifyListeners(SWT.Collapse, new Event()); - } - } - - if (!hScroll.getVisible()) { - return; - } - - int x = getColumnHeaderXPosition(col); - - int firstVisibleX = 0; - if (rowHeaderVisible) { - firstVisibleX = rowHeaderWidth; - } - - // if its visible just return - if (x >= firstVisibleX && x + col.getWidth() <= firstVisibleX + getClientArea().width - firstVisibleX) { - return; - } - - if (!getColumnScrolling()) { - if (x < firstVisibleX) { - hScroll.setSelection(getHScrollSelectionInPixels() - (firstVisibleX - x)); - } else { - if (col.getWidth() > getClientArea().width - firstVisibleX) { - hScroll.setSelection(getHScrollSelectionInPixels() + x - firstVisibleX); - } else { - x -= getClientArea().width - firstVisibleX - col.getWidth(); - hScroll.setSelection(getHScrollSelectionInPixels() + x - firstVisibleX); - } - } - } else { - if (x < firstVisibleX || col.getWidth() > getClientArea().width - firstVisibleX) { - final int sel = displayOrderedColumns.indexOf(col); - hScroll.setSelection(sel); - } else { - int availableWidth = getClientArea().width - firstVisibleX - col.getWidth(); - - GridColumn prevCol = getPreviousVisibleColumn(col); - GridColumn currentScrollTo = col; - - while (true) { - if (prevCol == null || prevCol.getWidth() > availableWidth) { - final int sel = displayOrderedColumns.indexOf(currentScrollTo); - hScroll.setSelection(sel); - break; - } else { - availableWidth -= prevCol.getWidth(); - currentScrollTo = prevCol; - prevCol = getPreviousVisibleColumn(prevCol); - } - } - } - } - - redraw(); - } - - /** - * Returns true if 'item' is currently being completely shown in this - * Grid's visible on-screen area. - * - *

- * Here, "completely" only refers to the item's height, not its width. This - * means this method returns true also if some cells are horizontally scrolled - * away. - * - * @param item - * @return true if 'item' is shown - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
  • ERROR_INVALID_ARGUMENT - if 'item' is not contained in the - * receiver
  • - *
- */ - boolean isShown(final GridItem item) { - checkWidget(); - - if (!item.isVisible()) { - return false; - } - - final int itemIndex = item.getRowIndex(); - - if (itemIndex == -1) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - final int firstVisibleIndex = getTopIndex(); - final int lastVisibleIndex = getBottomIndex(); - - return itemIndex >= firstVisibleIndex && itemIndex < lastVisibleIndex - || itemIndex == lastVisibleIndex && bottomIndexShownCompletely; - } - - /** - * Shows the item. If the item is already showing in the receiver, this method - * simply returns. Otherwise, the items are scrolled until the item is visible. - * - * @param item - * the item to be shown - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
  • ERROR_INVALID_ARGUMENT - if 'item' is not contained in the - * receiver
  • - *
- */ - public void showItem(final GridItem item) { - checkWidget(); - - updateScrollbars(); - - // if no items are visible on screen then abort - if (getVisibleGridHeight() < 1) { - return; - } - - // if its visible just return - if (isShown(item)) { - return; - } - - if (!item.isVisible()) { - GridItem parent = item.getParentItem(); - do { - if (!parent.isExpanded()) { - parent.setExpanded(true); - parent.fireEvent(SWT.Expand); - } - parent = parent.getParentItem(); - } while (parent != null); - } - - int newTopIndex = item.getRowIndex(); - - if (newTopIndex >= getBottomIndex()) { - final RowRange range = getRowRange(newTopIndex, getVisibleGridHeight(), true, true); // note: inverse==true - newTopIndex = range.startIndex; // note: use startIndex because of inverse==true - } - - setTopIndex(newTopIndex); - } - - /** - * Shows the selection. If the selection is already showing in the receiver, - * this method simply returns. Otherwise, the items are scrolled until the - * selection is visible. - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void showSelection() { - checkWidget(); - - if (scrollValuesObsolete) { - updateScrollbars(); - } - - if (!cellSelectionEnabled) { - if (selectedItems.size() == 0) { - return; - } - - showItem(selectedItems.get(0)); - } else { - if (selectedCells.size() == 0) { - return; - } - - showItem(getItem(selectedCells.get(0).y)); - showColumn(getColumn(selectedCells.get(0).x)); - } - - } - - /** - * Enables selection highlighting if the argument is true. - * - * @param selectionEnabled - * the selection enabled state - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setSelectionEnabled(final boolean selectionEnabled) { - checkWidget(); - - if (!selectionEnabled) { - selectedItems.clear(); - redraw(); - } - - this.selectionEnabled = selectionEnabled; - } - - /** - * Returns true if selection is enabled, false otherwise. - * - * @return the selection enabled state - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean getSelectionEnabled() { - checkWidget(); - return selectionEnabled; - } - - /** - * Computes and sets the height of the header row. This method will ask for the - * preferred size of all the column headers and use the max. - * - * @param gc - * GC for font metrics, etc. - */ - private void computeHeaderHeight(final GC gc) { - - int colHeaderHeight = 0; - for (final GridColumn column : columns) { - colHeaderHeight = Math.max(column.getHeaderHeight(gc), colHeaderHeight); - } - - int groupHeight = 0; - for (final GridColumnGroup group : columnGroups) { - groupHeight = Math.max(group.getHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, group).y, - groupHeight); - } - - headerHeight = colHeaderHeight + groupHeight; - groupHeaderHeight = groupHeight; - } - - private void computeHeaderHeight() { - estimate(this::computeHeaderHeight); - } - - private void computeFooterHeight(final GC gc) { - - int colFooterHeight = 0; - for (final GridColumn column : columns) { - colFooterHeight = Math.max(column.getFooterHeight(gc), colFooterHeight); - } - - footerHeight = colFooterHeight; - } - - /** - * Returns the computed default item height. Currently this method just gets the - * preferred size of all the cells in the given row and returns that (it is then - * used as the height of all rows with items having a height of -1). - * - * @param item - * item to use for sizing - * @param gc - * GC used to perform font metrics,etc. - * @return the row height - */ - private int computeItemHeight(final GridItem item, final GC gc) { - int height = 1; - - if (columns.size() == 0 || items.size() == 0) { - return height; - } - - for (final GridColumn column : columns) { - column.getCellRenderer().setColumn(column.index); - height = Math.max(height, column.getCellRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, item).y); - } - - if (rowHeaderVisible && rowHeaderRenderer != null) { - height = Math.max(height, rowHeaderRenderer.computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, item).y); - } - - return height <= 0 ? 16 : height; - } - - private int computeItemHeight(final GridItem item) { - return estimateWithResult(sizingGC -> computeItemHeight(item, sizingGC)); - } - - /** - * Returns the x position of the given column. Takes into account scroll - * position. - * - * @param column - * given column - * @return x position - */ - private int getColumnHeaderXPosition(final GridColumn column) { - if (!column.isVisible()) { - return -1; - } - - int x = 0; - - x -= getHScrollSelectionInPixels(); - - if (rowHeaderVisible) { - x += rowHeaderWidth; - } - for (final GridColumn column2 : displayOrderedColumns) { - - if (!column2.isVisible()) { - continue; - } - - if (column2 == column) { - break; - } - - x += column2.getWidth(); - } - - return x; - } - - /** - * Returns the hscroll selection in pixels. This method abstracts away the - * differences between column by column scrolling and pixel based scrolling. - * - * @return the horizontal scroll selection in pixels - */ - private int getHScrollSelectionInPixels() { - int selection = hScroll.getSelection(); - if (columnScrolling) { - int pixels = 0; - for (int i = 0; i < selection; i++) { - final GridColumn gridColumn = displayOrderedColumns.get(i); - if (gridColumn.isVisible()) { - pixels += gridColumn.getWidth(); - } else if (selection < displayOrderedColumns.size() - 1) { - selection += 1; - } - } - selection = pixels; - } - return selection; - } - - /** - * Returns the size of the preferred size of the inner table. - * - * @return the preferred size of the table. - */ - private Point getTableSize() { - int x = 0; - int y = 0; - - if (columnHeadersVisible) { - y += headerHeight; - } - - if (columnFootersVisible) { - y += footerHeight; - } - - y += getGridHeight(); - - if (rowHeaderVisible) { - x += rowHeaderWidth; - } - - for (final GridColumn column : columns) { - if (column.isVisible()) { - x += column.getWidth(); - } - } - - return new Point(x, y); - } - - /** - * Manages the header column dragging and calculates the drop point, triggers a - * redraw. - * - * @param x - * mouse x - * @return true if this event has been consumed. - */ - private boolean handleColumnDragging(final int x) { - - GridColumn local_dragDropBeforeColumn = null; - GridColumn local_dragDropAfterColumn = null; - - int x2 = 1; - - if (rowHeaderVisible) { - x2 += rowHeaderWidth + 1; - } - - x2 -= getHScrollSelectionInPixels(); - - GridColumn previousVisibleCol = null; - boolean nextVisibleColumnIsBeforeCol = false; - GridColumn firstVisibleCol = null; - GridColumn lastVisibleCol = null; - - if (x < x2) { - for (final GridColumn column : displayOrderedColumns) { - if (!column.isVisible()) { - continue; - } - local_dragDropBeforeColumn = column; - break; - } - local_dragDropAfterColumn = null; - } else { - for (final GridColumn column : displayOrderedColumns) { - if (!column.isVisible()) { - continue; - } - - if (firstVisibleCol == null) { - firstVisibleCol = column; - } - lastVisibleCol = column; - - if (nextVisibleColumnIsBeforeCol) { - local_dragDropBeforeColumn = column; - nextVisibleColumnIsBeforeCol = false; - } - - if (x >= x2 && x <= x2 + column.getWidth()) { - if (x <= x2 + column.getWidth() / 2) { - local_dragDropBeforeColumn = column; - local_dragDropAfterColumn = previousVisibleCol; - } else { - local_dragDropAfterColumn = column; - - // the next visible column is the before col - nextVisibleColumnIsBeforeCol = true; - } - } - - x2 += column.getWidth(); - previousVisibleCol = column; - } - - if (local_dragDropBeforeColumn == null) { - local_dragDropAfterColumn = lastVisibleCol; - } - } - - currentHeaderDragX = x; - - if (local_dragDropBeforeColumn != dragDropBeforeColumn - || dragDropBeforeColumn == null && dragDropAfterColumn == null) { - dragDropPointValid = true; - - // Determine if valid drop point - if (columnGroups.length != 0) { - - if (columnBeingPushed.getColumnGroup() == null) { - if (local_dragDropBeforeColumn != null && local_dragDropAfterColumn != null - && local_dragDropBeforeColumn.getColumnGroup() != null && local_dragDropBeforeColumn - .getColumnGroup() == local_dragDropAfterColumn.getColumnGroup()) { - // Dont move a column w/o a group in between two columns - // in the same group - dragDropPointValid = false; - } - } else { - if (!(local_dragDropBeforeColumn != null - && local_dragDropBeforeColumn.getColumnGroup() == columnBeingPushed.getColumnGroup()) - && !(local_dragDropAfterColumn != null && local_dragDropAfterColumn - .getColumnGroup() == columnBeingPushed.getColumnGroup())) { - // Dont move a column with a group - dragDropPointValid = false; - } - } - } else { - dragDropPointValid = true; - } - } - - dragDropBeforeColumn = local_dragDropBeforeColumn; - dragDropAfterColumn = local_dragDropAfterColumn; - - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - - return true; - } - - /** - * Handles the moving of columns after a column is dropped. - */ - private void handleColumnDrop() { - draggingColumn = false; - - if (dragDropBeforeColumn != columnBeingPushed && dragDropAfterColumn != columnBeingPushed - && (columnGroups.length == 0 || dragDropPointValid)) { - - int notifyFrom = displayOrderedColumns.indexOf(columnBeingPushed); - int notifyTo = notifyFrom; - - displayOrderedColumns.remove(columnBeingPushed); - - if (dragDropBeforeColumn == null) { - - notifyTo = displayOrderedColumns.size(); - displayOrderedColumns.add(columnBeingPushed); - } else if (dragDropAfterColumn == null) { - displayOrderedColumns.add(0, columnBeingPushed); - notifyFrom = 0; - } else { - int insertAtIndex = 0; - - if (columnGroups.length != 0) { - // ensure that we aren't putting this column into a group, - // this is possible if - // there are invisible columns between the after and before - // cols - - if (dragDropBeforeColumn.getColumnGroup() == columnBeingPushed.getColumnGroup()) { - insertAtIndex = displayOrderedColumns.indexOf(dragDropBeforeColumn); - } else if (dragDropAfterColumn.getColumnGroup() == columnBeingPushed.getColumnGroup()) { - insertAtIndex = displayOrderedColumns.indexOf(dragDropAfterColumn) + 1; - } else { - if (dragDropBeforeColumn.getColumnGroup() == null) { - insertAtIndex = displayOrderedColumns.indexOf(dragDropBeforeColumn); - } else { - final GridColumnGroup beforeGroup = dragDropBeforeColumn.getColumnGroup(); - insertAtIndex = displayOrderedColumns.indexOf(dragDropBeforeColumn); - while (insertAtIndex > 0 - && displayOrderedColumns.get(insertAtIndex - 1).getColumnGroup() == beforeGroup) { - insertAtIndex--; - } - - } - } - } else { - insertAtIndex = displayOrderedColumns.indexOf(dragDropBeforeColumn); - } - displayOrderedColumns.add(insertAtIndex, columnBeingPushed); - notifyFrom = Math.min(notifyFrom, insertAtIndex); - notifyTo = Math.max(notifyTo, insertAtIndex); - } - - for (int i = notifyFrom; i <= notifyTo; i++) { - displayOrderedColumns.get(i).fireMoved(); - } - clearDisplayOrderedCache(); - } - redraw(); - } - - /** - * Determines if the mouse is pushing the header but has since move out of the - * header bounds and therefore should be drawn unpushed. Also initiates a column - * header drag when appropriate. - * - * @param x - * mouse x - * @param y - * mouse y - * @return true if this event has been consumed. - */ - private boolean handleColumnHeaderHoverWhilePushing(final int x, final int y) { - final GridColumn overThis = overColumnHeader(x, y); - - if (overThis == columnBeingPushed != pushingAndHovering) { - pushingAndHovering = overThis == columnBeingPushed; - redraw(); - } - if (columnBeingPushed.getMoveable()) { - - if (pushingAndHovering && Math.abs(startHeaderPushX - x) > 3) { - - // stop pushing - pushingColumn = false; - columnBeingPushed.getHeaderRenderer().setMouseDown(false); - columnBeingPushed.getHeaderRenderer().setHover(false); - - // now dragging - draggingColumn = true; - columnBeingPushed.getHeaderRenderer().setMouseDown(false); - - startHeaderDragX = x; - - dragDropAfterColumn = null; - dragDropBeforeColumn = null; - dragDropPointValid = true; - - handleColumnDragging(x); - } - } - - return true; - } - - /** - * Determines if a column group header has been clicked and forwards the event - * to the header renderer. - * - * @param x - * mouse x - * @param y - * mouse y - * @return true if this event has been consumed. - */ - private boolean handleColumnGroupHeaderClick(final int x, final int y) { - - if (!columnHeadersVisible) { - return false; - } - - final GridColumnGroup overThis = overColumnGroupHeader(x, y); - - if (overThis == null) { - return false; - } - - int headerX = 0; - if (rowHeaderVisible) { - headerX += rowHeaderWidth; - } - - int width = 0; - boolean firstCol = false; - - for (final GridColumn col : displayOrderedColumns) { - if (col.getColumnGroup() == overThis && col.isVisible()) { - firstCol = true; - width += col.getWidth(); - } - if (!firstCol && col.isVisible()) { - headerX += col.getWidth(); - } - } - - overThis.getHeaderRenderer().setBounds(headerX - getHScrollSelectionInPixels(), 0, width, groupHeaderHeight); - return overThis.getHeaderRenderer().notify(IInternalWidget.LeftMouseButtonDown, new Point(x, y), overThis); - } - - /** - * Determines if a column header has been clicked, updates the renderer state - * and triggers a redraw if necesary. - * - * @param x - * mouse x - * @param y - * mouse y - * @return true if this event has been consumed. - */ - private boolean handleColumnHeaderPush(final int x, final int y) { - if (!columnHeadersVisible) { - return false; - } - - final ScrollBar verticalBar = getVerticalBar(); - final boolean clickOnScrollBar = x >= getClientArea().width; - if (clickOnScrollBar && verticalBar != null && verticalBar.isVisible()) { - // Bug 273916 : if one clicks on the tooltip and the mouse is located on the - // scrollbar, simulate a click on the scrollbar - verticalBar.setSelection(verticalBar.getSelection() - verticalBar.getIncrement()); - } - - final GridColumn overThis = overColumnHeader(x, y); - if (overThis == null) { - return false; - } - - columnBeingPushed = overThis; - - // draw pushed - columnBeingPushed.getHeaderRenderer().setMouseDown(true); - columnBeingPushed.getHeaderRenderer().setHover(true); - pushingAndHovering = true; - redraw(); - - startHeaderPushX = x; - pushingColumn = true; - - setCapture(true); - - return true; - } - - private boolean handleColumnFooterPush(final int x, final int y) { - if (!columnFootersVisible) { - return false; - } - - return overColumnFooter(x, y) != null; - } - - /** - * Sets the new width of the column being resized and fires the appropriate - * listeners. - * - * @param x - * mouse x - */ - private void handleColumnResizerDragging(final int x) { - int newWidth = resizingColumnStartWidth + x - resizingStartX; - if (newWidth < MIN_COLUMN_HEADER_WIDTH) { - newWidth = MIN_COLUMN_HEADER_WIDTH; - } - - if (columnScrolling) { - int maxWidth = getClientArea().width; - if (rowHeaderVisible) { - maxWidth -= rowHeaderWidth; - } - if (newWidth > maxWidth) { - newWidth = maxWidth; - } - } - - if (newWidth == columnBeingResized.getWidth()) { - return; - } - - columnBeingResized.setWidth(newWidth, false); - scrollValuesObsolete = true; - - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - - columnBeingResized.fireResized(); - - fireColumnsMoved(); - } - - void fireColumnsMoved() { - for (int index = displayOrderedColumns.indexOf(columnBeingResized) + 1; index < displayOrderedColumns - .size(); index++) { - final GridColumn col = displayOrderedColumns.get(index); - if (col.isVisible()) { - col.fireMoved(); - } - } - } - - void handlePacked(final GridColumn column) { - int index = 0; - - if (getHorizontalBar() != null) { - if (!getHorizontalBar().isVisible()) { - index = displayOrderedColumns.indexOf(column); - } - } - - for (; index < displayOrderedColumns.size(); index++) { - final GridColumn col = displayOrderedColumns.get(index); - if (col.isVisible()) { - col.fireMoved(); - } - } - } - - /** - * Sets the new height of the item of the row being resized and fires the - * appropriate listeners. - * - * @param x - * mouse x - */ - private void handleRowResizerDragging(final int y) { - int newHeight = resizingRowStartHeight + y - resizingStartY; - if (newHeight < MIN_ROW_HEADER_HEIGHT) { - newHeight = MIN_ROW_HEADER_HEIGHT; - } - - if (newHeight > getClientArea().height) { - newHeight = getClientArea().height; - } - - if (rowBeingResized == null || newHeight == rowBeingResized.getHeight()) { - return; - } - - final Event e = new Event(); - e.item = rowBeingResized; - e.widget = this; - e.detail = newHeight; - - rowBeingResized.notifyListeners(SWT.Resize, e); - - if (e.doit == false) { - return; - } - - newHeight = e.detail; - - if (newHeight < MIN_ROW_HEADER_HEIGHT) { - newHeight = MIN_ROW_HEADER_HEIGHT; - } - - if (newHeight > getClientArea().height) { - newHeight = getClientArea().height; - } - - rowBeingResized.setHeight(newHeight); - scrollValuesObsolete = true; - - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - } - - /** - * Determines if the mouse is hovering on a column resizer and changes the - * pointer and sets field appropriately. - * - * @param x - * mouse x - * @param y - * mouse y - * @return true if this event has been consumed. - */ - private boolean handleHoverOnColumnResizer(final int x, final int y) { - boolean over = false; - if (y <= headerHeight) { - int x2 = 0; - - if (rowHeaderVisible) { - x2 += rowHeaderWidth; - } - - x2 -= getHScrollSelectionInPixels(); - - for (final GridColumn column : displayOrderedColumns) { - if (!column.isVisible()) { - continue; - } - x2 += column.getWidth(); - - if (x2 >= x - COLUMN_RESIZER_THRESHOLD && x2 <= x + COLUMN_RESIZER_THRESHOLD) { - if (column.getResizeable()) { - if (column.getColumnGroup() != null && y <= groupHeaderHeight) { - // if this is not the last column - if (column != column.getColumnGroup().getLastVisibleColumn()) { - break; - } - } - - over = true; - columnBeingResized = column; - } - break; - } - } - } - - if (over != hoveringOnColumnResizer) { - if (over) { - setCursor(getDisplay().getSystemCursor(SWT.CURSOR_SIZEWE)); - } else { - columnBeingResized = null; - setCursor(null); - } - hoveringOnColumnResizer = over; - } - return over; - } - - /** - * Determines if the mouse is hovering on a row resizer and changes the pointer - * and sets field appropriately. - * - * @param x - * mouse x - * @param y - * mouse y - * @return true if this event has been consumed. - */ - private boolean handleHoverOnRowResizer(final int x, final int y) { - rowBeingResized = null; - boolean over = false; - if (x <= rowHeaderWidth) { - int y2 = 0; - - if (columnHeadersVisible) { - y2 += headerHeight; - } - - int row = getTopIndex(); - while (row < items.size() && y2 <= getClientArea().height) { - final GridItem currItem = items.get(row); - if (currItem.isVisible()) { - y2 += currItem.getHeight() + 1; - - if (y2 >= y - ROW_RESIZER_THRESHOLD && y2 <= y + ROW_RESIZER_THRESHOLD) { - // if (currItem.isResizeable()) - { - over = true; - rowBeingResized = currItem; - } - // do not brake here, because in case of overlapping - // row resizers we need to find the last one - } else { - if (rowBeingResized != null) { - // we have passed all (overlapping) row resizers, so break - break; - } - } - } - row++; - } - } - - if (over != hoveringOnRowResizer) { - if (over) { - setCursor(getDisplay().getSystemCursor(SWT.CURSOR_SIZENS)); - } else { - rowBeingResized = null; - setCursor(null); - } - hoveringOnRowResizer = over; - } - return over; - } - - /** - * Returns the cell at the given point in the receiver or null if no such cell - * exists. The point is in the coordinate system of the receiver. - * - * @param point - * the point used to locate the item - * @return the cell at the given point - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the point is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public Point getCell(final Point point) { - checkWidget(); - - if (point == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (point.x < 0 || point.x > getClientArea().width) { - return null; - } - - final GridItem item = getItem(point); - final GridColumn column = getColumn(point); - - if (item != null && column != null) { - return new Point(column.index, item.getRowIndex()); - } - - return null; - } - - /** - * Paints. - * - * @param e - * paint event - */ - private void onPaint(final PaintEvent e) { - int insertMarkPosX1 = -1; // we will populate these values while drawing the cells - int insertMarkPosX2 = -1; - int insertMarkPosY = -1; - boolean insertMarkPosFound = false; - - final GridCellSpanManager cellSpanManager = new GridCellSpanManager(); - final Rectangle originalClipping = e.gc.getClipping(); - - e.gc.setBackground(getBackground()); - this.drawBackground(e.gc, 0, 0, getSize().x, getSize().y); - - if (scrollValuesObsolete) { - updateScrollbars(); - scrollValuesObsolete = false; - } - - int x = 0; - int y = 0; - - if (columnHeadersVisible) { - paintHeader(e.gc); - y += headerHeight; - } - - final Rectangle clientArea = getClientArea(); - final int availableHeight = clientArea.height - y; - int visibleRows = availableHeight / itemHeight + 1; - if (items.size() > 0 && availableHeight > 0) { - final RowRange range = getRowRange(getTopIndex(), availableHeight, false, false); - if (range.height >= availableHeight) { - visibleRows = range.rows; - } else { - visibleRows = range.rows + (availableHeight - range.height) / itemHeight + 1; - } - } - - final int firstVisibleIndex = getTopIndex(); - int firstItemToDraw = firstVisibleIndex; - - if (hasSpanning) { - // We need to find the first Item to draw. An earlier item can row-span the - // first visible item. - for (int rowIndex = 0; rowIndex < firstVisibleIndex && rowIndex < items.size(); rowIndex++) { - int colIndex = 0; - - int maxRowSpanForItem = 0; - for (final GridColumn column : displayOrderedColumns) { - - if (!column.isVisible()) { - colIndex++; - continue; - } - - final int rowSpan = items.get(rowIndex).getRowSpan(colIndex); - maxRowSpanForItem = rowSpan > maxRowSpanForItem ? rowSpan : maxRowSpanForItem; - colIndex++; - } - - if (rowIndex + maxRowSpanForItem >= firstVisibleIndex) { - firstItemToDraw = rowIndex; - break; - } else { - rowIndex += maxRowSpanForItem; - } - } - - for (int rowIndex = firstItemToDraw; rowIndex < firstVisibleIndex && rowIndex < items.size(); rowIndex++) { - final GridItem itemForRow = items.get(rowIndex); - if (itemForRow.isVisible()) { - y = y - itemForRow.getHeight() - 1; - } - } - } - - int row = firstItemToDraw; - - for (int i = 0; i < visibleRows + firstVisibleIndex - firstItemToDraw; i++) { - - x = 0; - - x -= getHScrollSelectionInPixels(); - - // get the item to draw - GridItem item = null; - if (row < items.size()) { - item = items.get(row); - - while (!item.isVisible() && row < items.size() - 1) { - row++; - item = items.get(row); - } - } - if (item != null && !item.isVisible()) { - item = null; - } - - if (item != null) { - boolean cellInRowSelected = false; - - if (rowHeaderVisible) { - - // row header is actually painted later - x += rowHeaderWidth; - } - - final int focusY = y; - - int colIndex = 0; - - // draw regular cells for each column - for (final GridColumn column : displayOrderedColumns) { - - final boolean skipCell = cellSpanManager.skipCell(colIndex, row); - final int indexOfColumn = column.index; - - if (!column.isVisible()) { - colIndex++; - if (skipCell) { - cellSpanManager.consumeCell(colIndex, row); - } - continue; - } - - final int width = item.getCellSize(indexOfColumn).x; - - if (skipCell == false) { - - final int nrRowsToSpan = item.getRowSpan(indexOfColumn); - final int nrColumnsToSpan = item.getColumnSpan(indexOfColumn); - - if (nrRowsToSpan > 0 || nrColumnsToSpan > 0) { - cellSpanManager.addCellSpanInfo(colIndex, row, nrColumnsToSpan, nrRowsToSpan); - } - - if (x + width >= 0 && x < clientArea.width) { - final Point sizeOfColumn = item.getCellSize(indexOfColumn); - - column.getCellRenderer().setBounds(x, y, width, sizeOfColumn.y); - final int cellInHeaderDelta = columnHeadersVisible ? headerHeight - y : 0; - if (cellInHeaderDelta > 0) { - final Rectangle cellRect = new Rectangle(x - 1, y + cellInHeaderDelta, width + 1, - sizeOfColumn.y + 2 - cellInHeaderDelta); - e.gc.setClipping(originalClipping.intersection(cellRect)); - } else { - final Rectangle cellRect = new Rectangle(x - 1, y - 1, width + 1, sizeOfColumn.y + 2); - e.gc.setClipping(originalClipping.intersection(cellRect)); - } - - column.getCellRenderer().setRow(i + 1); - - column.getCellRenderer().setSelected(selectedItems.contains(item)); - column.getCellRenderer().setFocus(isFocusControl()); - column.getCellRenderer().setRowFocus(focusItem == item); - column.getCellRenderer() - .setCellFocus(cellSelectionEnabled && focusItem == item && focusColumn == column); - - column.getCellRenderer().setRowHover(hoveringItem == item); - column.getCellRenderer().setColumnHover(hoveringColumn == column); - - column.getCellRenderer().setColumn(indexOfColumn); - - if (selectedCells.contains(new Point(indexOfColumn, row))) { - column.getCellRenderer().setCellSelected(true); - cellInRowSelected = true; - } else { - column.getCellRenderer().setCellSelected(false); - } - - if (hoveringItem == item && hoveringColumn == column) { - column.getCellRenderer().setHoverDetail(hoveringDetail); - } else { - column.getCellRenderer().setHoverDetail(""); - } - - column.getCellRenderer().paint(e.gc, item); - - e.gc.setClipping((Rectangle) null); - - // collect the insertMark position - if (!insertMarkPosFound && insertMarkItem == item - && (insertMarkColumn == null || insertMarkColumn == column)) { - // y-pos - insertMarkPosY = y - 1; - if (!insertMarkBefore) { - insertMarkPosY += item.getHeight() + 1; - } - // x1-pos - insertMarkPosX1 = x; - if (column.isTree()) { - insertMarkPosX1 += Math.min(width, - column.getCellRenderer().getTextBounds(item, false).x); - } - - // x2-pos - if (insertMarkColumn == null) { - insertMarkPosX2 = clientArea.x + clientArea.width; - } else { - insertMarkPosX2 = x + width; - } - - insertMarkPosFound = true; - } - } - } else { - cellSpanManager.consumeCell(colIndex, row); - } - if(x > clientArea.width) { - break; - } - x += column.getWidth(); - colIndex++; - - } - - if (x < clientArea.width) { - // insertMarkPos needs correction - if (insertMarkPosFound && insertMarkColumn == null) { - insertMarkPosX2 = x; - } - - emptyCellRenderer.setSelected(selectedItems.contains(item)); - emptyCellRenderer.setFocus(isFocusControl()); - emptyCellRenderer.setRow(i + 1); - emptyCellRenderer.setBounds(x, y, clientArea.width - x + 1, item.getHeight()); - emptyCellRenderer.setColumn(getColumnCount()); - emptyCellRenderer.paint(e.gc, item); - } - - x = 0; - - if (rowHeaderVisible) { - - if (!cellSelectionEnabled) { - rowHeaderRenderer.setSelected(selectedItems.contains(item)); - } else { - rowHeaderRenderer.setSelected(cellInRowSelected); - } - if (!columnHeadersVisible || y >= headerHeight) { - rowHeaderRenderer.setBounds(0, y, rowHeaderWidth, item.getHeight() + 1); - rowHeaderRenderer.paint(e.gc, item); - } - x += rowHeaderWidth; - } - - // focus - if (isFocusControl() && !cellSelectionEnabled) { - if (item == focusItem) { - if (focusRenderer != null) { - int focusX = 0; - if (rowHeaderVisible) { - focusX = rowHeaderWidth; - } - focusRenderer.setBounds(focusX, focusY - 1, clientArea.width - focusX - 1, - item.getHeight() + 1); - focusRenderer.paint(e.gc, item); - } - } - } - - y += item.getHeight() + 1; - } else { - - if (rowHeaderVisible) { - // row header is actually painted later - x += rowHeaderWidth; - } - - emptyCellRenderer.setBounds(x, y, clientArea.width - x, itemHeight); - emptyCellRenderer.setFocus(false); - emptyCellRenderer.setSelected(false); - emptyCellRenderer.setRow(i + 1); - - for (final GridColumn column : displayOrderedColumns) { - - if (column.isVisible()) { - final int width = column.width; - if(x + width >= 0) { - emptyCellRenderer.setBounds(x, y, width, itemHeight); - emptyCellRenderer.setColumn(column.index); - emptyCellRenderer.paint(e.gc, this); - } - if(x > clientArea.width) { - break; - } - x += width; - } - } - - if (x < clientArea.width) { - emptyCellRenderer.setBounds(x, y, clientArea.width - x + 1, itemHeight); - emptyCellRenderer.setColumn(getColumnCount()); - emptyCellRenderer.paint(e.gc, this); - } - - x = 0; - - if (rowHeaderVisible) { - emptyRowHeaderRenderer.setBounds(x, y, rowHeaderWidth, itemHeight + 1); - emptyRowHeaderRenderer.paint(e.gc, this); - - x += rowHeaderWidth; - } - - y += itemHeight + 1; - } - - row++; - } - - // draw drop point - if (draggingColumn) { - if ((dragDropAfterColumn != null || dragDropBeforeColumn != null) - && dragDropAfterColumn != columnBeingPushed && dragDropBeforeColumn != columnBeingPushed - && dragDropPointValid) { - if (dragDropBeforeColumn != null) { - x = getColumnHeaderXPosition(dragDropBeforeColumn); - } else { - x = getColumnHeaderXPosition(dragDropAfterColumn) + dragDropAfterColumn.getWidth(); - } - - final Point size = dropPointRenderer.computeSize(e.gc, SWT.DEFAULT, SWT.DEFAULT, null); - x -= size.x / 2; - if (x < 0) { - x = 0; - } - dropPointRenderer.setBounds(x - 1, headerHeight + DROP_POINT_LOWER_OFFSET, size.x, size.y); - dropPointRenderer.paint(e.gc, null); - } - } - - // draw insertion mark - if (insertMarkPosFound) { - final Rectangle rect = new Rectangle(rowHeaderVisible ? rowHeaderWidth : 0, columnHeadersVisible ? headerHeight : 0, - clientArea.width, clientArea.height); - e.gc.setClipping(originalClipping.intersection(rect)); - insertMarkRenderer.paint(e.gc, - new Rectangle(insertMarkPosX1, insertMarkPosY, insertMarkPosX2 - insertMarkPosX1, 0)); - } - - if (columnFootersVisible) { - paintFooter(e.gc); - } - } - - /** - * Returns a column reference if the x,y coordinates are over a column header - * (header only). - * - * @param x - * mouse x - * @param y - * mouse y - * @return column reference which mouse is over, or null. - */ - private GridColumn overColumnHeader(final int x, final int y) { - GridColumn col = null; - - if (y <= headerHeight && y > 0) { - col = getColumn(new Point(x, y)); - if (col != null && col.getColumnGroup() != null) { - if (y <= groupHeaderHeight) { - return null; - } - } - } - - return col; - } - - /** - * Returns a column reference if the x,y coordinates are over a column header - * (header only). - * - * @param x - * mouse x - * @param y - * mouse y - * @return column reference which mouse is over, or null. - */ - private GridColumn overColumnFooter(final int x, final int y) { - if (y >= getClientArea().height - footerHeight) { - return getColumn(new Point(x, y)); - } - - return null; - } - - /** - * Returns a column group reference if the x,y coordinates are over a column - * group header (header only). - * - * @param x - * mouse x - * @param y - * mouse y - * @return column group reference which mouse is over, or null. - */ - private GridColumnGroup overColumnGroupHeader(final int x, final int y) { - GridColumnGroup group = null; - - if (y <= groupHeaderHeight && y > 0) { - final GridColumn col = getColumn(new Point(x, y)); - if (col != null) { - group = col.getColumnGroup(); - } - } - - return group; - } - - /** - * Paints the header. - * - * @param gc - * gc from paint event - */ - private void paintHeader(final GC gc) { - int x = 0; - int y = 0; - - x -= getHScrollSelectionInPixels(); - - if (rowHeaderVisible) { - // paint left corner - // topLeftRenderer.setBounds(0, y, rowHeaderWidth, headerHeight); - // topLeftRenderer.paint(gc, null); - x += rowHeaderWidth; - } - - GridColumnGroup previousPaintedGroup = null; - - for (final GridColumn column : displayOrderedColumns) { - if (x > getClientArea().width) { - break; - } - - int height = 0; - - if (!column.isVisible()) { - continue; - } - - if (column.getColumnGroup() != null) { - - if (column.getColumnGroup() != previousPaintedGroup) { - int width = column.getWidth(); - - GridColumn nextCol = null; - if (displayOrderedColumns.indexOf(column) + 1 < displayOrderedColumns.size()) { - nextCol = displayOrderedColumns.get(displayOrderedColumns.indexOf(column) + 1); - } - - while (nextCol != null && nextCol.getColumnGroup() == column.getColumnGroup()) { - - if (nextCol.getColumnGroup().getExpanded() && !nextCol.isDetail() - || !nextCol.getColumnGroup().getExpanded() && !nextCol.isSummary()) { - } else if (nextCol.isVisible()) { - width += nextCol.getWidth(); - } - - if (displayOrderedColumns.indexOf(nextCol) + 1 < displayOrderedColumns.size()) { - nextCol = displayOrderedColumns.get(displayOrderedColumns.indexOf(nextCol) + 1); - } else { - nextCol = null; - } - } - - boolean selected = true; - - for (int i = 0; i < column.getColumnGroup().getColumns().length; i++) { - final GridColumn col = column.getColumnGroup().getColumns()[i]; - if (col.isVisible() && (column.getMoveable() || !selectedColumns.contains(col))) { - selected = false; - break; - } - } - - column.getColumnGroup().getHeaderRenderer().setSelected(selected); - column.getColumnGroup().getHeaderRenderer() - .setHover(hoverColumnGroupHeader == column.getColumnGroup()); - column.getColumnGroup().getHeaderRenderer().setHoverDetail(hoveringDetail); - - column.getColumnGroup().getHeaderRenderer().setBounds(x, 0, width, groupHeaderHeight); - - column.getColumnGroup().getHeaderRenderer().paint(gc, column.getColumnGroup()); - - previousPaintedGroup = column.getColumnGroup(); - } - - height = headerHeight - groupHeaderHeight; - y = groupHeaderHeight; - } else { - height = headerHeight; - y = 0; - } - - if (pushingColumn) { - column.getHeaderRenderer().setHover(columnBeingPushed == column && pushingAndHovering); - } else { - column.getHeaderRenderer().setHover(hoveringColumnHeader == column); - } - - column.getHeaderRenderer().setHoverDetail(hoveringDetail); - - column.getHeaderRenderer().setBounds(x, y, column.getWidth(), height); - - if (cellSelectionEnabled) { - column.getHeaderRenderer().setSelected(selectedColumns.contains(column)); - } - - if (x + column.getWidth() >= 0) { - column.getHeaderRenderer().paint(gc, column); - } - - x += column.getWidth(); - } - - if (x < getClientArea().width) { - emptyColumnHeaderRenderer.setBounds(x, 0, getClientArea().width - x, headerHeight); - emptyColumnHeaderRenderer.paint(gc, null); - } - - x = 0; - - if (rowHeaderVisible) { - // paint left corner - topLeftRenderer.setBounds(0, 0, rowHeaderWidth, headerHeight); - topLeftRenderer.paint(gc, this); - x += rowHeaderWidth; - } - - if (draggingColumn) { - - gc.setAlpha(COLUMN_DRAG_ALPHA); - - columnBeingPushed.getHeaderRenderer().setSelected(false); - - int height = 0; - - if (columnBeingPushed.getColumnGroup() != null) { - height = headerHeight - groupHeaderHeight; - y = groupHeaderHeight; - } else { - height = headerHeight; - y = 0; - } - - columnBeingPushed.getHeaderRenderer().setBounds( - getColumnHeaderXPosition(columnBeingPushed) + currentHeaderDragX - startHeaderDragX, y, - columnBeingPushed.getWidth(), height); - columnBeingPushed.getHeaderRenderer().paint(gc, columnBeingPushed); - columnBeingPushed.getHeaderRenderer().setSelected(false); - - gc.setAlpha(-1); - gc.setAdvanced(false); - } - - } - - private void paintFooter(final GC gc) { - int x = 0; - int y = 0; - - x -= getHScrollSelectionInPixels(); - - if (rowHeaderVisible) { - // paint left corner - // topLeftRenderer.setBounds(0, y, rowHeaderWidth, headerHeight); - // topLeftRenderer.paint(gc, null); - x += rowHeaderWidth; - } - - for (final GridColumn column : displayOrderedColumns) { - if (x > getClientArea().width) { - break; - } - - int height = 0; - - if (!column.isVisible()) { - continue; - } - - height = footerHeight; - y = getClientArea().height - height; - - column.getFooterRenderer().setBounds(x, y, column.getWidth(), height); - if (x + column.getWidth() >= 0) { - column.getFooterRenderer().paint(gc, column); - } - - x += column.getWidth(); - } - - if (x < getClientArea().width) { - emptyColumnFooterRenderer.setBounds(x, getClientArea().height - footerHeight, getClientArea().width - x, - footerHeight); - emptyColumnFooterRenderer.paint(gc, null); - } - - if (rowHeaderVisible) { - // paint left corner - bottomLeftRenderer.setBounds(0, getClientArea().height - footerHeight, rowHeaderWidth, footerHeight); - bottomLeftRenderer.paint(gc, this); - x += rowHeaderWidth; - } - } - - /** - * Manages the state of the scrollbars when new items are added or the bounds - * are changed. - */ - private void updateScrollbars() { - final Point preferredSize = getTableSize(); - - Rectangle clientArea = getClientArea(); - - // First, figure out if the scrollbars should be visible and turn them - // on right away - // this will allow the computations further down to accommodate the - // correct client - // area - - // Turn the scrollbars on if necessary and do it all over again if - // necessary. This ensures - // that if a scrollbar is turned on/off, the other scrollbar's - // visibility may be affected (more - // area may have been added/removed. - for (int doublePass = 1; doublePass <= 2; doublePass++) { - - if (preferredSize.y > clientArea.height) { - vScroll.setVisible(true); - } else { - vScroll.setVisible(false); - vScroll.setValues(0, 0, 1, 1, 1, 1); - } - if (preferredSize.x > clientArea.width) { - hScroll.setVisible(true); - } else { - hScroll.setVisible(false); - hScroll.setValues(0, 0, 1, 1, 1, 1); - } - - // get the clientArea again with the now visible/invisible - // scrollbars - clientArea = getClientArea(); - } - - // if the scrollbar is visible set its values - if (vScroll.getVisible()) { - int max = currentVisibleItems; - int thumb = 1; - - if (!hasDifferingHeights) { - // in this case, the number of visible rows on screen is constant, - // so use this as thumb - thumb = (getVisibleGridHeight() + 1) / (itemHeight + 1); - } else { - // in this case, the number of visible rows on screen is variable, - // so we have to use 1 as thumb and decrease max by the number of - // rows on the last page - if (getVisibleGridHeight() >= 1) { - final RowRange range = getRowRange(-1, getVisibleGridHeight(), true, true); - max -= range.rows - 1; - } - } - - // if possible, remember selection, if selection is too large, just - // make it the max you can - final int selection = Math.min(vScroll.getSelection(), max); - - vScroll.setValues(selection, 0, max, thumb, 1, thumb); - } - - // if the scrollbar is visible set its values - if (hScroll.getVisible()) { - - if (!columnScrolling) { - // horizontal scrolling works pixel by pixel - - final int hiddenArea = preferredSize.x - clientArea.width + 1; - - // if possible, remember selection, if selection is too large, - // just - // make it the max you can - final int selection = Math.min(hScroll.getSelection(), hiddenArea - 1); - - hScroll.setValues(selection, 0, hiddenArea + clientArea.width - 1, clientArea.width, - HORZ_SCROLL_INCREMENT, clientArea.width); - } else { - // horizontal scrolling is column by column - - int hiddenArea = preferredSize.x - clientArea.width + 1; - - int max = 0; - int i = 0; - - while (hiddenArea > 0 && i < getColumnCount()) { - final GridColumn col = displayOrderedColumns.get(i); - - i++; - - if (col.isVisible()) { - hiddenArea -= col.getWidth(); - max++; - } - } - - max++; - - // max should never be greater than the number of visible cols - int visCols = 0; - for (final GridColumn element : columns) { - if (element.isVisible()) { - visCols++; - } - } - max = Math.min(visCols, max); - - // if possible, remember selection, if selection is too large, - // just - // make it the max you can - final int selection = Math.min(hScroll.getSelection(), max); - - hScroll.setValues(selection, 0, max, 1, 1, 1); - } - } - - } - - /** - * Adds/removes items from the selected items list based on the - * selection/deselection of the given item. - * - * @param item - * item being selected/unselected - * @param stateMask - * key state during selection - * - * @return selection event that needs to be fired or null - */ - private Event updateSelection(final GridItem item, final int stateMask) { - if (!selectionEnabled) { - return null; - } - - Event selectionEvent = null; - - if (selectionType == GridSelectionType.SINGLE) { - if (selectedItems.contains(item)) { - // Deselect when pressing CTRL - if ((stateMask & SWT.MOD1) == SWT.MOD1) { - selectedItems.clear(); - } - } else { - selectedItems.clear(); - selectedItems.add(item); - } - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - - selectionEvent = new Event(); - selectionEvent.item = item; - } else if (selectionType == GridSelectionType.MULTI) { - boolean shift = false; - boolean ctrl = false; - - if ((stateMask & SWT.MOD2) == SWT.MOD2) { - shift = true; - } - - if ((stateMask & SWT.MOD1) == SWT.MOD1) { - ctrl = true; - } - - if (!shift && !ctrl) { - if (selectedItems.size() == 1 && selectedItems.contains(item)) { - return null; - } - - selectedItems.clear(); - - selectedItems.add(item); - - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - - shiftSelectionAnchorItem = null; - - selectionEvent = new Event(); - selectionEvent.item = item; - } else if (shift) { - - if (shiftSelectionAnchorItem == null) { - shiftSelectionAnchorItem = focusItem; - } - - // if (shiftSelectionAnchorItem == item) - // { - // return; - // } - - boolean maintainAnchorSelection = false; - - if (!ctrl) { - if (selectedItems.contains(shiftSelectionAnchorItem)) { - maintainAnchorSelection = true; - } - selectedItems.clear(); - } - - final int anchorIndex = items.indexOf(shiftSelectionAnchorItem); - final int itemIndex = item.getRowIndex(); - - int min = 0; - int max = 0; - - if (anchorIndex < itemIndex) { - if (maintainAnchorSelection) { - min = anchorIndex; - } else { - min = anchorIndex + 1; - } - max = itemIndex; - } else { - if (maintainAnchorSelection) { - max = anchorIndex; - } else { - max = anchorIndex - 1; - } - min = itemIndex; - } - - for (int i = min; i <= max; i++) { - if (!selectedItems.contains(items.get(i)) && items.get(i).isVisible()) { - selectedItems.add(items.get(i)); - } - } - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - - selectionEvent = new Event(); - } else if (ctrl) { - if (selectedItems.contains(item)) { - selectedItems.remove(item); - } else { - selectedItems.add(item); - } - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - - shiftSelectionAnchorItem = null; - - selectionEvent = new Event(); - selectionEvent.item = item; - } - } - - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - - return selectionEvent; - } - - /** - * Updates cell selection. - * - * @param newCell - * newly clicked, navigated to cell. - * @param stateMask - * statemask during preceeding mouse or key event. - * @param dragging - * true if the user is dragging. - * @param reverseDuplicateSelections - * true if the user is reversing selection rather than adding to. - * - * @return selection event that will need to be fired or null. - */ - private Event updateCellSelection(final Point newCell, final int stateMask, final boolean dragging, - final boolean reverseDuplicateSelections) { - final Vector v = new Vector<>(); - v.add(newCell); - return updateCellSelection(v, stateMask, dragging, reverseDuplicateSelections); - } - - /** - * Updates cell selection. - * - * @param newCell - * newly clicked, navigated to cells. - * @param stateMask - * statemask during preceeding mouse or key event. - * @param dragging - * true if the user is dragging. - * @param reverseDuplicateSelections - * true if the user is reversing selection rather than adding to. - * - * @return selection event that will need to be fired or null. - */ - private Event updateCellSelection(final Vector newCells, final int stateMask, final boolean dragging, - final boolean reverseDuplicateSelections) { - boolean shift = false; - boolean ctrl = false; - - if ((stateMask & SWT.MOD2) == SWT.MOD2) { - shift = true; - } else { - shiftSelectionAnchorColumn = null; - shiftSelectionAnchorItem = null; - } - - if ((stateMask & SWT.MOD1) == SWT.MOD1) { - ctrl = true; - } - - if (!shift && !ctrl) { - if (newCells.equals(selectedCells)) { - return null; - } - - selectedCells.clear(); - for (final Point newCell : newCells) { - addToCellSelection(newCell); - } - - } else if (shift) { - - final Point newCell = newCells.get(0); // shift selection should only occur with one - // cell, ignoring others - - if (focusColumn == null || focusItem == null) { - return null; - } - - shiftSelectionAnchorColumn = getColumn(newCell.x); - shiftSelectionAnchorItem = getItem(newCell.y); - - if (ctrl) { - selectedCells.clear(); - addCellstThatDoNotAlreadyExist(selectedCells, selectedCellsBeforeRangeSelect); - } else { - selectedCells.clear(); - } - - GridColumn currentColumn = focusColumn; - GridItem currentItem = focusItem; - - GridColumn endColumn = getColumn(newCell.x); - GridItem endItem = getItem(newCell.y); - - final Point newRange = getSelectionRange(currentItem, currentColumn, endItem, endColumn); - - currentColumn = getColumn(newRange.x); - endColumn = getColumn(newRange.y); - - final GridColumn startCol = currentColumn; - - if (currentItem.getRowIndex() > endItem.getRowIndex()) { - final GridItem temp = currentItem; - currentItem = endItem; - endItem = temp; - } - - boolean firstLoop = true; - - do { - if (!firstLoop) { - currentItem = getNextVisibleItem(currentItem); - } - - firstLoop = false; - - boolean firstLoop2 = true; - - currentColumn = startCol; - - do { - if (!firstLoop2) { - final int index = displayOrderedColumns.indexOf(currentColumn) + 1; - - if (index < displayOrderedColumns.size()) { - currentColumn = getVisibleColumn_DegradeRight(currentItem, - displayOrderedColumns.get(index)); - } else { - currentColumn = null; - } - - if (currentColumn != null) { - if (displayOrderedColumns.indexOf(currentColumn) > displayOrderedColumns - .indexOf(endColumn)) { - currentColumn = null; - } - } - } - - firstLoop2 = false; - - if (currentColumn != null) { - final Point cell = new Point(currentColumn.index, currentItem.getRowIndex()); - addToCellSelection(cell); - } - } while (currentColumn != endColumn && currentColumn != null); - } while (currentItem != endItem); - } else if (ctrl) { - boolean reverse = reverseDuplicateSelections; - if (!selectedCells.containsAll(newCells)) { - reverse = false; - } - - if (dragging) { - selectedCells.clear(); - addCellstThatDoNotAlreadyExist(selectedCells, selectedCellsBeforeRangeSelect); - } - - if (reverse) { - selectedCells.removeAll(newCells); - } else { - for (final Point newCell : newCells) { - addToCellSelection(newCell); - } - } - } - - updateColumnSelection(); - - final Event e = new Event(); - if (dragging) { - e.detail = SWT.DRAG; - followupCellSelectionEventOwed = true; - } - - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - - return e; - } - - /** - * Adds Point objects from the itemsToBeAdded list that do not currently exist - * in the sourceList. - * - * @param sourceList - * @param itemsToBeAdded - */ - private void addCellstThatDoNotAlreadyExist(final List sourceList, final List itemsToBeAdded) { - if (itemsToBeAdded.size() > 0) { - // add all the cells from the itemsToBeAdded list that don't already exist in - // the sourceList - for (final Point cell : itemsToBeAdded) { - if (!sourceList.contains(cell)) { - sourceList.add(cell); - } - - } - } - } - - private void addToCellSelection(final Point newCell) { - if (newCell.x < 0 || newCell.x >= columns.size()) { - return; - } - - if (newCell.y < 0 || newCell.y >= items.size()) { - return; - } - - if (getColumn(newCell.x).getCellSelectionEnabled()) { - final Iterator it = selectedCells.iterator(); - boolean found = false; - while (it.hasNext()) { - final Point p = it.next(); - if (newCell.equals(p)) { - found = true; - break; - } - } - - if (!found) { - if (selectionType == GridSelectionType.SINGLE && selectedCells.size() > 0) { - return; - } - selectedCells.add(newCell); - } - } - } - - void updateColumnSelection() { - // Update the list of which columns have all their cells selected - selectedColumns.clear(); - - for (final Point cell : selectedCells) { - selectedColumns.add(getColumn(cell.x)); - } - } - - /** - * Initialize all listeners. - */ - private void initListeners() { - disposeListener = this::onDispose; - addListener(SWT.Dispose, disposeListener); - - addPaintListener(this::onPaint); - - addListener(SWT.Resize, e -> onResize()); - - if (getVerticalBar() != null) { - getVerticalBar().addListener(SWT.Selection, e -> onScrollSelection()); - } - - if (getHorizontalBar() != null) { - getHorizontalBar().addListener(SWT.Selection, e -> onScrollSelection()); - } - - defaultKeyListener = this::onKeyDown; - addListener(SWT.KeyDown, defaultKeyListener); - - addTraverseListener(e -> { - if (moveOnTab) { - e.doit = false; - if (selectedItems.isEmpty()) { - select(0); - return; - } - if (selectedItems.size() == 1) { - final int index = getSelectionIndex(); - if (SWT.TRAVERSE_TAB_NEXT == e.detail) { - select(index == getItemCount() - 1 ? 0 : index + 1); - } else if (SWT.TRAVERSE_TAB_PREVIOUS == e.detail) { - select(index == 0 ? getItemCount() - 1 : index - 1); - } - return; - } - return; - } else { - e.doit = true; - } - }); - - addListener(SWT.MouseDoubleClick, this::onMouseDoubleClick); - addListener(SWT.MouseDown, this::onMouseDown); - addListener(SWT.MouseUp, this::onMouseUp); - - addMouseMoveListener(this::onMouseMove); - - addMouseTrackListener(new MouseTrackListener() { - @Override - public void mouseEnter(final MouseEvent e) { - } - - @Override - public void mouseExit(final MouseEvent e) { - onMouseExit(e); - } - - @Override - public void mouseHover(final MouseEvent e) { - } - }); - - addFocusListener(new FocusListener() { - @Override - public void focusGained(final FocusEvent e) { - onFocusIn(); - redraw(); - } - - @Override - public void focusLost(final FocusEvent e) { - redraw(); - } - }); - - // Special code to reflect mouse wheel events if using an external - // scroller - addListener(SWT.MouseWheel, this::onMouseWheel); - } - - /** - * Disable default key listener - */ - public void disableDefaultKeyListener() { - if (defaultKeyListenerEnabled) { - removeListener(SWT.KeyDown, defaultKeyListener); - } - defaultKeyListenerEnabled = false; - } - - /** - * Enable default key listener - */ - public void enableDefaultKeyListener() { - if (!defaultKeyListenerEnabled) { - addListener(SWT.KeyDown, defaultKeyListener); - } - defaultKeyListenerEnabled = true; - } - - private void onFocusIn() { - if (!items.isEmpty() && focusItem == null) { - focusItem = items.get(0); - } - } - - private void onDispose(final Event event) { - // We only want to dispose of our items and such *after* anybody else who may - // have been - // listening to the dispose has had a chance to do whatever. - removeListener(SWT.Dispose, disposeListener); - notifyListeners(SWT.Dispose, event); - event.type = SWT.None; - - disposing = true; - - cellHeaderSelectionBackground.dispose(); - - for (final GridItem item : items) { - item.dispose(); - } - - for (final GridColumnGroup columnGroup : columnGroups) { - columnGroup.dispose(); - } - - for (final GridColumn col : columns) { - col.dispose(); - } - } - - /** - * Mouse wheel event handler. - * - * @param e - * event - */ - private void onMouseWheel(final Event e) { - if (vScroll.getVisible()) { - vScroll.handleMouseWheel(e); - if (getVerticalBar() == null) { - e.doit = false; - } - } else if (hScroll.getVisible()) { - hScroll.handleMouseWheel(e); - if (getHorizontalBar() == null) { - e.doit = false; - } - } - } - - /** - * Mouse down event handler. - * - * @param e - * event - */ - private void onMouseDown(final Event e) { - // for some reason, SWT prefers the children to get focus if - // there are any children - // the setFocus method on Composite will not set focus to the - // Composite if one of its - // children can get focus instead. This only affects the table - // when an editor is open - // and therefore the table has a child. The solution is to - // forceFocus() - if ((getStyle() & SWT.NO_FOCUS) != SWT.NO_FOCUS) { - forceFocus(); - } - - hideToolTip(); - - // if populated will be fired at end of method. - Event selectionEvent = null; - - cellSelectedOnLastMouseDown = false; - cellRowSelectedOnLastMouseDown = false; - cellColumnSelectedOnLastMouseDown = false; - - if (hoveringOnColumnResizer) { - if (e.button == 1) { - resizingColumn = true; - resizingStartX = e.x; - resizingColumnStartWidth = columnBeingResized.getWidth(); - } - return; - } - if (rowsResizeable && hoveringOnRowResizer) { - if (e.button == 1) { - resizingRow = true; - resizingStartY = e.y; - resizingRowStartHeight = rowBeingResized.getHeight(); - } - return; - } - - if (e.button == 1 && handleColumnHeaderPush(e.x, e.y)) { - return; - } - - if (e.button == 1 && handleColumnGroupHeaderClick(e.x, e.y)) { - return; - } - - if (e.button == 1 && handleColumnFooterPush(e.x, e.y)) { - return; - } - - final GridItem item = getItem(new Point(e.x, e.y)); - - if (e.button == 1 && item != null && handleCellClick(item, e.x, e.y)) { - return; - } - - if (isListening(SWT.DragDetect)) { - if (cellSelectionEnabled && hoveringOnSelectionDragArea - || !cellSelectionEnabled && item != null && selectedItems.contains(item)) { - if (dragDetect(e)) { - return; - } - } - } - - if (item != null) { - if (cellSelectionEnabled) { - final GridColumn col = getColumn(new Point(e.x, e.y)); - boolean isSelectedCell = false; - if (col != null) { - isSelectedCell = selectedCells.contains(new Point(col.index, item.getRowIndex())); - } - - if (e.button == 1 || e.button == 3 && col != null && !isSelectedCell) { - if (col != null) { - selectionEvent = updateCellSelection(new Point(col.index, item.getRowIndex()), e.stateMask, - false, true); - cellSelectedOnLastMouseDown = getCellSelectionCount() > 0; - - if (e.stateMask != SWT.MOD2) { - focusColumn = col; - focusItem = item; - } - // showColumn(col); - showItem(item); - redraw(); - } else if (rowHeaderVisible) { - if (e.x <= rowHeaderWidth) { - - final boolean shift = (e.stateMask & SWT.MOD2) != 0; - boolean ctrl = false; - if (!shift) { - ctrl = (e.stateMask & SWT.MOD1) != 0; - } - - final Vector cells = new Vector<>(); - - if (shift) { - getCells(item, focusItem, cells); - } else { - getCells(item, cells); - } - - int newStateMask = SWT.NONE; - if (ctrl) { - newStateMask = SWT.MOD1; - } - - selectionEvent = updateCellSelection(cells, newStateMask, shift, ctrl); - cellRowSelectedOnLastMouseDown = getCellSelectionCount() > 0; - - if (!shift) { - // set focus back to the first visible column - focusColumn = getColumn(new Point(rowHeaderWidth + 1, e.y)); - - focusItem = item; - } - showItem(item); - redraw(); - } - } - intendedFocusColumn = focusColumn; - } - } else { - if (e.button == 2 || e.button > 3) { - return; - } - - if (e.button == 3 && selectionType == GridSelectionType.MULTI) { - if ((e.stateMask & SWT.MOD2) == SWT.MOD2) { - return; - } - - if ((e.stateMask & SWT.MOD1) == SWT.MOD1) { - return; - } - - if (selectedItems.contains(item)) { - return; - } - } - selectionEvent = updateSelection(item, e.stateMask); - - focusItem = item; - showItem(item); - redraw(); - } - } else if (e.button == 1 && rowHeaderVisible && e.x <= rowHeaderWidth && e.y < headerHeight) { - // Nothing to select - if (items.size() == 0) { - return; - } - if (cellSelectionEnabled) { - // click on the top left corner means select everything - selectionEvent = selectAllCellsInternal(); - - focusColumn = getColumn(new Point(rowHeaderWidth + 1, 1)); - } else { - // click on the top left corner means select everything - selectionEvent = selectAllRowsInternal(); - } - focusItem = getItem(getTopIndex()); - } else if (cellSelectionEnabled && e.button == 1 && columnHeadersVisible && e.y <= headerHeight) { - // column cell selection - final GridColumn col = getColumn(new Point(e.x, e.y)); - - if (col == null) { - return; - } - - if (getItemCount() == 0) { - return; - } - - final Vector cells = new Vector<>(); - - final GridColumnGroup group = col.getColumnGroup(); - if (group != null && e.y < groupHeaderHeight) { - getCells(group, cells); - } else { - getCells(col, cells); - } - - selectionEvent = updateCellSelection(cells, e.stateMask, false, true); - cellColumnSelectedOnLastMouseDown = getCellSelectionCount() > 0; - - GridItem newFocusItem = getItem(0); - - while (newFocusItem != null && getSpanningColumn(newFocusItem, col) != null) { - newFocusItem = getNextVisibleItem(newFocusItem); - } - - if (newFocusItem != null) { - focusColumn = col; - focusItem = newFocusItem; - } - - showColumn(col); - redraw(); - } - - if (selectionEvent != null) { - selectionEvent.stateMask = e.stateMask; - selectionEvent.button = e.button; - selectionEvent.item = item; - selectionEvent.x = e.x; - selectionEvent.y = e.y; - notifyListeners(SWT.Selection, selectionEvent); - - if (!cellSelectionEnabled) { - if (isListening(SWT.DragDetect)) { - dragDetect(e); - } - } - } - - } - - /** - * Mouse double click event handler. - * - * @param e - * event - */ - private void onMouseDoubleClick(final Event e) { - if (e.button != 1) { - return; - } - - if (hoveringOnColumnResizer) { - columnBeingResized.pack(); - columnBeingResized.fireResized(); - for (int index = displayOrderedColumns.indexOf(columnBeingResized) + 1; index < displayOrderedColumns - .size(); index++) { - final GridColumn col = displayOrderedColumns.get(index); - if (col.isVisible()) { - col.fireMoved(); - } - } - resizingColumn = false; - handleHoverOnColumnResizer(e.x, e.y); - e.doit = false; - return; - } else if (rowsResizeable && hoveringOnRowResizer) { - final List sel = Arrays.asList(getSelection()); - if (sel.contains(rowBeingResized)) { - // the user double-clicked a row resizer of a selected row - // so update all selected rows - for (final GridItem element : sel) { - element.pack(); - } - redraw(); - } else { - // otherwise only update the row the user double-clicked - rowBeingResized.pack(); - } - - resizingRow = false; - handleHoverOnRowResizer(e.x, e.y); - e.doit = false; - return; - } - - if (e.y < headerHeight && columnHeadersVisible) { - e.doit = false; - return; - } - - final GridItem item = getItem(new Point(e.x, e.y)); - if (item != null) { - if (isListening(SWT.DefaultSelection)) { - final Event newEvent = new Event(); - newEvent.item = item; - - notifyListeners(SWT.DefaultSelection, newEvent); - } else if (item.getItemCount() > 0) { - item.setExpanded(!item.isExpanded()); - - if (item.isExpanded()) { - item.fireEvent(SWT.Expand); - } else { - item.fireEvent(SWT.Collapse); - } - } - } - } - - /** - * Mouse up handler. - * - * @param e - * event - */ - private void onMouseUp(final Event e) { - cellSelectedOnLastMouseDown = false; - - if (resizingColumn) { - resizingColumn = false; - handleHoverOnColumnResizer(e.x, e.y); // resets cursor if - // necessary - return; - } - if (resizingRow) { - resizingRow = false; - handleHoverOnRowResizer(e.x, e.y); // resets cursor if - // necessary - return; - } - - if (pushingColumn) { - pushingColumn = false; - columnBeingPushed.getHeaderRenderer().setMouseDown(false); - columnBeingPushed.getHeaderRenderer().setHover(false); - redraw(); - if (pushingAndHovering) { - columnBeingPushed.fireListeners(); - } - setCapture(false); - return; - } - - if (draggingColumn) { - handleColumnDrop(); - return; - } - - if (cellDragSelectionOccuring || cellRowDragSelectionOccuring || cellColumnDragSelectionOccuring) { - cellDragSelectionOccuring = false; - cellRowDragSelectionOccuring = false; - cellColumnDragSelectionOccuring = false; - setCursor(null); - - if (followupCellSelectionEventOwed) { - final Event se = new Event(); - se.button = e.button; - se.item = getItem(new Point(e.x, e.y)); - se.stateMask = e.stateMask; - se.x = e.x; - se.y = e.y; - - notifyListeners(SWT.Selection, se); - followupCellSelectionEventOwed = false; - } - } - } - - /** - * Mouse move event handler. - * - * @param e - * event - */ - private void onMouseMove(final MouseEvent e) { - // check to see if the mouse is outside the grid - // this should only happen when the mouse is captured for inplace - // tooltips - see bug 203364 - if (inplaceTooltipCapture && (e.x < 0 || e.y < 0 || e.x >= getBounds().width || e.y >= getBounds().height)) { - setCapture(false); - inplaceTooltipCapture = false; - return; // a mouseexit event should occur immediately - } - - // if populated will be fired at end of method. - Event selectionEvent = null; - - if ((e.stateMask & SWT.BUTTON1) == 0) { - handleHovering(e.x, e.y); - } else { - if (draggingColumn) { - handleColumnDragging(e.x); - return; - } - - if (resizingColumn) { - handleColumnResizerDragging(e.x); - return; - } - if (resizingRow) { - handleRowResizerDragging(e.y); - return; - } - if (pushingColumn) { - handleColumnHeaderHoverWhilePushing(e.x, e.y); - return; - } - if (cellSelectionEnabled) { - if (cellDragSelectionEnabled && !cellDragSelectionOccuring && cellSelectedOnLastMouseDown) { - cellDragSelectionOccuring = true; - // XXX: make this user definable - setCursor(getDisplay().getSystemCursor(SWT.CURSOR_CROSS)); - cellDragCTRL = (e.stateMask & SWT.MOD1) != 0; - if (cellDragCTRL) { - selectedCellsBeforeRangeSelect.clear(); - selectedCellsBeforeRangeSelect.addAll(selectedCells); - } - } - if (!cellRowDragSelectionOccuring && cellRowSelectedOnLastMouseDown) { - cellRowDragSelectionOccuring = true; - setCursor(getDisplay().getSystemCursor(SWT.CURSOR_CROSS)); - cellDragCTRL = (e.stateMask & SWT.MOD1) != 0; - if (cellDragCTRL) { - selectedCellsBeforeRangeSelect.clear(); - selectedCellsBeforeRangeSelect.addAll(selectedCells); - } - } - - if (!cellColumnDragSelectionOccuring && cellColumnSelectedOnLastMouseDown) { - cellColumnDragSelectionOccuring = true; - setCursor(getDisplay().getSystemCursor(SWT.CURSOR_CROSS)); - cellDragCTRL = (e.stateMask & SWT.MOD1) != 0; - if (cellDragCTRL) { - selectedCellsBeforeRangeSelect.clear(); - selectedCellsBeforeRangeSelect.addAll(selectedCells); - } - } - - final int ctrlFlag = cellDragCTRL ? SWT.MOD1 : SWT.NONE; - - if (cellDragSelectionOccuring && handleCellHover(e.x, e.y)) { - GridColumn intentColumn = hoveringColumn; - GridItem intentItem = hoveringItem; - - if (hoveringItem == null) { - if (e.y > headerHeight) { - // then we must be hovering way to the bottom - intentItem = getPreviousVisibleItem(null); - } else { - intentItem = items.get(0); - } - } - - if (hoveringColumn == null) { - if (e.x > rowHeaderWidth) { - // then we must be hovering way to the right - intentColumn = getVisibleColumn_DegradeLeft(intentItem, - displayOrderedColumns.get(displayOrderedColumns.size() - 1)); - } else { - GridColumn firstCol = displayOrderedColumns.get(0); - if (!firstCol.isVisible()) { - firstCol = getNextVisibleColumn(firstCol); - } - intentColumn = firstCol; - } - } - - showColumn(intentColumn); - showItem(intentItem); - selectionEvent = updateCellSelection(new Point(intentColumn.index, intentItem.getRowIndex()), - ctrlFlag | SWT.MOD2, true, false); - } - if (cellRowDragSelectionOccuring && handleCellHover(e.x, e.y)) { - GridItem intentItem = hoveringItem; - - if (hoveringItem == null) { - if (e.y > headerHeight) { - // then we must be hovering way to the bottom - intentItem = getPreviousVisibleItem(null); - } else { - if (getTopIndex() > 0) { - intentItem = getPreviousVisibleItem(items.get(getTopIndex())); - } else { - intentItem = items.get(0); - } - } - } - - final Vector cells = new Vector<>(); - - getCells(intentItem, focusItem, cells); - - showItem(intentItem); - selectionEvent = updateCellSelection(cells, ctrlFlag, true, false); - } - if (cellColumnDragSelectionOccuring && handleCellHover(e.x, e.y)) { - final GridColumn intentCol = hoveringColumn; - - if (intentCol == null) { - if (e.y < rowHeaderWidth) { - // TODO: get the first col to the left - } else { - // TODO: get the first col to the right - } - } - - if (intentCol == null) { - return; // temporary - } - - GridColumn iterCol = intentCol; - - final Vector newSelected = new Vector<>(); - - final boolean decreasing = displayOrderedColumns.indexOf(iterCol) > displayOrderedColumns - .indexOf(focusColumn); - - do { - getCells(iterCol, newSelected); - - if (iterCol == focusColumn) { - break; - } - - if (decreasing) { - iterCol = getPreviousVisibleColumn(iterCol); - } else { - iterCol = getNextVisibleColumn(iterCol); - } - - } while (true); - - selectionEvent = updateCellSelection(newSelected, ctrlFlag, true, false); - } - - } - } - - if (selectionEvent != null) { - selectionEvent.stateMask = e.stateMask; - selectionEvent.button = e.button; - selectionEvent.item = getItem(new Point(e.x, e.y)); - selectionEvent.x = e.x; - selectionEvent.y = e.y; - notifyListeners(SWT.Selection, selectionEvent); - } - } - - /** - * Handles the assignment of the correct values to the hover* field variables - * that let the painting code now what to paint as hovered. - * - * @param x - * mouse x coordinate - * @param y - * mouse y coordinate - */ - private void handleHovering(final int x, final int y) { - // TODO: need to clean up and refactor hover code - handleCellHover(x, y); - - // Is this Grid a DragSource ?? - if (cellSelectionEnabled && getData("DragSource") != null) { - if (handleHoverOnSelectionDragArea(x, y)) { - return; - } - } - - if (columnHeadersVisible) { - if (handleHoverOnColumnResizer(x, y)) { - // if (hoveringItem != null || !hoveringDetail.equals("") || hoveringColumn != - // null - // || hoveringColumnHeader != null || hoverColumnGroupHeader != null) - // { - // hoveringItem = null; - // hoveringDetail = ""; - // hoveringColumn = null; - // hoveringColumnHeader = null; - // hoverColumnGroupHeader = null; - // - // Rectangle clientArea = getClientArea(); - // redraw(clientArea.x,clientArea.y,clientArea.width,clientArea.height,false); - // } - return; - } - } - if (rowsResizeable && rowHeaderVisible) { - if (handleHoverOnRowResizer(x, y)) { - return; - } - } - - // handleCellHover(x, y); - } - - /** - * Refreshes the hover* variables according to the mouse location and current - * state of the table. This is useful is some method call, caused the state of - * the table to change and therefore the hover effects may have become out of - * date. - */ - protected void refreshHoverState() { - final Point p = getDisplay().map(null, this, getDisplay().getCursorLocation()); - handleHovering(p.x, p.y); - } - - /** - * Mouse exit event handler. - * - * @param e - * event - */ - private void onMouseExit(final MouseEvent e) { - hoveringItem = null; - hoveringDetail = ""; - hoveringColumn = null; - hoveringColumnHeader = null; - hoverColumnGroupHeader = null; - hoveringOverText = false; - hideToolTip(); - redraw(); - } - - /** - * Key down event handler. - * - * @param e - * event - */ - protected void onKeyDown(final Event e) { - if (focusColumn == null || focusColumn.isDisposed()) { - if (columns.size() == 0) { - return; - } - - focusColumn = getColumn(0); - intendedFocusColumn = focusColumn; - } - - if (e.character == '\r' && focusItem != null) { - final Event newEvent = new Event(); - newEvent.item = focusItem; - - notifyListeners(SWT.DefaultSelection, newEvent); - return; - } - - int attemptExpandCollapse = 0; - if ((e.character == '-' || !cellSelectionEnabled && e.keyCode == SWT.ARROW_LEFT) && focusItem != null - && focusItem.isExpanded()) { - attemptExpandCollapse = SWT.Collapse; - } else if ((e.character == '+' || !cellSelectionEnabled && e.keyCode == SWT.ARROW_RIGHT) && focusItem != null - && !focusItem.isExpanded()) { - attemptExpandCollapse = SWT.Expand; - } - - if (attemptExpandCollapse != 0 && focusItem != null && focusItem.hasChildren()) { - int performExpandCollapse = 0; - - if (cellSelectionEnabled && focusColumn != null && focusColumn.isTree()) { - performExpandCollapse = attemptExpandCollapse; - } else if (!cellSelectionEnabled) { - performExpandCollapse = attemptExpandCollapse; - } - - if (performExpandCollapse == SWT.Expand) { - focusItem.setExpanded(true); - focusItem.fireEvent(SWT.Expand); - return; - } - if (performExpandCollapse == SWT.Collapse) { - focusItem.setExpanded(false); - focusItem.fireEvent(SWT.Collapse); - return; - } - } - - if (e.character == ' ') { - handleSpaceBarDown(e); - } - - GridItem newSelection = null; - GridColumn newColumnFocus = null; - - // These two variables are used because the key navigation when the shift key is - // down is - // based, not off the focus item/column, but rather off the implied focus (i.e. - // where the - // keyboard has extended focus to). - GridItem impliedFocusItem = focusItem == null || focusItem.isDisposed() ? null : focusItem; - GridColumn impliedFocusColumn = focusColumn.isDisposed() ? null : focusColumn; - - if (cellSelectionEnabled && e.stateMask == SWT.MOD2) { - if (shiftSelectionAnchorColumn != null) { - if (shiftSelectionAnchorItem == null || shiftSelectionAnchorItem.isDisposed()) { - impliedFocusItem = focusItem; - } else { - impliedFocusItem = shiftSelectionAnchorItem; - } - impliedFocusColumn = shiftSelectionAnchorColumn.isDisposed() ? null : shiftSelectionAnchorColumn; - } - } - - switch (e.keyCode) { - case SWT.ARROW_RIGHT: - if (cellSelectionEnabled) { - if (impliedFocusItem != null && impliedFocusColumn != null) { - newSelection = impliedFocusItem; - - int index = displayOrderedColumns.indexOf(impliedFocusColumn); - - int jumpAhead = impliedFocusItem.getColumnSpan(impliedFocusColumn.index); - - jumpAhead++; - - while (jumpAhead > 0) { - index++; - if (index < displayOrderedColumns.size()) { - if (displayOrderedColumns.get(index).isVisible()) { - jumpAhead--; - } - } else { - break; - } - } - - if (index < displayOrderedColumns.size()) { - newColumnFocus = displayOrderedColumns.get(index); - } else { - newColumnFocus = impliedFocusColumn; - } - } - intendedFocusColumn = newColumnFocus; - } else { - if (impliedFocusItem != null && impliedFocusItem.hasChildren()) { - newSelection = impliedFocusItem.getItem(0); - } - } - break; - case SWT.ARROW_LEFT: - if (cellSelectionEnabled) { - if (impliedFocusItem != null && impliedFocusColumn != null) { - newSelection = impliedFocusItem; - - final int index = displayOrderedColumns.indexOf(impliedFocusColumn); - - if (index != 0) { - newColumnFocus = displayOrderedColumns.get(index - 1); - - newColumnFocus = getVisibleColumn_DegradeLeft(impliedFocusItem, newColumnFocus); - - if (newColumnFocus == null) { - newColumnFocus = impliedFocusColumn; - } - - } else { - newColumnFocus = impliedFocusColumn; - } - } - intendedFocusColumn = newColumnFocus; - } else { - if (impliedFocusItem != null && impliedFocusItem.getParentItem() != null) { - newSelection = impliedFocusItem.getParentItem(); - } - } - break; - case SWT.ARROW_UP: - if (impliedFocusItem != null) { - newSelection = getPreviousVisibleItem(impliedFocusItem); - } - - if (impliedFocusColumn != null) { - if (newSelection != null) { - newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, intendedFocusColumn); - } else { - newColumnFocus = impliedFocusColumn; - } - } - - break; - case SWT.ARROW_DOWN: - if (impliedFocusItem != null) { - newSelection = getNextVisibleItem(impliedFocusItem); - } else { - if (items.size() > 0) { - newSelection = items.get(0); - } - } - - if (impliedFocusColumn != null) { - if (newSelection != null && intendedFocusColumn != null) { - newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, intendedFocusColumn); - } else { - newColumnFocus = impliedFocusColumn; - } - } - break; - case SWT.HOME: - if (!cellSelectionEnabled) { - if (items.size() > 0) { - newSelection = items.get(0); - } - } else { - if (e.stateMask == SWT.MOD1 && items.size() > 0) { - impliedFocusItem = items.get(0); - } - newSelection = impliedFocusItem; - newColumnFocus = getVisibleColumn_DegradeRight(newSelection, displayOrderedColumns.get(0)); - intendedFocusColumn = newColumnFocus; - } - - break; - case SWT.END: - if (!cellSelectionEnabled) { - if (items.size() > 0) { - newSelection = getPreviousVisibleItem(null); - } - } else { - newSelection = impliedFocusItem; - newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, - displayOrderedColumns.get(displayOrderedColumns.size() - 1)); - } - - break; - case SWT.PAGE_UP: - final int topIndex = getTopIndex(); - - newSelection = items.get(topIndex); - - if (focusItem == newSelection) { - final RowRange range = getRowRange(getTopIndex(), getVisibleGridHeight(), false, true); - newSelection = items.get(range.startIndex); - } - - if (impliedFocusColumn != null) { - if (newSelection != null && intendedFocusColumn != null) { - newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, intendedFocusColumn); - } else { - newColumnFocus = impliedFocusColumn; - } - } - break; - case SWT.PAGE_DOWN: - final int bottomIndex = getBottomIndex(); - - newSelection = items.get(bottomIndex); - - if (!isShown(newSelection)) { - // the item at bottom index is not shown completely - final GridItem tmpItem = getPreviousVisibleItem(newSelection); - if (tmpItem != null) { - newSelection = tmpItem; - } - } - - if (focusItem == newSelection) { - final RowRange range = getRowRange(getBottomIndex(), getVisibleGridHeight(), true, false); - newSelection = items.get(range.endIndex); - } - - if (impliedFocusColumn != null) { - if (newSelection != null && intendedFocusColumn != null) { - newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, intendedFocusColumn); - } else { - newColumnFocus = impliedFocusColumn; - } - } - break; - default: - break; - } - - if (newSelection == null) { - return; - } - - if (cellSelectionEnabled) { - if (e.stateMask != SWT.MOD2) { - focusColumn = newColumnFocus; - } - showColumn(newColumnFocus); - - if (e.stateMask != SWT.MOD2) { - focusItem = newSelection; - } - showItem(newSelection); - - if (e.stateMask != SWT.MOD1 || isMod1Home(e)) { - final int stateMask = e.stateMask == SWT.MOD1 ? SWT.NONE : e.stateMask; - final Event selEvent = updateCellSelection( - new Point(newColumnFocus.index, newSelection.getRowIndex()), stateMask, false, false); - if (selEvent != null) { - selEvent.stateMask = stateMask; - selEvent.character = e.character; - selEvent.keyCode = e.keyCode; - notifyListeners(SWT.Selection, selEvent); - } - } - - redraw(); - } else { - Event selectionEvent = null; - if (selectionType == GridSelectionType.SINGLE || e.stateMask != SWT.MOD1) { - selectionEvent = updateSelection(newSelection, e.stateMask); - if (selectionEvent != null) { - selectionEvent.stateMask = e.stateMask; - selectionEvent.character = e.character; - selectionEvent.keyCode = e.keyCode; - } - } - - focusItem = newSelection; - showItem(newSelection); - redraw(); - - if (selectionEvent != null) { - notifyListeners(SWT.Selection, selectionEvent); - } - } - } - - private boolean isMod1Home(final Event e) { - return e.stateMask == SWT.MOD1 && e.keyCode == SWT.HOME; - } - - private void handleSpaceBarDown(final Event event) { - if (focusItem == null) { - return; - } - - if (selectionEnabled && !cellSelectionEnabled && !selectedItems.contains(focusItem)) { - selectedItems.add(focusItem); - redraw(); - final Event e = new Event(); - e.item = focusItem; - e.stateMask = event.stateMask; - e.character = event.character; - e.keyCode = event.keyCode; - notifyListeners(SWT.Selection, e); - } - - if (!cellSelectionEnabled) { - boolean checkFirstCol = false; - boolean first = true; - - for (final GridColumn col : columns) { - - if (first) { - if (!col.isCheck()) { - break; - } - - first = false; - checkFirstCol = true; - } else { - if (col.isCheck()) { - checkFirstCol = false; - break; - } - } - } - - if (checkFirstCol) { - focusItem.setChecked(!focusItem.getChecked()); - redraw(); - focusItem.fireCheckEvent(0); - } - } - } - - /** - * Resize event handler. - */ - private void onResize() { - - // CGross 1/2/08 - I don't really want to be doing this.... - // I shouldn't be changing something you user configured... - // leaving out for now - // if (columnScrolling) - // { - // int maxWidth = getClientArea().width; - // if (rowHeaderVisible) - // maxWidth -= rowHeaderWidth; - // - // for (Iterator cols = columns.iterator(); cols.hasNext();) { - // GridColumn col = (GridColumn) cols.next(); - // if (col.getWidth() > maxWidth) - // col.setWidth(maxWidth); - // } - // } - - scrollValuesObsolete = true; - topIndex = -1; - bottomIndex = -1; - } - - /** - * Scrollbar selection event handler. - */ - private void onScrollSelection() { - topIndex = -1; - bottomIndex = -1; - refreshHoverState(); - redraw(getClientArea().x, getClientArea().y, getClientArea().width, getClientArea().height, false); - } - - /** - * Returns the intersection of the given column and given item. - * - * @param column - * column - * @param item - * item - * @return x,y of top left corner of the cell - */ - Point getOrigin(final GridColumn column, final GridItem item) { - int x = 0; - - if (rowHeaderVisible) { - x += rowHeaderWidth; - } - - x -= getHScrollSelectionInPixels(); - - for (final GridColumn colIter : displayOrderedColumns) { - - if (colIter == column) { - break; - } - - if (colIter.isVisible()) { - x += colIter.getWidth(); - } - } - - int y = 0; - if (item != null) { - if (columnHeadersVisible) { - y += headerHeight; - } - - int currIndex = getTopIndex(); - final int itemIndex = item.getRowIndex(); - - if (itemIndex == -1) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - while (currIndex != itemIndex) { - if (currIndex < itemIndex) { - final GridItem currItem = items.get(currIndex); - if (currItem.isVisible()) { - y += currItem.getHeight() + 1; - } - currIndex++; - } else if (currIndex > itemIndex) { - currIndex--; - final GridItem currItem = items.get(currIndex); - if (currItem.isVisible()) { - y -= currItem.getHeight() + 1; - } - } - } - } else { - if (column.getColumnGroup() != null) { - y += groupHeaderHeight; - } - } - - return new Point(x, y); - } - - /** - * Determines (which cell/if a cell) has been clicked (mouse down really) and - * notifies the appropriate renderer. Returns true when a cell has responded to - * this event in some way and prevents the event from triggering an action - * further down the chain (like a selection). - * - * @param item - * item clicked - * @param x - * mouse x - * @param y - * mouse y - * @return true if this event has been consumed. - */ - private boolean handleCellClick(final GridItem item, final int x, final int y) { - - // if(!isTree) - // return false; - - final GridColumn col = getColumn(new Point(x, y)); - if (col == null) { - return false; - } - - col.getCellRenderer().setBounds(item.getBounds(col.index)); - return col.getCellRenderer().notify(IInternalWidget.LeftMouseButtonDown, new Point(x, y), item); - - } - - /** - * Sets the hovering variables (hoverItem,hoveringColumn) as well as hoverDetail - * by talking to the cell renderers. Triggers a redraw if necessary. - * - * @param x - * mouse x - * @param y - * mouse y - * @return true if a new section of the table is now being hovered - */ - private boolean handleCellHover(final int x, final int y) { - - String detail = ""; - - boolean overText = false; - - final GridColumn col = getColumn(new Point(x, y)); - final GridItem item; - // If the user select cells and drag, the mouse pointer could be out of the - // grid's bounds - if (x >= getClientArea().width - 1) { - item = hoveringItem; - } else if (x < getClientArea().x) { - item = hoveringItem; - } else { - item = getItem(new Point(x, y)); - } - - GridColumnGroup hoverColGroup = null; - GridColumn hoverColHeader = null; - - if (col != null) { - if (item != null) { - if (y < getClientArea().height - (columnFootersVisible ? footerHeight : 0)) { - col.getCellRenderer().setBounds(item.getBounds(col.index)); - - if (col.getCellRenderer().notify(IInternalWidget.MouseMove, new Point(x, y), item)) { - detail = col.getCellRenderer().getHoverDetail(); - } - - final Rectangle textBounds = col.getCellRenderer().getTextBounds(item, false); - - if (textBounds != null) { - final Point p = new Point(x - col.getCellRenderer().getBounds().x, - y - col.getCellRenderer().getBounds().y); - overText = textBounds.contains(p); - } - } - } else { - if (y < headerHeight) { - if (columnGroups.length != 0 && y < groupHeaderHeight && col.getColumnGroup() != null) { - hoverColGroup = col.getColumnGroup(); - hoverColGroup.getHeaderRenderer().setBounds(hoverColGroup.getBounds()); - if (hoverColGroup.getHeaderRenderer().notify(IInternalWidget.MouseMove, new Point(x, y), - hoverColGroup)) { - detail = hoverColGroup.getHeaderRenderer().getHoverDetail(); - } - - final Rectangle textBounds = hoverColGroup.getHeaderRenderer().getTextBounds(hoverColGroup, - false); - - if (textBounds != null) { - final Point p = new Point(x - hoverColGroup.getHeaderRenderer().getBounds().x, - y - hoverColGroup.getHeaderRenderer().getBounds().y); - overText = textBounds.contains(p); - } - } else { - // on col header - hoverColHeader = col; - - col.getHeaderRenderer().setBounds(col.getBounds()); - if (col.getHeaderRenderer().notify(IInternalWidget.MouseMove, new Point(x, y), col)) { - detail = col.getHeaderRenderer().getHoverDetail(); - } - - final Rectangle textBounds = col.getHeaderRenderer().getTextBounds(col, false); - - if (textBounds != null) { - final Point p = new Point(x - col.getHeaderRenderer().getBounds().x, - y - col.getHeaderRenderer().getBounds().y); - overText = textBounds.contains(p); - } - } - } - } - } - - boolean hoverChange = false; - - if (hoveringItem != item || !hoveringDetail.equals(detail) || hoveringColumn != col - || hoverColGroup != hoverColumnGroupHeader || hoverColHeader != hoveringColumnHeader) { - hoveringItem = item; - hoveringDetail = detail; - hoveringColumn = col; - hoveringColumnHeader = hoverColHeader; - hoverColumnGroupHeader = hoverColGroup; - - final Rectangle clientArea = getClientArea(); - redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); - - hoverChange = true; - } - - // do inplace toolTip stuff - if (hoverChange || hoveringOverText != overText) { - hoveringOverText = overText; - - if (overText) { - - Rectangle cellBounds = null; - Rectangle textBounds = null; - Rectangle preferredTextBounds = null; - - if(hoveringItem != null && hoveringItem.getToolTipText(col.index) == null && // no inplace tooltips - // when regular - // tooltip - !col.getWordWrap()) // dont show inplace tooltips for cells with wordwrap - { - cellBounds = col.getCellRenderer().getBounds(); - if (cellBounds.x + cellBounds.width > getSize().x) { - cellBounds.width = getSize().x - cellBounds.x; - } - textBounds = col.getCellRenderer().getTextBounds(item, false); - preferredTextBounds = col.getCellRenderer().getTextBounds(item, true); - } else if (hoveringColumnHeader != null && hoveringColumnHeader.getHeaderTooltip() == null) // no - // inplace - // tooltips - // when - // regular - // tooltip - { - cellBounds = hoveringColumnHeader.getHeaderRenderer().getBounds(); - if (cellBounds.x + cellBounds.width > getSize().x) { - cellBounds.width = getSize().x - cellBounds.x; - } - textBounds = hoveringColumnHeader.getHeaderRenderer().getTextBounds(col, false); - preferredTextBounds = hoveringColumnHeader.getHeaderRenderer().getTextBounds(col, true); - } else if (hoverColumnGroupHeader != null) { - cellBounds = hoverColumnGroupHeader.getHeaderRenderer().getBounds(); - if (cellBounds.x + cellBounds.width > getSize().x) { - cellBounds.width = getSize().x - cellBounds.x; - } - textBounds = hoverColumnGroupHeader.getHeaderRenderer().getTextBounds(hoverColumnGroupHeader, - false); - preferredTextBounds = hoverColumnGroupHeader.getHeaderRenderer() - .getTextBounds(hoverColumnGroupHeader, true); - } - - // if we are truncated - if (textBounds != null && textBounds.width < preferredTextBounds.width) { - showToolTip(item, col, hoverColumnGroupHeader, - new Point(cellBounds.x + textBounds.x, cellBounds.y + textBounds.y)); - // the following 2 lines are done here rather than in showToolTip to allow - // that method to be overridden yet still capture the mouse. - setCapture(true); - inplaceTooltipCapture = true; - } - } else { - hideToolTip(); - } - } - - // do normal cell specific tooltip stuff - if (hoverChange) { - String newTip = null; - if (hoveringItem != null && hoveringColumn != null) { - // get cell specific tooltip - newTip = hoveringItem.getToolTipText(hoveringColumn.index); - } else if (hoveringColumn != null && hoveringColumnHeader != null) { - // get column header specific tooltip - newTip = hoveringColumn.getHeaderTooltip(); - } - - if (newTip == null) { // no cell or column header specific tooltip then use base Grid tooltip - newTip = getToolTipText(); - } - - // Avoid unnecessarily resetting tooltip - this will cause the tooltip to jump - // around - if (newTip != null && !newTip.equals(displayedToolTipText)) { - updateToolTipText(newTip); - } else if (newTip == null && displayedToolTipText != null) { - updateToolTipText(null); - } - displayedToolTipText = newTip; - } - - return hoverChange; - } - - /** - * Sets the tooltip for the whole Grid to the given text. This method is made - * available for subclasses to override, when a subclass wants to display a - * different than the standard SWT/OS tooltip. Generally, those subclasses would - * override this event and use this tooltip text in their own tooltip or just - * override this method to prevent the SWT/OS tooltip from displaying. - * - * @param text - */ - protected void updateToolTipText(final String text) { - super.setToolTipText(text); - } - - /** - * Marks the scroll values obsolete so they will be recalculated. - */ - protected void setScrollValuesObsolete() { - scrollValuesObsolete = true; - redraw(); - } - - /** - * Inserts a new column into the table. - * - * @param column - * new column - * @param index - * index to insert new column - * @return current number of columns - */ - int newColumn(final GridColumn column, final int index) { - - final int size = columns.size(); - if (index == -1) { - column.index = size; - columns.add(column); - displayOrderedColumns.add(column); - } else { - column.index = index; - columns.add(index, column); - for(int i = index + 1; i < size; i++) { - columns.get(i).index = i; - } - displayOrderedColumns.add(index, column); - - dataVisualizer.addColumn(index); - for(int i = 0; i < size; i++) { - columns.get(i).setColumnIndex(i); - } - } - - estimate(sizingGC -> { - computeHeaderHeight(sizingGC); - computeFooterHeight(sizingGC); - }); - - updatePrimaryCheckColumn(); - - for (final GridItem item : items) { - item.columnAdded(index); - } - - scrollValuesObsolete = true; - redraw(); - clearDisplayOrderedCache(); - return size - 1; - } - - /** - * Removes the given column from the table. - * - * @param column - * column to remove - */ - void removeColumn(final GridColumn column) { - boolean selectionModified = false; - - final int index = column.index; - - if (cellSelectionEnabled) { - final Vector removeSelectedCells = new Vector<>(); - - for (final Point cell : selectedCells) { - if (cell.x == index) { - removeSelectedCells.add(cell); - } - } - - if (removeSelectedCells.size() > 0) { - selectedCells.removeAll(removeSelectedCells); - selectionModified = true; - } - - for (final Point cell : selectedCells) { - if (cell.x >= index) { - cell.x--; - selectionModified = true; - } - } - } - - columns.remove(column); - final int size = columns.size(); - for(int i = index; i < size; i++) { - columns.get(i).index = i; - } - displayOrderedColumns.remove(column); - dataVisualizer.clearColumn(index); - - if (focusColumn == column) { - focusColumn = null; - } - - updatePrimaryCheckColumn(); - - scrollValuesObsolete = true; - - redraw(); - - int i = 0; - for (final GridColumn col : columns) { - col.setColumnIndex(i); - i++; - } - - if (selectionModified && !disposing) { - updateColumnSelection(); - } - clearDisplayOrderedCache(); - } - - /** - * Manages the setting of the checkbox column when the SWT.CHECK style was given - * to the table. This method will ensure that the first column of the table - * always has a checkbox when SWT.CHECK is given to the table. - */ - private void updatePrimaryCheckColumn() { - if ((getStyle() & SWT.CHECK) == SWT.CHECK) { - boolean firstCol = true; - - for (final GridColumn col : columns) { - col.setTableCheck(firstCol); - firstCol = false; - } - } - } - - void newRootItem(final GridItem item, final int index) { - if (index == -1 || index >= rootItems.size()) { - rootItems.add(item); - } else { - rootItems.add(index, item); - } - } - - void removeRootItem(final GridItem item) { - rootItems.remove(item); - } - - /** - * Creates the new item at the given index. Only called from GridItem - * constructor. - * - * @param item - * new item - * @param index - * index to insert the item at - * @return the index where the item was insert - */ - int newItem(final GridItem item, int index, final boolean root) { - int row = 0; - - if (!isTree) { - if (item.getParentItem() != null) { - isTree = true; - } - } - - // Have to convert indexes, this method needs a flat index, the method is called - // with indexes - // that are relative to the level - if (root && index != -1) { - if (index >= rootItems.size()) { - index = -1; - } else { - index = rootItems.get(index).getRowIndex(); - } - } else if (!root) { - if (index >= item.getParentItem().getItems().length || index == -1) { - GridItem rightMostDescendent = item.getParentItem(); - - while (rightMostDescendent.getItems().length > 0) { - rightMostDescendent = rightMostDescendent.getItems()[rightMostDescendent.getItems().length - 1]; - } - - index = rightMostDescendent.getRowIndex() + 1; - } else { - index = item.getParentItem().getItems()[index].getRowIndex(); - } - } - - if (index == -1) { - items.add(item); - row = items.size() - 1; - } else { - items.add(index, item); - row = index; - for (int i = index + 1; i < items.size(); i++) { - items.get(i).increaseRow(); - } - } - - estimate(sizingGC -> { - if (items.size() == 1 && !userModifiedItemHeight) { - itemHeight = computeItemHeight(item, sizingGC); - // virtual problems here - if ((getStyle() & SWT.VIRTUAL) != 0) { - item.setHasSetData(false); - } - } - - item.initializeHeight(itemHeight); - - if (isRowHeaderVisible() && isAutoWidth()) { - rowHeaderWidth = Math.max(rowHeaderWidth, // - rowHeaderRenderer.computeSize(sizingGC, SWT.DEFAULT, SWT.DEFAULT, item).x); - } - }); - - scrollValuesObsolete = true; - topIndex = -1; - bottomIndex = -1; - - currentVisibleItems++; - - redraw(); - - return row; - } - - /** - * Removes the given item from the table. This method is only called from the - * item's dispose method. - * - * @param item - * item to remove - */ - void removeItem(final GridItem item) { - - final Point[] cells = getCells(item); - boolean selectionModified = false; - - final int index = item.getRowIndex(); - - items.remove(item); - - dataVisualizer.clearRow(item); - - if (disposing) { - return; - } - - for (int i = index; i < items.size(); i++) { - items.get(i).decreaseRow(); - } - - if (selectedItems.remove(item)) { - selectionModified = true; - } - - for (final Point cell : cells) { - if (selectedCells.remove(cell)) { - selectionModified = true; - } - } - - if (focusItem == item) { - focusItem = null; - } - - scrollValuesObsolete = true; - topIndex = -1; - bottomIndex = -1; - if (item.isVisible()) { - currentVisibleItems--; - } - - if (selectionModified && !disposing) { - updateColumnSelection(); - } - - redraw(); - // Need to update the scrollbars see see 375327 - updateScrollbars(); - } - - /** - * Creates the given column group at the given index. This method is only called - * from the {@code GridColumnGroup}'s constructor. - * - * @param group - * group to add. - */ - void newColumnGroup(final GridColumnGroup group) { - final GridColumnGroup[] newColumnGroups = new GridColumnGroup[columnGroups.length + 1]; - System.arraycopy(columnGroups, 0, newColumnGroups, 0, columnGroups.length); - newColumnGroups[newColumnGroups.length - 1] = group; - columnGroups = newColumnGroups; - - // if we just added the first col group, then we need to up the row - // height - if (columnGroups.length == 1) { - computeHeaderHeight(); - } - - scrollValuesObsolete = true; - redraw(); - } - - /** - * Removes the given column group from the table. This method is only called - * from the {@code GridColumnGroup}'s dispose method. - * - * @param group - * group to remove. - */ - void removeColumnGroup(final GridColumnGroup group) { - final GridColumnGroup[] newColumnGroups = new GridColumnGroup[columnGroups.length - 1]; - int newIndex = 0; - for (final GridColumnGroup columnGroup : columnGroups) { - if (columnGroup != group) { - newColumnGroups[newIndex] = columnGroup; - newIndex++; - } - } - columnGroups = newColumnGroups; - - if (columnGroups.length == 0) { - computeHeaderHeight(); - } - - scrollValuesObsolete = true; - redraw(); - } - - /** - * Updates the cached number of visible items by the given amount. - * - * @param amount - * amount to update cached total - */ - void updateVisibleItems(final int amount) { - currentVisibleItems += amount; - } - - /** - * Returns the current item in focus. - * - * @return item in focus or {@code null}. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public GridItem getFocusItem() { - checkWidget(); - return focusItem; - } - - /** - * Returns the current cell in focus. If cell selection is disabled, this method - * returns null. - * - * @return cell in focus or {@code null}. x represents the column and y the row - * the cell is in - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public Point getFocusCell() { - checkWidget(); - if (!cellSelectionEnabled) { - return null; - } - - int x = -1; - int y = -1; - - if (focusColumn != null) { - x = focusColumn.index; - } - - if (focusItem != null) { - y = focusItem.getRowIndex(); - } - - return new Point(x, y); - } - - /** - * Sets the focused item to the given item. - * - * @param item - * item to focus. - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if item is disposed
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setFocusItem(final GridItem item) { - checkWidget(); - // TODO: check and make sure this item is valid for focus - if (item == null || item.isDisposed() || item.getParent() != this) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - focusItem = item; - } - - /** - * Sets the focused item to the given column. Column focus is only applicable - * when cell selection is enabled. - * - * @param column - * column to focus. - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if item is disposed
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setFocusColumn(final GridColumn column) { - checkWidget(); - // TODO: check and make sure this item is valid for focus - if (column == null || column.isDisposed() || column.getParent() != this || !column.isVisible()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - focusColumn = column; - intendedFocusColumn = column; - } - - /** - * Returns an array of the columns in their display order. - * - * @return columns in display order - */ - GridColumn[] getColumnsInOrder() { - checkWidget(); - return displayOrderedColumns.toArray(new GridColumn[columns.size()]); - } - - /** - * Returns true if the table is set to horizontally scroll column-by-column - * rather than pixel-by-pixel. - * - * @return true if the table is scrolled horizontally by column - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean getColumnScrolling() { - checkWidget(); - return columnScrolling; - } - - /** - * Sets the table scrolling method to either scroll column-by-column (true) or - * pixel-by-pixel (false). - * - * @param columnScrolling - * true to horizontally scroll by column, false to scroll by pixel - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setColumnScrolling(final boolean columnScrolling) { - checkWidget(); - if (rowHeaderVisible && !columnScrolling) { - return; - } - - this.columnScrolling = columnScrolling; - scrollValuesObsolete = true; - redraw(); - } - - /** - * Returns the first visible column that is not spanned by any other column that - * is either the given column or any of the columns displaying to the left of - * the given column. If the given column and subsequent columns to the right are - * either not visible or spanned, this method will return null. - * - * @param item - * @param col - * @return - */ - GridColumn getVisibleColumn_DegradeLeft(final GridItem item, final GridColumn col) { - int index = displayOrderedColumns.indexOf(col); - - GridColumn prevCol = col; - - int i = 0; - while (!prevCol.isVisible()) { - i++; - if (index - i < 0) { - return null; - } - - prevCol = displayOrderedColumns.get(index - i); - } - - index = displayOrderedColumns.indexOf(prevCol); - - for (int j = 0; j < index; j++) { - final GridColumn tempCol = displayOrderedColumns.get(j); - - if (!tempCol.isVisible()) { - continue; - } - - if(item.getColumnSpan(tempCol.index) >= index - j) { - prevCol = tempCol; - break; - } - } - - return prevCol; - } - - /** - * Returns the first visible column that is not spanned by any other column that - * is either the given column or any of the columns displaying to the right of - * the given column. If the given column and subsequent columns to the right are - * either not visible or spanned, this method will return null. - * - * @param item - * @param col - * @return - */ - GridColumn getVisibleColumn_DegradeRight(final GridItem item, final GridColumn col) { - int index = displayOrderedColumns.indexOf(col); - - int i = 0; - GridColumn nextCol = col; - while (!nextCol.isVisible()) { - i++; - if (index + i == displayOrderedColumns.size()) { - return null; - } - - nextCol = displayOrderedColumns.get(index + i); - } - - index = displayOrderedColumns.indexOf(nextCol); - final int startIndex = index; - - while (index > 0) { - - index--; - final GridColumn prevCol = displayOrderedColumns.get(index); - - if(item.getColumnSpan(prevCol.index) >= startIndex - index) { - if (startIndex == displayOrderedColumns.size() - 1) { - return null; - } else { - return getVisibleColumn_DegradeRight(item, displayOrderedColumns.get(startIndex + 1)); - } - } - - } - - return nextCol; - } - - /** - * Returns true if the cells are selectable in the reciever. - * - * @return cell selection enablement status. - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public boolean getCellSelectionEnabled() { - checkWidget(); - return cellSelectionEnabled; - } - - /** - * Sets whether cells are selectable in the receiver. - * - * @param cellSelection - * the cellSelection to set - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setCellSelectionEnabled(final boolean cellSelection) { - checkWidget(); - if (!cellSelection) { - selectedCells.clear(); - redraw(); - } else { - if ((getStyle() & SWT.SINGLE) == 0) { - // To keep compatibility, one can selected multiple cells - selectionType = GridSelectionType.MULTI; - } - selectedItems.clear(); - redraw(); - } - - cellSelectionEnabled = cellSelection; - } - - /** - * @return true if cell selection is enabled - */ - public boolean isCellSelectionEnabled() { - return cellSelectionEnabled; - } - - /** - * Sets whether cells are selectable in the receiver by dragging the mouse - * cursor. - * - * @param cellDragSelection - * the cellDragSelection to set - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setCellDragSelectionEnabled(final boolean cellDragSelection) { - checkWidget(); - cellDragSelectionEnabled = cellDragSelection; - } - - /** - * @return true if cell drag selection is enabled - */ - public boolean isCellDragSelectionEnabled() { - return cellDragSelectionEnabled; - } - - /** - * Deselects the given cell in the receiver. If the given cell is already - * deselected it remains deselected. Invalid cells are ignored. - * - * @param cell - * cell to deselect. - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the cell is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void deselectCell(final Point cell) { - checkWidget(); - - if (cell == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - selectedCells.remove(cell); - updateColumnSelection(); - redraw(); - } - - /** - * Deselects the given cells. Invalid cells are ignored. - * - * @param cells - * the cells to deselect. - * - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the set of cells or any cell is - * null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void deselectCells(final Point[] cells) { - checkWidget(); - - if (cells == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - for (final Point cell : cells) { - if (cell == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - } - - for (final Point cell : cells) { - selectedCells.remove(cell); - } - - updateColumnSelection(); - - redraw(); - } - - /** - * Deselects all selected cells in the receiver. - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void deselectAllCells() { - checkWidget(); - selectedCells.clear(); - updateColumnSelection(); - redraw(); - } - - /** - * Selects the given cell. Invalid cells are ignored. - * - * @param cell - * point whose x values is a column index and y value is an item - * index - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void selectCell(final Point cell) { - checkWidget(); - - if (!cellSelectionEnabled) { - return; - } - - if (cell == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - addToCellSelection(cell); - updateColumnSelection(); - redraw(); - } - - /** - * Selects the given cells. Invalid cells are ignored. - * - * @param cells - * an arry of points whose x value is a column index and y value is - * an item index - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the set of cells or an individual - * cell is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void selectCells(final Point[] cells) { - checkWidget(); - - if (!cellSelectionEnabled) { - return; - } - - if (cells == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - for (final Point cell : cells) { - if (cell == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - } - - for (final Point cell : cells) { - addToCellSelection(cell); - } - - updateColumnSelection(); - redraw(); - } - - /** - * Selects all cells in the receiver. - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void selectAllCells() { - checkWidget(); - selectAllCellsInternal(); - } - - /** - * Selects all cells in the receiver. - * - * @return An Event object - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - private Event selectAllCellsInternal() { - if (!cellSelectionEnabled) { - return selectAllRowsInternal(); - } - - if (columns.size() == 0) { - return null; - } - - if (items.size() == 0) { - return null; - } - - int index = 0; - GridColumn column = displayOrderedColumns.get(index); - - while (!column.isVisible()) { - index++; - - if (index >= columns.size()) { - return null; - } - - column = displayOrderedColumns.get(index); - } - - final GridColumn oldFocusColumn = focusColumn; - final GridItem oldFocusItem = focusItem; - - focusColumn = column; - focusItem = items.get(0); - - final GridItem lastItem = getPreviousVisibleItem(null); - final GridColumn lastCol = getVisibleColumn_DegradeLeft(lastItem, - displayOrderedColumns.get(displayOrderedColumns.size() - 1)); - - final Event event = updateCellSelection(new Point(lastCol.index, lastItem.getRowIndex()), SWT.MOD2, true, - false); - - focusColumn = oldFocusColumn; - focusItem = oldFocusItem; - - updateColumnSelection(); - - redraw(); - return event; - } - - /** - * Selects rows in the receiver. - * - * @return An Event object - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - private Event selectAllRowsInternal() { - if (cellSelectionEnabled) { - return selectAllCellsInternal(); - } - - if (GridSelectionType.MULTI != selectionType) { - return null; - } - - if (items.size() == 0) { - return null; - } - - deselectAll(); - - final GridItem oldFocusItem = focusItem; - - final GridItem firstItem = getItem(getTopIndex()); - final GridItem lastItem = getPreviousVisibleItem(null); - - setFocusItem(firstItem); - updateSelection(firstItem, SWT.NONE); - - final Event event = updateSelection(lastItem, SWT.MOD2); - - setFocusItem(oldFocusItem); - - redraw(); - return event; - } - - /** - * Selects all cells in the given column in the receiver. - * - * @param col - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void selectColumn(final int col) { - checkWidget(); - final Vector cells = new Vector<>(); - getCells(getColumn(col), cells); - selectCells(cells.toArray(new Point[0])); - } - - /** - * Selects all cells in the given column group in the receiver. - * - * @param colGroup - * the column group - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void selectColumnGroup(final int colGroup) { - selectColumnGroup(getColumnGroup(colGroup)); - } - - /** - * Selects all cells in the given column group in the receiver. - * - * @param colGroup - * the column group - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void selectColumnGroup(final GridColumnGroup colGroup) { - checkWidget(); - final Vector cells = new Vector<>(); - getCells(colGroup, cells); - selectCells(cells.toArray(new Point[0])); - } - - /** - * Selects the selection to the given cell. The existing selection is cleared - * before selecting the given cell. - * - * @param cell - * point whose x values is a column index and y value is an item - * index - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the cell is invalid
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setCellSelection(final Point cell) { - checkWidget(); - - if (!cellSelectionEnabled) { - return; - } - - if (cell == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (!isValidCell(cell)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - selectedCells.clear(); - addToCellSelection(cell); - updateColumnSelection(); - redraw(); - } - - /** - * Selects the selection to the given set of cell. The existing selection is - * cleared before selecting the given cells. - * - * @param cells - * point array whose x values is a column index and y value is an - * item index - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the cell array or an individual cell - * is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the a cell is invalid
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public void setCellSelection(final Point[] cells) { - checkWidget(); - - if (!cellSelectionEnabled) { - return; - } - - if (cells == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - for (final Point cell : cells) { - if (cell == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (!isValidCell(cell)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - - selectedCells.clear(); - for (final Point cell : cells) { - addToCellSelection(cell); - } - - updateColumnSelection(); - redraw(); - } - - /** - * Returns an array of cells that are currently selected in the receiver. The - * order of the items is unspecified. An empty array indicates that no items are - * selected. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * selection, so modifying the array will not affect the receiver. - *

- * - * @return an array representing the cell selection - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public Point[] getCellSelection() { - checkWidget(); - return selectedCells.toArray(new Point[selectedCells.size()]); - } - - GridColumn getFocusColumn() { - return focusColumn; - } - - void updateColumnFocus() { - if (!focusColumn.isVisible()) { - final int index = displayOrderedColumns.indexOf(focusColumn); - if (index > 0) { - GridColumn prev = displayOrderedColumns.get(index - 1); - prev = getVisibleColumn_DegradeLeft(focusItem, prev); - if (prev == null) { - prev = getVisibleColumn_DegradeRight(focusItem, focusColumn); - } - focusColumn = prev; - } else { - focusColumn = getVisibleColumn_DegradeRight(focusItem, focusColumn); - } - } - } - - private void getCells(final GridColumn col, final Vector cells) { - - final int colIndex = col.index; - - int columnAtPosition = 0; - for (final GridColumn nextCol : displayOrderedColumns) { - if (!nextCol.isVisible()) { - continue; - } - - if (nextCol == col) { - break; - } - - columnAtPosition++; - } - - GridItem item = null; - if (getItemCount() > 0) { - item = getItem(0); - } - - while (item != null) { - // is cell spanned - final int position = -1; - boolean spanned = false; - for (final GridColumn nextCol : displayOrderedColumns) { - if (!nextCol.isVisible()) { - continue; - } - - if (nextCol == col) { - break; - } - - final int span = item.getColumnSpan(nextCol.index); - - if (position + span >= columnAtPosition) { - spanned = true; - break; - } - } - - if (!spanned && item.getColumnSpan(colIndex) == 0) { - cells.add(new Point(colIndex, item.getRowIndex())); - } - - item = getNextVisibleItem(item); - } - } - - private void getCells(final GridColumnGroup colGroup, final Vector cells) { - final GridColumn[] cols = colGroup.getColumns(); - for (final GridColumn col : cols) { - getCells(col, cells); - } - } - - private void getCells(final GridItem item, final Vector cells) { - final int itemIndex = item.getRowIndex(); - - int span = 0; - - for (final GridColumn nextCol : displayOrderedColumns) { - - if (span > 0) { - span--; - continue; - } - - if (!nextCol.isVisible()) { - continue; - } - - span = item.getColumnSpan(nextCol.index); - - cells.add(new Point(nextCol.index, itemIndex)); - } - } - - private Point[] getCells(final GridItem item) { - final Vector cells = new Vector<>(); - - final int itemIndex = item.getRowIndex(); - - int span = 0; - - for (final GridColumn nextCol : displayOrderedColumns) { - - if (span > 0) { - span--; - continue; - } - - if (!nextCol.isVisible()) { - continue; - } - - span = item.getColumnSpan(nextCol.index); - - cells.add(new Point(nextCol.index, itemIndex)); - } - return cells.toArray(new Point[] {}); - } - - private void getCells(final GridItem fromItem, final GridItem toItem, final Vector cells) { - final boolean descending = fromItem.getRowIndex() < toItem.getRowIndex(); - - GridItem iterItem = toItem; - - do { - getCells(iterItem, cells); - - if (iterItem == fromItem) { - break; - } - - if (descending) { - iterItem = getPreviousVisibleItem(iterItem); - } else { - iterItem = getNextVisibleItem(iterItem); - } - } while (true); - } - - private int blend(final int v1, final int v2, final int ratio) { - return (ratio * v1 + (100 - ratio) * v2) / 100; - } - - private RGB blend(final RGB c1, final RGB c2, final int ratio) { - final int r = blend(c1.red, c2.red, ratio); - final int g = blend(c1.green, c2.green, ratio); - final int b = blend(c1.blue, c2.blue, ratio); - return new RGB(r, g, b); - } - - /** - * Returns a point whose x and y values are the to and from column indexes of - * the new selection range inclusive of all spanned columns. - * - * @param fromItem - * @param fromColumn - * @param toItem - * @param toColumn - * @return - */ - private Point getSelectionRange(GridItem fromItem, GridColumn fromColumn, GridItem toItem, GridColumn toColumn) { - if (displayOrderedColumns.indexOf(fromColumn) > displayOrderedColumns.indexOf(toColumn)) { - final GridColumn temp = fromColumn; - fromColumn = toColumn; - toColumn = temp; - } - - if (fromItem.getRowIndex() > toItem.getRowIndex()) { - final GridItem temp = fromItem; - fromItem = toItem; - toItem = temp; - } - - boolean firstTime = true; - GridItem iterItem = fromItem; - - final int fromIndex = fromColumn.index; - final int toIndex = toColumn.index; - - do { - if (!firstTime) { - iterItem = getNextVisibleItem(iterItem); - } else { - firstTime = false; - } - - final Point cols = getRowSelectionRange(iterItem, fromColumn, toColumn); - - // check and see if column spanning means that the range increased - if (cols.x != fromIndex || cols.y != toIndex) { - final GridColumn newFrom = getColumn(cols.x); - final GridColumn newTo = getColumn(cols.y); - - // Unfortunately we have to start all over again from the top with the new range - return getSelectionRange(fromItem, newFrom, toItem, newTo); - } - } while (iterItem != toItem); - - return new Point(fromColumn.index, toColumn.index); - } - - /** - * Returns a point whose x and y value are the to and from column indexes of the - * new selection range inclusive of all spanned columns. - * - * @param item - * @param fromColumn - * @param toColumn - * @return - */ - private Point getRowSelectionRange(final GridItem item, final GridColumn fromColumn, final GridColumn toColumn) { - - int newFrom = fromColumn.index; - int newTo = toColumn.index; - - int span = 0; - int spanningColIndex = -1; - boolean spanningBeyondToCol = false; - - for (final GridColumn col : displayOrderedColumns) { - - if (!col.isVisible()) { - if (span > 0) { - span--; - } - continue; - } - - if (span > 0) { - if (col == fromColumn) { - newFrom = spanningColIndex; - } else if (col == toColumn && span > 1) { - spanningBeyondToCol = true; - } - - span--; - - if (spanningBeyondToCol && span == 0) { - newTo = col.index; - break; - } - } else { - final int index = col.index; - span = item.getColumnSpan(index); - if (span > 0) { - spanningColIndex = index; - } - - if (col == toColumn && span > 0) { - spanningBeyondToCol = true; - } - } - - if (col == toColumn && !spanningBeyondToCol) { - break; - } - - } - - return new Point(newFrom, newTo); - } - - /** - * Returns the column which is spanning the given column for the given item or - * null if it is not being spanned. - * - * @param item - * @param column - * @return - */ - private GridColumn getSpanningColumn(final GridItem item, final GridColumn column) { - int span = 0; - GridColumn spanningCol = null; - - for (final GridColumn col : displayOrderedColumns) { - - if (col == column) { - return spanningCol; - } - - if (span > 0) { - span--; - if (span == 0) { - spanningCol = null; - } - } else { - span = item.getColumnSpan(col.index); - - if (span > 0) { - spanningCol = col; - } - } - } - return spanningCol; - } - - /** - * Returns true if the given cell's x and y values are valid column and item - * indexes respectively. - * - * @param cell - * @return - */ - private boolean isValidCell(final Point cell) { - if (cell.x < 0 || cell.x >= columns.size()) { - return false; - } - - if (cell.y < 0 || cell.y >= items.size()) { - return false; - } - - return true; - } - - /** - * Shows the inplace tooltip for the given item and column. The location is the - * x and y origin of the text in the cell. - *

- * This method may be overriden to provide their own custom tooltips. - * - * @param item - * the item currently hovered over or null. - * @param column - * the column currently hovered over or null. - * @param group - * the group currently hovered over or null. - * @param location - * the x,y origin of the text in the hovered object. - */ - protected void showToolTip(final GridItem item, final GridColumn column, final GridColumnGroup group, - final Point location) { - if (inplaceToolTip == null) { - inplaceToolTip = new GridToolTip(this); - } - - if (group != null) { - inplaceToolTip.setFont(getFont()); - inplaceToolTip.setText(group.getText()); - } else if (item != null) { - inplaceToolTip.setFont(item.getFont(column.index)); - inplaceToolTip.setText(item.getText(column.index)); - } else if (column != null) { - inplaceToolTip.setFont(getFont()); - inplaceToolTip.setText(column.getText()); - } - - final Point p = getDisplay().map(this, null, location); - - inplaceToolTip.setLocation(p); - - inplaceToolTip.setVisible(true); - } - - /** - * Hides the inplace tooltip. - *

- * This method must be overriden when showToolTip is overriden. Subclasses must - * call super when overriding this method. - */ - protected void hideToolTip() { - if (inplaceToolTip != null) { - inplaceToolTip.setVisible(false); - } - if (inplaceTooltipCapture) { - setCapture(false); - inplaceTooltipCapture = false; - } - } - - void recalculateRowHeaderHeight(final GridItem item, final int oldHeight, final int newHeight) { - checkWidget(); - - if (newHeight > itemHeight) { - itemHeight = newHeight; - - userModifiedItemHeight = false; - hasDifferingHeights = false; - - itemHeight = computeItemHeight(items.get(0)); - - for (final GridItem item2 : items) { - item2.setHeight(itemHeight); - } - - setScrollValuesObsolete(); - redraw(); - } - - } - - void recalculateRowHeaderWidth(final GridItem item, final int oldWidth, final int newWidth) { - if (!isAutoWidth()) { - return; - } - - if (newWidth > rowHeaderWidth) { - rowHeaderWidth = newWidth; - } else if (newWidth < rowHeaderWidth && oldWidth == rowHeaderWidth) { - // if the changed width is smaller, and the previous width of that rows header - // was equal - // to the current row header width then its possible that we may need to make - // the new - // row header width smaller, but to do that we need to ask all the rows all over - // again - computeRowHeaderWidth(newWidth); - } - redraw(); - } - - /** - * {@inheritDoc} - */ - @Override - public void setFont(final Font font) { - dataVisualizer.setDefaultFont(font); - defaultFont = font; - super.setFont(font); - } - - /** - * Returns the row header width or 0 if row headers are not visible. - * - * @return the width of the row headers - * @throws org.eclipse.swt.SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getItemHeaderWidth() { - checkWidget(); - if (!rowHeaderVisible) { - return 0; - } - return rowHeaderWidth; - } - - /** - * Sets the row header width to the specified value. This automatically disables - * the auto width feature of the grid. - * - * @param width - * the width of the row header - * @see #getItemHeaderWidth() - * @see #setAutoWidth(boolean) - */ - public void setItemHeaderWidth(final int width) { - checkWidget(); - rowHeaderWidth = width; - setAutoWidth(false); - redraw(); - } - - /** - * Sets the number of items contained in the receiver. - * - * @param count - * the number of items - * - * @exception org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setItemCount(int count) { - checkWidget(); - setRedraw(false); - if (count < 0) { - count = 0; - } - - if (count < items.size()) { - - selectedCells.clear(); - for (int i = items.size() - 1; i >= count; i--) { - final GridItem removed = items.remove(i); - rootItems.remove(i); - - selectedItems.remove(removed); - - if (removed.isVisible()) { - currentVisibleItems--; - } - removed.disposeOnly(); - } - if (!disposing) { - updateColumnSelection(); - } - scrollValuesObsolete = true; - topIndex = -1; - bottomIndex = -1; - } - - while (count > items.size()) { - new GridItem(this, SWT.NONE); - } - setRedraw(true); - } - - /** - * Initialize accessibility. - */ - private void initAccessible() { - final Accessible accessible = getAccessible(); - accessible.addAccessibleListener(new AccessibleAdapter() { - @Override - public void getDescription(final AccessibleEvent e) { - final int childID = e.childID; - if (childID >= 0 && childID < items.size()) { - String descrption = ""; - for (int i = 0; i < columns.size(); i++) { - if (i != 0) { - descrption += columns.get(i).getText() + " : "; - descrption += items.get(childID).getText(i) + " "; - } - } - e.result = descrption; - } - } - - @Override - public void getName(final AccessibleEvent e) { - final int childID = e.childID; - if (childID >= 0 && childID < items.size()) { - // Name of the items - e.result = items.get(childID).getText(); - } else if (childID >= items.size() && childID < items.size() + columns.size()) { - // Name of the column headers - e.result = columns.get(childID - items.size()).getText(); - } else if (childID >= items.size() + columns.size() - && childID < items.size() + columns.size() + columnGroups.length) { - // Name of the column group headers - e.result = columnGroups[childID - items.size() - columns.size()].getText(); - } else if (childID >= items.size() + columns.size() + columnGroups.length - && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { - // Name of the toggle button for column group headers - e.result = ACC_TOGGLE_BUTTON_NAME; - } - } - }); - - accessible.addAccessibleControlListener(new AccessibleControlAdapter() { - @Override - public void getChildAtPoint(final AccessibleControlEvent e) { - final Point location = toControl(e.x, e.y); - e.childID = ACC.CHILDID_SELF; - - // Grid Items - final GridItem item = getItem(location); - if (item != null) { - for (int i = 0; i < getItemCount(); i++) { - if (item.equals(getItem(i))) { - e.childID = i; - return; - } - } - } else { - // Column Headers - final GridColumn column = overColumnHeader(location.x, location.y); - final int itemCount = getItemCount(); - if (column != null) { - for (int i = 0; i < getColumns().length; i++) { - if (column.equals(getColumn(i))) { - e.childID = itemCount + i; - return; - } - } - } else { - // Column Group headers - final GridColumnGroup columnGroup = overColumnGroupHeader(location.x, location.y); - if (columnGroup != null) { - for (int i = 0; i < getColumnGroups().length; i++) { - if (columnGroup.equals(getColumnGroup(i))) { - final Rectangle toggle = ((DefaultColumnGroupHeaderRenderer) columnGroup - .getHeaderRenderer()).getToggleBounds(); - if (toggle.contains(location.x, location.y)) { - // Toggle button for column group - // header - e.childID = itemCount + getColumns().length + getColumnGroups().length + i; - } else { - // Column Group header - e.childID = itemCount + getColumns().length + i; - } - return; - } - } - } - } - } - } - - @Override - public void getChildCount(final AccessibleControlEvent e) { - if (e.childID == ACC.CHILDID_SELF) { - int length = items.size(); - - if (isTree) { - // Child count for parent. Here if the item parent - // is not an other item, - // it is consider as children of Grid - for (final GridItem item : items) { - if (item.getParentItem() != null) { - length--; - } - } - } - e.detail = length; - } - } - - @Override - public void getChildren(final AccessibleControlEvent e) { - if (e.childID == ACC.CHILDID_SELF) { - int length = items.size(); - if (isTree) { - for (final GridItem item : items) { - if (item.getParentItem() != null) { - length--; - } - } - - final Object[] children = new Object[length]; - int j = 0; - - for (int i = 0; i < items.size(); i++) { - if (items.get(i).getParentItem() == null) { - children[j] = Integer.valueOf(i); - j++; - } - } - e.children = children; - } else { - final Object[] children = new Object[length]; - for (int i = 0; i < items.size(); i++) { - children[i] = Integer.valueOf(i); - } - e.children = children; - } - } - } - - @Override - public void getDefaultAction(final AccessibleControlEvent e) { - final int childID = e.childID; - if (childID >= 0 && childID < items.size()) { - if (getItem(childID).hasChildren()) { - // Action of tree items - if (getItem(childID).isExpanded()) { - e.result = ACC_ITEM_ACTION_COLLAPSE; - } else { - e.result = ACC_ITEM_ACTION_EXPAND; - } - } else { - // action of default items - e.result = ACC_ITEM_DEFAULT_ACTION; - } - } else if (childID >= items.size() && childID < items.size() + columns.size() + columnGroups.length) { - // action of column and column group header - e.result = ACC_COLUMN_DEFAULT_ACTION; - } else if (childID >= items.size() + columns.size() + columnGroups.length - && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { - // action of toggle button of column group header - e.result = SWT.getMessage("SWT_Press"); - } - } - - @Override - public void getLocation(final AccessibleControlEvent e) { - // location of parent - Rectangle location = getBounds(); - location.x = 0; - location.y = 0; - final int childID = e.childID; - - if (childID >= 0 && childID < items.size()) { - // location of items - final GridItem item = getItem(childID); - if (item != null) { - final Point p = getOrigin(columns.get(0), item); - location.y = p.y; - location.height = item.getHeight(); - } - } else if (childID >= items.size() && childID < items.size() + columns.size()) { - // location of columns headers - final GridColumn column = getColumn(childID - items.size()); - if (column != null) { - location.x = getColumnHeaderXPosition(column); - if (column.getColumnGroup() == null) { - location.y = 0; - } else { - location.y = groupHeaderHeight; - } - location.height = headerHeight; - location.width = column.getWidth(); - } - } else if (childID >= items.size() + columns.size() - && childID < items.size() + columns.size() + columnGroups.length) { - // location of column group header - final GridColumnGroup columnGroup = getColumnGroup(childID - items.size() - columns.size()); - if (columnGroup != null) { - location.y = 0; - location.height = groupHeaderHeight; - location.x = getColumnHeaderXPosition(columnGroup.getFirstVisibleColumn()); - int width = 0; - for (int i = 0; i < columnGroup.getColumns().length; i++) { - if (columnGroup.getColumns()[i].isVisible()) { - width += columnGroup.getColumns()[i].getWidth(); - } - } - location.width = width; - } - } else if (childID >= items.size() + columns.size() + columnGroups.length - && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { - // location of toggle button of column group header - final GridColumnGroup columnGroup = getColumnGroup( - childID - items.size() - columns.size() - columnGroups.length); - location = ((DefaultColumnGroupHeaderRenderer) columnGroup.getHeaderRenderer()).getToggleBounds(); - } - - if (location != null) { - final Point pt = toDisplay(location.x, location.y); - e.x = pt.x; - e.y = pt.y; - e.width = location.width; - e.height = location.height; - } - } - - @Override - public void getRole(final AccessibleControlEvent e) { - final int childID = e.childID; - if (childID >= 0 && childID < items.size()) { - // role of items - if (isTree) { - e.detail = ACC.ROLE_TREEITEM; - } else { - e.detail = ACC.ROLE_LISTITEM; - } - } else if (childID >= items.size() && childID < items.size() + columns.size() + columnGroups.length) { - // role of columns headers and column group headers - e.detail = ACC.ROLE_TABLECOLUMNHEADER; - } else if (childID >= items.size() + columns.size() + columnGroups.length - && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { - // role of toggle button of column group headers - e.detail = ACC.ROLE_PUSHBUTTON; - } else if (childID == ACC.CHILDID_SELF) { - // role of parent - if (isTree) { - e.detail = ACC.ROLE_TREE; - } else { - e.detail = ACC.ROLE_TABLE; - } - } - } - - @Override - public void getSelection(final AccessibleControlEvent e) { - e.childID = ACC.CHILDID_NONE; - if (selectedItems.size() == 1) { - // Single selection - e.childID = selectedItems.get(0).getRowIndex(); - } else if (selectedItems.size() > 1) { - // multiple selection - e.childID = ACC.CHILDID_MULTIPLE; - final int length = selectedItems.size(); - final Object[] children = new Object[length]; - - for (int i = 0; i < length; i++) { - final GridItem item = selectedItems.get(i); - children[i] = Integer.valueOf(item.getRowIndex()); - } - e.children = children; - } - } - - @Override - public void getState(final AccessibleControlEvent e) { - final int childID = e.childID; - if (childID >= 0 && childID < items.size()) { - // state of items - e.detail = ACC.STATE_SELECTABLE; - if (getDisplay().getActiveShell() == getParent().getShell()) { - e.detail |= ACC.STATE_FOCUSABLE; - } - - if (selectedItems.contains(getItem(childID))) { - e.detail |= ACC.STATE_SELECTED; - if (getDisplay().getActiveShell() == getParent().getShell()) { - e.detail |= ACC.STATE_FOCUSED; - } - } - - if (getItem(childID).getChecked()) { - e.detail |= ACC.STATE_CHECKED; - } - - // only for tree type items - if (getItem(childID).hasChildren()) { - if (getItem(childID).isExpanded()) { - e.detail |= ACC.STATE_EXPANDED; - } else { - e.detail |= ACC.STATE_COLLAPSED; - } - } - - if (!getItem(childID).isVisible()) { - e.detail |= ACC.STATE_INVISIBLE; - } - } else if (childID >= items.size() && childID < items.size() + columns.size() + columnGroups.length) { - // state of column headers and column group headers - e.detail = ACC.STATE_READONLY; - } else if (childID >= items.size() + columns.size() + columnGroups.length - && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { - // state of toggle button of column group headers - if (getColumnGroup(childID - items.size() - columns.size() - columnGroups.length).getExpanded()) { - e.detail = ACC.STATE_EXPANDED; - } else { - e.detail = ACC.STATE_COLLAPSED; - } - } - } - - @Override - public void getValue(final AccessibleControlEvent e) { - final int childID = e.childID; - if (childID >= 0 && childID < items.size()) { - // value for tree items - if (isTree) { - e.result = "" + getItem(childID).getLevel(); - } - } - } - }); - - addListener(SWT.Selection, event -> { - if (selectedItems.size() > 0) { - accessible.setFocus(selectedItems.get(selectedItems.size() - 1).getRowIndex()); - } - }); - - addTreeListener(new TreeListener() { - @Override - public void treeCollapsed(final TreeEvent e) { - if (getFocusItem() != null) { - accessible.setFocus(getFocusItem().getRowIndex()); - } - } - - @Override - public void treeExpanded(final TreeEvent e) { - if (getFocusItem() != null) { - accessible.setFocus(getFocusItem().getRowIndex()); - } - } - }); - } - - /** - * @return the disposing - */ - boolean isDisposing() { - return disposing; - } - - /** - * @param hasSpanning - * the hasSpanning to set - */ - void setHasSpanning(final boolean hasSpanning) { - this.hasSpanning = hasSpanning; - } - - /** - * Returns the receiver's tool tip text, or null if it has not been set. - * - * @return the receiver's tool tip text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public String getToolTipText() { - checkWidget(); - return toolTipText; - } - - /** - * Sets the receiver's tool tip text to the argument, which may be null - * indicating that no tool tip text should be shown. - * - * @param string - * the new tool tip text (or null) - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public void setToolTipText(final String string) { - checkWidget(); - toolTipText = string; - } - - /** - * Updates the row height when the first image is set on an item. - * - * @param column - * the column the image is change - * @param item - * item which images has just been set on. - */ - void imageSetOnItem(final int column, final GridItem item) { - if (sizeOnEveryItemImageChange) { - if (item == null || item.getImage(column) == null) { - return; - } - - int height = item.getImage(column).getBounds().height; - // FIXME Needs better algorithm - if(height + 20 > itemHeight) { - height = computeItemHeight(item); - setItemHeight(height); - } - } else { - if (firstImageSet || userModifiedItemHeight) { - return; - } - - final int height = computeItemHeight(item); - setItemHeight(height); - - firstImageSet = true; - } - } - - /** - * Determines if the mouse is hovering on the selection drag area and changes - * the pointer and sets field appropriately. - *

- * Note: The 'selection drag area' is that part of the selection, on which a - * drag event can be initiated. This is either the border of the selection (i.e. - * a cell border between a slected and a non-selected cell) or the complete - * selection (i.e. anywhere on a selected cell). What area serves as drag area - * is determined by {@link #setDragOnFullSelection(boolean)}. - * - * @param x - * @param y - * @return - * @see #setDragOnFullSelection(boolean) - */ - private boolean handleHoverOnSelectionDragArea(final int x, final int y) { - boolean over = false; - // Point inSelection = null; - - if ((!rowHeaderVisible || x > rowHeaderWidth - SELECTION_DRAG_BORDER_THRESHOLD) - && (!columnHeadersVisible || y > headerHeight - SELECTION_DRAG_BORDER_THRESHOLD)) { - // not on a header - - // if(!dragOnFullSelection) - // { - // // drag area is the border of the selection - // - // if(cellSelectionEnabled) - // { - // Point neP = new Point( x-SELECTION_DRAG_BORDER_THRESHOLD, - // y-SELECTION_DRAG_BORDER_THRESHOLD ); - // Point ne = getCell(neP); - // Point nwP = new Point( x+SELECTION_DRAG_BORDER_THRESHOLD, - // y-SELECTION_DRAG_BORDER_THRESHOLD ); - // Point nw = getCell(nwP); - // Point swP = new Point( x+SELECTION_DRAG_BORDER_THRESHOLD, - // y+SELECTION_DRAG_BORDER_THRESHOLD ); - // Point sw = getCell(swP); - // Point seP = new Point( x-SELECTION_DRAG_BORDER_THRESHOLD, - // y+SELECTION_DRAG_BORDER_THRESHOLD ); - // Point se = getCell(seP); - // - // boolean neSel = ne != null && isCellSelected(ne); - // boolean nwSel = nw != null && isCellSelected(nw); - // boolean swSel = sw != null && isCellSelected(sw); - // boolean seSel = se != null && isCellSelected(se); - // - // over = (neSel || nwSel || swSel || seSel) && (!neSel || !nwSel || !swSel || - // !seSel); - //// inSelection = neSel ? neP : nwSel ? nwP : swSel ? swP : seSel ? seP : null; - // } - // else - // { - // Point nP = new Point( x, y-SELECTION_DRAG_BORDER_THRESHOLD ); - // GridItem n = getItem(nP); - // Point sP = new Point( x, y+SELECTION_DRAG_BORDER_THRESHOLD ); - // GridItem s = getItem(sP); - // - // boolean nSel = n != null && isSelected(n); - // boolean sSel = s != null && isSelected(s); - // - // over = nSel != sSel; - //// inSelection = nSel ? nP : sSel ? sP : null; - // } - // } - // else - // { - // drag area is the entire selection - - if (cellSelectionEnabled) { - final Point p = new Point(x, y); - final Point cell = getCell(p); - over = cell != null && isCellSelected(cell); - // inSelection = over ? p : null; - } else { - final Point p = new Point(x, y); - final GridItem item = getItem(p); - over = item != null && isSelected(item); - // inSelection = over ? p : null; - } - } - // } - - if (over != hoveringOnSelectionDragArea) { - // if (over) - // { - // // use drag cursor only in border mode - // if (!dragOnFullSelection) - // setCursor(getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL)); - //// potentialDragStart = inSelection; - // } - // else - // { - // setCursor(null); - //// potentialDragStart = null; - // } - hoveringOnSelectionDragArea = over; - } - return over; - } - - /** - * Display a mark indicating the point at which an item will be inserted. This - * is used as a visual hint to show where a dragged item will be inserted when - * dropped on the grid. This method should not be called directly, instead - * {@link DND#FEEDBACK_INSERT_BEFORE} or {@link DND#FEEDBACK_INSERT_AFTER} - * should be set in {@link DropTargetEvent#feedback} from within a - * {@link DropTargetListener}. - * - * @param item - * the insert item. Null will clear the insertion mark. - * @param column - * the column of the cell. Null will make the insertion mark span all - * columns. - * @param before - * true places the insert mark above 'item'. false places the insert - * mark below 'item'. - * - * @exception IllegalArgumentException - *

    - *
  • ERROR_INVALID_ARGUMENT - if the item or column has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - void setInsertMark(final GridItem item, final GridColumn column, final boolean before) { - checkWidget(); - if (item != null) { - if (item.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - if (column != null) { - if (column.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - insertMarkItem = item; - insertMarkColumn = column; - insertMarkBefore = before; - redraw(); - } - - /** - * A helper method for {@link GridDropTargetEffect#dragOver(DropTargetEvent)}. - * - * @param point - * @return true if point is near the top or bottom border of the visible grid - * area - */ - boolean isInDragScrollArea(final Point point) { - final int rhw = rowHeaderVisible ? rowHeaderWidth : 0; - final int chh = columnHeadersVisible ? headerHeight : 0; - final Rectangle top = new Rectangle(rhw, chh, getClientArea().width - rhw, DRAG_SCROLL_AREA_HEIGHT); - final Rectangle bottom = new Rectangle(rhw, getClientArea().height - DRAG_SCROLL_AREA_HEIGHT, - getClientArea().width - rhw, DRAG_SCROLL_AREA_HEIGHT); - return top.contains(point) || bottom.contains(point); - } - - /** - * Clears the item at the given zero-relative index in the receiver. The text, - * icon and other attributes of the item are set to the default value. If the - * table was created with the SWT.VIRTUAL style, these attributes - * are requested again as needed. - * - * @param index - * the index of the item to clear - * @param allChildren - * true if all child items of the indexed item should be - * cleared recursively, and false otherwise - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and - * the number of elements in the list minus 1 (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SWT#VIRTUAL - * @see SWT#SetData - */ - public void clear(final int index, final boolean allChildren) { - checkWidget(); - if (index < 0 || index >= items.size()) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - - final GridItem item = getItem(index); - item.clear(allChildren); - redraw(); - } - - /** - * Clears the items in the receiver which are between the given zero-relative - * start and end indices (inclusive). The text, icon and other attributes of the - * items are set to their default values. If the table was created with the - * SWT.VIRTUAL style, these attributes are requested again as - * needed. - * - * @param start - * the start index of the item to clear - * @param end - * the end index of the item to clear - * @param allChildren - * true if all child items of the range of items should - * be cleared recursively, and false otherwise - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if either the start or end are not - * between 0 and the number of elements in the list minus 1 - * (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SWT#VIRTUAL - * @see SWT#SetData - */ - public void clear(final int start, final int end, final boolean allChildren) { - checkWidget(); - if (start > end) { - return; - } - - final int count = items.size(); - if (!(0 <= start && start <= end && end < count)) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - for (int i = start; i <= end; i++) { - final GridItem item = items.get(i); - item.clear(allChildren); - } - redraw(); - } - - /** - * Clears the items at the given zero-relative indices in the receiver. The - * text, icon and other attributes of the items are set to their default values. - * If the table was created with the SWT.VIRTUAL style, these - * attributes are requested again as needed. - * - * @param indices - * the array of indices of the items - * @param allChildren - * true if all child items of the indexed items should - * be cleared recursively, and false otherwise - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and - * the number of elements in the list minus 1 (inclusive)
  • - *
  • ERROR_NULL_ARGUMENT - if the indices array is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SWT#VIRTUAL - * @see SWT#SetData - */ - public void clear(final int[] indices, final boolean allChildren) { - checkWidget(); - if (indices == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (indices.length == 0) { - return; - } - - final int count = items.size(); - for (final int index : indices) { - if (!(0 <= index && index < count)) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - } - for (final int indice : indices) { - final GridItem item = items.get(indice); - item.clear(allChildren); - } - redraw(); - } - - /** - * Clears all the items in the receiver. The text, icon and other attributes of - * the items are set to their default values. If the table was created with the - * SWT.VIRTUAL style, these attributes are requested again as - * needed. - * - * @param allChildren - * true if all child items of each item should be - * cleared recursively, and false otherwise - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SWT#VIRTUAL - * @see SWT#SetData - */ - public void clearAll(final boolean allChildren) { - checkWidget(); - if (items.size() > 0) { - clear(0, items.size() - 1, allChildren); - } - } - - /** - * Recalculate the height of the header - */ - public void recalculateHeader() { - final int previous = getHeaderHeight(); - computeHeaderHeight(); - - if (previous != getHeaderHeight()) { - scrollValuesObsolete = true; - redraw(); - } - } - - /** - * Query the grid for all currently visible rows and columns - *

- * This support is provisional and may change - *

- * - * @return all currently visible rows and columns - */ - public GridVisibleRange getVisibleRange() { - // FIXME I think we should remember the topIndex in the onPaint-method - final int topIndex = getTopIndex(); - final int bottomIndex = getBottomIndex(); - final int startColumnIndex = getStartColumnIndex(); - final int endColumnIndex = getEndColumnIndex(); - - final GridVisibleRange range = new GridVisibleRange(); - range.items = new GridItem[0]; - range.columns = new GridColumn[0]; - - if (topIndex <= bottomIndex) { - if (items.size() > 0) { - range.items = new GridItem[bottomIndex - topIndex + 1]; - for (int i = topIndex; i <= bottomIndex; i++) { - range.items[i - topIndex] = items.get(i); - } - } - } - - if (startColumnIndex <= endColumnIndex) { - if (displayOrderedColumns.size() > 0) { - final List cols = new ArrayList<>(); - for (int i = startColumnIndex; i <= endColumnIndex; i++) { - final GridColumn col = displayOrderedColumns.get(i); - if (col.isVisible()) { - cols.add(col); - } - } - - range.columns = new GridColumn[cols.size()]; - cols.toArray(range.columns); - } - } - - return range; - } - - int getStartColumnIndex() { - checkWidget(); - - if (startColumnIndex != -1) { - return startColumnIndex; - } - - if (!hScroll.getVisible()) { - startColumnIndex = 0; - } - - startColumnIndex = hScroll.getSelection(); - - return startColumnIndex; - } - - int getEndColumnIndex() { - checkWidget(); - - if (endColumnIndex != -1) { - return endColumnIndex; - } - - if (displayOrderedColumns.size() == 0) { - endColumnIndex = 0; - } else if (getVisibleGridWidth() < 1) { - endColumnIndex = getStartColumnIndex(); - } else { - int x = 0; - x -= getHScrollSelectionInPixels(); - - if (rowHeaderVisible) { - // row header is actually painted later - x += rowHeaderWidth; - } - - final int startIndex = getStartColumnIndex(); - final GridColumn[] columns = new GridColumn[displayOrderedColumns.size()]; - displayOrderedColumns.toArray(columns); - - for (int i = startIndex; i < columns.length; i++) { - endColumnIndex = i; - final GridColumn column = columns[i]; - - if (column.isVisible()) { - x += column.getWidth(); - } - - if (x > getClientArea().width) { - - break; - } - } - - } - - endColumnIndex = Math.max(0, endColumnIndex); - - return endColumnIndex; - } - - void setSizeOnEveryItemImageChange(final boolean sizeOnEveryItemImageChange) { - this.sizeOnEveryItemImageChange = sizeOnEveryItemImageChange; - } - - /** - * Returns the width of the row headers. - * - * @return width of the column header row - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread - * that created the receiver
  • - *
- */ - public int getRowHeaderWidth() { - checkWidget(); - return rowHeaderWidth; - } - - /** - * Sets the value of the auto-height feature. When enabled, this feature resizes - * the height of rows to reflect the content of cells with word-wrapping - * enabled. Cell word-wrapping is enabled via the - * GridColumn.setWordWrap(boolean) method. If column headers have word-wrapping - * enabled, this feature will also resize the height of the column headers as - * necessary. - * - * @param enabled - * Set to true to enable this feature, false (default) otherwise. - */ - public void setAutoHeight(final boolean enabled) { - if (autoHeight == enabled) { - return; - } - - checkWidget(); - autoHeight = enabled; - setRowsResizeable(false); // turn of resizing of row height since it conflicts with this property - redraw(); - } - - /** - * Returns the value of the auto-height feature, which resizes row heights and - * column header heights based on word-wrapped content. - * - * @return Returns whether or not the auto-height feature is enabled. - * @see #setAutoHeight(boolean) - */ - public boolean isAutoHeight() { - return autoHeight; - } - - /** - * Sets the value of the auto-width feature. When enabled, this feature resizes - * the width of the row headers to reflect the content of row headers. - * - * @param enabled - * Set to true to enable this feature, false (default) otherwise. - * @see #isAutoWidth() - */ - public void setAutoWidth(final boolean enabled) { - if (autoWidth == enabled) { - return; - } - - checkWidget(); - autoWidth = enabled; - redraw(); - } - - /** - * Returns the value of the auto-height feature, which resizes row header width - * based on content. - * - * @return Returns whether or not the auto-width feature is enabled. - * @see #setAutoWidth(boolean) - */ - public boolean isAutoWidth() { - return autoWidth; - } - - /** - * Sets the value of the word-wrap feature for row headers. When enabled, this - * feature will word-wrap the contents of row headers. - * - * @param enabled - * Set to true to enable this feature, false (default) otherwise. - * @see #isWordWrapHeader() - */ - public void setWordWrapHeader(final boolean enabled) { - if (wordWrapRowHeader == enabled) { - return; - } - - checkWidget(); - wordWrapRowHeader = enabled; - redraw(); - } - - /** - * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color) - */ - @Override - public void setForeground(final Color color) { - dataVisualizer.setDefaultForeground(color); - super.setForeground(color); - } - - /** - * Returns the value of the row header word-wrap feature, which word-wraps the - * content of row headers. - * - * @return Returns whether or not the row header word-wrap feature is enabled. - * @see #setWordWrapHeader(boolean) - */ - public boolean isWordWrapHeader() { - return wordWrapRowHeader; - } - - /** - * Refresh hasData {@link GridItem} state if {@link Grid} is virtual - */ - public void refreshData() { - if ((getStyle() & SWT.VIRTUAL) != 0) { - for (final GridItem item : items) { - item.setHasSetData(false); - } - } - } - - /** - * @return true if the mouse navigation is enabled on tab/shift tab - */ - public boolean isMoveOnTab() { - checkWidget(); - return moveOnTab; - } - - /** - * This param allows user to change the current selection by pressing TAB and - * SHIFT-TAB - * - * @param moveOnTab - * if true, navigation with tab key is enabled. - */ - public void setMoveOnTab(final boolean moveOnTab) { - checkWidget(); - this.moveOnTab = moveOnTab; - } - - private void computeRowHeaderWidth(final int minWidth) { - estimate(sizingGC -> {// - final int width = items.stream() // - .mapToInt(item -> rowHeaderRenderer.computeSize(sizingGC, SWT.DEFAULT, SWT.DEFAULT, item).x) // - .max() // - .orElse(minWidth); - rowHeaderWidth = width > minWidth ? width : minWidth; - }); - } - - private int estimateWithResult(final ToIntFunction function) { - final GC gc = new GC(Grid.this); - try { - return function.applyAsInt(gc); - } finally { - gc.dispose(); - } - } - - private void estimate(final Consumer consumer) { - estimateWithResult(gc -> { - consumer.accept(gc); - return 0; - }); - } - - /** - * @return true if the grid has focus - */ - public boolean isFocusOnGrid() { - checkWidget(); - return getDisplay().getFocusControl() == this; - } - - /** - * Change selection type (single or multi) - * - * @param selectionType - * the new selection type - */ - public void setSelectionType(final GridSelectionType selectionType) { - checkWidget(); - this.selectionType = selectionType; - } - - /** - * @see org.eclipse.swt.widgets.Control#addMouseListener(org.eclipse.swt.events.MouseListener) - */ - @Override - public void addMouseListener(final MouseListener sourceListener) { - checkWidget(); - if (sourceListener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - addListener(SWT.MouseUp, e -> { - sourceListener.mouseUp(new MouseEvent(e)); - }); - addListener(SWT.MouseDown, e -> { - sourceListener.mouseDown(new MouseEvent(e)); - }); - addListener(SWT.MouseDoubleClick, e -> { - if (e.doit) { - sourceListener.mouseDoubleClick(new MouseEvent(e)); - } - }); - } - - /** - * @see org.eclipse.swt.widgets.Widget#addListener(int, - * org.eclipse.swt.widgets.Listener) - */ - @Override - public void addListener(final int eventType, final Listener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (eventType == SWT.MouseDoubleClick) { - super.addListener(SWT.MouseDoubleClick, e -> { - if (e.doit) { - listener.handleEvent(e); - } - }); - } else { - super.addListener(eventType, listener); - } - - } - -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + * Chuck.Mastrandrea@sas.com - wordwrapping in bug 222280 + * smcduff@hotmail.com - wordwrapping in bug 222280 + * Claes Rosell - rowspan in bug 272384 + * Marco Maccaferri - fixed arrow scrolling in bug 294767 + * higerinbeijing@gmail.com . fixed selectionEvent.item in bug 286617 + * balarkrishnan@yahoo.com - fix in bug 298684 + * Enrico Schnepel - new API in 238729, bugfix in 294952, 322114 + * Benjamin Bortfeldt - new tooltip support in 300797 + * Thomas Halm - bugfix in 315397 + * Justin Dolezy - bugfix in 316598 + * Cosmin Ghita - bugfix in 323687 + * Pinard-Legry Guilhaume - bugfix in 267057 + * Thorsten Schenkel - bugfix in 356803 + * Mirko Paturzo - improvement (bugfix in 419928) + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; +import java.util.function.Consumer; +import java.util.function.ToIntFunction; + +import org.eclipse.nebula.widgets.grid.internal.DefaultBottomLeftRenderer; +import org.eclipse.nebula.widgets.grid.internal.DefaultColumnGroupHeaderRenderer; +import org.eclipse.nebula.widgets.grid.internal.DefaultDropPointRenderer; +import org.eclipse.nebula.widgets.grid.internal.DefaultEmptyColumnFooterRenderer; +import org.eclipse.nebula.widgets.grid.internal.DefaultEmptyColumnHeaderRenderer; +import org.eclipse.nebula.widgets.grid.internal.DefaultEmptyRowHeaderRenderer; +import org.eclipse.nebula.widgets.grid.internal.DefaultFocusRenderer; +import org.eclipse.nebula.widgets.grid.internal.DefaultInsertMarkRenderer; +import org.eclipse.nebula.widgets.grid.internal.DefaultRowHeaderRenderer; +import org.eclipse.nebula.widgets.grid.internal.DefaultTopLeftRenderer; +import org.eclipse.nebula.widgets.grid.internal.GridToolTip; +import org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy; +import org.eclipse.nebula.widgets.grid.internal.NullScrollBarProxy; +import org.eclipse.nebula.widgets.grid.internal.ScrollBarProxyAdapter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.accessibility.Accessible; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleControlAdapter; +import org.eclipse.swt.accessibility.AccessibleControlEvent; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TreeEvent; +import org.eclipse.swt.events.TreeListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.TypedListener; + +/** + * The Grid widget is a spreadsheet/table component that offers features not + * currently found in the base SWT Table. Features include cell selection, + * column grouping, column spanning, row headers, and more. + *

+ * The item children that may be added to instances of this class must be of + * type {@code GridItem}. + *

+ *
+ *
Styles:
+ *
SWT.SINGLE, SWT.MULTI, SWT.NO_FOCUS, SWT.CHECK, SWT.VIRTUAL
+ *
Events:
+ *
Selection, DefaultSelection
+ *
+ * + * @author chris.gross@us.ibm.com + * @author Mirko Paturzo + * + */ +public class Grid extends Canvas { + + /** + * Cached default font of Control.getFont. + */ + private Font defaultFont; + + // TODO: figure out better way to allow renderers to trigger events + // TODO: scroll as necessary when performing drag select (current strategy ok) + // TODO: need to refactor the way the range select remembers older selection + // TODO: remember why i decided i needed to refactor the way the range select + // remembers older selection + // TODO: need to alter how column drag selection works to allow selection of + // spanned cells + // TODO: JAVADOC! + // TODO: column freezing + + // TODO: Performance - need to cache top index + + /** + * @return {@link DataVisualizer} + */ + public DataVisualizer getDataVisualizer() { + return dataVisualizer; + } + + /** + * Object holding the visible range + */ + public static class GridVisibleRange { + private GridItem[] items = new GridItem[0]; + private GridColumn[] columns = new GridColumn[0]; + + /** + * @return the current items shown + */ + public GridItem[] getItems() { + return items; + } + + /** + * @return the current columns shown + */ + public GridColumn[] getColumns() { + return columns; + } + } + + /** + * Clear simply all GridItems + */ + public void clearItems() { + items.clear(); + rootItems.clear(); + deselectAll(); + redraw(); + } + + /** + * Accessibility default action for column headers and column group headers. + */ + private static final String ACC_COLUMN_DEFAULT_ACTION = "Click"; + + /** + * Accessibility default action for items. + */ + private static final String ACC_ITEM_DEFAULT_ACTION = "Double Click"; + + /** + * Accessibility expand action for tree items. + */ + private static final String ACC_ITEM_ACTION_EXPAND = "Expand"; + + /** + * Accessibility collapse action for tree items. + */ + private static final String ACC_ITEM_ACTION_COLLAPSE = "Collapse"; + + /** + * Accessibility name for the column group header toggle button. + */ + private static final String ACC_TOGGLE_BUTTON_NAME = "Toggle Button"; + + /** + * Alpha blending value used when drawing the dragged column header. + */ + private static final int COLUMN_DRAG_ALPHA = 128; + + /** + * Number of pixels below the header to draw the drop point. + */ + private static final int DROP_POINT_LOWER_OFFSET = 3; + + /** + * Horizontal scrolling increment, in pixels. + */ + private static final int HORZ_SCROLL_INCREMENT = 5; + + /** + * The area to the left and right of the column boundary/resizer that is still + * considered the resizer area. This prevents a user from having to be *exactly* + * over the resizer. + */ + private static final int COLUMN_RESIZER_THRESHOLD = 4; + + /** + * @see #COLUMN_RESIZER_THRESHOLD + */ + private static final int ROW_RESIZER_THRESHOLD = 3; + + /** + * The minimum width of a column header. + */ + private static final int MIN_COLUMN_HEADER_WIDTH = 20; + /** + * The minimum height of a row header. + */ + private static final int MIN_ROW_HEADER_HEIGHT = 10; + + /** + * The number used when sizing the row header (i.e. size it for '1000') + * initially. + */ + // private static final int INITIAL_ROW_HEADER_SIZING_VALUE = 1000; + + /** + * The factor to multiply the current row header sizing value by when + * determining the next sizing value. Used for performance reasons. + */ + // private static final int ROW_HEADER_SIZING_MULTIPLIER = 10; + + /** + * Tracks whether the scroll values are correct. If not they will be recomputed + * in onPaint. This allows us to get a free ride on top of the OS's paint event + * merging to assure that we don't perform this expensive operation when + * unnecessary. + */ + private boolean scrollValuesObsolete = false; + + /** + * When this variable is true, the pack is based only on the visible lines on + * the screen. + */ + private boolean visibleLinesBasedColumnPack = false; + + /** + * All items in the table, not just root items. + */ + private final List items = new ArrayList<>(); + + /** + * All root items. + */ + private final List rootItems = new ArrayList<>(); + + /** + * List of selected items. + */ + private final List selectedItems = new ArrayList<>(); + + /** + * Reference to the item in focus. + */ + private GridItem focusItem; + + private boolean cellSelectionEnabled = false; + private boolean cellDragSelectionEnabled = true; + + private final List selectedCells = new ArrayList<>(); + private final List selectedCellsBeforeRangeSelect = new ArrayList<>(); + + private boolean cellDragSelectionOccuring = false; + private boolean cellRowDragSelectionOccuring = false; + private boolean cellColumnDragSelectionOccuring = false; + private boolean cellDragCTRL = false; + private boolean followupCellSelectionEventOwed = false; + + private boolean cellSelectedOnLastMouseDown; + private boolean cellRowSelectedOnLastMouseDown; + private boolean cellColumnSelectedOnLastMouseDown; + + private GridColumn shiftSelectionAnchorColumn; + + private GridColumn focusColumn; + + private final List selectedColumns = new ArrayList<>(); + + /** + * This is the column that the user last navigated to, but may not be the + * focusColumn because that column may be spanned in the current row. This is + * only used in situations where the user has used the keyboard to navigate up + * or down in the table and the focusColumn has switched to a new column because + * the intended column (was maintained in this var) was spanned. The table will + * attempt to set focus back to the intended column during subsequent up/down + * navigations. + */ + private GridColumn intendedFocusColumn; + + /** + * List of table columns in creation/index order. + */ + private final List columns = new ArrayList<>(); + + /** + * List of the table columns in the order they are displayed. + */ + private final List displayOrderedColumns = new ArrayList<>(); + + private GridColumnGroup[] columnGroups = new GridColumnGroup[0]; + + /** + * Renderer to paint the top left area when both column and row headers are + * shown. + */ + private IRenderer topLeftRenderer = new DefaultTopLeftRenderer(); + + /** + * Renderer to paint the bottom left area when row headers and column footers + * are shown + */ + private IRenderer bottomLeftRenderer = new DefaultBottomLeftRenderer(); + + /** + * Renderer used to paint row headers. + */ + private IRenderer rowHeaderRenderer = new DefaultRowHeaderRenderer(); + + /** + * Renderer used to paint empty column headers, used when the columns don't fill + * the horz space. + */ + private IRenderer emptyColumnHeaderRenderer = new DefaultEmptyColumnHeaderRenderer(); + + /** + * Renderer used to paint empty column footers, used when the columns don't fill + * the horz space. + */ + private IRenderer emptyColumnFooterRenderer = new DefaultEmptyColumnFooterRenderer(); + + /** + * Renderer used to paint empty cells to fill horz and vert space. + */ + private GridCellRenderer emptyCellRenderer = new DefaultEmptyCellRenderer(); + + /** + * Renderer used to paint empty row headers when the rows don't fill the + * vertical space. + */ + private IRenderer emptyRowHeaderRenderer = new DefaultEmptyRowHeaderRenderer(); + + /** + * Renderers the UI affordance identifying where the dragged column will be + * dropped. + */ + private final IRenderer dropPointRenderer = new DefaultDropPointRenderer(); + + /** + * Renderer used to paint on top of an already painted row to denote focus. + */ + private IRenderer focusRenderer = new DefaultFocusRenderer(); + + /** + * Are row headers visible? + */ + private boolean rowHeaderVisible = false; + + /** + * Are column headers visible? + */ + private boolean columnHeadersVisible = false; + + /** + * Are column footers visible? + */ + private boolean columnFootersVisible = false; + + /** + * Type of selection behavior. Valid values are SWT.SINGLE and SWT.MULTI. + */ + private GridSelectionType selectionType = GridSelectionType.SINGLE; + + /** + * True if selection highlighting is enabled. + */ + private boolean selectionEnabled = true; + + /** + * Default height of items. This value is used for GridItems with a + * height of -1. + */ + private int itemHeight = 1; + + private boolean userModifiedItemHeight = false; + + /** + * Width of each row header. + */ + private int rowHeaderWidth = 0; + + /** + * The row header width is variable. The row header width gets larger as more + * rows are added to the table to ensure that the row header has enough room to + * display the longest string of numbers that display in the row header. This + * determination of how wide to make the row header is rather slow and therefore + * is only done at every 1000 items (or so). This variable remembers how many + * items were last computed and therefore when the number of items is greater + * than this value, we need to recalculate the row header width. See newItem(). + */ + // private int lastRowHeaderWidthCalculationAt = 0; + + /** + * Height of each column header. + */ + private int headerHeight = 0; + + /** + * Height of each column footer + */ + private int footerHeight = 0; + + /** + * True if mouse is hover on a column boundary and can resize the column. + */ + boolean hoveringOnColumnResizer = false; + + /** + * Reference to the column being resized. + */ + private GridColumn columnBeingResized; + + /** + * Are this Grid's rows resizeable? + */ + private boolean rowsResizeable = false; + + /** + * Is the user currently resizing a column? + */ + private boolean resizingColumn = false; + + /** + * The mouse X position when the user starts the resize. + */ + private int resizingStartX = 0; + + /** + * The width of the column when the user starts the resize. This, together with + * the resizingStartX determines the current width during resize. + */ + private int resizingColumnStartWidth = 0; + + private boolean hoveringOnRowResizer = false; + private GridItem rowBeingResized; + private boolean resizingRow = false; + private int resizingStartY; + private int resizingRowStartHeight; + + /** + * Reference to the column whose header is currently in a pushed state. + */ + private GridColumn columnBeingPushed; + + /** + * Is the user currently pushing a column header? + */ + private boolean pushingColumn = false; + + /** + * Is the user currently pushing a column header and hovering over that same + * header? + */ + private boolean pushingAndHovering = false; + + /** + * X position of the mouse when the user first pushes a column header. + */ + private int startHeaderPushX = 0; + + /** + * X position of the mouse when the user has initiated a drag. This is different + * than startHeaderPushX because the mouse is allowed some 'wiggle-room' until + * the header is put into drag mode. + */ + private int startHeaderDragX = 0; + + /** + * The current X position of the mouse during a header drag. + */ + private int currentHeaderDragX = 0; + + /** + * Are we currently dragging a column header? + */ + private boolean draggingColumn = false; + + private GridColumn dragDropBeforeColumn = null; + + private GridColumn dragDropAfterColumn = null; + + /** + * True if the current dragDropPoint is a valid drop point for the dragged + * column. This is false if the column groups are involved and a column is being + * dropped into or out of its column group. + */ + private boolean dragDropPointValid = true; + + /** + * Reference to the currently item that the mouse is currently hovering over. + */ + private GridItem hoveringItem; + + /** + * Reference to the column that the mouse is currently hovering over. Includes + * the header and all cells (all rows) in this column. + */ + private GridColumn hoveringColumn; + + private GridColumn hoveringColumnHeader; + + private GridColumnGroup hoverColumnGroupHeader; + + /** + * String-based detail of what is being hovered over in a cell. This allows a + * renderer to differentiate between hovering over different parts of the cell. + * For example, hovering over a checkbox in the cell or hovering over a tree + * node in the cell. The table does nothing with this string except to set it + * back in the renderer when its painted. The renderer sets this during its + * notify method (InternalWidget.HOVER) and the table pulls it back and + * maintains it so it can be set back when the cell is painted. The renderer + * determines what the hover detail means and how it affects painting. + */ + private String hoveringDetail = ""; + + /** + * True if the mouse is hovering of a cell's text. + */ + private boolean hoveringOverText = false; + + /** + * Are the grid lines visible? + */ + private boolean linesVisible = true; + + /** + * Are tree lines visible? + */ + private boolean treeLinesVisible = true; + + /** + * Grid line color. + */ + private Color lineColor; + + /** + * Vertical scrollbar proxy. + *

+ * Note: + *

    + *
  • {@link Grid#getTopIndex()} is the only method allowed to call + * vScroll.getSelection() (except #updateScrollbars() of course)
  • + *
  • {@link Grid#setTopIndex(int)} is the only method allowed to call + * vScroll.setSelection(int)
  • + *
+ */ + private IScrollBarProxy vScroll; + + /** + * Horizontal scrollbar proxy. + */ + private IScrollBarProxy hScroll; + + /** + * The number of GridItems whose visible = true. Maintained for performance + * reasons (rather than iterating over all items). + */ + private int currentVisibleItems = 0; + + /** + * Item selected when a multiple selection using shift+click first occurs. This + * item anchors all further shift+click selections. + */ + private GridItem shiftSelectionAnchorItem; + + private boolean columnScrolling = false; + + private int groupHeaderHeight; + + private Color cellHeaderSelectionBackground; + + /** + * Dispose listener. This listener is removed during the dispose event to allow + * re-firing of the event. + */ + private Listener disposeListener; + + /** + * The inplace tooltip. + */ + private GridToolTip inplaceToolTip; + + private Color backgroundColor; + + /** + * True if the widget is being disposed. When true, events are not fired. + */ + private boolean disposing = false; + + /** + * True if there is at least one tree node. This is used by accessibility and + * various places for optimization. + */ + private boolean isTree = false; + + /** + * True if there is at least one GridItem with an individual + * height. This value is only set to true in + * {@link GridItem#setHeight(int,boolean)} and it is never reset to false. + */ + boolean hasDifferingHeights = false; + + /** + * True if three is at least one cell spanning columns. This is used in various + * places for optimizatoin. + */ + private boolean hasSpanning = false; + + /** + * Index of first visible item. The value must never be read directly. It is + * cached and updated when appropriate. #getTopIndex should be called for every + * client (even internal callers). A value of -1 indicates that the value is old + * and will be recomputed. + * + * @see #bottomIndex + */ + int topIndex = -1; + /** + * Index of last visible item. The value must never be read directly. It is + * cached and updated when appropriate. #getBottomIndex() should be called for + * every client (even internal callers). A value of -1 indicates that the value + * is old and will be recomputed. + *

+ * Note that the item with this index is often only partly visible; maybe only a + * single line of pixels is visible. In extreme cases, bottomIndex may be the + * same as topIndex. + * + * @see #topIndex + */ + int bottomIndex = -1; + + /** + * Index of the first visible column. A value of -1 indicates that the value is + * old and will be recomputed. + */ + int startColumnIndex = -1; + + /** + * Index of the the last visible column. A value of -1 indicates that the value + * is old and will be recomputed. + */ + int endColumnIndex = -1; + + /** + * True if the last visible item is completely visible. The value must never be + * read directly. It is cached and updated when appropriate. #isShown() should + * be called for every client (even internal callers). + * + * @see #bottomIndex + */ + private boolean bottomIndexShownCompletely = false; + + /** + * Tooltip text - overriden because we have cell specific tooltips + */ + private String toolTipText = null; + + /** + * Flag that is set to true as soon as one image is set on any one item. This is + * used to mimic Table behavior that resizes the rows on the first image added. + * See imageSetOnItem. + */ + private boolean firstImageSet = false; + + /** + * Mouse capture flag. Used for inplace tooltips. This flag must be used to + * ensure that we don't setCapture(false) in situations where we didn't do + * setCapture(true). The OS (SWT?) will automatically capture the mouse for us + * during a drag operation. + */ + private boolean inplaceTooltipCapture; + + /** + * This is the tooltip text currently used. This could be the tooltip text for + * the currently hovered cell, or the general grid tooltip. See handleCellHover. + */ + private String displayedToolTipText; + + /** + * The height of the area at the top and bottom of the visible grid area in + * which scrolling is initiated while dragging over this Grid. + */ + private static final int DRAG_SCROLL_AREA_HEIGHT = 12; + + /** + * Threshold for the selection border used for drag n drop in mode + * (!{@link #dragOnFullSelection}}. + */ + private static final int SELECTION_DRAG_BORDER_THRESHOLD = 2; + + private boolean hoveringOnSelectionDragArea = false; + + private GridItem insertMarkItem = null; + private GridColumn insertMarkColumn = null; + private boolean insertMarkBefore = false; + private final IRenderer insertMarkRenderer = new DefaultInsertMarkRenderer(); + private boolean sizeOnEveryItemImageChange; + private boolean autoHeight = false; + private boolean autoWidth = true; + private boolean wordWrapRowHeader = false; + + private final DataVisualizer dataVisualizer; + + private Listener defaultKeyListener; + + private boolean defaultKeyListenerEnabled = true; + + /** + * caching column orders improves grid rendering + */ + private int[] columnOrders; + + /** + * If true, when user types TAB the selection moved to the next line, and + * SHIFT-TAB move to the previous line + */ + private boolean moveOnTab = false; + + /** + * A range of rows in a Grid. + *

+ * A row in this sense exists only for visible items (i.e. items with + * {@link GridItem#isVisible()} == true). Therefore, the items at 'startIndex' + * and 'endIndex' are always visible. + * + * @see Grid#getRowRange(int, int, boolean, boolean) + */ + private static class RowRange { + /** index of first item in range */ + public int startIndex; + /** index of last item in range */ + public int endIndex; + /** number of rows (i.e. visible items) in this range */ + public int rows; + /** + * height in pixels of this range (including horizontal separator between rows) + */ + public int height; + } + + /** + * Filters out unnecessary styles, adds mandatory styles and generally manages + * the style to pass to the super class. + * + * @param style + * user specified style. + * @return style to pass to the super class. + */ + private static int checkStyle(final int style) { + final int mask = SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE + | SWT.MULTI | SWT.NO_FOCUS | SWT.CHECK | SWT.VIRTUAL; + int newStyle = style & mask; + newStyle |= SWT.DOUBLE_BUFFERED; + return newStyle; + } + + /** + * Grid with generic DataVisualizer + * + * @param parent + * component + * @param style + * grid style + */ + public Grid(final Composite parent, final int style) { + this(new GridItemDataVisualizer(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE), + Display.getCurrent().getSystemColor(SWT.COLOR_BLACK), null), parent, style); + } + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * + * @param dataVisualizer + * manage all data of grid and its items + * @param parent + * a composite control which will be the parent of the new instance + * (cannot be null) + * @param style + * the style of control to construct + * @throws IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the parent
  • + *
+ * @see SWT#SINGLE + * @see SWT#MULTI + */ + public Grid(final DataVisualizer dataVisualizer, final Composite parent, final int style) { + super(parent, checkStyle(style)); + + this.dataVisualizer = dataVisualizer; + + // initialize drag & drop support + setData("DEFAULT_DRAG_SOURCE_EFFECT", new GridDragSourceEffect(this)); + setData("DEFAULT_DROP_TARGET_EFFECT", new GridDropTargetEffect(this)); + + topLeftRenderer.setDisplay(getDisplay()); + bottomLeftRenderer.setDisplay(getDisplay()); + rowHeaderRenderer.setDisplay(getDisplay()); + emptyColumnHeaderRenderer.setDisplay(getDisplay()); + emptyColumnFooterRenderer.setDisplay(getDisplay()); + emptyCellRenderer.setDisplay(getDisplay()); + dropPointRenderer.setDisplay(getDisplay()); + focusRenderer.setDisplay(getDisplay()); + emptyRowHeaderRenderer.setDisplay(getDisplay()); + insertMarkRenderer.setDisplay(getDisplay()); + + setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND)); + setLineColor(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + + if ((style & SWT.MULTI) != 0) { + selectionType = GridSelectionType.MULTI; + } + + if (getVerticalBar() != null) { + getVerticalBar().setVisible(false); + vScroll = new ScrollBarProxyAdapter(getVerticalBar()); + } else { + vScroll = new NullScrollBarProxy(); + } + + if (getHorizontalBar() != null) { + getHorizontalBar().setVisible(false); + hScroll = new ScrollBarProxyAdapter(getHorizontalBar()); + } else { + hScroll = new NullScrollBarProxy(); + } + + scrollValuesObsolete = true; + + initListeners(); + initAccessible(); + + estimate(sizingGC -> itemHeight = sizingGC.getFontMetrics().getHeight() + 2); + + final RGB sel = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB(); + final RGB white = getDisplay().getSystemColor(SWT.COLOR_WHITE).getRGB(); + + final RGB cellSel = blend(sel, white, 50); + + cellHeaderSelectionBackground = new Color(getDisplay(), cellSel); + + setDragDetect(false); + } + + /** + * {@inheritDoc} + */ + @Override + public Color getBackground() { + checkWidget(); + if (backgroundColor == null) { + return getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + } + return backgroundColor; + } + + /** + * {@inheritDoc} + */ + @Override + public void setBackground(final Color color) { + checkWidget(); + backgroundColor = color; + dataVisualizer.setDefaultBackground(color); + redraw(); + } + + /** + * Returns the background color of column and row headers when a cell in the row + * or header is selected. + * + * @return cell header selection background color + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public Color getCellHeaderSelectionBackground() { + checkWidget(); + return cellHeaderSelectionBackground; + } + + /** + * Sets the background color of column and row headers displayed when a cell in + * the row or header is selected. + * + * @param cellSelectionBackground + * color to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setCellHeaderSelectionBackground(final Color cellSelectionBackground) { + checkWidget(); + cellHeaderSelectionBackground = cellSelectionBackground; + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the receiver's selection changes, by sending it one of the messages defined + * in the {@code SelectionListener} interface. + *

+ * Cell selection events may have Event.detail = SWT.DRAG when the + * user is drag selecting multiple cells. A follow up selection event will be + * generated when the drag is complete. + * + * @param listener + * the listener which should be notified + * @throws IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + addListener(SWT.Selection, new TypedListener(listener)); + addListener(SWT.DefaultSelection, new TypedListener(listener)); + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the receiver's items changes, by sending it one of the messages defined in + * the {@code TreeListener} interface. + * + * @param listener + * the listener which should be notified + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * @see TreeListener + * @see #removeTreeListener + * @see org.eclipse.swt.events.TreeEvent + */ + public void addTreeListener(final TreeListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + addListener(SWT.Expand, new TypedListener(listener)); + addListener(SWT.Collapse, new TypedListener(listener)); + } + + /** + * {@inheritDoc} + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + checkWidget(); + + Point prefSize = null; + if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) { + prefSize = getTableSize(); + prefSize.x += 2 * getBorderWidth(); + prefSize.y += 2 * getBorderWidth(); + } + + int x = 0; + int y = 0; + + if (wHint == SWT.DEFAULT) { + x += prefSize.x; + if (getVerticalBar() != null) { + x += getVerticalBar().getSize().x; + } + } else { + x = wHint; + } + + if (hHint == SWT.DEFAULT) { + y += prefSize.y; + if (getHorizontalBar() != null) { + y += getHorizontalBar().getSize().y; + } + } else { + y = hHint; + } + + return new Point(x, y); + } + + /** + * Deselects the item at the given zero-relative index in the receiver. If the + * item at the index was already deselected, it remains deselected. Indices that + * are out of range are ignored. + *

+ * If cell selection is enabled, all cells in the specified item are deselected. + * + * @param index + * the index of the item to deselect + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void deselect(final int index) { + checkWidget(); + + if (index < 0 || index > items.size() - 1) { + return; + } + + final GridItem item = items.get(index); + + if (!cellSelectionEnabled) { + if (selectedItems.contains(item)) { + selectedItems.remove(item); + } + } else { + deselectCells(getCells(item)); + } + redraw(); + } + + /** + * Deselects the items at the given zero-relative indices in the receiver. If + * the item at the given zero-relative index in the receiver is selected, it is + * deselected. If the item at the index was not selected, it remains deselected. + * The range of the indices is inclusive. Indices that are out of range are + * ignored. + *

+ * If cell selection is enabled, all cells in the given range are deselected. + * + * @param start + * the start index of the items to deselect + * @param end + * the end index of the items to deselect + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void deselect(final int start, final int end) { + checkWidget(); + + for (int i = start; i <= end; i++) { + if (i < 0) { + continue; + } + if (i > items.size() - 1) { + break; + } + + final GridItem item = items.get(i); + + if (!cellSelectionEnabled) { + if (selectedItems.contains(item)) { + selectedItems.remove(item); + } + } else { + deselectCells(getCells(item)); + } + } + redraw(); + } + + /** + * Deselects the items at the given zero-relative indices in the receiver. If + * the item at the given zero-relative index in the receiver is selected, it is + * deselected. If the item at the index was not selected, it remains deselected. + * Indices that are out of range and duplicate indices are ignored. + *

+ * If cell selection is enabled, all cells in the given items are deselected. + * + * @param indices + * the array of indices for the items to deselect + * @throws IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the set of indices is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void deselect(final int[] indices) { + checkWidget(); + if (indices == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + for (final int j : indices) { + if (j >= 0 && j < items.size()) { + final GridItem item = items.get(j); + + if (!cellSelectionEnabled) { + if (selectedItems.contains(item)) { + selectedItems.remove(item); + } + } else { + deselectCells(getCells(item)); + } + } + } + redraw(); + } + + /** + * Deselects all selected items in the receiver. If cell selection is enabled, + * all cells are deselected. + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void deselectAll() { + checkWidget(); + + if (!cellSelectionEnabled) { + selectedItems.clear(); + redraw(); + } else { + deselectAllCells(); + } + } + + /** + * Returns the column at the given, zero-relative index in the receiver. Throws + * an exception if the index is out of range. If no {@code GridColumn}s were + * created by the programmer, this method will throw {@code ERROR_INVALID_RANGE} + * despite the fact that a single column of data may be visible in the table. + * This occurs when the programmer uses the table like a list, adding items but + * never creating a column. + * + * @param index + * the index of the column to return + * @return the column at the given index + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the + * number of elements in the list minus 1 (inclusive)
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridColumn getColumn(final int index) { + checkWidget(); + + if (index < 0 || index > getColumnCount() - 1) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + + return columns.get(index); + } + + /** + * Returns the column at the given point in the receiver or null if no such + * column exists. The point is in the coordinate system of the receiver. + * + * @param point + * the point used to locate the column + * @return the column at the given point + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the point is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridColumn getColumn(final Point point) { + return getColumn(null, point); + } + + /** + * Returns the column at the given point and a known item in the receiver or + * null if no such column exists. The point is in the coordinate system of the + * receiver. + * + * @param item + * a known GridItem + * @param point + * the point used to locate the column + * @return the column at the given point + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the point is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + private GridColumn getColumn(GridItem item, final Point point) { + checkWidget(); + if (point == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + GridColumn overThis = null; + + int x2 = 0; + + if (rowHeaderVisible) { + if (point.x <= rowHeaderWidth) { + return null; + } + + x2 += rowHeaderWidth; + } + + x2 -= getHScrollSelectionInPixels(); + + for (final GridColumn column : displayOrderedColumns) { + if (!column.isVisible()) { + continue; + } + + if (point.x >= x2 && point.x < x2 + column.getWidth()) { + overThis = column; + break; + } + + x2 += column.getWidth(); + } + + if (overThis == null) { + return null; + } + + if (hasSpanning) { + // special logic for column spanning + if (item == null) { + item = getItem(point); + } + + if (item != null) { + final int displayColIndex = displayOrderedColumns.indexOf(overThis); + + // track back all previous columns and check their spanning + for (int i = 0; i < displayColIndex; i++) { + if (!displayOrderedColumns.get(i).isVisible()) { + continue; + } + + final int colIndex = displayOrderedColumns.get(i).index; + final int span = item.getColumnSpan(colIndex); + + if (i + span >= displayColIndex) { + overThis = displayOrderedColumns.get(i); + break; + } + } + } + } + + return overThis; + } + + /** + * Returns the number of columns contained in the receiver. If no + * {@code GridColumn}s were created by the programmer, this value is zero, + * despite the fact that visually, one column of items may be visible. This + * occurs when the programmer uses the table like a list, adding items but never + * creating a column. + * + * @return the number of columns + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getColumnCount() { + checkWidget(); + return columns.size(); + } + + /** + * Returns an array of zero-relative integers that map the creation order of the + * receiver's items to the order in which they are currently being displayed. + *

+ * Specifically, the indices of the returned array represent the current visual + * order of the items, and the contents of the array represent the creation + * order of the items. + *

+ *

+ * Note: This is not the actual structure used by the receiver to maintain its + * list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the current visual order of the receiver's items + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int[] getColumnOrder() { + checkWidget(); + if (columnOrders == null) { + columnOrders = new int[columns.size()]; + int i = 0; + for (final GridColumn col : displayOrderedColumns) { + columnOrders[i] = col.index; + i++; + } + } + return columnOrders; + } + + /** + * Returns the number of column groups contained in the receiver. + * + * @return the number of column groups + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getColumnGroupCount() { + checkWidget(); + return columnGroups.length; + } + + /** + * Returns an array of {@code GridColumnGroup}s which are the column groups in + * the receiver. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the column groups in the receiver + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridColumnGroup[] getColumnGroups() { + checkWidget(); + final GridColumnGroup[] newArray = new GridColumnGroup[columnGroups.length]; + System.arraycopy(columnGroups, 0, newArray, 0, columnGroups.length); + return newArray; + } + + /** + * Returns the column group at the given, zero-relative index in the receiver. + * Throws an exception if the index is out of range. + * + * @param index + * the index of the column group to return + * @return the column group at the given index + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the + * number of elements in the list minus 1 (inclusive)
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridColumnGroup getColumnGroup(final int index) { + checkWidget(); + + if (index < 0 || index >= columnGroups.length) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + + return columnGroups[index]; + } + + /** + * Sets the order that the items in the receiver should be displayed in to the + * given argument which is described in terms of the zero-relative ordering of + * when the items were added. + * + * @param order + * the new order to display the items + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS -if not called from the thread + * that created the receiver
  • + *
+ * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item order is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the order is not the same length + * as the number of items, or if an item is listed twice, or if the + * order splits a column group
  • + *
+ */ + public void setColumnOrder(final int[] order) { + checkWidget(); + + if (order == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (order.length != displayOrderedColumns.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + final boolean[] seen = new boolean[displayOrderedColumns.size()]; + + for (int i = 0; i < order.length; i++) { + if (order[i] < 0 || order[i] >= displayOrderedColumns.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + if (seen[order[i]]) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + seen[order[i]] = true; + } + + if (columnGroups.length != 0) { + GridColumnGroup currentGroup = null; + int colsInGroup = 0; + + for (final int element : order) { + final GridColumn col = getColumn(element); + + if (currentGroup != null) { + if (col.getColumnGroup() != currentGroup && colsInGroup > 0) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } else { + colsInGroup--; + if (colsInGroup <= 0) { + currentGroup = null; + } + } + } else if (col.getColumnGroup() != null) { + currentGroup = col.getColumnGroup(); + colsInGroup = currentGroup.getColumns().length - 1; + } + } + } + + final GridColumn[] cols = getColumns(); + + displayOrderedColumns.clear(); + + for (final int element : order) { + displayOrderedColumns.add(cols[element]); + } + clearDisplayOrderedCache(); + } + + /** + * This method is used for clearing columns displayed ordering cache + */ + private void clearDisplayOrderedCache() { + columnOrders = null; + } + + /** + * Returns an array of {@code GridColumn}s which are the columns in the + * receiver. If no {@code GridColumn}s were created by the programmer, the array + * is empty, despite the fact that visually, one column of items may be visible. + * This occurs when the programmer uses the table like a list, adding items but + * never creating a column. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the items in the receiver + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridColumn[] getColumns() { + checkWidget(); + return columns.toArray(new GridColumn[columns.size()]); + } + + /** + * Returns the empty cell renderer. + * + * @return Returns the emptyCellRenderer. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridCellRenderer getEmptyCellRenderer() { + checkWidget(); + return emptyCellRenderer; + } + + /** + * Returns the empty column header renderer. + * + * @return Returns the emptyColumnHeaderRenderer. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public IRenderer getEmptyColumnHeaderRenderer() { + checkWidget(); + return emptyColumnHeaderRenderer; + } + + /** + * Returns the empty column footer renderer. + * + * @return Returns the emptyColumnFooterRenderer. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public IRenderer getEmptyColumnFooterRenderer() { + checkWidget(); + return emptyColumnFooterRenderer; + } + + /** + * Returns the empty row header renderer. + * + * @return Returns the emptyRowHeaderRenderer. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public IRenderer getEmptyRowHeaderRenderer() { + checkWidget(); + return emptyRowHeaderRenderer; + } + + /** + * Returns the externally managed horizontal scrollbar. + * + * @return the external horizontal scrollbar. + * @see #setHorizontalScrollBarProxy(IScrollBarProxy) + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + protected IScrollBarProxy getHorizontalScrollBarProxy() { + checkWidget(); + return hScroll; + } + + /** + * Returns the externally managed vertical scrollbar. + * + * @return the external vertical scrollbar. + * @see #setlVerticalScrollBarProxy(IScrollBarProxy) + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + protected IScrollBarProxy getVerticalScrollBarProxy() { + checkWidget(); + return vScroll; + } + + /** + * Gets the focus renderer. + * + * @return Returns the focusRenderer. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public IRenderer getFocusRenderer() { + checkWidget(); + return focusRenderer; + } + + /** + * Returns the height of the column headers. If this table has column groups, + * the returned value includes the height of group headers. + * + * @return height of the column header row + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getHeaderHeight() { + checkWidget(); + return headerHeight; + } + + /** + * Cached default font of Control.getFont + * + * @see org.eclipse.swt.widgets.Control#getFont() + */ + @Override + public Font getFont() { + if (defaultFont == null) { + defaultFont = super.getFont(); + } + return defaultFont; + } + + /** + * Returns the height of the column footers. + * + * @return height of the column footer row + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getFooterHeight() { + checkWidget(); + return footerHeight; + } + + /** + * Returns the height of the column group headers. + * + * @return height of column group headers + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getGroupHeaderHeight() { + checkWidget(); + return groupHeaderHeight; + } + + /** + * Returns {@code true} if the receiver's header is visible, and {@code false} + * otherwise. + * + * @return the receiver's header's visibility state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean getHeaderVisible() { + checkWidget(); + return columnHeadersVisible; + } + + /** + * Returns {@code true} if the receiver's footer is visible, and {@code false} + * otherwise + * + * @return the receiver's footer's visibility state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean getFooterVisible() { + checkWidget(); + return columnFootersVisible; + } + + /** + * Returns the item at the given, zero-relative index in the receiver. Throws an + * exception if the index is out of range. + * + * @param index + * the index of the item to return + * @return the item at the given index + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the + * number of elements in the list minus 1 (inclusive)
  • * + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridItem getItem(final int index) { + checkWidget(); + + if (index < 0 || index >= items.size()) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + + return items.get(index); + } + + /** + * Returns the item at the given point in the receiver or null if no such item + * exists. The point is in the coordinate system of the receiver. + * + * @param point + * the point used to locate the item + * @return the item at the given point + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the point is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridItem getItem(final Point point) { + checkWidget(); + + if (point == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (point.x < 0 || point.x > getClientArea().width) { + return null; + } + + final Point p = new Point(point.x, point.y); + + int y2 = 0; + + if (columnHeadersVisible) { + if (p.y <= headerHeight) { + return null; + } + y2 += headerHeight; + } + + GridItem itemToReturn = null; + + int row = getTopIndex(); + while (row < items.size() && y2 <= getClientArea().height) { + final GridItem currItem = items.get(row); + if (currItem.isVisible()) { + final int currItemHeight = currItem.getHeight(); + + if (p.y >= y2 && p.y < y2 + currItemHeight + 1) { + itemToReturn = currItem; + break; + } + + y2 += currItemHeight + 1; + } + row++; + } + + if (hasSpanning) { + if (itemToReturn != null) { + final int itemIndex = getIndexOfItem(itemToReturn); + + final GridColumn gridColumn = getColumn(itemToReturn, point); + final int displayColIndex = displayOrderedColumns.indexOf(gridColumn); + + // track back all previous columns and check their spanning + int indexNextItemToCheck = 0; + for (int i = 0; i < itemIndex; i++) { + if (i < indexNextItemToCheck) { + continue; + } + final GridItem gridItem = this.getItem(i); + if (gridItem.isVisible() == false) { + continue; + } + final int span = gridItem.getRowSpan(displayColIndex); + + if (i + span >= itemIndex) { + itemToReturn = gridItem; + break; + } + indexNextItemToCheck = i + span + 1; + } + } + } + + return itemToReturn; + } + + /** + * Returns the number of items contained in the receiver. + * + * @return the number of items + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getItemCount() { + checkWidget(); + return items.size(); + } + + /** + * Returns the default height of the items in this Grid. See + * {@link #setItemHeight(int)} for details. + * + *

+ * IMPORTANT: The Grid's items need not all have the height returned by this + * method, because an item's height may have been changed by calling + * {@link GridItem#setHeight(int)}. + * + * @return default height of items + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * @see #setItemHeight(int) + */ + public int getItemHeight() { + checkWidget(); + return itemHeight; + } + + /** + * Sets the default height for this Grid's items. When this method + * is called, all existing items are resized to the specified height and items + * created afterwards will be initially sized to this height. + *

+ * As long as no default height was set by the client through this method, the + * preferred height of the first item in this Grid is used as a + * default for all items (and is returned by {@link #getItemHeight()}). + * + * @param height + * default height in pixels + * @throws IllegalArgumentException + *

    + *
  • ERROR_INVALID_ARGUMENT - if the height is < 1
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * + * @see GridItem#getHeight() + * @see GridItem#setHeight(int) + */ + public void setItemHeight(final int height) { + checkWidget(); + if (height < 1) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + itemHeight = height; + userModifiedItemHeight = true; + for (final GridItem item : items) { + item.setHeight(height); + } + hasDifferingHeights = false; + setScrollValuesObsolete(); + redraw(); + } + + /** + * Returns true if the rows are resizable. + * + * @return the row resizeable state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * @see #setRowsResizeable(boolean) + */ + public boolean getRowsResizeable() { + checkWidget(); + return rowsResizeable; + } + + /** + * Sets the rows resizeable state of this Grid. The default is + * 'false'. + *

+ * If a row in a Grid is resizeable, then the user can + * interactively change its height by dragging the border of the row header. + *

+ * Note that for rows to be resizable the row headers must be visible. + * + * @param rowsResizeable + * true if this Grid's rows should be resizable + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * @see #setRowHeaderVisible(boolean) + */ + public void setRowsResizeable(final boolean rowsResizeable) { + checkWidget(); + this.rowsResizeable = rowsResizeable; + } + + /** + * Returns a (possibly empty) array of {@code GridItem}s which are the items in + * the receiver. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the items in the receiver + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridItem[] getItems() { + checkWidget(); + return items.toArray(new GridItem[items.size()]); + } + + /** + * + * @param item + * @return t + */ + public int getIndexOfItem(final GridItem item) { + checkWidget(); + + return item.getRowIndex(); + } + + /** + * Returns the line color. + * + * @return Returns the lineColor. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public Color getLineColor() { + checkWidget(); + return lineColor; + } + + /** + * Returns true if the lines are visible. + * + * @return Returns the linesVisible. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean getLinesVisible() { + checkWidget(); + return linesVisible; + } + + /** + * Returns true if the tree lines are visible. + * + * @return Returns the treeLinesVisible. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean getTreeLinesVisible() { + checkWidget(); + return treeLinesVisible; + } + + /** + * Returns the next visible item in the table. + * + * @param item + * item + * @return next visible item or null + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridItem getNextVisibleItem(final GridItem item) { + checkWidget(); + + int index = item.getRowIndex(); + if (items.size() == index + 1) { + return null; + } + + GridItem nextItem = items.get(index + 1); + + while (!nextItem.isVisible()) { + index++; + if (items.size() == index + 1) { + return null; + } + + nextItem = items.get(index + 1); + } + + return nextItem; + } + + /** + * Returns the previous visible item in the table. Passing null for the item + * will return the last visible item in the table. + * + * @param item + * item or null + * @return previous visible item or if item==null last visible item + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridItem getPreviousVisibleItem(final GridItem item) { + checkWidget(); + + int index = 0; + if (item == null) { + index = items.size(); + } else { + index = item.getRowIndex(); + if (index <= 0) { + return null; + } + } + + GridItem prevItem = items.get(index - 1); + + while (!prevItem.isVisible()) { + index--; + if (index == 0) { + return null; + } + + prevItem = items.get(index - 1); + } + + return prevItem; + } + + /** + * Returns the previous visible column in the table. + * + * @param column + * column + * @return previous visible column or null + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridColumn getPreviousVisibleColumn(final GridColumn column) { + checkWidget(); + + int index = displayOrderedColumns.indexOf(column); + + if (index == 0) { + return null; + } + + index--; + + GridColumn previous = displayOrderedColumns.get(index); + + while (!previous.isVisible()) { + if (index == 0) { + return null; + } + + index--; + previous = displayOrderedColumns.get(index); + } + + return previous; + } + + /** + * Returns the next visible column in the table. + * + * @param column + * column + * @return next visible column or null + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridColumn getNextVisibleColumn(final GridColumn column) { + checkWidget(); + + int index = displayOrderedColumns.indexOf(column); + + if (index == displayOrderedColumns.size() - 1) { + return null; + } + + index++; + + GridColumn next = displayOrderedColumns.get(index); + + while (!next.isVisible()) { + if (index == displayOrderedColumns.size() - 1) { + return null; + } + + index++; + next = displayOrderedColumns.get(index); + } + + return next; + } + + /** + * Returns the number of root items contained in the receiver. + * + * @return the number of items + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getRootItemCount() { + checkWidget(); + return rootItems.size(); + } + + /** + * Returns a (possibly empty) array of {@code GridItem}s which are the root + * items in the receiver. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the root items in the receiver + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridItem[] getRootItems() { + checkWidget(); + + return rootItems.toArray(new GridItem[rootItems.size()]); + } + + /** + * TODO: asl;fj + * + * @param index + * @return asdf + */ + public GridItem getRootItem(final int index) { + checkWidget(); + + if (index < 0 || index >= rootItems.size()) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + + return rootItems.get(index); + } + + /** + * Gets the row header renderer. + * + * @return Returns the rowHeaderRenderer. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public IRenderer getRowHeaderRenderer() { + checkWidget(); + return rowHeaderRenderer; + } + + /** + * Returns a array of {@code GridItem}s that are currently selected in the + * receiver. The order of the items is unspecified. An empty array indicates + * that no items are selected. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * selection, so modifying the array will not affect the receiver. + *

+ * If cell selection is enabled, any items which contain at least one selected + * cell are returned. + * + * @return an array representing the selection + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridItem[] getSelection() { + checkWidget(); + + if (!cellSelectionEnabled) { + return selectedItems.toArray(new GridItem[selectedItems.size()]); + } else { + final Vector items = new Vector<>(); + final int itemCount = getItemCount(); + + for (final Point cell : selectedCells) { + if (cell.y >= 0 && cell.y < itemCount) { + final GridItem item = getItem(cell.y); + if (!items.contains(item)) { + items.add(item); + } + } + } + return items.toArray(new GridItem[] {}); + } + } + + /** + * Returns the number of selected items contained in the receiver. If cell + * selection is enabled, the number of items with at least one selected cell are + * returned. + * + * @return the number of selected items + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getSelectionCount() { + checkWidget(); + + if (!cellSelectionEnabled) { + return selectedItems.size(); + } else { + final Vector items = new Vector<>(); + for (final Point cell : selectedCells) { + final GridItem item = getItem(cell.y); + if (!items.contains(item)) { + items.add(item); + } + } + return items.size(); + } + } + + /** + * Returns the number of selected cells contained in the receiver. + * + * @return the number of selected cells + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getCellSelectionCount() { + checkWidget(); + return selectedCells.size(); + } + + /** + * Returns the zero-relative index of the item which is currently selected in + * the receiver, or -1 if no item is selected. If cell selection is enabled, + * returns the index of first item that contains at least one selected cell. + * + * @return the index of the selected item + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getSelectionIndex() { + checkWidget(); + + if (!cellSelectionEnabled) { + if (selectedItems.size() == 0) { + return -1; + } + + return selectedItems.get(0).getRowIndex(); + } else { + if (selectedCells.size() == 0) { + return -1; + } + + return selectedCells.get(0).y; + } + } + + /** + * Returns the zero-relative indices of the items which are currently selected + * in the receiver. The order of the indices is unspecified. The array is empty + * if no items are selected. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * selection, so modifying the array will not affect the receiver. + *

+ * If cell selection is enabled, returns the indices of any items which contain + * at least one selected cell. + * + * @return the array of indices of the selected items + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int[] getSelectionIndices() { + checkWidget(); + + if (!cellSelectionEnabled) { + final int[] indices = new int[selectedItems.size()]; + int i = 0; + for (final GridItem item : selectedItems) { + indices[i] = item.getRowIndex(); + i++; + } + return indices; + } else { + final Vector selectedRows = new Vector<>(); + for (final Point cell : selectedCells) { + final GridItem item = getItem(cell.y); + if (!selectedRows.contains(item)) { + selectedRows.add(item); + } + } + final int[] indices = new int[selectedRows.size()]; + int i = 0; + for (final GridItem item : selectedRows) { + indices[i] = item.getRowIndex(); + i++; + } + return indices; + } + } + + /** + * Returns the zero-relative index of the item which is currently at the top of + * the receiver. This index can change when items are scrolled or new items are + * added or removed. + * + * @return the index of the top item + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getTopIndex() { + checkWidget(); + + if (topIndex != -1) { + return topIndex; + } + + if (!vScroll.getVisible()) { + topIndex = 0; + } else { + // figure out first visible row and last visible row + int firstVisibleIndex = vScroll.getSelection(); + + if (isTree) { + final Iterator itemsIter = items.iterator(); + int row = firstVisibleIndex + 1; + + while (row > 0 && itemsIter.hasNext()) { + final GridItem item = itemsIter.next(); + + if (item.isVisible()) { + row--; + if (row == 0) { + firstVisibleIndex = item.getRowIndex(); + } + } + } + } + + topIndex = firstVisibleIndex; + + /* + * MOPR here lies more potential for increasing performance for the case (isTree + * || hasDifferingHeights) the topIndex could be derived from the previous value + * depending on a delta of the vScroll.getSelection() instead of being + * calculated completely anew + */ + } + + return topIndex; + } + + /** + * Returns the zero-relative index of the item which is currently at the bottom + * of the receiver. This index can change when items are scrolled, expanded or + * collapsed or new items are added or removed. + *

+ * Note that the item with this index is often only partly visible; maybe only a + * single line of pixels is visible. Use {@link #isShown(GridItem)} to find out. + *

+ * In extreme cases, getBottomIndex() may return the same value as + * {@link #getTopIndex()}. + * + * @return the index of the bottom item + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + int getBottomIndex() { + checkWidget(); + + if (bottomIndex != -1) { + return bottomIndex; + } + + if (items.size() == 0) { + bottomIndex = 0; + } else if (getVisibleGridHeight() < 1) { + bottomIndex = getTopIndex(); + } else { + final RowRange range = getRowRange(getTopIndex(), getVisibleGridHeight(), false, false); + + bottomIndex = range.endIndex; + bottomIndexShownCompletely = range.height <= getVisibleGridHeight(); + } + + return bottomIndex; + } + + /** + * Returns a {@link RowRange} ranging from the grid item at startIndex to that + * at endIndex. + *

+ * This is primarily used to measure the height in pixel of such a range and to + * count the number of visible grid items within the range. + * + * @param startIndex + * index of the first item in the range or -1 to the first visible + * item in this grid + * @param endIndex + * index of the last item in the range or -1 to use the last visible + * item in this grid + * @return + */ + private RowRange getRowRange(int startIndex, int endIndex) { + + // parameter preparation + if (startIndex == -1) { + // search frist visible item + do { + startIndex++; + } while (startIndex < items.size() && !items.get(startIndex).isVisible()); + if (startIndex == items.size()) { + return null; + } + } + if (endIndex == -1) { + // search last visible item + endIndex = items.size(); + do { + endIndex--; + } while (endIndex >= 0 && !items.get(endIndex).isVisible()); + if (endIndex == -1) { + return null; + } + } + + // fail fast + if (startIndex < 0 || endIndex < 0 || startIndex >= items.size() || endIndex >= items.size() + || endIndex < startIndex || items.get(startIndex).isVisible() == false + || items.get(endIndex).isVisible() == false) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + final RowRange range = new RowRange(); + range.startIndex = startIndex; + range.endIndex = endIndex; + + if (isTree || hasDifferingHeights) { + for (int idx = startIndex; idx <= endIndex; idx++) { + final GridItem currItem = items.get(idx); + + if (currItem.isVisible()) { + if (range.rows > 0) { + range.height++; // height of horizontal row separator + } + range.height += currItem.getHeight(); + range.rows++; + } + } + } else { + range.rows = range.endIndex - range.startIndex + 1; + range.height = (itemHeight + 1) * range.rows - 1; + } + + return range; + } + + /** + * This method can be used to build a range of grid rows that is allowed to span + * a certain height in pixels. + *

+ * It returns a {@link RowRange} that contains information about the range, + * especially the index of the last element in the range (or if inverse == true, + * then the index of the first element). + *

+ * Note: Even if 'forceEndCompletelyInside' is set to true, the last item will + * not lie completely within the availableHeight, if (height of item at + * startIndex < availableHeight). + * + * @param startIndex + * index of the first (if inverse==false) or last (if inverse==true) + * item in the range + * @param availableHeight + * height in pixels + * @param forceEndCompletelyInside + * if true, the last item in the range will lie completely within the + * availableHeight, otherwise it may lie partly outside this range + * @param inverse + * if true, then the first item in the range will be searched, not + * the last + * @return range of grid rows + * @see RowRange + */ + private RowRange getRowRange(int startIndex, final int availableHeight, final boolean forceEndCompletelyInside, + final boolean inverse) { + // parameter preparation + if (startIndex == -1) { + if (!inverse) { + // search frist visible item + do { + startIndex++; + } while (startIndex < items.size() && !items.get(startIndex).isVisible()); + if (startIndex == items.size()) { + return null; + } + } else { + // search last visible item + startIndex = items.size(); + do { + startIndex--; + } while (startIndex >= 0 && !items.get(startIndex).isVisible()); + if (startIndex == -1) { + return null; + } + } + } + + // fail fast + if (startIndex < 0 || startIndex >= items.size() || items.get(startIndex).isVisible() == false) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + final RowRange range = new RowRange(); + + if (availableHeight <= 0) { + // special case: empty range + range.startIndex = startIndex; + range.endIndex = startIndex; + range.rows = 0; + range.height = 0; + return range; + } + + if (isTree || hasDifferingHeights) { + int otherIndex = startIndex; // tentative end index + int consumedItems = 0; + int consumedHeight = 0; + + // consume height for startEnd (note: no separator pixel added here) + consumedItems++; + consumedHeight += items.get(otherIndex).getHeight(); + + // note: we use "+2" in next line, because we only try to add another row if + // there + // is room for the separator line + at least one pixel row for the additional + // item + while (consumedHeight + 2 <= availableHeight) { + // STEP 1: + // try to find a visible item we can add + + int nextIndex = otherIndex; + GridItem nextItem; + + do { + if (!inverse) { + nextIndex++; + } else { + nextIndex--; + } + + if (nextIndex >= 0 && nextIndex < items.size()) { + nextItem = items.get(nextIndex); + } else { + nextItem = null; + } + } while (nextItem != null && !nextItem.isVisible()); + + if (nextItem == null) { + // no visible item found + break; + } + + if (forceEndCompletelyInside) { + // must lie completely within the allowed height + if (!(consumedHeight + 1 + nextItem.getHeight() <= availableHeight)) { + break; + } + } + + // we found one !! + + // STEP 2: + // Consume height for this item + + consumedItems++; + consumedHeight += 1; // height of separator line + consumedHeight += nextItem.getHeight(); + + // STEP 3: + // make this item it the current guess for the other end + otherIndex = nextIndex; + } + + range.startIndex = !inverse ? startIndex : otherIndex; + range.endIndex = !inverse ? otherIndex : startIndex; + range.rows = consumedItems; + range.height = consumedHeight; + } else { + int availableRows = (availableHeight + 1) / (itemHeight + 1); + + if((itemHeight + 1) * range.rows - 1 + 1 < availableHeight) { + // not all available space used yet + // - so add another row if it need not be completely within availableHeight + if (!forceEndCompletelyInside) { + availableRows++; + } + } + + int otherIndex = startIndex + (availableRows - 1) * (!inverse ? 1 : -1); + if (otherIndex < 0) { + otherIndex = 0; + } + if (otherIndex >= items.size()) { + otherIndex = items.size() - 1; + } + + range.startIndex = !inverse ? startIndex : otherIndex; + range.endIndex = !inverse ? otherIndex : startIndex; + range.rows = range.endIndex - range.startIndex + 1; + range.height = (itemHeight + 1) * range.rows - 1; + } + + return range; + } + + /** + * Returns the height of the plain grid in pixels. + *

+ * This includes all rows for visible items (i.e. items that return true on + * {@link GridItem#isVisible()} ; not only those currently visible on screen) + * and the 1 pixel separator between rows. + *

+ * This does not include the height of the column headers. + * + * @return height of plain grid + */ + int getGridHeight() { + final RowRange range = getRowRange(-1, -1); + return range != null ? range.height : 0; + /* + * MOPR currently this method is only used in #getTableSize() ; if it will be + * used for more important things in the future (e.g. the max value for + * vScroll.setValues() when doing pixel-by-pixel vertical scrolling) then this + * value should at least be cached or even updated incrementally when grid items + * are added/removed or expaned/collapsed (similar as #currentVisibleItems). + * (this is only necessary in the case (isTree || hasDifferingHeights)) + */ + } + + /** + * Returns the height of the on-screen area that is available for showing the + * grid's rows, i.e. the client area of the scrollable minus the height of the + * column headers (if shown). + * + * @return height of visible grid in pixels + */ + int getVisibleGridHeight() { + return getClientArea().height - (columnHeadersVisible ? headerHeight : 0) + - (columnFootersVisible ? footerHeight : 0); + } + + /** + * Returns the height of the screen area that is available for showing the grid + * columns + * + * @return + */ + int getVisibleGridWidth() { + return getClientArea().width - (rowHeaderVisible ? rowHeaderWidth : 0); + } + + /** + * Gets the top left renderer. + * + * @return Returns the topLeftRenderer. + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public IRenderer getTopLeftRenderer() { + checkWidget(); + return topLeftRenderer; + } + + /** + * Gets the bottom left renderer. + * + * @return Returns the bottomLeftRenderer. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public IRenderer getBottomLeftRenderer() { + checkWidget(); + return bottomLeftRenderer; + } + + /** + * Searches the receiver's list starting at the first column (index 0) until a + * column is found that is equal to the argument, and returns the index of that + * column. If no column is found, returns -1. + * + * @param column + * the search column + * @return the index of the column + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the column is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int indexOf(final GridColumn column) { + checkWidget(); + + if (column == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (column.getParent() != this) { + return -1; + } + + return column.index; + } + + /** + * Searches the receiver's list starting at the first item (index 0) until an + * item is found that is equal to the argument, and returns the index of that + * item. If no item is found, returns -1. + * + * @param item + * the search item + * @return the index of the item + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int indexOf(final GridItem item) { + checkWidget(); + + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (item.getParent() != this) { + return -1; + } + + return items.indexOf(item); + } + + /** + * Returns {@code true} if the receiver's row header is visible, and + * {@code false} otherwise. + *

+ * + * @return the receiver's row header's visibility state + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean isRowHeaderVisible() { + checkWidget(); + return rowHeaderVisible; + } + + /** + * Returns {@code true} if the item is selected, and {@code false} otherwise. + * Indices out of range are ignored. If cell selection is enabled, returns true + * if the item at the given index contains at least one selected cell. + * + * @param index + * the index of the item + * @return the visibility state of the item at the index + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean isSelected(final int index) { + checkWidget(); + + if (index < 0 || index >= items.size()) { + return false; + } + + if (!cellSelectionEnabled) { + return isSelected(items.get(index)); + } else { + for (final Point cell : selectedCells) { + if (cell.y == index) { + return true; + } + } + return false; + } + } + + /** + * Returns true if the given item is selected. If cell selection is enabled, + * returns true if the given item contains at least one selected cell. + * + * @param item + * item + * @return true if the item is selected. + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean isSelected(final GridItem item) { + checkWidget(); + if (!cellSelectionEnabled) { + return selectedItems.contains(item); + } else { + final int index = item.getRowIndex(); + if (index == -1) { + return false; + } + for (final Point cell : selectedCells) { + if (cell.y == index) { + return true; + } + } + return false; + } + } + + /** + * Returns true if the given cell is selected. + * + * @param cell + * cell + * @return true if the cell is selected. + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the cell is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean isCellSelected(final Point cell) { + checkWidget(); + + if (cell == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + return selectedCells.contains(cell); + } + + /** + * Removes the item from the receiver at the given zero-relative index. + * + * @param index + * the index for the item + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the + * number of elements in the list minus 1 (inclusive)
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void remove(final int index) { + checkWidget(); + if (index < 0 || index > items.size() - 1) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + final GridItem item = items.get(index); + item.dispose(); + redraw(); + } + + /** + * Removes the items from the receiver which are between the given zero-relative + * start and end indices (inclusive). + * + * @param start + * the start of the range + * @param end + * the end of the range + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if either the start or end are not + * between 0 and the number of elements in the list minus 1 + * (inclusive)
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void remove(final int start, final int end) { + checkWidget(); + + for (int i = end; i >= start; i--) { + if (i < 0 || i > items.size() - 1) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + final GridItem item = items.get(i); + item.dispose(); + } + redraw(); + } + + /** + * Removes the items from the receiver's list at the given zero-relative + * indices. + * + * @param indices + * the array of indices of the items + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the + * number of elements in the list minus 1 (inclusive)
  • + *
  • ERROR_NULL_ARGUMENT - if the indices array is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void remove(final int[] indices) { + checkWidget(); + + if (indices == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final GridItem[] removeThese = new GridItem[indices.length]; + for (int i = 0; i < indices.length; i++) { + final int j = indices[i]; + if (j < items.size() && j >= 0) { + removeThese[i] = items.get(j); + } else { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + + } + for (final GridItem item : removeThese) { + item.dispose(); + } + redraw(); + } + + /** + * Removes all of the items from the receiver. + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * Call {@link Grid} disposeAllItems and clearItems.. Is faster + */ + @Deprecated + public void removeAll() { + checkWidget(); + + while (items.size() > 0) { + items.get(0).dispose(); + } + deselectAll(); + redraw(); + } + + /** + * All items needs to call the disposeOnly method + */ + public void disposeAllItems() { + checkWidget(); + + final GridItem[] items = getItems(); + for (final GridItem gridItem : items) { + gridItem.disposeOnly(); + } + clearItems(); + scrollValuesObsolete = true; + topIndex = -1; + bottomIndex = -1; + currentVisibleItems = 0; + updateColumnSelection(); + focusItem = null; + selectedItems.clear(); + redraw(); + // Need to update the scrollbars see see 375327 + updateScrollbars(); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the receiver's selection changes. + * + * @param listener + * the listener which should no longer be notified + * @see SelectionListener + * @see #addSelectionListener(SelectionListener) + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + removeListener(SWT.Selection, listener); + removeListener(SWT.DefaultSelection, listener); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the receiver's items changes. + * + * @param listener + * the listener which should no longer be notified + * @see TreeListener + * @see #addTreeListener(TreeListener) + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void removeTreeListener(final TreeListener listener) { + checkWidget(); + removeListener(SWT.Expand, listener); + removeListener(SWT.Collapse, listener); + } + + /** + * Selects the item at the given zero-relative index in the receiver. If the + * item at the index was already selected, it remains selected. Indices that are + * out of range are ignored. + *

+ * If cell selection is enabled, selects all cells at the given index. + * + * @param index + * the index of the item to select + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void select(final int index) { + checkWidget(); + + if (!selectionEnabled) { + return; + } + + if (index < 0 || index >= items.size()) { + return; + } + + final GridItem item = items.get(index); + + if (!cellSelectionEnabled) { + if (selectionType == GridSelectionType.MULTI && selectedItems.contains(item)) { + return; + } + + if (selectionType == GridSelectionType.SINGLE) { + selectedItems.clear(); + } + + selectedItems.add(item); + } else { + selectCells(getCells(item)); + } + + redraw(); + } + + /** + * Selects the items in the range specified by the given zero-relative indices + * in the receiver. The range of indices is inclusive. The current selection is + * not cleared before the new items are selected. + *

+ * If an item in the given range is not selected, it is selected. If an item in + * the given range was already selected, it remains selected. Indices that are + * out of range are ignored and no items will be selected if start is greater + * than end. If the receiver is single-select and there is more than one item in + * the given range, then all indices are ignored. + *

+ * If cell selection is enabled, all cells within the given range are selected. + * + * @param start + * the start of the range + * @param end + * the end of the range + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * @see Grid#setSelection(int,int) + */ + public void select(final int start, final int end) { + checkWidget(); + + if (!selectionEnabled) { + return; + } + + if (selectionType == GridSelectionType.SINGLE && start != end) { + return; + } + + if (!cellSelectionEnabled) { + if (selectionType == GridSelectionType.SINGLE) { + selectedItems.clear(); + } + } + + for (int i = start; i <= end; i++) { + if (i < 0) { + continue; + } + if (i > items.size() - 1) { + break; + } + + final GridItem item = items.get(i); + + if (!cellSelectionEnabled) { + if (!selectedItems.contains(item)) { + selectedItems.add(item); + } + } else { + selectCells(getCells(item)); + } + } + + redraw(); + } + + /** + * Selects the items at the given zero-relative indices in the receiver. The + * current selection is not cleared before the new items are selected. + *

+ * If the item at a given index is not selected, it is selected. If the item at + * a given index was already selected, it remains selected. Indices that are out + * of range and duplicate indices are ignored. If the receiver is single-select + * and multiple indices are specified, then all indices are ignored. + *

+ * If cell selection is enabled, all cells within the given indices are + * selected. + * + * @param indices + * the array of indices for the items to select + * @throws IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the array of indices is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * @see Grid#setSelection(int[]) + */ + public void select(final int[] indices) { + checkWidget(); + + if (indices == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (!selectionEnabled) { + return; + } + + if (selectionType == GridSelectionType.SINGLE && indices.length > 1) { + return; + } + + if (!cellSelectionEnabled) { + if (selectionType == GridSelectionType.SINGLE) { + selectedItems.clear(); + } + } + + for (final int j : indices) { + if (j >= 0 && j < items.size()) { + final GridItem item = items.get(j); + + if (!cellSelectionEnabled) { + if (!selectedItems.contains(item)) { + selectedItems.add(item); + } + } else { + selectCells(getCells(item)); + } + } + } + redraw(); + } + + /** + * Selects all of the items in the receiver. + *

+ * If the receiver is single-select, do nothing. If cell selection is enabled, + * all cells are selected. + * + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void selectAll() { + checkWidget(); + + if (!selectionEnabled) { + return; + } + + if (selectionType == GridSelectionType.SINGLE) { + return; + } + + if (cellSelectionEnabled) { + selectAllCells(); + return; + } + + selectedItems.clear(); + selectedItems.addAll(items); + redraw(); + } + + /** + * Sets the empty cell renderer. + * + * @param emptyCellRenderer + * The emptyCellRenderer to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setEmptyCellRenderer(final GridCellRenderer emptyCellRenderer) { + checkWidget(); + emptyCellRenderer.setDisplay(getDisplay()); + this.emptyCellRenderer = emptyCellRenderer; + } + + /** + * Sets the empty column header renderer. + * + * @param emptyColumnHeaderRenderer + * The emptyColumnHeaderRenderer to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setEmptyColumnHeaderRenderer(final IRenderer emptyColumnHeaderRenderer) { + checkWidget(); + emptyColumnHeaderRenderer.setDisplay(getDisplay()); + this.emptyColumnHeaderRenderer = emptyColumnHeaderRenderer; + } + + /** + * Sets the empty column footer renderer. + * + * @param emptyColumnFooterRenderer + * The emptyColumnFooterRenderer to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setEmptyColumnFooterRenderer(final IRenderer emptyColumnFooterRenderer) { + checkWidget(); + emptyColumnFooterRenderer.setDisplay(getDisplay()); + this.emptyColumnFooterRenderer = emptyColumnFooterRenderer; + } + + /** + * Sets the empty row header renderer. + * + * @param emptyRowHeaderRenderer + * The emptyRowHeaderRenderer to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setEmptyRowHeaderRenderer(final IRenderer emptyRowHeaderRenderer) { + checkWidget(); + emptyRowHeaderRenderer.setDisplay(getDisplay()); + this.emptyRowHeaderRenderer = emptyRowHeaderRenderer; + } + + /** + * Sets the external horizontal scrollbar. Allows the scrolling to be managed + * externally from the table. This functionality is only intended when + * SWT.H_SCROLL is not given. + *

+ * Using this feature, a ScrollBar could be instantiated outside the table, + * wrapped in IScrollBar and thus be 'connected' to the table. + * + * @param scroll + * The horizontal scrollbar to set. + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + protected void setHorizontalScrollBarProxy(final IScrollBarProxy scroll) { + checkWidget(); + if (getHorizontalBar() != null) { + return; + } + hScroll = scroll; + + hScroll.addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(final SelectionEvent e) { + onScrollSelection(); + } + + @Override + public void widgetDefaultSelected(final SelectionEvent e) { + } + }); + } + + /** + * Sets the external vertical scrollbar. Allows the scrolling to be managed + * externally from the table. This functionality is only intended when + * SWT.V_SCROLL is not given. + *

+ * Using this feature, a ScrollBar could be instantiated outside the table, + * wrapped in IScrollBar and thus be 'connected' to the table. + * + * @param scroll + * The vertical scrollbar to set. + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + protected void setlVerticalScrollBarProxy(final IScrollBarProxy scroll) { + checkWidget(); + if (getVerticalBar() != null) { + return; + } + vScroll = scroll; + + vScroll.addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(final SelectionEvent e) { + onScrollSelection(); + } + + @Override + public void widgetDefaultSelected(final SelectionEvent e) { + } + }); + } + + /** + * Sets the focus renderer. + * + * @param focusRenderer + * The focusRenderer to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setFocusRenderer(final IRenderer focusRenderer) { + checkWidget(); + this.focusRenderer = focusRenderer; + } + + /** + * Marks the receiver's header as visible if the argument is {@code true}, and + * marks it invisible otherwise. + * + * @param show + * the new visibility state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setHeaderVisible(final boolean show) { + checkWidget(); + columnHeadersVisible = show; + redraw(); + } + + /** + * Marks the receiver's footer as visible if the argument is {@code true}, and + * marks it invisible otherwise. + * + * @param show + * the new visibility state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setFooterVisible(final boolean show) { + checkWidget(); + columnFootersVisible = show; + redraw(); + } + + /** + * Sets the line color. + * + * @param lineColor + * The lineColor to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setLineColor(final Color lineColor) { + checkWidget(); + this.lineColor = lineColor; + } + + /** + * Sets the line visibility. + * + * @param linesVisible + * Te linesVisible to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setLinesVisible(final boolean linesVisible) { + checkWidget(); + this.linesVisible = linesVisible; + redraw(); + } + + /** + * Sets the tree line visibility. + * + * @param treeLinesVisible + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setTreeLinesVisible(final boolean treeLinesVisible) { + checkWidget(); + this.treeLinesVisible = treeLinesVisible; + redraw(); + } + + /** + * Sets the row header renderer. + * + * @param rowHeaderRenderer + * The rowHeaderRenderer to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setRowHeaderRenderer(final IRenderer rowHeaderRenderer) { + checkWidget(); + rowHeaderRenderer.setDisplay(getDisplay()); + this.rowHeaderRenderer = rowHeaderRenderer; + } + + /** + * Marks the receiver's row header as visible if the argument is {@code true}, + * and marks it invisible otherwise. When row headers are visible, horizontal + * scrolling is always done by column rather than by pixel. + * + * @param show + * the new visibility state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setRowHeaderVisible(final boolean show) { + setRowHeaderVisible(show, 1); + } + + /** + * Marks the receiver's row header as visible if the argument is {@code true}, + * and marks it invisible otherwise. When row headers are visible, horizontal + * scrolling is always done by column rather than by pixel. + * + * @param show + * the new visibility state + * @param minWidth + * the minimun width of the row column + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setRowHeaderVisible(final boolean show, final int minWidth) { + checkWidget(); + rowHeaderVisible = show; + setColumnScrolling(true); + + if (show && isAutoWidth()) { + computeRowHeaderWidth(minWidth); + } + + redraw(); + } + + /** + * Selects the item at the given zero-relative index in the receiver. The + * current selection is first cleared, then the new item is selected. + *

+ * If cell selection is enabled, all cells within the item at the given index + * are selected. + * + * @param index + * the index of the item to select + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setSelection(final int index) { + checkWidget(); + + if (!selectionEnabled) { + return; + } + + if (index >= 0 && index < items.size()) { + if (!cellSelectionEnabled) { + selectedItems.clear(); + selectedItems.add(items.get(index)); + redraw(); + } else { + selectedCells.clear(); + selectCells(getCells(items.get(index))); + } + } + } + + /** + * Selects the items in the range specified by the given zero-relative indices + * in the receiver. The range of indices is inclusive. The current selection is + * cleared before the new items are selected. + *

+ * Indices that are out of range are ignored and no items will be selected if + * start is greater than end. If the receiver is single-select and there is more + * than one item in the given range, then all indices are ignored. + *

+ * If cell selection is enabled, all cells within the given range are selected. + * + * @param start + * the start index of the items to select + * @param end + * the end index of the items to select + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * @see Grid#deselectAll() + * @see Grid#select(int,int) + */ + public void setSelection(final int start, final int end) { + checkWidget(); + + if (!selectionEnabled) { + return; + } + + if (selectionType == GridSelectionType.SINGLE && start != end) { + return; + } + + if (!cellSelectionEnabled) { + selectedItems.clear(); + } else { + selectedCells.clear(); + } + + for (int i = start; i <= end; i++) { + if (i < 0) { + continue; + } + if (i > items.size() - 1) { + break; + } + + final GridItem item = items.get(i); + + if (!cellSelectionEnabled) { + selectedItems.add(item); + } else { + selectCells(getCells(item)); + } + } + redraw(); + } + + /** + * If true, column pack is based only with the visible lines (from + * topIndex to bottomIndex). false pack is in default mode. + * + * @return optimizedColumnPack value + */ + public boolean isVisibleLinesColumnPack() { + return visibleLinesBasedColumnPack; + } + + /** + * Set optimizedColumnPack to true for column pack based only with + * the visible lines. + * + * @param visibleLinesBasedColumnPack + */ + public void setVisibleLinesColumnPack(final boolean visibleLinesBasedColumnPack) { + this.visibleLinesBasedColumnPack = visibleLinesBasedColumnPack; + } + + /** + * Selects the items at the given zero-relative indices in the receiver. The + * current selection is cleared before the new items are selected. + *

+ * Indices that are out of range and duplicate indices are ignored. If the + * receiver is single-select and multiple indices are specified, then all + * indices are ignored. + *

+ * If cell selection is enabled, all cells within the given indices are + * selected. + * + * @param indices + * the indices of the items to select + * @throws IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the array of indices is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * @see Grid#deselectAll() + * @see Grid#select(int[]) + */ + public void setSelection(final int[] indices) { + checkWidget(); + + if (!selectionEnabled) { + return; + } + + if (selectionType == GridSelectionType.SINGLE && indices.length > 1) { + return; + } + + if (!cellSelectionEnabled) { + selectedItems.clear(); + } else { + selectedCells.clear(); + } + + for (final int j : indices) { + if (j < 0) { + continue; + } + if (j > items.size() - 1) { + break; + } + + final GridItem item = items.get(j); + + if (!cellSelectionEnabled) { + selectedItems.add(item); + } else { + selectCells(getCells(item)); + } + } + redraw(); + } + + /** + * Sets the receiver's selection to be the given array of items. The current + * selection is cleared before the new items are selected. + *

+ * Items that are not in the receiver are ignored. If the receiver is + * single-select and multiple items are specified, then all items are ignored. + * If cell selection is enabled, all cells within the given items are selected. + * + * @param _items + * the array of items + * @throws IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the array of items is null
  • + *
  • ERROR_INVALID_ARGUMENT - if one of the items has been + * disposed
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ * @see Grid#deselectAll() + * @see Grid#select(int[]) + * @see Grid#setSelection(int[]) + */ + public void setSelection(final GridItem[] _items) { + checkWidget(); + + if (!selectionEnabled) { + return; + } + + if (_items == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (selectionType == GridSelectionType.SINGLE && _items.length > 1) { + return; + } + + if (!cellSelectionEnabled) { + selectedItems.clear(); + } else { + selectedCells.clear(); + } + + for (final GridItem item : _items) { + if (item == null) { + continue; + } + if (item.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + if (item.getParent() != this) { + continue; + } + + if (!cellSelectionEnabled) { + selectedItems.add(item); + } else { + selectCells(getCells(item)); + } + } + + redraw(); + } + + /** + * Sets the zero-relative index of the item which is currently at the top of the + * receiver. This index can change when items are scrolled or new items are + * added and removed. + * + * @param index + * the index of the top item + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setTopIndex(final int index) { + checkWidget(); + if (index < 0 || index >= items.size()) { + return; + } + + final GridItem item = items.get(index); + if (!item.isVisible()) { + return; + } + + if (!vScroll.getVisible()) { + return; + } + + int vScrollAmount = 0; + + for (int i = 0; i < index; i++) { + if (items.get(i).isVisible()) { + vScrollAmount++; + } + } + + vScroll.setSelection(vScrollAmount); + topIndex = -1; + bottomIndex = -1; + redraw(); + } + + /** + * Sets the top left renderer. + * + * @param topLeftRenderer + * The topLeftRenderer to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setTopLeftRenderer(final IRenderer topLeftRenderer) { + checkWidget(); + topLeftRenderer.setDisplay(getDisplay()); + this.topLeftRenderer = topLeftRenderer; + } + + /** + * Sets the bottom left renderer. + * + * @param bottomLeftRenderer + * The topLeftRenderer to set. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setBottomLeftRenderer(final IRenderer bottomLeftRenderer) { + checkWidget(); + bottomLeftRenderer.setDisplay(getDisplay()); + this.bottomLeftRenderer = bottomLeftRenderer; + } + + /** + * Shows the column. If the column is already showing in the receiver, this + * method simply returns. Otherwise, the columns are scrolled until the column + * is visible. + * + * @param col + * the column to be shown + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void showColumn(final GridColumn col) { + checkWidget(); + + if (!col.isVisible()) { + final GridColumnGroup group = col.getColumnGroup(); + group.setExpanded(!group.getExpanded()); + if (group.getExpanded()) { + group.notifyListeners(SWT.Expand, new Event()); + } else { + group.notifyListeners(SWT.Collapse, new Event()); + } + } + + if (!hScroll.getVisible()) { + return; + } + + int x = getColumnHeaderXPosition(col); + + int firstVisibleX = 0; + if (rowHeaderVisible) { + firstVisibleX = rowHeaderWidth; + } + + // if its visible just return + if (x >= firstVisibleX && x + col.getWidth() <= firstVisibleX + getClientArea().width - firstVisibleX) { + return; + } + + if (!getColumnScrolling()) { + if (x < firstVisibleX) { + hScroll.setSelection(getHScrollSelectionInPixels() - (firstVisibleX - x)); + } else { + if (col.getWidth() > getClientArea().width - firstVisibleX) { + hScroll.setSelection(getHScrollSelectionInPixels() + x - firstVisibleX); + } else { + x -= getClientArea().width - firstVisibleX - col.getWidth(); + hScroll.setSelection(getHScrollSelectionInPixels() + x - firstVisibleX); + } + } + } else { + if (x < firstVisibleX || col.getWidth() > getClientArea().width - firstVisibleX) { + final int sel = displayOrderedColumns.indexOf(col); + hScroll.setSelection(sel); + } else { + int availableWidth = getClientArea().width - firstVisibleX - col.getWidth(); + + GridColumn prevCol = getPreviousVisibleColumn(col); + GridColumn currentScrollTo = col; + + while (true) { + if (prevCol == null || prevCol.getWidth() > availableWidth) { + final int sel = displayOrderedColumns.indexOf(currentScrollTo); + hScroll.setSelection(sel); + break; + } else { + availableWidth -= prevCol.getWidth(); + currentScrollTo = prevCol; + prevCol = getPreviousVisibleColumn(prevCol); + } + } + } + } + + redraw(); + } + + /** + * Returns true if 'item' is currently being completely shown in this + * Grid's visible on-screen area. + * + *

+ * Here, "completely" only refers to the item's height, not its width. This + * means this method returns true also if some cells are horizontally scrolled + * away. + * + * @param item + * @return true if 'item' is shown + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
  • ERROR_INVALID_ARGUMENT - if 'item' is not contained in the + * receiver
  • + *
+ */ + boolean isShown(final GridItem item) { + checkWidget(); + + if (!item.isVisible()) { + return false; + } + + final int itemIndex = item.getRowIndex(); + + if (itemIndex == -1) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + final int firstVisibleIndex = getTopIndex(); + final int lastVisibleIndex = getBottomIndex(); + + return itemIndex >= firstVisibleIndex && itemIndex < lastVisibleIndex + || itemIndex == lastVisibleIndex && bottomIndexShownCompletely; + } + + /** + * Shows the item. If the item is already showing in the receiver, this method + * simply returns. Otherwise, the items are scrolled until the item is visible. + * + * @param item + * the item to be shown + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
  • ERROR_INVALID_ARGUMENT - if 'item' is not contained in the + * receiver
  • + *
+ */ + public void showItem(final GridItem item) { + checkWidget(); + + updateScrollbars(); + + // if no items are visible on screen then abort + if (getVisibleGridHeight() < 1) { + return; + } + + // if its visible just return + if (isShown(item)) { + return; + } + + if (!item.isVisible()) { + GridItem parent = item.getParentItem(); + do { + if (!parent.isExpanded()) { + parent.setExpanded(true); + parent.fireEvent(SWT.Expand); + } + parent = parent.getParentItem(); + } while (parent != null); + } + + int newTopIndex = item.getRowIndex(); + + if (newTopIndex >= getBottomIndex()) { + final RowRange range = getRowRange(newTopIndex, getVisibleGridHeight(), true, true); // note: inverse==true + newTopIndex = range.startIndex; // note: use startIndex because of inverse==true + } + + setTopIndex(newTopIndex); + } + + /** + * Shows the selection. If the selection is already showing in the receiver, + * this method simply returns. Otherwise, the items are scrolled until the + * selection is visible. + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void showSelection() { + checkWidget(); + + if (scrollValuesObsolete) { + updateScrollbars(); + } + + if (!cellSelectionEnabled) { + if (selectedItems.size() == 0) { + return; + } + + showItem(selectedItems.get(0)); + } else { + if (selectedCells.size() == 0) { + return; + } + + showItem(getItem(selectedCells.get(0).y)); + showColumn(getColumn(selectedCells.get(0).x)); + } + + } + + /** + * Enables selection highlighting if the argument is true. + * + * @param selectionEnabled + * the selection enabled state + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setSelectionEnabled(final boolean selectionEnabled) { + checkWidget(); + + if (!selectionEnabled) { + selectedItems.clear(); + redraw(); + } + + this.selectionEnabled = selectionEnabled; + } + + /** + * Returns true if selection is enabled, false otherwise. + * + * @return the selection enabled state + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean getSelectionEnabled() { + checkWidget(); + return selectionEnabled; + } + + /** + * Computes and sets the height of the header row. This method will ask for the + * preferred size of all the column headers and use the max. + * + * @param gc + * GC for font metrics, etc. + */ + private void computeHeaderHeight(final GC gc) { + + int colHeaderHeight = 0; + for (final GridColumn column : columns) { + colHeaderHeight = Math.max(column.getHeaderHeight(gc), colHeaderHeight); + } + + int groupHeight = 0; + for (final GridColumnGroup group : columnGroups) { + groupHeight = Math.max(group.getHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, group).y, + groupHeight); + } + + headerHeight = colHeaderHeight + groupHeight; + groupHeaderHeight = groupHeight; + } + + private void computeHeaderHeight() { + estimate(this::computeHeaderHeight); + } + + private void computeFooterHeight(final GC gc) { + + int colFooterHeight = 0; + for (final GridColumn column : columns) { + colFooterHeight = Math.max(column.getFooterHeight(gc), colFooterHeight); + } + + footerHeight = colFooterHeight; + } + + /** + * Returns the computed default item height. Currently this method just gets the + * preferred size of all the cells in the given row and returns that (it is then + * used as the height of all rows with items having a height of -1). + * + * @param item + * item to use for sizing + * @param gc + * GC used to perform font metrics,etc. + * @return the row height + */ + private int computeItemHeight(final GridItem item, final GC gc) { + int height = 1; + + if (columns.size() == 0 || items.size() == 0) { + return height; + } + + for (final GridColumn column : columns) { + column.getCellRenderer().setColumn(column.index); + height = Math.max(height, column.getCellRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, item).y); + } + + if (rowHeaderVisible && rowHeaderRenderer != null) { + height = Math.max(height, rowHeaderRenderer.computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, item).y); + } + + return height <= 0 ? 16 : height; + } + + private int computeItemHeight(final GridItem item) { + return estimateWithResult(sizingGC -> computeItemHeight(item, sizingGC)); + } + + /** + * Returns the x position of the given column. Takes into account scroll + * position. + * + * @param column + * given column + * @return x position + */ + private int getColumnHeaderXPosition(final GridColumn column) { + if (!column.isVisible()) { + return -1; + } + + int x = 0; + + x -= getHScrollSelectionInPixels(); + + if (rowHeaderVisible) { + x += rowHeaderWidth; + } + for (final GridColumn column2 : displayOrderedColumns) { + + if (!column2.isVisible()) { + continue; + } + + if (column2 == column) { + break; + } + + x += column2.getWidth(); + } + + return x; + } + + /** + * Returns the hscroll selection in pixels. This method abstracts away the + * differences between column by column scrolling and pixel based scrolling. + * + * @return the horizontal scroll selection in pixels + */ + private int getHScrollSelectionInPixels() { + int selection = hScroll.getSelection(); + if (columnScrolling) { + int pixels = 0; + for (int i = 0; i < selection; i++) { + final GridColumn gridColumn = displayOrderedColumns.get(i); + if (gridColumn.isVisible()) { + pixels += gridColumn.getWidth(); + } else if (selection < displayOrderedColumns.size() - 1) { + selection += 1; + } + } + selection = pixels; + } + return selection; + } + + /** + * Returns the size of the preferred size of the inner table. + * + * @return the preferred size of the table. + */ + private Point getTableSize() { + int x = 0; + int y = 0; + + if (columnHeadersVisible) { + y += headerHeight; + } + + if (columnFootersVisible) { + y += footerHeight; + } + + y += getGridHeight(); + + if (rowHeaderVisible) { + x += rowHeaderWidth; + } + + for (final GridColumn column : columns) { + if (column.isVisible()) { + x += column.getWidth(); + } + } + + return new Point(x, y); + } + + /** + * Manages the header column dragging and calculates the drop point, triggers a + * redraw. + * + * @param x + * mouse x + * @return true if this event has been consumed. + */ + private boolean handleColumnDragging(final int x) { + + GridColumn local_dragDropBeforeColumn = null; + GridColumn local_dragDropAfterColumn = null; + + int x2 = 1; + + if (rowHeaderVisible) { + x2 += rowHeaderWidth + 1; + } + + x2 -= getHScrollSelectionInPixels(); + + GridColumn previousVisibleCol = null; + boolean nextVisibleColumnIsBeforeCol = false; + GridColumn firstVisibleCol = null; + GridColumn lastVisibleCol = null; + + if (x < x2) { + for (final GridColumn column : displayOrderedColumns) { + if (!column.isVisible()) { + continue; + } + local_dragDropBeforeColumn = column; + break; + } + local_dragDropAfterColumn = null; + } else { + for (final GridColumn column : displayOrderedColumns) { + if (!column.isVisible()) { + continue; + } + + if (firstVisibleCol == null) { + firstVisibleCol = column; + } + lastVisibleCol = column; + + if (nextVisibleColumnIsBeforeCol) { + local_dragDropBeforeColumn = column; + nextVisibleColumnIsBeforeCol = false; + } + + if (x >= x2 && x <= x2 + column.getWidth()) { + if (x <= x2 + column.getWidth() / 2) { + local_dragDropBeforeColumn = column; + local_dragDropAfterColumn = previousVisibleCol; + } else { + local_dragDropAfterColumn = column; + + // the next visible column is the before col + nextVisibleColumnIsBeforeCol = true; + } + } + + x2 += column.getWidth(); + previousVisibleCol = column; + } + + if (local_dragDropBeforeColumn == null) { + local_dragDropAfterColumn = lastVisibleCol; + } + } + + currentHeaderDragX = x; + + if (local_dragDropBeforeColumn != dragDropBeforeColumn + || dragDropBeforeColumn == null && dragDropAfterColumn == null) { + dragDropPointValid = true; + + // Determine if valid drop point + if (columnGroups.length != 0) { + + if (columnBeingPushed.getColumnGroup() == null) { + if (local_dragDropBeforeColumn != null && local_dragDropAfterColumn != null + && local_dragDropBeforeColumn.getColumnGroup() != null && local_dragDropBeforeColumn + .getColumnGroup() == local_dragDropAfterColumn.getColumnGroup()) { + // Dont move a column w/o a group in between two columns + // in the same group + dragDropPointValid = false; + } + } else { + if (!(local_dragDropBeforeColumn != null + && local_dragDropBeforeColumn.getColumnGroup() == columnBeingPushed.getColumnGroup()) + && !(local_dragDropAfterColumn != null && local_dragDropAfterColumn + .getColumnGroup() == columnBeingPushed.getColumnGroup())) { + // Dont move a column with a group + dragDropPointValid = false; + } + } + } else { + dragDropPointValid = true; + } + } + + dragDropBeforeColumn = local_dragDropBeforeColumn; + dragDropAfterColumn = local_dragDropAfterColumn; + + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + + return true; + } + + /** + * Handles the moving of columns after a column is dropped. + */ + private void handleColumnDrop() { + draggingColumn = false; + + if (dragDropBeforeColumn != columnBeingPushed && dragDropAfterColumn != columnBeingPushed + && (columnGroups.length == 0 || dragDropPointValid)) { + + int notifyFrom = displayOrderedColumns.indexOf(columnBeingPushed); + int notifyTo = notifyFrom; + + displayOrderedColumns.remove(columnBeingPushed); + + if (dragDropBeforeColumn == null) { + + notifyTo = displayOrderedColumns.size(); + displayOrderedColumns.add(columnBeingPushed); + } else if (dragDropAfterColumn == null) { + displayOrderedColumns.add(0, columnBeingPushed); + notifyFrom = 0; + } else { + int insertAtIndex = 0; + + if (columnGroups.length != 0) { + // ensure that we aren't putting this column into a group, + // this is possible if + // there are invisible columns between the after and before + // cols + + if (dragDropBeforeColumn.getColumnGroup() == columnBeingPushed.getColumnGroup()) { + insertAtIndex = displayOrderedColumns.indexOf(dragDropBeforeColumn); + } else if (dragDropAfterColumn.getColumnGroup() == columnBeingPushed.getColumnGroup()) { + insertAtIndex = displayOrderedColumns.indexOf(dragDropAfterColumn) + 1; + } else { + if (dragDropBeforeColumn.getColumnGroup() == null) { + insertAtIndex = displayOrderedColumns.indexOf(dragDropBeforeColumn); + } else { + final GridColumnGroup beforeGroup = dragDropBeforeColumn.getColumnGroup(); + insertAtIndex = displayOrderedColumns.indexOf(dragDropBeforeColumn); + while (insertAtIndex > 0 + && displayOrderedColumns.get(insertAtIndex - 1).getColumnGroup() == beforeGroup) { + insertAtIndex--; + } + + } + } + } else { + insertAtIndex = displayOrderedColumns.indexOf(dragDropBeforeColumn); + } + displayOrderedColumns.add(insertAtIndex, columnBeingPushed); + notifyFrom = Math.min(notifyFrom, insertAtIndex); + notifyTo = Math.max(notifyTo, insertAtIndex); + } + + for (int i = notifyFrom; i <= notifyTo; i++) { + displayOrderedColumns.get(i).fireMoved(); + } + clearDisplayOrderedCache(); + } + redraw(); + } + + /** + * Determines if the mouse is pushing the header but has since move out of the + * header bounds and therefore should be drawn unpushed. Also initiates a column + * header drag when appropriate. + * + * @param x + * mouse x + * @param y + * mouse y + * @return true if this event has been consumed. + */ + private boolean handleColumnHeaderHoverWhilePushing(final int x, final int y) { + final GridColumn overThis = overColumnHeader(x, y); + + if (overThis == columnBeingPushed != pushingAndHovering) { + pushingAndHovering = overThis == columnBeingPushed; + redraw(); + } + if (columnBeingPushed.getMoveable()) { + + if (pushingAndHovering && Math.abs(startHeaderPushX - x) > 3) { + + // stop pushing + pushingColumn = false; + columnBeingPushed.getHeaderRenderer().setMouseDown(false); + columnBeingPushed.getHeaderRenderer().setHover(false); + + // now dragging + draggingColumn = true; + columnBeingPushed.getHeaderRenderer().setMouseDown(false); + + startHeaderDragX = x; + + dragDropAfterColumn = null; + dragDropBeforeColumn = null; + dragDropPointValid = true; + + handleColumnDragging(x); + } + } + + return true; + } + + /** + * Determines if a column group header has been clicked and forwards the event + * to the header renderer. + * + * @param x + * mouse x + * @param y + * mouse y + * @return true if this event has been consumed. + */ + private boolean handleColumnGroupHeaderClick(final int x, final int y) { + + if (!columnHeadersVisible) { + return false; + } + + final GridColumnGroup overThis = overColumnGroupHeader(x, y); + + if (overThis == null) { + return false; + } + + int headerX = 0; + if (rowHeaderVisible) { + headerX += rowHeaderWidth; + } + + int width = 0; + boolean firstCol = false; + + for (final GridColumn col : displayOrderedColumns) { + if (col.getColumnGroup() == overThis && col.isVisible()) { + firstCol = true; + width += col.getWidth(); + } + if (!firstCol && col.isVisible()) { + headerX += col.getWidth(); + } + } + + overThis.getHeaderRenderer().setBounds(headerX - getHScrollSelectionInPixels(), 0, width, groupHeaderHeight); + return overThis.getHeaderRenderer().notify(IInternalWidget.LeftMouseButtonDown, new Point(x, y), overThis); + } + + /** + * Determines if a column header has been clicked, updates the renderer state + * and triggers a redraw if necesary. + * + * @param x + * mouse x + * @param y + * mouse y + * @return true if this event has been consumed. + */ + private boolean handleColumnHeaderPush(final int x, final int y) { + if (!columnHeadersVisible) { + return false; + } + + final ScrollBar verticalBar = getVerticalBar(); + final boolean clickOnScrollBar = x >= getClientArea().width; + if (clickOnScrollBar && verticalBar != null && verticalBar.isVisible()) { + // Bug 273916 : if one clicks on the tooltip and the mouse is located on the + // scrollbar, simulate a click on the scrollbar + verticalBar.setSelection(verticalBar.getSelection() - verticalBar.getIncrement()); + } + + final GridColumn overThis = overColumnHeader(x, y); + if (overThis == null) { + return false; + } + + columnBeingPushed = overThis; + + // draw pushed + columnBeingPushed.getHeaderRenderer().setMouseDown(true); + columnBeingPushed.getHeaderRenderer().setHover(true); + pushingAndHovering = true; + redraw(); + + startHeaderPushX = x; + pushingColumn = true; + + setCapture(true); + + return true; + } + + private boolean handleColumnFooterPush(final int x, final int y) { + if (!columnFootersVisible) { + return false; + } + + return overColumnFooter(x, y) != null; + } + + /** + * Sets the new width of the column being resized and fires the appropriate + * listeners. + * + * @param x + * mouse x + */ + private void handleColumnResizerDragging(final int x) { + int newWidth = resizingColumnStartWidth + x - resizingStartX; + if (newWidth < MIN_COLUMN_HEADER_WIDTH) { + newWidth = MIN_COLUMN_HEADER_WIDTH; + } + + if (columnScrolling) { + int maxWidth = getClientArea().width; + if (rowHeaderVisible) { + maxWidth -= rowHeaderWidth; + } + if (newWidth > maxWidth) { + newWidth = maxWidth; + } + } + + if (newWidth == columnBeingResized.getWidth()) { + return; + } + + columnBeingResized.setWidth(newWidth, false); + scrollValuesObsolete = true; + + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + + columnBeingResized.fireResized(); + + fireColumnsMoved(); + } + + void fireColumnsMoved() { + for (int index = displayOrderedColumns.indexOf(columnBeingResized) + 1; index < displayOrderedColumns + .size(); index++) { + final GridColumn col = displayOrderedColumns.get(index); + if (col.isVisible()) { + col.fireMoved(); + } + } + } + + void handlePacked(final GridColumn column) { + int index = 0; + + if (getHorizontalBar() != null) { + if (!getHorizontalBar().isVisible()) { + index = displayOrderedColumns.indexOf(column); + } + } + + for (; index < displayOrderedColumns.size(); index++) { + final GridColumn col = displayOrderedColumns.get(index); + if (col.isVisible()) { + col.fireMoved(); + } + } + } + + /** + * Sets the new height of the item of the row being resized and fires the + * appropriate listeners. + * + * @param x + * mouse x + */ + private void handleRowResizerDragging(final int y) { + int newHeight = resizingRowStartHeight + y - resizingStartY; + if (newHeight < MIN_ROW_HEADER_HEIGHT) { + newHeight = MIN_ROW_HEADER_HEIGHT; + } + + if (newHeight > getClientArea().height) { + newHeight = getClientArea().height; + } + + if (rowBeingResized == null || newHeight == rowBeingResized.getHeight()) { + return; + } + + final Event e = new Event(); + e.item = rowBeingResized; + e.widget = this; + e.detail = newHeight; + + rowBeingResized.notifyListeners(SWT.Resize, e); + + if (e.doit == false) { + return; + } + + newHeight = e.detail; + + if (newHeight < MIN_ROW_HEADER_HEIGHT) { + newHeight = MIN_ROW_HEADER_HEIGHT; + } + + if (newHeight > getClientArea().height) { + newHeight = getClientArea().height; + } + + rowBeingResized.setHeight(newHeight); + scrollValuesObsolete = true; + + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + } + + /** + * Determines if the mouse is hovering on a column resizer and changes the + * pointer and sets field appropriately. + * + * @param x + * mouse x + * @param y + * mouse y + * @return true if this event has been consumed. + */ + private boolean handleHoverOnColumnResizer(final int x, final int y) { + boolean over = false; + if (y <= headerHeight) { + int x2 = 0; + + if (rowHeaderVisible) { + x2 += rowHeaderWidth; + } + + x2 -= getHScrollSelectionInPixels(); + + for (final GridColumn column : displayOrderedColumns) { + if (!column.isVisible()) { + continue; + } + x2 += column.getWidth(); + + if (x2 >= x - COLUMN_RESIZER_THRESHOLD && x2 <= x + COLUMN_RESIZER_THRESHOLD) { + if (column.getResizeable()) { + if (column.getColumnGroup() != null && y <= groupHeaderHeight) { + // if this is not the last column + if (column != column.getColumnGroup().getLastVisibleColumn()) { + break; + } + } + + over = true; + columnBeingResized = column; + } + break; + } + } + } + + if (over != hoveringOnColumnResizer) { + if (over) { + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_SIZEWE)); + } else { + columnBeingResized = null; + setCursor(null); + } + hoveringOnColumnResizer = over; + } + return over; + } + + /** + * Determines if the mouse is hovering on a row resizer and changes the pointer + * and sets field appropriately. + * + * @param x + * mouse x + * @param y + * mouse y + * @return true if this event has been consumed. + */ + private boolean handleHoverOnRowResizer(final int x, final int y) { + rowBeingResized = null; + boolean over = false; + if (x <= rowHeaderWidth) { + int y2 = 0; + + if (columnHeadersVisible) { + y2 += headerHeight; + } + + int row = getTopIndex(); + while (row < items.size() && y2 <= getClientArea().height) { + final GridItem currItem = items.get(row); + if (currItem.isVisible()) { + y2 += currItem.getHeight() + 1; + + if (y2 >= y - ROW_RESIZER_THRESHOLD && y2 <= y + ROW_RESIZER_THRESHOLD) { + // if (currItem.isResizeable()) + { + over = true; + rowBeingResized = currItem; + } + // do not brake here, because in case of overlapping + // row resizers we need to find the last one + } else { + if (rowBeingResized != null) { + // we have passed all (overlapping) row resizers, so break + break; + } + } + } + row++; + } + } + + if (over != hoveringOnRowResizer) { + if (over) { + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_SIZENS)); + } else { + rowBeingResized = null; + setCursor(null); + } + hoveringOnRowResizer = over; + } + return over; + } + + /** + * Returns the cell at the given point in the receiver or null if no such cell + * exists. The point is in the coordinate system of the receiver. + * + * @param point + * the point used to locate the item + * @return the cell at the given point + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the point is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public Point getCell(final Point point) { + checkWidget(); + + if (point == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (point.x < 0 || point.x > getClientArea().width) { + return null; + } + + final GridItem item = getItem(point); + final GridColumn column = getColumn(point); + + if (item != null && column != null) { + return new Point(column.index, item.getRowIndex()); + } + + return null; + } + + /** + * Paints. + * + * @param e + * paint event + */ + private void onPaint(final PaintEvent e) { + int insertMarkPosX1 = -1; // we will populate these values while drawing the cells + int insertMarkPosX2 = -1; + int insertMarkPosY = -1; + boolean insertMarkPosFound = false; + + final GridCellSpanManager cellSpanManager = new GridCellSpanManager(); + final Rectangle originalClipping = e.gc.getClipping(); + + e.gc.setBackground(getBackground()); + this.drawBackground(e.gc, 0, 0, getSize().x, getSize().y); + + if (scrollValuesObsolete) { + updateScrollbars(); + scrollValuesObsolete = false; + } + + int x = 0; + int y = 0; + + if (columnHeadersVisible) { + paintHeader(e.gc); + y += headerHeight; + } + + final Rectangle clientArea = getClientArea(); + final int availableHeight = clientArea.height - y; + int visibleRows = availableHeight / itemHeight + 1; + if (items.size() > 0 && availableHeight > 0) { + final RowRange range = getRowRange(getTopIndex(), availableHeight, false, false); + if (range.height >= availableHeight) { + visibleRows = range.rows; + } else { + visibleRows = range.rows + (availableHeight - range.height) / itemHeight + 1; + } + } + + final int firstVisibleIndex = getTopIndex(); + int firstItemToDraw = firstVisibleIndex; + + if (hasSpanning) { + // We need to find the first Item to draw. An earlier item can row-span the + // first visible item. + for (int rowIndex = 0; rowIndex < firstVisibleIndex && rowIndex < items.size(); rowIndex++) { + int colIndex = 0; + + int maxRowSpanForItem = 0; + for (final GridColumn column : displayOrderedColumns) { + + if (!column.isVisible()) { + colIndex++; + continue; + } + + final int rowSpan = items.get(rowIndex).getRowSpan(colIndex); + maxRowSpanForItem = rowSpan > maxRowSpanForItem ? rowSpan : maxRowSpanForItem; + colIndex++; + } + + if (rowIndex + maxRowSpanForItem >= firstVisibleIndex) { + firstItemToDraw = rowIndex; + break; + } else { + rowIndex += maxRowSpanForItem; + } + } + + for (int rowIndex = firstItemToDraw; rowIndex < firstVisibleIndex && rowIndex < items.size(); rowIndex++) { + final GridItem itemForRow = items.get(rowIndex); + if (itemForRow.isVisible()) { + y = y - itemForRow.getHeight() - 1; + } + } + } + + int row = firstItemToDraw; + + for (int i = 0; i < visibleRows + firstVisibleIndex - firstItemToDraw; i++) { + + x = 0; + + x -= getHScrollSelectionInPixels(); + + // get the item to draw + GridItem item = null; + if (row < items.size()) { + item = items.get(row); + + while (!item.isVisible() && row < items.size() - 1) { + row++; + item = items.get(row); + } + } + if (item != null && !item.isVisible()) { + item = null; + } + + if (item != null) { + boolean cellInRowSelected = false; + + if (rowHeaderVisible) { + + // row header is actually painted later + x += rowHeaderWidth; + } + + final int focusY = y; + + int colIndex = 0; + + // draw regular cells for each column + for (final GridColumn column : displayOrderedColumns) { + + final boolean skipCell = cellSpanManager.skipCell(colIndex, row); + final int indexOfColumn = column.index; + + if (!column.isVisible()) { + colIndex++; + if (skipCell) { + cellSpanManager.consumeCell(colIndex, row); + } + continue; + } + + final int width = item.getCellSize(indexOfColumn).x; + + if (skipCell == false) { + + final int nrRowsToSpan = item.getRowSpan(indexOfColumn); + final int nrColumnsToSpan = item.getColumnSpan(indexOfColumn); + + if (nrRowsToSpan > 0 || nrColumnsToSpan > 0) { + cellSpanManager.addCellSpanInfo(colIndex, row, nrColumnsToSpan, nrRowsToSpan); + } + + if (x + width >= 0 && x < clientArea.width) { + final Point sizeOfColumn = item.getCellSize(indexOfColumn); + + column.getCellRenderer().setBounds(x, y, width, sizeOfColumn.y); + final int cellInHeaderDelta = columnHeadersVisible ? headerHeight - y : 0; + if (cellInHeaderDelta > 0) { + final Rectangle cellRect = new Rectangle(x - 1, y + cellInHeaderDelta, width + 1, + sizeOfColumn.y + 2 - cellInHeaderDelta); + e.gc.setClipping(originalClipping.intersection(cellRect)); + } else { + final Rectangle cellRect = new Rectangle(x - 1, y - 1, width + 1, sizeOfColumn.y + 2); + e.gc.setClipping(originalClipping.intersection(cellRect)); + } + + column.getCellRenderer().setRow(i + 1); + + column.getCellRenderer().setSelected(selectedItems.contains(item)); + column.getCellRenderer().setFocus(isFocusControl()); + column.getCellRenderer().setRowFocus(focusItem == item); + column.getCellRenderer() + .setCellFocus(cellSelectionEnabled && focusItem == item && focusColumn == column); + + column.getCellRenderer().setRowHover(hoveringItem == item); + column.getCellRenderer().setColumnHover(hoveringColumn == column); + + column.getCellRenderer().setColumn(indexOfColumn); + + if (selectedCells.contains(new Point(indexOfColumn, row))) { + column.getCellRenderer().setCellSelected(true); + cellInRowSelected = true; + } else { + column.getCellRenderer().setCellSelected(false); + } + + if (hoveringItem == item && hoveringColumn == column) { + column.getCellRenderer().setHoverDetail(hoveringDetail); + } else { + column.getCellRenderer().setHoverDetail(""); + } + + column.getCellRenderer().paint(e.gc, item); + + e.gc.setClipping((Rectangle) null); + + // collect the insertMark position + if (!insertMarkPosFound && insertMarkItem == item + && (insertMarkColumn == null || insertMarkColumn == column)) { + // y-pos + insertMarkPosY = y - 1; + if (!insertMarkBefore) { + insertMarkPosY += item.getHeight() + 1; + } + // x1-pos + insertMarkPosX1 = x; + if (column.isTree()) { + insertMarkPosX1 += Math.min(width, + column.getCellRenderer().getTextBounds(item, false).x); + } + + // x2-pos + if (insertMarkColumn == null) { + insertMarkPosX2 = clientArea.x + clientArea.width; + } else { + insertMarkPosX2 = x + width; + } + + insertMarkPosFound = true; + } + } + } else { + cellSpanManager.consumeCell(colIndex, row); + } + if(x > clientArea.width) { + break; + } + x += column.getWidth(); + colIndex++; + + } + + if (x < clientArea.width) { + // insertMarkPos needs correction + if (insertMarkPosFound && insertMarkColumn == null) { + insertMarkPosX2 = x; + } + + emptyCellRenderer.setSelected(selectedItems.contains(item)); + emptyCellRenderer.setFocus(isFocusControl()); + emptyCellRenderer.setRow(i + 1); + emptyCellRenderer.setBounds(x, y, clientArea.width - x + 1, item.getHeight()); + emptyCellRenderer.setColumn(getColumnCount()); + emptyCellRenderer.paint(e.gc, item); + } + + x = 0; + + if (rowHeaderVisible) { + + if (!cellSelectionEnabled) { + rowHeaderRenderer.setSelected(selectedItems.contains(item)); + } else { + rowHeaderRenderer.setSelected(cellInRowSelected); + } + if (!columnHeadersVisible || y >= headerHeight) { + rowHeaderRenderer.setBounds(0, y, rowHeaderWidth, item.getHeight() + 1); + rowHeaderRenderer.paint(e.gc, item); + } + x += rowHeaderWidth; + } + + // focus + if (isFocusControl() && !cellSelectionEnabled) { + if (item == focusItem) { + if (focusRenderer != null) { + int focusX = 0; + if (rowHeaderVisible) { + focusX = rowHeaderWidth; + } + focusRenderer.setBounds(focusX, focusY - 1, clientArea.width - focusX - 1, + item.getHeight() + 1); + focusRenderer.paint(e.gc, item); + } + } + } + + y += item.getHeight() + 1; + } else { + + if (rowHeaderVisible) { + // row header is actually painted later + x += rowHeaderWidth; + } + + emptyCellRenderer.setBounds(x, y, clientArea.width - x, itemHeight); + emptyCellRenderer.setFocus(false); + emptyCellRenderer.setSelected(false); + emptyCellRenderer.setRow(i + 1); + + for (final GridColumn column : displayOrderedColumns) { + + if (column.isVisible()) { + final int width = column.width; + if(x + width >= 0) { + emptyCellRenderer.setBounds(x, y, width, itemHeight); + emptyCellRenderer.setColumn(column.index); + emptyCellRenderer.paint(e.gc, this); + } + if(x > clientArea.width) { + break; + } + x += width; + } + } + + if (x < clientArea.width) { + emptyCellRenderer.setBounds(x, y, clientArea.width - x + 1, itemHeight); + emptyCellRenderer.setColumn(getColumnCount()); + emptyCellRenderer.paint(e.gc, this); + } + + x = 0; + + if (rowHeaderVisible) { + emptyRowHeaderRenderer.setBounds(x, y, rowHeaderWidth, itemHeight + 1); + emptyRowHeaderRenderer.paint(e.gc, this); + + x += rowHeaderWidth; + } + + y += itemHeight + 1; + } + + row++; + } + + // draw drop point + if (draggingColumn) { + if ((dragDropAfterColumn != null || dragDropBeforeColumn != null) + && dragDropAfterColumn != columnBeingPushed && dragDropBeforeColumn != columnBeingPushed + && dragDropPointValid) { + if (dragDropBeforeColumn != null) { + x = getColumnHeaderXPosition(dragDropBeforeColumn); + } else { + x = getColumnHeaderXPosition(dragDropAfterColumn) + dragDropAfterColumn.getWidth(); + } + + final Point size = dropPointRenderer.computeSize(e.gc, SWT.DEFAULT, SWT.DEFAULT, null); + x -= size.x / 2; + if (x < 0) { + x = 0; + } + dropPointRenderer.setBounds(x - 1, headerHeight + DROP_POINT_LOWER_OFFSET, size.x, size.y); + dropPointRenderer.paint(e.gc, null); + } + } + + // draw insertion mark + if (insertMarkPosFound) { + final Rectangle rect = new Rectangle(rowHeaderVisible ? rowHeaderWidth : 0, columnHeadersVisible ? headerHeight : 0, + clientArea.width, clientArea.height); + e.gc.setClipping(originalClipping.intersection(rect)); + insertMarkRenderer.paint(e.gc, + new Rectangle(insertMarkPosX1, insertMarkPosY, insertMarkPosX2 - insertMarkPosX1, 0)); + } + + if (columnFootersVisible) { + paintFooter(e.gc); + } + } + + /** + * Returns a column reference if the x,y coordinates are over a column header + * (header only). + * + * @param x + * mouse x + * @param y + * mouse y + * @return column reference which mouse is over, or null. + */ + private GridColumn overColumnHeader(final int x, final int y) { + GridColumn col = null; + + if (y <= headerHeight && y > 0) { + col = getColumn(new Point(x, y)); + if (col != null && col.getColumnGroup() != null) { + if (y <= groupHeaderHeight) { + return null; + } + } + } + + return col; + } + + /** + * Returns a column reference if the x,y coordinates are over a column header + * (header only). + * + * @param x + * mouse x + * @param y + * mouse y + * @return column reference which mouse is over, or null. + */ + private GridColumn overColumnFooter(final int x, final int y) { + if (y >= getClientArea().height - footerHeight) { + return getColumn(new Point(x, y)); + } + + return null; + } + + /** + * Returns a column group reference if the x,y coordinates are over a column + * group header (header only). + * + * @param x + * mouse x + * @param y + * mouse y + * @return column group reference which mouse is over, or null. + */ + private GridColumnGroup overColumnGroupHeader(final int x, final int y) { + GridColumnGroup group = null; + + if (y <= groupHeaderHeight && y > 0) { + final GridColumn col = getColumn(new Point(x, y)); + if (col != null) { + group = col.getColumnGroup(); + } + } + + return group; + } + + /** + * Paints the header. + * + * @param gc + * gc from paint event + */ + private void paintHeader(final GC gc) { + int x = 0; + int y = 0; + + x -= getHScrollSelectionInPixels(); + + if (rowHeaderVisible) { + // paint left corner + // topLeftRenderer.setBounds(0, y, rowHeaderWidth, headerHeight); + // topLeftRenderer.paint(gc, null); + x += rowHeaderWidth; + } + + GridColumnGroup previousPaintedGroup = null; + + for (final GridColumn column : displayOrderedColumns) { + if (x > getClientArea().width) { + break; + } + + int height = 0; + + if (!column.isVisible()) { + continue; + } + + if (column.getColumnGroup() != null) { + + if (column.getColumnGroup() != previousPaintedGroup) { + int width = column.getWidth(); + + GridColumn nextCol = null; + if (displayOrderedColumns.indexOf(column) + 1 < displayOrderedColumns.size()) { + nextCol = displayOrderedColumns.get(displayOrderedColumns.indexOf(column) + 1); + } + + while (nextCol != null && nextCol.getColumnGroup() == column.getColumnGroup()) { + + if (nextCol.getColumnGroup().getExpanded() && !nextCol.isDetail() + || !nextCol.getColumnGroup().getExpanded() && !nextCol.isSummary()) { + } else if (nextCol.isVisible()) { + width += nextCol.getWidth(); + } + + if (displayOrderedColumns.indexOf(nextCol) + 1 < displayOrderedColumns.size()) { + nextCol = displayOrderedColumns.get(displayOrderedColumns.indexOf(nextCol) + 1); + } else { + nextCol = null; + } + } + + boolean selected = true; + + for (int i = 0; i < column.getColumnGroup().getColumns().length; i++) { + final GridColumn col = column.getColumnGroup().getColumns()[i]; + if (col.isVisible() && (column.getMoveable() || !selectedColumns.contains(col))) { + selected = false; + break; + } + } + + column.getColumnGroup().getHeaderRenderer().setSelected(selected); + column.getColumnGroup().getHeaderRenderer() + .setHover(hoverColumnGroupHeader == column.getColumnGroup()); + column.getColumnGroup().getHeaderRenderer().setHoverDetail(hoveringDetail); + + column.getColumnGroup().getHeaderRenderer().setBounds(x, 0, width, groupHeaderHeight); + + column.getColumnGroup().getHeaderRenderer().paint(gc, column.getColumnGroup()); + + previousPaintedGroup = column.getColumnGroup(); + } + + height = headerHeight - groupHeaderHeight; + y = groupHeaderHeight; + } else { + height = headerHeight; + y = 0; + } + + if (pushingColumn) { + column.getHeaderRenderer().setHover(columnBeingPushed == column && pushingAndHovering); + } else { + column.getHeaderRenderer().setHover(hoveringColumnHeader == column); + } + + column.getHeaderRenderer().setHoverDetail(hoveringDetail); + + column.getHeaderRenderer().setBounds(x, y, column.getWidth(), height); + + if (cellSelectionEnabled) { + column.getHeaderRenderer().setSelected(selectedColumns.contains(column)); + } + + if (x + column.getWidth() >= 0) { + column.getHeaderRenderer().paint(gc, column); + } + + x += column.getWidth(); + } + + if (x < getClientArea().width) { + emptyColumnHeaderRenderer.setBounds(x, 0, getClientArea().width - x, headerHeight); + emptyColumnHeaderRenderer.paint(gc, null); + } + + x = 0; + + if (rowHeaderVisible) { + // paint left corner + topLeftRenderer.setBounds(0, 0, rowHeaderWidth, headerHeight); + topLeftRenderer.paint(gc, this); + x += rowHeaderWidth; + } + + if (draggingColumn) { + + gc.setAlpha(COLUMN_DRAG_ALPHA); + + columnBeingPushed.getHeaderRenderer().setSelected(false); + + int height = 0; + + if (columnBeingPushed.getColumnGroup() != null) { + height = headerHeight - groupHeaderHeight; + y = groupHeaderHeight; + } else { + height = headerHeight; + y = 0; + } + + columnBeingPushed.getHeaderRenderer().setBounds( + getColumnHeaderXPosition(columnBeingPushed) + currentHeaderDragX - startHeaderDragX, y, + columnBeingPushed.getWidth(), height); + columnBeingPushed.getHeaderRenderer().paint(gc, columnBeingPushed); + columnBeingPushed.getHeaderRenderer().setSelected(false); + + gc.setAlpha(-1); + gc.setAdvanced(false); + } + + } + + private void paintFooter(final GC gc) { + int x = 0; + int y = 0; + + x -= getHScrollSelectionInPixels(); + + if (rowHeaderVisible) { + // paint left corner + // topLeftRenderer.setBounds(0, y, rowHeaderWidth, headerHeight); + // topLeftRenderer.paint(gc, null); + x += rowHeaderWidth; + } + + for (final GridColumn column : displayOrderedColumns) { + if (x > getClientArea().width) { + break; + } + + int height = 0; + + if (!column.isVisible()) { + continue; + } + + height = footerHeight; + y = getClientArea().height - height; + + column.getFooterRenderer().setBounds(x, y, column.getWidth(), height); + if (x + column.getWidth() >= 0) { + column.getFooterRenderer().paint(gc, column); + } + + x += column.getWidth(); + } + + if (x < getClientArea().width) { + emptyColumnFooterRenderer.setBounds(x, getClientArea().height - footerHeight, getClientArea().width - x, + footerHeight); + emptyColumnFooterRenderer.paint(gc, null); + } + + if (rowHeaderVisible) { + // paint left corner + bottomLeftRenderer.setBounds(0, getClientArea().height - footerHeight, rowHeaderWidth, footerHeight); + bottomLeftRenderer.paint(gc, this); + x += rowHeaderWidth; + } + } + + /** + * Manages the state of the scrollbars when new items are added or the bounds + * are changed. + */ + private void updateScrollbars() { + final Point preferredSize = getTableSize(); + + Rectangle clientArea = getClientArea(); + + // First, figure out if the scrollbars should be visible and turn them + // on right away + // this will allow the computations further down to accommodate the + // correct client + // area + + // Turn the scrollbars on if necessary and do it all over again if + // necessary. This ensures + // that if a scrollbar is turned on/off, the other scrollbar's + // visibility may be affected (more + // area may have been added/removed. + for (int doublePass = 1; doublePass <= 2; doublePass++) { + + if (preferredSize.y > clientArea.height) { + vScroll.setVisible(true); + } else { + vScroll.setVisible(false); + vScroll.setValues(0, 0, 1, 1, 1, 1); + } + if (preferredSize.x > clientArea.width) { + hScroll.setVisible(true); + } else { + hScroll.setVisible(false); + hScroll.setValues(0, 0, 1, 1, 1, 1); + } + + // get the clientArea again with the now visible/invisible + // scrollbars + clientArea = getClientArea(); + } + + // if the scrollbar is visible set its values + if (vScroll.getVisible()) { + int max = currentVisibleItems; + int thumb = 1; + + if (!hasDifferingHeights) { + // in this case, the number of visible rows on screen is constant, + // so use this as thumb + thumb = (getVisibleGridHeight() + 1) / (itemHeight + 1); + } else { + // in this case, the number of visible rows on screen is variable, + // so we have to use 1 as thumb and decrease max by the number of + // rows on the last page + if (getVisibleGridHeight() >= 1) { + final RowRange range = getRowRange(-1, getVisibleGridHeight(), true, true); + max -= range.rows - 1; + } + } + + // if possible, remember selection, if selection is too large, just + // make it the max you can + final int selection = Math.min(vScroll.getSelection(), max); + + vScroll.setValues(selection, 0, max, thumb, 1, thumb); + } + + // if the scrollbar is visible set its values + if (hScroll.getVisible()) { + + if (!columnScrolling) { + // horizontal scrolling works pixel by pixel + + final int hiddenArea = preferredSize.x - clientArea.width + 1; + + // if possible, remember selection, if selection is too large, + // just + // make it the max you can + final int selection = Math.min(hScroll.getSelection(), hiddenArea - 1); + + hScroll.setValues(selection, 0, hiddenArea + clientArea.width - 1, clientArea.width, + HORZ_SCROLL_INCREMENT, clientArea.width); + } else { + // horizontal scrolling is column by column + + int hiddenArea = preferredSize.x - clientArea.width + 1; + + int max = 0; + int i = 0; + + while (hiddenArea > 0 && i < getColumnCount()) { + final GridColumn col = displayOrderedColumns.get(i); + + i++; + + if (col.isVisible()) { + hiddenArea -= col.getWidth(); + max++; + } + } + + max++; + + // max should never be greater than the number of visible cols + int visCols = 0; + for (final GridColumn element : columns) { + if (element.isVisible()) { + visCols++; + } + } + max = Math.min(visCols, max); + + // if possible, remember selection, if selection is too large, + // just + // make it the max you can + final int selection = Math.min(hScroll.getSelection(), max); + + hScroll.setValues(selection, 0, max, 1, 1, 1); + } + } + + } + + /** + * Adds/removes items from the selected items list based on the + * selection/deselection of the given item. + * + * @param item + * item being selected/unselected + * @param stateMask + * key state during selection + * + * @return selection event that needs to be fired or null + */ + private Event updateSelection(final GridItem item, final int stateMask) { + if (!selectionEnabled) { + return null; + } + + Event selectionEvent = null; + + if (selectionType == GridSelectionType.SINGLE) { + if (selectedItems.contains(item)) { + // Deselect when pressing CTRL + if ((stateMask & SWT.MOD1) == SWT.MOD1) { + selectedItems.clear(); + } + } else { + selectedItems.clear(); + selectedItems.add(item); + } + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + + selectionEvent = new Event(); + selectionEvent.item = item; + } else if (selectionType == GridSelectionType.MULTI) { + boolean shift = false; + boolean ctrl = false; + + if ((stateMask & SWT.MOD2) == SWT.MOD2) { + shift = true; + } + + if ((stateMask & SWT.MOD1) == SWT.MOD1) { + ctrl = true; + } + + if (!shift && !ctrl) { + if (selectedItems.size() == 1 && selectedItems.contains(item)) { + return null; + } + + selectedItems.clear(); + + selectedItems.add(item); + + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + + shiftSelectionAnchorItem = null; + + selectionEvent = new Event(); + selectionEvent.item = item; + } else if (shift) { + + if (shiftSelectionAnchorItem == null) { + shiftSelectionAnchorItem = focusItem; + } + + // if (shiftSelectionAnchorItem == item) + // { + // return; + // } + + boolean maintainAnchorSelection = false; + + if (!ctrl) { + if (selectedItems.contains(shiftSelectionAnchorItem)) { + maintainAnchorSelection = true; + } + selectedItems.clear(); + } + + final int anchorIndex = items.indexOf(shiftSelectionAnchorItem); + final int itemIndex = item.getRowIndex(); + + int min = 0; + int max = 0; + + if (anchorIndex < itemIndex) { + if (maintainAnchorSelection) { + min = anchorIndex; + } else { + min = anchorIndex + 1; + } + max = itemIndex; + } else { + if (maintainAnchorSelection) { + max = anchorIndex; + } else { + max = anchorIndex - 1; + } + min = itemIndex; + } + + for (int i = min; i <= max; i++) { + if (!selectedItems.contains(items.get(i)) && items.get(i).isVisible()) { + selectedItems.add(items.get(i)); + } + } + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + + selectionEvent = new Event(); + } else if (ctrl) { + if (selectedItems.contains(item)) { + selectedItems.remove(item); + } else { + selectedItems.add(item); + } + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + + shiftSelectionAnchorItem = null; + + selectionEvent = new Event(); + selectionEvent.item = item; + } + } + + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + + return selectionEvent; + } + + /** + * Updates cell selection. + * + * @param newCell + * newly clicked, navigated to cell. + * @param stateMask + * statemask during preceeding mouse or key event. + * @param dragging + * true if the user is dragging. + * @param reverseDuplicateSelections + * true if the user is reversing selection rather than adding to. + * + * @return selection event that will need to be fired or null. + */ + private Event updateCellSelection(final Point newCell, final int stateMask, final boolean dragging, + final boolean reverseDuplicateSelections) { + final Vector v = new Vector<>(); + v.add(newCell); + return updateCellSelection(v, stateMask, dragging, reverseDuplicateSelections); + } + + /** + * Updates cell selection. + * + * @param newCell + * newly clicked, navigated to cells. + * @param stateMask + * statemask during preceeding mouse or key event. + * @param dragging + * true if the user is dragging. + * @param reverseDuplicateSelections + * true if the user is reversing selection rather than adding to. + * + * @return selection event that will need to be fired or null. + */ + private Event updateCellSelection(final Vector newCells, final int stateMask, final boolean dragging, + final boolean reverseDuplicateSelections) { + boolean shift = false; + boolean ctrl = false; + + if ((stateMask & SWT.MOD2) == SWT.MOD2) { + shift = true; + } else { + shiftSelectionAnchorColumn = null; + shiftSelectionAnchorItem = null; + } + + if ((stateMask & SWT.MOD1) == SWT.MOD1) { + ctrl = true; + } + + if (!shift && !ctrl) { + if (newCells.equals(selectedCells)) { + return null; + } + + selectedCells.clear(); + for (final Point newCell : newCells) { + addToCellSelection(newCell); + } + + } else if (shift) { + + final Point newCell = newCells.get(0); // shift selection should only occur with one + // cell, ignoring others + + if (focusColumn == null || focusItem == null) { + return null; + } + + shiftSelectionAnchorColumn = getColumn(newCell.x); + shiftSelectionAnchorItem = getItem(newCell.y); + + if (ctrl) { + selectedCells.clear(); + addCellstThatDoNotAlreadyExist(selectedCells, selectedCellsBeforeRangeSelect); + } else { + selectedCells.clear(); + } + + GridColumn currentColumn = focusColumn; + GridItem currentItem = focusItem; + + GridColumn endColumn = getColumn(newCell.x); + GridItem endItem = getItem(newCell.y); + + final Point newRange = getSelectionRange(currentItem, currentColumn, endItem, endColumn); + + currentColumn = getColumn(newRange.x); + endColumn = getColumn(newRange.y); + + final GridColumn startCol = currentColumn; + + if (currentItem.getRowIndex() > endItem.getRowIndex()) { + final GridItem temp = currentItem; + currentItem = endItem; + endItem = temp; + } + + boolean firstLoop = true; + + do { + if (!firstLoop) { + currentItem = getNextVisibleItem(currentItem); + } + + firstLoop = false; + + boolean firstLoop2 = true; + + currentColumn = startCol; + + do { + if (!firstLoop2) { + final int index = displayOrderedColumns.indexOf(currentColumn) + 1; + + if (index < displayOrderedColumns.size()) { + currentColumn = getVisibleColumn_DegradeRight(currentItem, + displayOrderedColumns.get(index)); + } else { + currentColumn = null; + } + + if (currentColumn != null) { + if (displayOrderedColumns.indexOf(currentColumn) > displayOrderedColumns + .indexOf(endColumn)) { + currentColumn = null; + } + } + } + + firstLoop2 = false; + + if (currentColumn != null) { + final Point cell = new Point(currentColumn.index, currentItem.getRowIndex()); + addToCellSelection(cell); + } + } while (currentColumn != endColumn && currentColumn != null); + } while (currentItem != endItem); + } else if (ctrl) { + boolean reverse = reverseDuplicateSelections; + if (!selectedCells.containsAll(newCells)) { + reverse = false; + } + + if (dragging) { + selectedCells.clear(); + addCellstThatDoNotAlreadyExist(selectedCells, selectedCellsBeforeRangeSelect); + } + + if (reverse) { + selectedCells.removeAll(newCells); + } else { + for (final Point newCell : newCells) { + addToCellSelection(newCell); + } + } + } + + updateColumnSelection(); + + final Event e = new Event(); + if (dragging) { + e.detail = SWT.DRAG; + followupCellSelectionEventOwed = true; + } + + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + + return e; + } + + /** + * Adds Point objects from the itemsToBeAdded list that do not currently exist + * in the sourceList. + * + * @param sourceList + * @param itemsToBeAdded + */ + private void addCellstThatDoNotAlreadyExist(final List sourceList, final List itemsToBeAdded) { + if (itemsToBeAdded.size() > 0) { + // add all the cells from the itemsToBeAdded list that don't already exist in + // the sourceList + for (final Point cell : itemsToBeAdded) { + if (!sourceList.contains(cell)) { + sourceList.add(cell); + } + + } + } + } + + private void addToCellSelection(final Point newCell) { + if (newCell.x < 0 || newCell.x >= columns.size()) { + return; + } + + if (newCell.y < 0 || newCell.y >= items.size()) { + return; + } + + if (getColumn(newCell.x).getCellSelectionEnabled()) { + final Iterator it = selectedCells.iterator(); + boolean found = false; + while (it.hasNext()) { + final Point p = it.next(); + if (newCell.equals(p)) { + found = true; + break; + } + } + + if (!found) { + if (selectionType == GridSelectionType.SINGLE && selectedCells.size() > 0) { + return; + } + selectedCells.add(newCell); + } + } + } + + void updateColumnSelection() { + // Update the list of which columns have all their cells selected + selectedColumns.clear(); + + for (final Point cell : selectedCells) { + selectedColumns.add(getColumn(cell.x)); + } + } + + /** + * Initialize all listeners. + */ + private void initListeners() { + disposeListener = this::onDispose; + addListener(SWT.Dispose, disposeListener); + + addPaintListener(this::onPaint); + + addListener(SWT.Resize, e -> onResize()); + + if (getVerticalBar() != null) { + getVerticalBar().addListener(SWT.Selection, e -> onScrollSelection()); + } + + if (getHorizontalBar() != null) { + getHorizontalBar().addListener(SWT.Selection, e -> onScrollSelection()); + } + + defaultKeyListener = this::onKeyDown; + addListener(SWT.KeyDown, defaultKeyListener); + + addTraverseListener(e -> { + if (moveOnTab) { + e.doit = false; + if (selectedItems.isEmpty()) { + select(0); + return; + } + if (selectedItems.size() == 1) { + final int index = getSelectionIndex(); + if (SWT.TRAVERSE_TAB_NEXT == e.detail) { + select(index == getItemCount() - 1 ? 0 : index + 1); + } else if (SWT.TRAVERSE_TAB_PREVIOUS == e.detail) { + select(index == 0 ? getItemCount() - 1 : index - 1); + } + return; + } + return; + } else { + e.doit = true; + } + }); + + addListener(SWT.MouseDoubleClick, this::onMouseDoubleClick); + addListener(SWT.MouseDown, this::onMouseDown); + addListener(SWT.MouseUp, this::onMouseUp); + + addMouseMoveListener(this::onMouseMove); + + addMouseTrackListener(new MouseTrackListener() { + @Override + public void mouseEnter(final MouseEvent e) { + } + + @Override + public void mouseExit(final MouseEvent e) { + onMouseExit(e); + } + + @Override + public void mouseHover(final MouseEvent e) { + } + }); + + addFocusListener(new FocusListener() { + @Override + public void focusGained(final FocusEvent e) { + onFocusIn(); + redraw(); + } + + @Override + public void focusLost(final FocusEvent e) { + redraw(); + } + }); + + // Special code to reflect mouse wheel events if using an external + // scroller + addListener(SWT.MouseWheel, this::onMouseWheel); + } + + /** + * Disable default key listener + */ + public void disableDefaultKeyListener() { + if (defaultKeyListenerEnabled) { + removeListener(SWT.KeyDown, defaultKeyListener); + } + defaultKeyListenerEnabled = false; + } + + /** + * Enable default key listener + */ + public void enableDefaultKeyListener() { + if (!defaultKeyListenerEnabled) { + addListener(SWT.KeyDown, defaultKeyListener); + } + defaultKeyListenerEnabled = true; + } + + private void onFocusIn() { + if (!items.isEmpty() && focusItem == null) { + focusItem = items.get(0); + } + } + + private void onDispose(final Event event) { + // We only want to dispose of our items and such *after* anybody else who may + // have been + // listening to the dispose has had a chance to do whatever. + removeListener(SWT.Dispose, disposeListener); + notifyListeners(SWT.Dispose, event); + event.type = SWT.None; + + disposing = true; + + cellHeaderSelectionBackground.dispose(); + + for (final GridItem item : items) { + item.dispose(); + } + + for (final GridColumnGroup columnGroup : columnGroups) { + columnGroup.dispose(); + } + + for (final GridColumn col : columns) { + col.dispose(); + } + } + + /** + * Mouse wheel event handler. + * + * @param e + * event + */ + private void onMouseWheel(final Event e) { + if (vScroll.getVisible()) { + vScroll.handleMouseWheel(e); + if (getVerticalBar() == null) { + e.doit = false; + } + } else if (hScroll.getVisible()) { + hScroll.handleMouseWheel(e); + if (getHorizontalBar() == null) { + e.doit = false; + } + } + } + + /** + * Mouse down event handler. + * + * @param e + * event + */ + private void onMouseDown(final Event e) { + // for some reason, SWT prefers the children to get focus if + // there are any children + // the setFocus method on Composite will not set focus to the + // Composite if one of its + // children can get focus instead. This only affects the table + // when an editor is open + // and therefore the table has a child. The solution is to + // forceFocus() + if ((getStyle() & SWT.NO_FOCUS) != SWT.NO_FOCUS) { + forceFocus(); + } + + hideToolTip(); + + // if populated will be fired at end of method. + Event selectionEvent = null; + + cellSelectedOnLastMouseDown = false; + cellRowSelectedOnLastMouseDown = false; + cellColumnSelectedOnLastMouseDown = false; + + if (hoveringOnColumnResizer) { + if (e.button == 1) { + resizingColumn = true; + resizingStartX = e.x; + resizingColumnStartWidth = columnBeingResized.getWidth(); + } + return; + } + if (rowsResizeable && hoveringOnRowResizer) { + if (e.button == 1) { + resizingRow = true; + resizingStartY = e.y; + resizingRowStartHeight = rowBeingResized.getHeight(); + } + return; + } + + if (e.button == 1 && handleColumnHeaderPush(e.x, e.y)) { + return; + } + + if (e.button == 1 && handleColumnGroupHeaderClick(e.x, e.y)) { + return; + } + + if (e.button == 1 && handleColumnFooterPush(e.x, e.y)) { + return; + } + + final GridItem item = getItem(new Point(e.x, e.y)); + + if (e.button == 1 && item != null && handleCellClick(item, e.x, e.y)) { + return; + } + + if (isListening(SWT.DragDetect)) { + if (cellSelectionEnabled && hoveringOnSelectionDragArea + || !cellSelectionEnabled && item != null && selectedItems.contains(item)) { + if (dragDetect(e)) { + return; + } + } + } + + if (item != null) { + if (cellSelectionEnabled) { + final GridColumn col = getColumn(new Point(e.x, e.y)); + boolean isSelectedCell = false; + if (col != null) { + isSelectedCell = selectedCells.contains(new Point(col.index, item.getRowIndex())); + } + + if (e.button == 1 || e.button == 3 && col != null && !isSelectedCell) { + if (col != null) { + selectionEvent = updateCellSelection(new Point(col.index, item.getRowIndex()), e.stateMask, + false, true); + cellSelectedOnLastMouseDown = getCellSelectionCount() > 0; + + if (e.stateMask != SWT.MOD2) { + focusColumn = col; + focusItem = item; + } + // showColumn(col); + showItem(item); + redraw(); + } else if (rowHeaderVisible) { + if (e.x <= rowHeaderWidth) { + + final boolean shift = (e.stateMask & SWT.MOD2) != 0; + boolean ctrl = false; + if (!shift) { + ctrl = (e.stateMask & SWT.MOD1) != 0; + } + + final Vector cells = new Vector<>(); + + if (shift) { + getCells(item, focusItem, cells); + } else { + getCells(item, cells); + } + + int newStateMask = SWT.NONE; + if (ctrl) { + newStateMask = SWT.MOD1; + } + + selectionEvent = updateCellSelection(cells, newStateMask, shift, ctrl); + cellRowSelectedOnLastMouseDown = getCellSelectionCount() > 0; + + if (!shift) { + // set focus back to the first visible column + focusColumn = getColumn(new Point(rowHeaderWidth + 1, e.y)); + + focusItem = item; + } + showItem(item); + redraw(); + } + } + intendedFocusColumn = focusColumn; + } + } else { + if (e.button == 2 || e.button > 3) { + return; + } + + if (e.button == 3 && selectionType == GridSelectionType.MULTI) { + if ((e.stateMask & SWT.MOD2) == SWT.MOD2) { + return; + } + + if ((e.stateMask & SWT.MOD1) == SWT.MOD1) { + return; + } + + if (selectedItems.contains(item)) { + return; + } + } + selectionEvent = updateSelection(item, e.stateMask); + + focusItem = item; + showItem(item); + redraw(); + } + } else if (e.button == 1 && rowHeaderVisible && e.x <= rowHeaderWidth && e.y < headerHeight) { + // Nothing to select + if (items.size() == 0) { + return; + } + if (cellSelectionEnabled) { + // click on the top left corner means select everything + selectionEvent = selectAllCellsInternal(); + + focusColumn = getColumn(new Point(rowHeaderWidth + 1, 1)); + } else { + // click on the top left corner means select everything + selectionEvent = selectAllRowsInternal(); + } + focusItem = getItem(getTopIndex()); + } else if (cellSelectionEnabled && e.button == 1 && columnHeadersVisible && e.y <= headerHeight) { + // column cell selection + final GridColumn col = getColumn(new Point(e.x, e.y)); + + if (col == null) { + return; + } + + if (getItemCount() == 0) { + return; + } + + final Vector cells = new Vector<>(); + + final GridColumnGroup group = col.getColumnGroup(); + if (group != null && e.y < groupHeaderHeight) { + getCells(group, cells); + } else { + getCells(col, cells); + } + + selectionEvent = updateCellSelection(cells, e.stateMask, false, true); + cellColumnSelectedOnLastMouseDown = getCellSelectionCount() > 0; + + GridItem newFocusItem = getItem(0); + + while (newFocusItem != null && getSpanningColumn(newFocusItem, col) != null) { + newFocusItem = getNextVisibleItem(newFocusItem); + } + + if (newFocusItem != null) { + focusColumn = col; + focusItem = newFocusItem; + } + + showColumn(col); + redraw(); + } + + if (selectionEvent != null) { + selectionEvent.stateMask = e.stateMask; + selectionEvent.button = e.button; + selectionEvent.item = item; + selectionEvent.x = e.x; + selectionEvent.y = e.y; + notifyListeners(SWT.Selection, selectionEvent); + + if (!cellSelectionEnabled) { + if (isListening(SWT.DragDetect)) { + dragDetect(e); + } + } + } + + } + + /** + * Mouse double click event handler. + * + * @param e + * event + */ + private void onMouseDoubleClick(final Event e) { + if (e.button != 1) { + return; + } + + if (hoveringOnColumnResizer) { + columnBeingResized.pack(); + columnBeingResized.fireResized(); + for (int index = displayOrderedColumns.indexOf(columnBeingResized) + 1; index < displayOrderedColumns + .size(); index++) { + final GridColumn col = displayOrderedColumns.get(index); + if (col.isVisible()) { + col.fireMoved(); + } + } + resizingColumn = false; + handleHoverOnColumnResizer(e.x, e.y); + e.doit = false; + return; + } else if (rowsResizeable && hoveringOnRowResizer) { + final List sel = Arrays.asList(getSelection()); + if (sel.contains(rowBeingResized)) { + // the user double-clicked a row resizer of a selected row + // so update all selected rows + for (final GridItem element : sel) { + element.pack(); + } + redraw(); + } else { + // otherwise only update the row the user double-clicked + rowBeingResized.pack(); + } + + resizingRow = false; + handleHoverOnRowResizer(e.x, e.y); + e.doit = false; + return; + } + + if (e.y < headerHeight && columnHeadersVisible) { + e.doit = false; + return; + } + + final GridItem item = getItem(new Point(e.x, e.y)); + if (item != null) { + if (isListening(SWT.DefaultSelection)) { + final Event newEvent = new Event(); + newEvent.item = item; + + notifyListeners(SWT.DefaultSelection, newEvent); + } else if (item.getItemCount() > 0) { + item.setExpanded(!item.isExpanded()); + + if (item.isExpanded()) { + item.fireEvent(SWT.Expand); + } else { + item.fireEvent(SWT.Collapse); + } + } + } + } + + /** + * Mouse up handler. + * + * @param e + * event + */ + private void onMouseUp(final Event e) { + cellSelectedOnLastMouseDown = false; + + if (resizingColumn) { + resizingColumn = false; + handleHoverOnColumnResizer(e.x, e.y); // resets cursor if + // necessary + return; + } + if (resizingRow) { + resizingRow = false; + handleHoverOnRowResizer(e.x, e.y); // resets cursor if + // necessary + return; + } + + if (pushingColumn) { + pushingColumn = false; + columnBeingPushed.getHeaderRenderer().setMouseDown(false); + columnBeingPushed.getHeaderRenderer().setHover(false); + redraw(); + if (pushingAndHovering) { + columnBeingPushed.fireListeners(); + } + setCapture(false); + return; + } + + if (draggingColumn) { + handleColumnDrop(); + return; + } + + if (cellDragSelectionOccuring || cellRowDragSelectionOccuring || cellColumnDragSelectionOccuring) { + cellDragSelectionOccuring = false; + cellRowDragSelectionOccuring = false; + cellColumnDragSelectionOccuring = false; + setCursor(null); + + if (followupCellSelectionEventOwed) { + final Event se = new Event(); + se.button = e.button; + se.item = getItem(new Point(e.x, e.y)); + se.stateMask = e.stateMask; + se.x = e.x; + se.y = e.y; + + notifyListeners(SWT.Selection, se); + followupCellSelectionEventOwed = false; + } + } + } + + /** + * Mouse move event handler. + * + * @param e + * event + */ + private void onMouseMove(final MouseEvent e) { + // check to see if the mouse is outside the grid + // this should only happen when the mouse is captured for inplace + // tooltips - see bug 203364 + if (inplaceTooltipCapture && (e.x < 0 || e.y < 0 || e.x >= getBounds().width || e.y >= getBounds().height)) { + setCapture(false); + inplaceTooltipCapture = false; + return; // a mouseexit event should occur immediately + } + + // if populated will be fired at end of method. + Event selectionEvent = null; + + if ((e.stateMask & SWT.BUTTON1) == 0) { + handleHovering(e.x, e.y); + } else { + if (draggingColumn) { + handleColumnDragging(e.x); + return; + } + + if (resizingColumn) { + handleColumnResizerDragging(e.x); + return; + } + if (resizingRow) { + handleRowResizerDragging(e.y); + return; + } + if (pushingColumn) { + handleColumnHeaderHoverWhilePushing(e.x, e.y); + return; + } + if (cellSelectionEnabled) { + if (cellDragSelectionEnabled && !cellDragSelectionOccuring && cellSelectedOnLastMouseDown) { + cellDragSelectionOccuring = true; + // XXX: make this user definable + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_CROSS)); + cellDragCTRL = (e.stateMask & SWT.MOD1) != 0; + if (cellDragCTRL) { + selectedCellsBeforeRangeSelect.clear(); + selectedCellsBeforeRangeSelect.addAll(selectedCells); + } + } + if (!cellRowDragSelectionOccuring && cellRowSelectedOnLastMouseDown) { + cellRowDragSelectionOccuring = true; + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_CROSS)); + cellDragCTRL = (e.stateMask & SWT.MOD1) != 0; + if (cellDragCTRL) { + selectedCellsBeforeRangeSelect.clear(); + selectedCellsBeforeRangeSelect.addAll(selectedCells); + } + } + + if (!cellColumnDragSelectionOccuring && cellColumnSelectedOnLastMouseDown) { + cellColumnDragSelectionOccuring = true; + setCursor(getDisplay().getSystemCursor(SWT.CURSOR_CROSS)); + cellDragCTRL = (e.stateMask & SWT.MOD1) != 0; + if (cellDragCTRL) { + selectedCellsBeforeRangeSelect.clear(); + selectedCellsBeforeRangeSelect.addAll(selectedCells); + } + } + + final int ctrlFlag = cellDragCTRL ? SWT.MOD1 : SWT.NONE; + + if (cellDragSelectionOccuring && handleCellHover(e.x, e.y)) { + GridColumn intentColumn = hoveringColumn; + GridItem intentItem = hoveringItem; + + if (hoveringItem == null) { + if (e.y > headerHeight) { + // then we must be hovering way to the bottom + intentItem = getPreviousVisibleItem(null); + } else { + intentItem = items.get(0); + } + } + + if (hoveringColumn == null) { + if (e.x > rowHeaderWidth) { + // then we must be hovering way to the right + intentColumn = getVisibleColumn_DegradeLeft(intentItem, + displayOrderedColumns.get(displayOrderedColumns.size() - 1)); + } else { + GridColumn firstCol = displayOrderedColumns.get(0); + if (!firstCol.isVisible()) { + firstCol = getNextVisibleColumn(firstCol); + } + intentColumn = firstCol; + } + } + + showColumn(intentColumn); + showItem(intentItem); + selectionEvent = updateCellSelection(new Point(intentColumn.index, intentItem.getRowIndex()), + ctrlFlag | SWT.MOD2, true, false); + } + if (cellRowDragSelectionOccuring && handleCellHover(e.x, e.y)) { + GridItem intentItem = hoveringItem; + + if (hoveringItem == null) { + if (e.y > headerHeight) { + // then we must be hovering way to the bottom + intentItem = getPreviousVisibleItem(null); + } else { + if (getTopIndex() > 0) { + intentItem = getPreviousVisibleItem(items.get(getTopIndex())); + } else { + intentItem = items.get(0); + } + } + } + + final Vector cells = new Vector<>(); + + getCells(intentItem, focusItem, cells); + + showItem(intentItem); + selectionEvent = updateCellSelection(cells, ctrlFlag, true, false); + } + if (cellColumnDragSelectionOccuring && handleCellHover(e.x, e.y)) { + final GridColumn intentCol = hoveringColumn; + + if (intentCol == null) { + if (e.y < rowHeaderWidth) { + // TODO: get the first col to the left + } else { + // TODO: get the first col to the right + } + } + + if (intentCol == null) { + return; // temporary + } + + GridColumn iterCol = intentCol; + + final Vector newSelected = new Vector<>(); + + final boolean decreasing = displayOrderedColumns.indexOf(iterCol) > displayOrderedColumns + .indexOf(focusColumn); + + do { + getCells(iterCol, newSelected); + + if (iterCol == focusColumn) { + break; + } + + if (decreasing) { + iterCol = getPreviousVisibleColumn(iterCol); + } else { + iterCol = getNextVisibleColumn(iterCol); + } + + } while (true); + + selectionEvent = updateCellSelection(newSelected, ctrlFlag, true, false); + } + + } + } + + if (selectionEvent != null) { + selectionEvent.stateMask = e.stateMask; + selectionEvent.button = e.button; + selectionEvent.item = getItem(new Point(e.x, e.y)); + selectionEvent.x = e.x; + selectionEvent.y = e.y; + notifyListeners(SWT.Selection, selectionEvent); + } + } + + /** + * Handles the assignment of the correct values to the hover* field variables + * that let the painting code now what to paint as hovered. + * + * @param x + * mouse x coordinate + * @param y + * mouse y coordinate + */ + private void handleHovering(final int x, final int y) { + // TODO: need to clean up and refactor hover code + handleCellHover(x, y); + + // Is this Grid a DragSource ?? + if (cellSelectionEnabled && getData("DragSource") != null) { + if (handleHoverOnSelectionDragArea(x, y)) { + return; + } + } + + if (columnHeadersVisible) { + if (handleHoverOnColumnResizer(x, y)) { + // if (hoveringItem != null || !hoveringDetail.equals("") || hoveringColumn != + // null + // || hoveringColumnHeader != null || hoverColumnGroupHeader != null) + // { + // hoveringItem = null; + // hoveringDetail = ""; + // hoveringColumn = null; + // hoveringColumnHeader = null; + // hoverColumnGroupHeader = null; + // + // Rectangle clientArea = getClientArea(); + // redraw(clientArea.x,clientArea.y,clientArea.width,clientArea.height,false); + // } + return; + } + } + if (rowsResizeable && rowHeaderVisible) { + if (handleHoverOnRowResizer(x, y)) { + return; + } + } + + // handleCellHover(x, y); + } + + /** + * Refreshes the hover* variables according to the mouse location and current + * state of the table. This is useful is some method call, caused the state of + * the table to change and therefore the hover effects may have become out of + * date. + */ + protected void refreshHoverState() { + final Point p = getDisplay().map(null, this, getDisplay().getCursorLocation()); + handleHovering(p.x, p.y); + } + + /** + * Mouse exit event handler. + * + * @param e + * event + */ + private void onMouseExit(final MouseEvent e) { + hoveringItem = null; + hoveringDetail = ""; + hoveringColumn = null; + hoveringColumnHeader = null; + hoverColumnGroupHeader = null; + hoveringOverText = false; + hideToolTip(); + redraw(); + } + + /** + * Key down event handler. + * + * @param e + * event + */ + protected void onKeyDown(final Event e) { + if (focusColumn == null || focusColumn.isDisposed()) { + if (columns.size() == 0) { + return; + } + + focusColumn = getColumn(0); + intendedFocusColumn = focusColumn; + } + + if (e.character == '\r' && focusItem != null) { + final Event newEvent = new Event(); + newEvent.item = focusItem; + + notifyListeners(SWT.DefaultSelection, newEvent); + return; + } + + int attemptExpandCollapse = 0; + if ((e.character == '-' || !cellSelectionEnabled && e.keyCode == SWT.ARROW_LEFT) && focusItem != null + && focusItem.isExpanded()) { + attemptExpandCollapse = SWT.Collapse; + } else if ((e.character == '+' || !cellSelectionEnabled && e.keyCode == SWT.ARROW_RIGHT) && focusItem != null + && !focusItem.isExpanded()) { + attemptExpandCollapse = SWT.Expand; + } + + if (attemptExpandCollapse != 0 && focusItem != null && focusItem.hasChildren()) { + int performExpandCollapse = 0; + + if (cellSelectionEnabled && focusColumn != null && focusColumn.isTree()) { + performExpandCollapse = attemptExpandCollapse; + } else if (!cellSelectionEnabled) { + performExpandCollapse = attemptExpandCollapse; + } + + if (performExpandCollapse == SWT.Expand) { + focusItem.setExpanded(true); + focusItem.fireEvent(SWT.Expand); + return; + } + if (performExpandCollapse == SWT.Collapse) { + focusItem.setExpanded(false); + focusItem.fireEvent(SWT.Collapse); + return; + } + } + + if (e.character == ' ') { + handleSpaceBarDown(e); + } + + GridItem newSelection = null; + GridColumn newColumnFocus = null; + + // These two variables are used because the key navigation when the shift key is + // down is + // based, not off the focus item/column, but rather off the implied focus (i.e. + // where the + // keyboard has extended focus to). + GridItem impliedFocusItem = focusItem == null || focusItem.isDisposed() ? null : focusItem; + GridColumn impliedFocusColumn = focusColumn.isDisposed() ? null : focusColumn; + + if (cellSelectionEnabled && e.stateMask == SWT.MOD2) { + if (shiftSelectionAnchorColumn != null) { + if (shiftSelectionAnchorItem == null || shiftSelectionAnchorItem.isDisposed()) { + impliedFocusItem = focusItem; + } else { + impliedFocusItem = shiftSelectionAnchorItem; + } + impliedFocusColumn = shiftSelectionAnchorColumn.isDisposed() ? null : shiftSelectionAnchorColumn; + } + } + + switch (e.keyCode) { + case SWT.ARROW_RIGHT: + if (cellSelectionEnabled) { + if (impliedFocusItem != null && impliedFocusColumn != null) { + newSelection = impliedFocusItem; + + int index = displayOrderedColumns.indexOf(impliedFocusColumn); + + int jumpAhead = impliedFocusItem.getColumnSpan(impliedFocusColumn.index); + + jumpAhead++; + + while (jumpAhead > 0) { + index++; + if (index < displayOrderedColumns.size()) { + if (displayOrderedColumns.get(index).isVisible()) { + jumpAhead--; + } + } else { + break; + } + } + + if (index < displayOrderedColumns.size()) { + newColumnFocus = displayOrderedColumns.get(index); + } else { + newColumnFocus = impliedFocusColumn; + } + } + intendedFocusColumn = newColumnFocus; + } else { + if (impliedFocusItem != null && impliedFocusItem.hasChildren()) { + newSelection = impliedFocusItem.getItem(0); + } + } + break; + case SWT.ARROW_LEFT: + if (cellSelectionEnabled) { + if (impliedFocusItem != null && impliedFocusColumn != null) { + newSelection = impliedFocusItem; + + final int index = displayOrderedColumns.indexOf(impliedFocusColumn); + + if (index != 0) { + newColumnFocus = displayOrderedColumns.get(index - 1); + + newColumnFocus = getVisibleColumn_DegradeLeft(impliedFocusItem, newColumnFocus); + + if (newColumnFocus == null) { + newColumnFocus = impliedFocusColumn; + } + + } else { + newColumnFocus = impliedFocusColumn; + } + } + intendedFocusColumn = newColumnFocus; + } else { + if (impliedFocusItem != null && impliedFocusItem.getParentItem() != null) { + newSelection = impliedFocusItem.getParentItem(); + } + } + break; + case SWT.ARROW_UP: + if (impliedFocusItem != null) { + newSelection = getPreviousVisibleItem(impliedFocusItem); + } + + if (impliedFocusColumn != null) { + if (newSelection != null) { + newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, intendedFocusColumn); + } else { + newColumnFocus = impliedFocusColumn; + } + } + + break; + case SWT.ARROW_DOWN: + if (impliedFocusItem != null) { + newSelection = getNextVisibleItem(impliedFocusItem); + } else { + if (items.size() > 0) { + newSelection = items.get(0); + } + } + + if (impliedFocusColumn != null) { + if (newSelection != null && intendedFocusColumn != null) { + newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, intendedFocusColumn); + } else { + newColumnFocus = impliedFocusColumn; + } + } + break; + case SWT.HOME: + if (!cellSelectionEnabled) { + if (items.size() > 0) { + newSelection = items.get(0); + } + } else { + if (e.stateMask == SWT.MOD1 && items.size() > 0) { + impliedFocusItem = items.get(0); + } + newSelection = impliedFocusItem; + newColumnFocus = getVisibleColumn_DegradeRight(newSelection, displayOrderedColumns.get(0)); + intendedFocusColumn = newColumnFocus; + } + + break; + case SWT.END: + if (!cellSelectionEnabled) { + if (items.size() > 0) { + newSelection = getPreviousVisibleItem(null); + } + } else { + newSelection = impliedFocusItem; + newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, + displayOrderedColumns.get(displayOrderedColumns.size() - 1)); + } + + break; + case SWT.PAGE_UP: + final int topIndex = getTopIndex(); + + newSelection = items.get(topIndex); + + if (focusItem == newSelection) { + final RowRange range = getRowRange(getTopIndex(), getVisibleGridHeight(), false, true); + newSelection = items.get(range.startIndex); + } + + if (impliedFocusColumn != null) { + if (newSelection != null && intendedFocusColumn != null) { + newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, intendedFocusColumn); + } else { + newColumnFocus = impliedFocusColumn; + } + } + break; + case SWT.PAGE_DOWN: + final int bottomIndex = getBottomIndex(); + + newSelection = items.get(bottomIndex); + + if (!isShown(newSelection)) { + // the item at bottom index is not shown completely + final GridItem tmpItem = getPreviousVisibleItem(newSelection); + if (tmpItem != null) { + newSelection = tmpItem; + } + } + + if (focusItem == newSelection) { + final RowRange range = getRowRange(getBottomIndex(), getVisibleGridHeight(), true, false); + newSelection = items.get(range.endIndex); + } + + if (impliedFocusColumn != null) { + if (newSelection != null && intendedFocusColumn != null) { + newColumnFocus = getVisibleColumn_DegradeLeft(newSelection, intendedFocusColumn); + } else { + newColumnFocus = impliedFocusColumn; + } + } + break; + default: + break; + } + + if (newSelection == null) { + return; + } + + if (cellSelectionEnabled) { + if (e.stateMask != SWT.MOD2) { + focusColumn = newColumnFocus; + } + showColumn(newColumnFocus); + + if (e.stateMask != SWT.MOD2) { + focusItem = newSelection; + } + showItem(newSelection); + + if (e.stateMask != SWT.MOD1 || isMod1Home(e)) { + final int stateMask = e.stateMask == SWT.MOD1 ? SWT.NONE : e.stateMask; + final Event selEvent = updateCellSelection( + new Point(newColumnFocus.index, newSelection.getRowIndex()), stateMask, false, false); + if (selEvent != null) { + selEvent.stateMask = stateMask; + selEvent.character = e.character; + selEvent.keyCode = e.keyCode; + notifyListeners(SWT.Selection, selEvent); + } + } + + redraw(); + } else { + Event selectionEvent = null; + if (selectionType == GridSelectionType.SINGLE || e.stateMask != SWT.MOD1) { + selectionEvent = updateSelection(newSelection, e.stateMask); + if (selectionEvent != null) { + selectionEvent.stateMask = e.stateMask; + selectionEvent.character = e.character; + selectionEvent.keyCode = e.keyCode; + } + } + + focusItem = newSelection; + showItem(newSelection); + redraw(); + + if (selectionEvent != null) { + notifyListeners(SWT.Selection, selectionEvent); + } + } + } + + private boolean isMod1Home(final Event e) { + return e.stateMask == SWT.MOD1 && e.keyCode == SWT.HOME; + } + + private void handleSpaceBarDown(final Event event) { + if (focusItem == null) { + return; + } + + if (selectionEnabled && !cellSelectionEnabled && !selectedItems.contains(focusItem)) { + selectedItems.add(focusItem); + redraw(); + final Event e = new Event(); + e.item = focusItem; + e.stateMask = event.stateMask; + e.character = event.character; + e.keyCode = event.keyCode; + notifyListeners(SWT.Selection, e); + } + + if (!cellSelectionEnabled) { + boolean checkFirstCol = false; + boolean first = true; + + for (final GridColumn col : columns) { + + if (first) { + if (!col.isCheck()) { + break; + } + + first = false; + checkFirstCol = true; + } else { + if (col.isCheck()) { + checkFirstCol = false; + break; + } + } + } + + if (checkFirstCol) { + focusItem.setChecked(!focusItem.getChecked()); + redraw(); + focusItem.fireCheckEvent(0); + } + } + } + + /** + * Resize event handler. + */ + private void onResize() { + + // CGross 1/2/08 - I don't really want to be doing this.... + // I shouldn't be changing something you user configured... + // leaving out for now + // if (columnScrolling) + // { + // int maxWidth = getClientArea().width; + // if (rowHeaderVisible) + // maxWidth -= rowHeaderWidth; + // + // for (Iterator cols = columns.iterator(); cols.hasNext();) { + // GridColumn col = (GridColumn) cols.next(); + // if (col.getWidth() > maxWidth) + // col.setWidth(maxWidth); + // } + // } + + scrollValuesObsolete = true; + topIndex = -1; + bottomIndex = -1; + } + + /** + * Scrollbar selection event handler. + */ + private void onScrollSelection() { + topIndex = -1; + bottomIndex = -1; + refreshHoverState(); + redraw(getClientArea().x, getClientArea().y, getClientArea().width, getClientArea().height, false); + } + + /** + * Returns the intersection of the given column and given item. + * + * @param column + * column + * @param item + * item + * @return x,y of top left corner of the cell + */ + Point getOrigin(final GridColumn column, final GridItem item) { + int x = 0; + + if (rowHeaderVisible) { + x += rowHeaderWidth; + } + + x -= getHScrollSelectionInPixels(); + + for (final GridColumn colIter : displayOrderedColumns) { + + if (colIter == column) { + break; + } + + if (colIter.isVisible()) { + x += colIter.getWidth(); + } + } + + int y = 0; + if (item != null) { + if (columnHeadersVisible) { + y += headerHeight; + } + + int currIndex = getTopIndex(); + final int itemIndex = item.getRowIndex(); + + if (itemIndex == -1) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + while (currIndex != itemIndex) { + if (currIndex < itemIndex) { + final GridItem currItem = items.get(currIndex); + if (currItem.isVisible()) { + y += currItem.getHeight() + 1; + } + currIndex++; + } else if (currIndex > itemIndex) { + currIndex--; + final GridItem currItem = items.get(currIndex); + if (currItem.isVisible()) { + y -= currItem.getHeight() + 1; + } + } + } + } else { + if (column.getColumnGroup() != null) { + y += groupHeaderHeight; + } + } + + return new Point(x, y); + } + + /** + * Determines (which cell/if a cell) has been clicked (mouse down really) and + * notifies the appropriate renderer. Returns true when a cell has responded to + * this event in some way and prevents the event from triggering an action + * further down the chain (like a selection). + * + * @param item + * item clicked + * @param x + * mouse x + * @param y + * mouse y + * @return true if this event has been consumed. + */ + private boolean handleCellClick(final GridItem item, final int x, final int y) { + + // if(!isTree) + // return false; + + final GridColumn col = getColumn(new Point(x, y)); + if (col == null) { + return false; + } + + col.getCellRenderer().setBounds(item.getBounds(col.index)); + return col.getCellRenderer().notify(IInternalWidget.LeftMouseButtonDown, new Point(x, y), item); + + } + + /** + * Sets the hovering variables (hoverItem,hoveringColumn) as well as hoverDetail + * by talking to the cell renderers. Triggers a redraw if necessary. + * + * @param x + * mouse x + * @param y + * mouse y + * @return true if a new section of the table is now being hovered + */ + private boolean handleCellHover(final int x, final int y) { + + String detail = ""; + + boolean overText = false; + + final GridColumn col = getColumn(new Point(x, y)); + final GridItem item; + // If the user select cells and drag, the mouse pointer could be out of the + // grid's bounds + if (x >= getClientArea().width - 1) { + item = hoveringItem; + } else if (x < getClientArea().x) { + item = hoveringItem; + } else { + item = getItem(new Point(x, y)); + } + + GridColumnGroup hoverColGroup = null; + GridColumn hoverColHeader = null; + + if (col != null) { + if (item != null) { + if (y < getClientArea().height - (columnFootersVisible ? footerHeight : 0)) { + col.getCellRenderer().setBounds(item.getBounds(col.index)); + + if (col.getCellRenderer().notify(IInternalWidget.MouseMove, new Point(x, y), item)) { + detail = col.getCellRenderer().getHoverDetail(); + } + + final Rectangle textBounds = col.getCellRenderer().getTextBounds(item, false); + + if (textBounds != null) { + final Point p = new Point(x - col.getCellRenderer().getBounds().x, + y - col.getCellRenderer().getBounds().y); + overText = textBounds.contains(p); + } + } + } else { + if (y < headerHeight) { + if (columnGroups.length != 0 && y < groupHeaderHeight && col.getColumnGroup() != null) { + hoverColGroup = col.getColumnGroup(); + hoverColGroup.getHeaderRenderer().setBounds(hoverColGroup.getBounds()); + if (hoverColGroup.getHeaderRenderer().notify(IInternalWidget.MouseMove, new Point(x, y), + hoverColGroup)) { + detail = hoverColGroup.getHeaderRenderer().getHoverDetail(); + } + + final Rectangle textBounds = hoverColGroup.getHeaderRenderer().getTextBounds(hoverColGroup, + false); + + if (textBounds != null) { + final Point p = new Point(x - hoverColGroup.getHeaderRenderer().getBounds().x, + y - hoverColGroup.getHeaderRenderer().getBounds().y); + overText = textBounds.contains(p); + } + } else { + // on col header + hoverColHeader = col; + + col.getHeaderRenderer().setBounds(col.getBounds()); + if (col.getHeaderRenderer().notify(IInternalWidget.MouseMove, new Point(x, y), col)) { + detail = col.getHeaderRenderer().getHoverDetail(); + } + + final Rectangle textBounds = col.getHeaderRenderer().getTextBounds(col, false); + + if (textBounds != null) { + final Point p = new Point(x - col.getHeaderRenderer().getBounds().x, + y - col.getHeaderRenderer().getBounds().y); + overText = textBounds.contains(p); + } + } + } + } + } + + boolean hoverChange = false; + + if (hoveringItem != item || !hoveringDetail.equals(detail) || hoveringColumn != col + || hoverColGroup != hoverColumnGroupHeader || hoverColHeader != hoveringColumnHeader) { + hoveringItem = item; + hoveringDetail = detail; + hoveringColumn = col; + hoveringColumnHeader = hoverColHeader; + hoverColumnGroupHeader = hoverColGroup; + + final Rectangle clientArea = getClientArea(); + redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); + + hoverChange = true; + } + + // do inplace toolTip stuff + if (hoverChange || hoveringOverText != overText) { + hoveringOverText = overText; + + if (overText) { + + Rectangle cellBounds = null; + Rectangle textBounds = null; + Rectangle preferredTextBounds = null; + + if(hoveringItem != null && hoveringItem.getToolTipText(col.index) == null && // no inplace tooltips + // when regular + // tooltip + !col.getWordWrap()) // dont show inplace tooltips for cells with wordwrap + { + cellBounds = col.getCellRenderer().getBounds(); + if (cellBounds.x + cellBounds.width > getSize().x) { + cellBounds.width = getSize().x - cellBounds.x; + } + textBounds = col.getCellRenderer().getTextBounds(item, false); + preferredTextBounds = col.getCellRenderer().getTextBounds(item, true); + } else if (hoveringColumnHeader != null && hoveringColumnHeader.getHeaderTooltip() == null) // no + // inplace + // tooltips + // when + // regular + // tooltip + { + cellBounds = hoveringColumnHeader.getHeaderRenderer().getBounds(); + if (cellBounds.x + cellBounds.width > getSize().x) { + cellBounds.width = getSize().x - cellBounds.x; + } + textBounds = hoveringColumnHeader.getHeaderRenderer().getTextBounds(col, false); + preferredTextBounds = hoveringColumnHeader.getHeaderRenderer().getTextBounds(col, true); + } else if (hoverColumnGroupHeader != null) { + cellBounds = hoverColumnGroupHeader.getHeaderRenderer().getBounds(); + if (cellBounds.x + cellBounds.width > getSize().x) { + cellBounds.width = getSize().x - cellBounds.x; + } + textBounds = hoverColumnGroupHeader.getHeaderRenderer().getTextBounds(hoverColumnGroupHeader, + false); + preferredTextBounds = hoverColumnGroupHeader.getHeaderRenderer() + .getTextBounds(hoverColumnGroupHeader, true); + } + + // if we are truncated + if (textBounds != null && textBounds.width < preferredTextBounds.width) { + showToolTip(item, col, hoverColumnGroupHeader, + new Point(cellBounds.x + textBounds.x, cellBounds.y + textBounds.y)); + // the following 2 lines are done here rather than in showToolTip to allow + // that method to be overridden yet still capture the mouse. + setCapture(true); + inplaceTooltipCapture = true; + } + } else { + hideToolTip(); + } + } + + // do normal cell specific tooltip stuff + if (hoverChange) { + String newTip = null; + if (hoveringItem != null && hoveringColumn != null) { + // get cell specific tooltip + newTip = hoveringItem.getToolTipText(hoveringColumn.index); + } else if (hoveringColumn != null && hoveringColumnHeader != null) { + // get column header specific tooltip + newTip = hoveringColumn.getHeaderTooltip(); + } + + if (newTip == null) { // no cell or column header specific tooltip then use base Grid tooltip + newTip = getToolTipText(); + } + + // Avoid unnecessarily resetting tooltip - this will cause the tooltip to jump + // around + if (newTip != null && !newTip.equals(displayedToolTipText)) { + updateToolTipText(newTip); + } else if (newTip == null && displayedToolTipText != null) { + updateToolTipText(null); + } + displayedToolTipText = newTip; + } + + return hoverChange; + } + + /** + * Sets the tooltip for the whole Grid to the given text. This method is made + * available for subclasses to override, when a subclass wants to display a + * different than the standard SWT/OS tooltip. Generally, those subclasses would + * override this event and use this tooltip text in their own tooltip or just + * override this method to prevent the SWT/OS tooltip from displaying. + * + * @param text + */ + protected void updateToolTipText(final String text) { + super.setToolTipText(text); + } + + /** + * Marks the scroll values obsolete so they will be recalculated. + */ + protected void setScrollValuesObsolete() { + scrollValuesObsolete = true; + redraw(); + } + + /** + * Inserts a new column into the table. + * + * @param column + * new column + * @param index + * index to insert new column + * @return current number of columns + */ + int newColumn(final GridColumn column, final int index) { + + final int size = columns.size(); + if (index == -1) { + column.index = size; + columns.add(column); + displayOrderedColumns.add(column); + } else { + column.index = index; + columns.add(index, column); + for(int i = index + 1; i < size; i++) { + columns.get(i).index = i; + } + displayOrderedColumns.add(index, column); + + dataVisualizer.addColumn(index); + for(int i = 0; i < size; i++) { + columns.get(i).setColumnIndex(i); + } + } + + estimate(sizingGC -> { + computeHeaderHeight(sizingGC); + computeFooterHeight(sizingGC); + }); + + updatePrimaryCheckColumn(); + + for (final GridItem item : items) { + item.columnAdded(index); + } + + scrollValuesObsolete = true; + redraw(); + clearDisplayOrderedCache(); + return size - 1; + } + + /** + * Removes the given column from the table. + * + * @param column + * column to remove + */ + void removeColumn(final GridColumn column) { + boolean selectionModified = false; + + final int index = column.index; + + if (cellSelectionEnabled) { + final Vector removeSelectedCells = new Vector<>(); + + for (final Point cell : selectedCells) { + if (cell.x == index) { + removeSelectedCells.add(cell); + } + } + + if (removeSelectedCells.size() > 0) { + selectedCells.removeAll(removeSelectedCells); + selectionModified = true; + } + + for (final Point cell : selectedCells) { + if (cell.x >= index) { + cell.x--; + selectionModified = true; + } + } + } + + columns.remove(column); + final int size = columns.size(); + for(int i = index; i < size; i++) { + columns.get(i).index = i; + } + displayOrderedColumns.remove(column); + dataVisualizer.clearColumn(index); + + if (focusColumn == column) { + focusColumn = null; + } + + updatePrimaryCheckColumn(); + + scrollValuesObsolete = true; + + redraw(); + + int i = 0; + for (final GridColumn col : columns) { + col.setColumnIndex(i); + i++; + } + + if (selectionModified && !disposing) { + updateColumnSelection(); + } + clearDisplayOrderedCache(); + } + + /** + * Manages the setting of the checkbox column when the SWT.CHECK style was given + * to the table. This method will ensure that the first column of the table + * always has a checkbox when SWT.CHECK is given to the table. + */ + private void updatePrimaryCheckColumn() { + if ((getStyle() & SWT.CHECK) == SWT.CHECK) { + boolean firstCol = true; + + for (final GridColumn col : columns) { + col.setTableCheck(firstCol); + firstCol = false; + } + } + } + + void newRootItem(final GridItem item, final int index) { + if (index == -1 || index >= rootItems.size()) { + rootItems.add(item); + } else { + rootItems.add(index, item); + } + } + + void removeRootItem(final GridItem item) { + rootItems.remove(item); + } + + /** + * Creates the new item at the given index. Only called from GridItem + * constructor. + * + * @param item + * new item + * @param index + * index to insert the item at + * @return the index where the item was insert + */ + int newItem(final GridItem item, int index, final boolean root) { + int row = 0; + + if (!isTree) { + if (item.getParentItem() != null) { + isTree = true; + } + } + + // Have to convert indexes, this method needs a flat index, the method is called + // with indexes + // that are relative to the level + if (root && index != -1) { + if (index >= rootItems.size()) { + index = -1; + } else { + index = rootItems.get(index).getRowIndex(); + } + } else if (!root) { + if (index >= item.getParentItem().getItems().length || index == -1) { + GridItem rightMostDescendent = item.getParentItem(); + + while (rightMostDescendent.getItems().length > 0) { + rightMostDescendent = rightMostDescendent.getItems()[rightMostDescendent.getItems().length - 1]; + } + + index = rightMostDescendent.getRowIndex() + 1; + } else { + index = item.getParentItem().getItems()[index].getRowIndex(); + } + } + + if (index == -1) { + items.add(item); + row = items.size() - 1; + } else { + items.add(index, item); + row = index; + for (int i = index + 1; i < items.size(); i++) { + items.get(i).increaseRow(); + } + } + + estimate(sizingGC -> { + if (items.size() == 1 && !userModifiedItemHeight) { + itemHeight = computeItemHeight(item, sizingGC); + // virtual problems here + if ((getStyle() & SWT.VIRTUAL) != 0) { + item.setHasSetData(false); + } + } + + item.initializeHeight(itemHeight); + + if (isRowHeaderVisible() && isAutoWidth()) { + rowHeaderWidth = Math.max(rowHeaderWidth, // + rowHeaderRenderer.computeSize(sizingGC, SWT.DEFAULT, SWT.DEFAULT, item).x); + } + }); + + scrollValuesObsolete = true; + topIndex = -1; + bottomIndex = -1; + + currentVisibleItems++; + + redraw(); + + return row; + } + + /** + * Removes the given item from the table. This method is only called from the + * item's dispose method. + * + * @param item + * item to remove + */ + void removeItem(final GridItem item) { + + final Point[] cells = getCells(item); + boolean selectionModified = false; + + final int index = item.getRowIndex(); + + items.remove(item); + + dataVisualizer.clearRow(item); + + if (disposing) { + return; + } + + for (int i = index; i < items.size(); i++) { + items.get(i).decreaseRow(); + } + + if (selectedItems.remove(item)) { + selectionModified = true; + } + + for (final Point cell : cells) { + if (selectedCells.remove(cell)) { + selectionModified = true; + } + } + + if (focusItem == item) { + focusItem = null; + } + + scrollValuesObsolete = true; + topIndex = -1; + bottomIndex = -1; + if (item.isVisible()) { + currentVisibleItems--; + } + + if (selectionModified && !disposing) { + updateColumnSelection(); + } + + redraw(); + // Need to update the scrollbars see see 375327 + updateScrollbars(); + } + + /** + * Creates the given column group at the given index. This method is only called + * from the {@code GridColumnGroup}'s constructor. + * + * @param group + * group to add. + */ + void newColumnGroup(final GridColumnGroup group) { + final GridColumnGroup[] newColumnGroups = new GridColumnGroup[columnGroups.length + 1]; + System.arraycopy(columnGroups, 0, newColumnGroups, 0, columnGroups.length); + newColumnGroups[newColumnGroups.length - 1] = group; + columnGroups = newColumnGroups; + + // if we just added the first col group, then we need to up the row + // height + if (columnGroups.length == 1) { + computeHeaderHeight(); + } + + scrollValuesObsolete = true; + redraw(); + } + + /** + * Removes the given column group from the table. This method is only called + * from the {@code GridColumnGroup}'s dispose method. + * + * @param group + * group to remove. + */ + void removeColumnGroup(final GridColumnGroup group) { + final GridColumnGroup[] newColumnGroups = new GridColumnGroup[columnGroups.length - 1]; + int newIndex = 0; + for (final GridColumnGroup columnGroup : columnGroups) { + if (columnGroup != group) { + newColumnGroups[newIndex] = columnGroup; + newIndex++; + } + } + columnGroups = newColumnGroups; + + if (columnGroups.length == 0) { + computeHeaderHeight(); + } + + scrollValuesObsolete = true; + redraw(); + } + + /** + * Updates the cached number of visible items by the given amount. + * + * @param amount + * amount to update cached total + */ + void updateVisibleItems(final int amount) { + currentVisibleItems += amount; + } + + /** + * Returns the current item in focus. + * + * @return item in focus or {@code null}. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public GridItem getFocusItem() { + checkWidget(); + return focusItem; + } + + /** + * Returns the current cell in focus. If cell selection is disabled, this method + * returns null. + * + * @return cell in focus or {@code null}. x represents the column and y the row + * the cell is in + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public Point getFocusCell() { + checkWidget(); + if (!cellSelectionEnabled) { + return null; + } + + int x = -1; + int y = -1; + + if (focusColumn != null) { + x = focusColumn.index; + } + + if (focusItem != null) { + y = focusItem.getRowIndex(); + } + + return new Point(x, y); + } + + /** + * Sets the focused item to the given item. + * + * @param item + * item to focus. + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if item is disposed
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setFocusItem(final GridItem item) { + checkWidget(); + // TODO: check and make sure this item is valid for focus + if (item == null || item.isDisposed() || item.getParent() != this) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + focusItem = item; + } + + /** + * Sets the focused item to the given column. Column focus is only applicable + * when cell selection is enabled. + * + * @param column + * column to focus. + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if item is disposed
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setFocusColumn(final GridColumn column) { + checkWidget(); + // TODO: check and make sure this item is valid for focus + if (column == null || column.isDisposed() || column.getParent() != this || !column.isVisible()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + focusColumn = column; + intendedFocusColumn = column; + } + + /** + * Returns an array of the columns in their display order. + * + * @return columns in display order + */ + GridColumn[] getColumnsInOrder() { + checkWidget(); + return displayOrderedColumns.toArray(new GridColumn[columns.size()]); + } + + /** + * Returns true if the table is set to horizontally scroll column-by-column + * rather than pixel-by-pixel. + * + * @return true if the table is scrolled horizontally by column + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean getColumnScrolling() { + checkWidget(); + return columnScrolling; + } + + /** + * Sets the table scrolling method to either scroll column-by-column (true) or + * pixel-by-pixel (false). + * + * @param columnScrolling + * true to horizontally scroll by column, false to scroll by pixel + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setColumnScrolling(final boolean columnScrolling) { + checkWidget(); + if (rowHeaderVisible && !columnScrolling) { + return; + } + + this.columnScrolling = columnScrolling; + scrollValuesObsolete = true; + redraw(); + } + + /** + * Returns the first visible column that is not spanned by any other column that + * is either the given column or any of the columns displaying to the left of + * the given column. If the given column and subsequent columns to the right are + * either not visible or spanned, this method will return null. + * + * @param item + * @param col + * @return + */ + GridColumn getVisibleColumn_DegradeLeft(final GridItem item, final GridColumn col) { + int index = displayOrderedColumns.indexOf(col); + + GridColumn prevCol = col; + + int i = 0; + while (!prevCol.isVisible()) { + i++; + if (index - i < 0) { + return null; + } + + prevCol = displayOrderedColumns.get(index - i); + } + + index = displayOrderedColumns.indexOf(prevCol); + + for (int j = 0; j < index; j++) { + final GridColumn tempCol = displayOrderedColumns.get(j); + + if (!tempCol.isVisible()) { + continue; + } + + if(item.getColumnSpan(tempCol.index) >= index - j) { + prevCol = tempCol; + break; + } + } + + return prevCol; + } + + /** + * Returns the first visible column that is not spanned by any other column that + * is either the given column or any of the columns displaying to the right of + * the given column. If the given column and subsequent columns to the right are + * either not visible or spanned, this method will return null. + * + * @param item + * @param col + * @return + */ + GridColumn getVisibleColumn_DegradeRight(final GridItem item, final GridColumn col) { + int index = displayOrderedColumns.indexOf(col); + + int i = 0; + GridColumn nextCol = col; + while (!nextCol.isVisible()) { + i++; + if (index + i == displayOrderedColumns.size()) { + return null; + } + + nextCol = displayOrderedColumns.get(index + i); + } + + index = displayOrderedColumns.indexOf(nextCol); + final int startIndex = index; + + while (index > 0) { + + index--; + final GridColumn prevCol = displayOrderedColumns.get(index); + + if(item.getColumnSpan(prevCol.index) >= startIndex - index) { + if (startIndex == displayOrderedColumns.size() - 1) { + return null; + } else { + return getVisibleColumn_DegradeRight(item, displayOrderedColumns.get(startIndex + 1)); + } + } + + } + + return nextCol; + } + + /** + * Returns true if the cells are selectable in the reciever. + * + * @return cell selection enablement status. + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public boolean getCellSelectionEnabled() { + checkWidget(); + return cellSelectionEnabled; + } + + /** + * Sets whether cells are selectable in the receiver. + * + * @param cellSelection + * the cellSelection to set + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setCellSelectionEnabled(final boolean cellSelection) { + checkWidget(); + if (!cellSelection) { + selectedCells.clear(); + redraw(); + } else { + if ((getStyle() & SWT.SINGLE) == 0) { + // To keep compatibility, one can selected multiple cells + selectionType = GridSelectionType.MULTI; + } + selectedItems.clear(); + redraw(); + } + + cellSelectionEnabled = cellSelection; + } + + /** + * @return true if cell selection is enabled + */ + public boolean isCellSelectionEnabled() { + return cellSelectionEnabled; + } + + /** + * Sets whether cells are selectable in the receiver by dragging the mouse + * cursor. + * + * @param cellDragSelection + * the cellDragSelection to set + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setCellDragSelectionEnabled(final boolean cellDragSelection) { + checkWidget(); + cellDragSelectionEnabled = cellDragSelection; + } + + /** + * @return true if cell drag selection is enabled + */ + public boolean isCellDragSelectionEnabled() { + return cellDragSelectionEnabled; + } + + /** + * Deselects the given cell in the receiver. If the given cell is already + * deselected it remains deselected. Invalid cells are ignored. + * + * @param cell + * cell to deselect. + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the cell is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void deselectCell(final Point cell) { + checkWidget(); + + if (cell == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + selectedCells.remove(cell); + updateColumnSelection(); + redraw(); + } + + /** + * Deselects the given cells. Invalid cells are ignored. + * + * @param cells + * the cells to deselect. + * + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the set of cells or any cell is + * null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void deselectCells(final Point[] cells) { + checkWidget(); + + if (cells == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + for (final Point cell : cells) { + if (cell == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + } + + for (final Point cell : cells) { + selectedCells.remove(cell); + } + + updateColumnSelection(); + + redraw(); + } + + /** + * Deselects all selected cells in the receiver. + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void deselectAllCells() { + checkWidget(); + selectedCells.clear(); + updateColumnSelection(); + redraw(); + } + + /** + * Selects the given cell. Invalid cells are ignored. + * + * @param cell + * point whose x values is a column index and y value is an item + * index + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void selectCell(final Point cell) { + checkWidget(); + + if (!cellSelectionEnabled) { + return; + } + + if (cell == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + addToCellSelection(cell); + updateColumnSelection(); + redraw(); + } + + /** + * Selects the given cells. Invalid cells are ignored. + * + * @param cells + * an arry of points whose x value is a column index and y value is + * an item index + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the set of cells or an individual + * cell is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void selectCells(final Point[] cells) { + checkWidget(); + + if (!cellSelectionEnabled) { + return; + } + + if (cells == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + for (final Point cell : cells) { + if (cell == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + } + + for (final Point cell : cells) { + addToCellSelection(cell); + } + + updateColumnSelection(); + redraw(); + } + + /** + * Selects all cells in the receiver. + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void selectAllCells() { + checkWidget(); + selectAllCellsInternal(); + } + + /** + * Selects all cells in the receiver. + * + * @return An Event object + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + private Event selectAllCellsInternal() { + if (!cellSelectionEnabled) { + return selectAllRowsInternal(); + } + + if (columns.size() == 0) { + return null; + } + + if (items.size() == 0) { + return null; + } + + int index = 0; + GridColumn column = displayOrderedColumns.get(index); + + while (!column.isVisible()) { + index++; + + if (index >= columns.size()) { + return null; + } + + column = displayOrderedColumns.get(index); + } + + final GridColumn oldFocusColumn = focusColumn; + final GridItem oldFocusItem = focusItem; + + focusColumn = column; + focusItem = items.get(0); + + final GridItem lastItem = getPreviousVisibleItem(null); + final GridColumn lastCol = getVisibleColumn_DegradeLeft(lastItem, + displayOrderedColumns.get(displayOrderedColumns.size() - 1)); + + final Event event = updateCellSelection(new Point(lastCol.index, lastItem.getRowIndex()), SWT.MOD2, true, + false); + + focusColumn = oldFocusColumn; + focusItem = oldFocusItem; + + updateColumnSelection(); + + redraw(); + return event; + } + + /** + * Selects rows in the receiver. + * + * @return An Event object + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + private Event selectAllRowsInternal() { + if (cellSelectionEnabled) { + return selectAllCellsInternal(); + } + + if (GridSelectionType.MULTI != selectionType) { + return null; + } + + if (items.size() == 0) { + return null; + } + + deselectAll(); + + final GridItem oldFocusItem = focusItem; + + final GridItem firstItem = getItem(getTopIndex()); + final GridItem lastItem = getPreviousVisibleItem(null); + + setFocusItem(firstItem); + updateSelection(firstItem, SWT.NONE); + + final Event event = updateSelection(lastItem, SWT.MOD2); + + setFocusItem(oldFocusItem); + + redraw(); + return event; + } + + /** + * Selects all cells in the given column in the receiver. + * + * @param col + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void selectColumn(final int col) { + checkWidget(); + final Vector cells = new Vector<>(); + getCells(getColumn(col), cells); + selectCells(cells.toArray(new Point[0])); + } + + /** + * Selects all cells in the given column group in the receiver. + * + * @param colGroup + * the column group + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void selectColumnGroup(final int colGroup) { + selectColumnGroup(getColumnGroup(colGroup)); + } + + /** + * Selects all cells in the given column group in the receiver. + * + * @param colGroup + * the column group + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void selectColumnGroup(final GridColumnGroup colGroup) { + checkWidget(); + final Vector cells = new Vector<>(); + getCells(colGroup, cells); + selectCells(cells.toArray(new Point[0])); + } + + /** + * Selects the selection to the given cell. The existing selection is cleared + * before selecting the given cell. + * + * @param cell + * point whose x values is a column index and y value is an item + * index + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the cell is invalid
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setCellSelection(final Point cell) { + checkWidget(); + + if (!cellSelectionEnabled) { + return; + } + + if (cell == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (!isValidCell(cell)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + + selectedCells.clear(); + addToCellSelection(cell); + updateColumnSelection(); + redraw(); + } + + /** + * Selects the selection to the given set of cell. The existing selection is + * cleared before selecting the given cells. + * + * @param cells + * point array whose x values is a column index and y value is an + * item index + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the cell array or an individual cell + * is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the a cell is invalid
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public void setCellSelection(final Point[] cells) { + checkWidget(); + + if (!cellSelectionEnabled) { + return; + } + + if (cells == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + for (final Point cell : cells) { + if (cell == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (!isValidCell(cell)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + + selectedCells.clear(); + for (final Point cell : cells) { + addToCellSelection(cell); + } + + updateColumnSelection(); + redraw(); + } + + /** + * Returns an array of cells that are currently selected in the receiver. The + * order of the items is unspecified. An empty array indicates that no items are + * selected. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * selection, so modifying the array will not affect the receiver. + *

+ * + * @return an array representing the cell selection + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public Point[] getCellSelection() { + checkWidget(); + return selectedCells.toArray(new Point[selectedCells.size()]); + } + + GridColumn getFocusColumn() { + return focusColumn; + } + + void updateColumnFocus() { + if (!focusColumn.isVisible()) { + final int index = displayOrderedColumns.indexOf(focusColumn); + if (index > 0) { + GridColumn prev = displayOrderedColumns.get(index - 1); + prev = getVisibleColumn_DegradeLeft(focusItem, prev); + if (prev == null) { + prev = getVisibleColumn_DegradeRight(focusItem, focusColumn); + } + focusColumn = prev; + } else { + focusColumn = getVisibleColumn_DegradeRight(focusItem, focusColumn); + } + } + } + + private void getCells(final GridColumn col, final Vector cells) { + + final int colIndex = col.index; + + int columnAtPosition = 0; + for (final GridColumn nextCol : displayOrderedColumns) { + if (!nextCol.isVisible()) { + continue; + } + + if (nextCol == col) { + break; + } + + columnAtPosition++; + } + + GridItem item = null; + if (getItemCount() > 0) { + item = getItem(0); + } + + while (item != null) { + // is cell spanned + final int position = -1; + boolean spanned = false; + for (final GridColumn nextCol : displayOrderedColumns) { + if (!nextCol.isVisible()) { + continue; + } + + if (nextCol == col) { + break; + } + + final int span = item.getColumnSpan(nextCol.index); + + if (position + span >= columnAtPosition) { + spanned = true; + break; + } + } + + if (!spanned && item.getColumnSpan(colIndex) == 0) { + cells.add(new Point(colIndex, item.getRowIndex())); + } + + item = getNextVisibleItem(item); + } + } + + private void getCells(final GridColumnGroup colGroup, final Vector cells) { + final GridColumn[] cols = colGroup.getColumns(); + for (final GridColumn col : cols) { + getCells(col, cells); + } + } + + private void getCells(final GridItem item, final Vector cells) { + final int itemIndex = item.getRowIndex(); + + int span = 0; + + for (final GridColumn nextCol : displayOrderedColumns) { + + if (span > 0) { + span--; + continue; + } + + if (!nextCol.isVisible()) { + continue; + } + + span = item.getColumnSpan(nextCol.index); + + cells.add(new Point(nextCol.index, itemIndex)); + } + } + + private Point[] getCells(final GridItem item) { + final Vector cells = new Vector<>(); + + final int itemIndex = item.getRowIndex(); + + int span = 0; + + for (final GridColumn nextCol : displayOrderedColumns) { + + if (span > 0) { + span--; + continue; + } + + if (!nextCol.isVisible()) { + continue; + } + + span = item.getColumnSpan(nextCol.index); + + cells.add(new Point(nextCol.index, itemIndex)); + } + return cells.toArray(new Point[] {}); + } + + private void getCells(final GridItem fromItem, final GridItem toItem, final Vector cells) { + final boolean descending = fromItem.getRowIndex() < toItem.getRowIndex(); + + GridItem iterItem = toItem; + + do { + getCells(iterItem, cells); + + if (iterItem == fromItem) { + break; + } + + if (descending) { + iterItem = getPreviousVisibleItem(iterItem); + } else { + iterItem = getNextVisibleItem(iterItem); + } + } while (true); + } + + private int blend(final int v1, final int v2, final int ratio) { + return (ratio * v1 + (100 - ratio) * v2) / 100; + } + + private RGB blend(final RGB c1, final RGB c2, final int ratio) { + final int r = blend(c1.red, c2.red, ratio); + final int g = blend(c1.green, c2.green, ratio); + final int b = blend(c1.blue, c2.blue, ratio); + return new RGB(r, g, b); + } + + /** + * Returns a point whose x and y values are the to and from column indexes of + * the new selection range inclusive of all spanned columns. + * + * @param fromItem + * @param fromColumn + * @param toItem + * @param toColumn + * @return + */ + private Point getSelectionRange(GridItem fromItem, GridColumn fromColumn, GridItem toItem, GridColumn toColumn) { + if (displayOrderedColumns.indexOf(fromColumn) > displayOrderedColumns.indexOf(toColumn)) { + final GridColumn temp = fromColumn; + fromColumn = toColumn; + toColumn = temp; + } + + if (fromItem.getRowIndex() > toItem.getRowIndex()) { + final GridItem temp = fromItem; + fromItem = toItem; + toItem = temp; + } + + boolean firstTime = true; + GridItem iterItem = fromItem; + + final int fromIndex = fromColumn.index; + final int toIndex = toColumn.index; + + do { + if (!firstTime) { + iterItem = getNextVisibleItem(iterItem); + } else { + firstTime = false; + } + + final Point cols = getRowSelectionRange(iterItem, fromColumn, toColumn); + + // check and see if column spanning means that the range increased + if (cols.x != fromIndex || cols.y != toIndex) { + final GridColumn newFrom = getColumn(cols.x); + final GridColumn newTo = getColumn(cols.y); + + // Unfortunately we have to start all over again from the top with the new range + return getSelectionRange(fromItem, newFrom, toItem, newTo); + } + } while (iterItem != toItem); + + return new Point(fromColumn.index, toColumn.index); + } + + /** + * Returns a point whose x and y value are the to and from column indexes of the + * new selection range inclusive of all spanned columns. + * + * @param item + * @param fromColumn + * @param toColumn + * @return + */ + private Point getRowSelectionRange(final GridItem item, final GridColumn fromColumn, final GridColumn toColumn) { + + int newFrom = fromColumn.index; + int newTo = toColumn.index; + + int span = 0; + int spanningColIndex = -1; + boolean spanningBeyondToCol = false; + + for (final GridColumn col : displayOrderedColumns) { + + if (!col.isVisible()) { + if (span > 0) { + span--; + } + continue; + } + + if (span > 0) { + if (col == fromColumn) { + newFrom = spanningColIndex; + } else if (col == toColumn && span > 1) { + spanningBeyondToCol = true; + } + + span--; + + if (spanningBeyondToCol && span == 0) { + newTo = col.index; + break; + } + } else { + final int index = col.index; + span = item.getColumnSpan(index); + if (span > 0) { + spanningColIndex = index; + } + + if (col == toColumn && span > 0) { + spanningBeyondToCol = true; + } + } + + if (col == toColumn && !spanningBeyondToCol) { + break; + } + + } + + return new Point(newFrom, newTo); + } + + /** + * Returns the column which is spanning the given column for the given item or + * null if it is not being spanned. + * + * @param item + * @param column + * @return + */ + private GridColumn getSpanningColumn(final GridItem item, final GridColumn column) { + int span = 0; + GridColumn spanningCol = null; + + for (final GridColumn col : displayOrderedColumns) { + + if (col == column) { + return spanningCol; + } + + if (span > 0) { + span--; + if (span == 0) { + spanningCol = null; + } + } else { + span = item.getColumnSpan(col.index); + + if (span > 0) { + spanningCol = col; + } + } + } + return spanningCol; + } + + /** + * Returns true if the given cell's x and y values are valid column and item + * indexes respectively. + * + * @param cell + * @return + */ + private boolean isValidCell(final Point cell) { + if (cell.x < 0 || cell.x >= columns.size()) { + return false; + } + + if (cell.y < 0 || cell.y >= items.size()) { + return false; + } + + return true; + } + + /** + * Shows the inplace tooltip for the given item and column. The location is the + * x and y origin of the text in the cell. + *

+ * This method may be overriden to provide their own custom tooltips. + * + * @param item + * the item currently hovered over or null. + * @param column + * the column currently hovered over or null. + * @param group + * the group currently hovered over or null. + * @param location + * the x,y origin of the text in the hovered object. + */ + protected void showToolTip(final GridItem item, final GridColumn column, final GridColumnGroup group, + final Point location) { + if (inplaceToolTip == null) { + inplaceToolTip = new GridToolTip(this); + } + + if (group != null) { + inplaceToolTip.setFont(getFont()); + inplaceToolTip.setText(group.getText()); + } else if (item != null) { + inplaceToolTip.setFont(item.getFont(column.index)); + inplaceToolTip.setText(item.getText(column.index)); + } else if (column != null) { + inplaceToolTip.setFont(getFont()); + inplaceToolTip.setText(column.getText()); + } + + final Point p = getDisplay().map(this, null, location); + + inplaceToolTip.setLocation(p); + + inplaceToolTip.setVisible(true); + } + + /** + * Hides the inplace tooltip. + *

+ * This method must be overriden when showToolTip is overriden. Subclasses must + * call super when overriding this method. + */ + protected void hideToolTip() { + if (inplaceToolTip != null) { + inplaceToolTip.setVisible(false); + } + if (inplaceTooltipCapture) { + setCapture(false); + inplaceTooltipCapture = false; + } + } + + void recalculateRowHeaderHeight(final GridItem item, final int oldHeight, final int newHeight) { + checkWidget(); + + if (newHeight > itemHeight) { + itemHeight = newHeight; + + userModifiedItemHeight = false; + hasDifferingHeights = false; + + itemHeight = computeItemHeight(items.get(0)); + + for (final GridItem item2 : items) { + item2.setHeight(itemHeight); + } + + setScrollValuesObsolete(); + redraw(); + } + + } + + void recalculateRowHeaderWidth(final GridItem item, final int oldWidth, final int newWidth) { + if (!isAutoWidth()) { + return; + } + + if (newWidth > rowHeaderWidth) { + rowHeaderWidth = newWidth; + } else if (newWidth < rowHeaderWidth && oldWidth == rowHeaderWidth) { + // if the changed width is smaller, and the previous width of that rows header + // was equal + // to the current row header width then its possible that we may need to make + // the new + // row header width smaller, but to do that we need to ask all the rows all over + // again + computeRowHeaderWidth(newWidth); + } + redraw(); + } + + /** + * {@inheritDoc} + */ + @Override + public void setFont(final Font font) { + dataVisualizer.setDefaultFont(font); + defaultFont = font; + super.setFont(font); + } + + /** + * Returns the row header width or 0 if row headers are not visible. + * + * @return the width of the row headers + * @throws org.eclipse.swt.SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getItemHeaderWidth() { + checkWidget(); + if (!rowHeaderVisible) { + return 0; + } + return rowHeaderWidth; + } + + /** + * Sets the row header width to the specified value. This automatically disables + * the auto width feature of the grid. + * + * @param width + * the width of the row header + * @see #getItemHeaderWidth() + * @see #setAutoWidth(boolean) + */ + public void setItemHeaderWidth(final int width) { + checkWidget(); + rowHeaderWidth = width; + setAutoWidth(false); + redraw(); + } + + /** + * Sets the number of items contained in the receiver. + * + * @param count + * the number of items + * + * @exception org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setItemCount(int count) { + checkWidget(); + setRedraw(false); + if (count < 0) { + count = 0; + } + + if (count < items.size()) { + + selectedCells.clear(); + for (int i = items.size() - 1; i >= count; i--) { + final GridItem removed = items.remove(i); + rootItems.remove(i); + + selectedItems.remove(removed); + + if (removed.isVisible()) { + currentVisibleItems--; + } + removed.disposeOnly(); + } + if (!disposing) { + updateColumnSelection(); + } + scrollValuesObsolete = true; + topIndex = -1; + bottomIndex = -1; + } + + while (count > items.size()) { + new GridItem(this, SWT.NONE); + } + setRedraw(true); + } + + /** + * Initialize accessibility. + */ + private void initAccessible() { + final Accessible accessible = getAccessible(); + accessible.addAccessibleListener(new AccessibleAdapter() { + @Override + public void getDescription(final AccessibleEvent e) { + final int childID = e.childID; + if (childID >= 0 && childID < items.size()) { + String descrption = ""; + for (int i = 0; i < columns.size(); i++) { + if (i != 0) { + descrption += columns.get(i).getText() + " : "; + descrption += items.get(childID).getText(i) + " "; + } + } + e.result = descrption; + } + } + + @Override + public void getName(final AccessibleEvent e) { + final int childID = e.childID; + if (childID >= 0 && childID < items.size()) { + // Name of the items + e.result = items.get(childID).getText(); + } else if (childID >= items.size() && childID < items.size() + columns.size()) { + // Name of the column headers + e.result = columns.get(childID - items.size()).getText(); + } else if (childID >= items.size() + columns.size() + && childID < items.size() + columns.size() + columnGroups.length) { + // Name of the column group headers + e.result = columnGroups[childID - items.size() - columns.size()].getText(); + } else if (childID >= items.size() + columns.size() + columnGroups.length + && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { + // Name of the toggle button for column group headers + e.result = ACC_TOGGLE_BUTTON_NAME; + } + } + }); + + accessible.addAccessibleControlListener(new AccessibleControlAdapter() { + @Override + public void getChildAtPoint(final AccessibleControlEvent e) { + final Point location = toControl(e.x, e.y); + e.childID = ACC.CHILDID_SELF; + + // Grid Items + final GridItem item = getItem(location); + if (item != null) { + for (int i = 0; i < getItemCount(); i++) { + if (item.equals(getItem(i))) { + e.childID = i; + return; + } + } + } else { + // Column Headers + final GridColumn column = overColumnHeader(location.x, location.y); + final int itemCount = getItemCount(); + if (column != null) { + for (int i = 0; i < getColumns().length; i++) { + if (column.equals(getColumn(i))) { + e.childID = itemCount + i; + return; + } + } + } else { + // Column Group headers + final GridColumnGroup columnGroup = overColumnGroupHeader(location.x, location.y); + if (columnGroup != null) { + for (int i = 0; i < getColumnGroups().length; i++) { + if (columnGroup.equals(getColumnGroup(i))) { + final Rectangle toggle = ((DefaultColumnGroupHeaderRenderer) columnGroup + .getHeaderRenderer()).getToggleBounds(); + if (toggle.contains(location.x, location.y)) { + // Toggle button for column group + // header + e.childID = itemCount + getColumns().length + getColumnGroups().length + i; + } else { + // Column Group header + e.childID = itemCount + getColumns().length + i; + } + return; + } + } + } + } + } + } + + @Override + public void getChildCount(final AccessibleControlEvent e) { + if (e.childID == ACC.CHILDID_SELF) { + int length = items.size(); + + if (isTree) { + // Child count for parent. Here if the item parent + // is not an other item, + // it is consider as children of Grid + for (final GridItem item : items) { + if (item.getParentItem() != null) { + length--; + } + } + } + e.detail = length; + } + } + + @Override + public void getChildren(final AccessibleControlEvent e) { + if (e.childID == ACC.CHILDID_SELF) { + int length = items.size(); + if (isTree) { + for (final GridItem item : items) { + if (item.getParentItem() != null) { + length--; + } + } + + final Object[] children = new Object[length]; + int j = 0; + + for (int i = 0; i < items.size(); i++) { + if (items.get(i).getParentItem() == null) { + children[j] = Integer.valueOf(i); + j++; + } + } + e.children = children; + } else { + final Object[] children = new Object[length]; + for (int i = 0; i < items.size(); i++) { + children[i] = Integer.valueOf(i); + } + e.children = children; + } + } + } + + @Override + public void getDefaultAction(final AccessibleControlEvent e) { + final int childID = e.childID; + if (childID >= 0 && childID < items.size()) { + if (getItem(childID).hasChildren()) { + // Action of tree items + if (getItem(childID).isExpanded()) { + e.result = ACC_ITEM_ACTION_COLLAPSE; + } else { + e.result = ACC_ITEM_ACTION_EXPAND; + } + } else { + // action of default items + e.result = ACC_ITEM_DEFAULT_ACTION; + } + } else if (childID >= items.size() && childID < items.size() + columns.size() + columnGroups.length) { + // action of column and column group header + e.result = ACC_COLUMN_DEFAULT_ACTION; + } else if (childID >= items.size() + columns.size() + columnGroups.length + && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { + // action of toggle button of column group header + e.result = SWT.getMessage("SWT_Press"); + } + } + + @Override + public void getLocation(final AccessibleControlEvent e) { + // location of parent + Rectangle location = getBounds(); + location.x = 0; + location.y = 0; + final int childID = e.childID; + + if (childID >= 0 && childID < items.size()) { + // location of items + final GridItem item = getItem(childID); + if (item != null) { + final Point p = getOrigin(columns.get(0), item); + location.y = p.y; + location.height = item.getHeight(); + } + } else if (childID >= items.size() && childID < items.size() + columns.size()) { + // location of columns headers + final GridColumn column = getColumn(childID - items.size()); + if (column != null) { + location.x = getColumnHeaderXPosition(column); + if (column.getColumnGroup() == null) { + location.y = 0; + } else { + location.y = groupHeaderHeight; + } + location.height = headerHeight; + location.width = column.getWidth(); + } + } else if (childID >= items.size() + columns.size() + && childID < items.size() + columns.size() + columnGroups.length) { + // location of column group header + final GridColumnGroup columnGroup = getColumnGroup(childID - items.size() - columns.size()); + if (columnGroup != null) { + location.y = 0; + location.height = groupHeaderHeight; + location.x = getColumnHeaderXPosition(columnGroup.getFirstVisibleColumn()); + int width = 0; + for (int i = 0; i < columnGroup.getColumns().length; i++) { + if (columnGroup.getColumns()[i].isVisible()) { + width += columnGroup.getColumns()[i].getWidth(); + } + } + location.width = width; + } + } else if (childID >= items.size() + columns.size() + columnGroups.length + && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { + // location of toggle button of column group header + final GridColumnGroup columnGroup = getColumnGroup( + childID - items.size() - columns.size() - columnGroups.length); + location = ((DefaultColumnGroupHeaderRenderer) columnGroup.getHeaderRenderer()).getToggleBounds(); + } + + if (location != null) { + final Point pt = toDisplay(location.x, location.y); + e.x = pt.x; + e.y = pt.y; + e.width = location.width; + e.height = location.height; + } + } + + @Override + public void getRole(final AccessibleControlEvent e) { + final int childID = e.childID; + if (childID >= 0 && childID < items.size()) { + // role of items + if (isTree) { + e.detail = ACC.ROLE_TREEITEM; + } else { + e.detail = ACC.ROLE_LISTITEM; + } + } else if (childID >= items.size() && childID < items.size() + columns.size() + columnGroups.length) { + // role of columns headers and column group headers + e.detail = ACC.ROLE_TABLECOLUMNHEADER; + } else if (childID >= items.size() + columns.size() + columnGroups.length + && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { + // role of toggle button of column group headers + e.detail = ACC.ROLE_PUSHBUTTON; + } else if (childID == ACC.CHILDID_SELF) { + // role of parent + if (isTree) { + e.detail = ACC.ROLE_TREE; + } else { + e.detail = ACC.ROLE_TABLE; + } + } + } + + @Override + public void getSelection(final AccessibleControlEvent e) { + e.childID = ACC.CHILDID_NONE; + if (selectedItems.size() == 1) { + // Single selection + e.childID = selectedItems.get(0).getRowIndex(); + } else if (selectedItems.size() > 1) { + // multiple selection + e.childID = ACC.CHILDID_MULTIPLE; + final int length = selectedItems.size(); + final Object[] children = new Object[length]; + + for (int i = 0; i < length; i++) { + final GridItem item = selectedItems.get(i); + children[i] = Integer.valueOf(item.getRowIndex()); + } + e.children = children; + } + } + + @Override + public void getState(final AccessibleControlEvent e) { + final int childID = e.childID; + if (childID >= 0 && childID < items.size()) { + // state of items + e.detail = ACC.STATE_SELECTABLE; + if (getDisplay().getActiveShell() == getParent().getShell()) { + e.detail |= ACC.STATE_FOCUSABLE; + } + + if (selectedItems.contains(getItem(childID))) { + e.detail |= ACC.STATE_SELECTED; + if (getDisplay().getActiveShell() == getParent().getShell()) { + e.detail |= ACC.STATE_FOCUSED; + } + } + + if (getItem(childID).getChecked()) { + e.detail |= ACC.STATE_CHECKED; + } + + // only for tree type items + if (getItem(childID).hasChildren()) { + if (getItem(childID).isExpanded()) { + e.detail |= ACC.STATE_EXPANDED; + } else { + e.detail |= ACC.STATE_COLLAPSED; + } + } + + if (!getItem(childID).isVisible()) { + e.detail |= ACC.STATE_INVISIBLE; + } + } else if (childID >= items.size() && childID < items.size() + columns.size() + columnGroups.length) { + // state of column headers and column group headers + e.detail = ACC.STATE_READONLY; + } else if (childID >= items.size() + columns.size() + columnGroups.length + && childID < items.size() + columns.size() + columnGroups.length + columnGroups.length) { + // state of toggle button of column group headers + if (getColumnGroup(childID - items.size() - columns.size() - columnGroups.length).getExpanded()) { + e.detail = ACC.STATE_EXPANDED; + } else { + e.detail = ACC.STATE_COLLAPSED; + } + } + } + + @Override + public void getValue(final AccessibleControlEvent e) { + final int childID = e.childID; + if (childID >= 0 && childID < items.size()) { + // value for tree items + if (isTree) { + e.result = "" + getItem(childID).getLevel(); + } + } + } + }); + + addListener(SWT.Selection, event -> { + if (selectedItems.size() > 0) { + accessible.setFocus(selectedItems.get(selectedItems.size() - 1).getRowIndex()); + } + }); + + addTreeListener(new TreeListener() { + @Override + public void treeCollapsed(final TreeEvent e) { + if (getFocusItem() != null) { + accessible.setFocus(getFocusItem().getRowIndex()); + } + } + + @Override + public void treeExpanded(final TreeEvent e) { + if (getFocusItem() != null) { + accessible.setFocus(getFocusItem().getRowIndex()); + } + } + }); + } + + /** + * @return the disposing + */ + boolean isDisposing() { + return disposing; + } + + /** + * @param hasSpanning + * the hasSpanning to set + */ + void setHasSpanning(final boolean hasSpanning) { + this.hasSpanning = hasSpanning; + } + + /** + * Returns the receiver's tool tip text, or null if it has not been set. + * + * @return the receiver's tool tip text + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public String getToolTipText() { + checkWidget(); + return toolTipText; + } + + /** + * Sets the receiver's tool tip text to the argument, which may be null + * indicating that no tool tip text should be shown. + * + * @param string + * the new tool tip text (or null) + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public void setToolTipText(final String string) { + checkWidget(); + toolTipText = string; + } + + /** + * Updates the row height when the first image is set on an item. + * + * @param column + * the column the image is change + * @param item + * item which images has just been set on. + */ + void imageSetOnItem(final int column, final GridItem item) { + if (sizeOnEveryItemImageChange) { + if (item == null || item.getImage(column) == null) { + return; + } + + int height = item.getImage(column).getBounds().height; + // FIXME Needs better algorithm + if(height + 20 > itemHeight) { + height = computeItemHeight(item); + setItemHeight(height); + } + } else { + if (firstImageSet || userModifiedItemHeight) { + return; + } + + final int height = computeItemHeight(item); + setItemHeight(height); + + firstImageSet = true; + } + } + + /** + * Determines if the mouse is hovering on the selection drag area and changes + * the pointer and sets field appropriately. + *

+ * Note: The 'selection drag area' is that part of the selection, on which a + * drag event can be initiated. This is either the border of the selection (i.e. + * a cell border between a slected and a non-selected cell) or the complete + * selection (i.e. anywhere on a selected cell). What area serves as drag area + * is determined by {@link #setDragOnFullSelection(boolean)}. + * + * @param x + * @param y + * @return + * @see #setDragOnFullSelection(boolean) + */ + private boolean handleHoverOnSelectionDragArea(final int x, final int y) { + boolean over = false; + // Point inSelection = null; + + if ((!rowHeaderVisible || x > rowHeaderWidth - SELECTION_DRAG_BORDER_THRESHOLD) + && (!columnHeadersVisible || y > headerHeight - SELECTION_DRAG_BORDER_THRESHOLD)) { + // not on a header + + // if(!dragOnFullSelection) + // { + // // drag area is the border of the selection + // + // if(cellSelectionEnabled) + // { + // Point neP = new Point( x-SELECTION_DRAG_BORDER_THRESHOLD, + // y-SELECTION_DRAG_BORDER_THRESHOLD ); + // Point ne = getCell(neP); + // Point nwP = new Point( x+SELECTION_DRAG_BORDER_THRESHOLD, + // y-SELECTION_DRAG_BORDER_THRESHOLD ); + // Point nw = getCell(nwP); + // Point swP = new Point( x+SELECTION_DRAG_BORDER_THRESHOLD, + // y+SELECTION_DRAG_BORDER_THRESHOLD ); + // Point sw = getCell(swP); + // Point seP = new Point( x-SELECTION_DRAG_BORDER_THRESHOLD, + // y+SELECTION_DRAG_BORDER_THRESHOLD ); + // Point se = getCell(seP); + // + // boolean neSel = ne != null && isCellSelected(ne); + // boolean nwSel = nw != null && isCellSelected(nw); + // boolean swSel = sw != null && isCellSelected(sw); + // boolean seSel = se != null && isCellSelected(se); + // + // over = (neSel || nwSel || swSel || seSel) && (!neSel || !nwSel || !swSel || + // !seSel); + //// inSelection = neSel ? neP : nwSel ? nwP : swSel ? swP : seSel ? seP : null; + // } + // else + // { + // Point nP = new Point( x, y-SELECTION_DRAG_BORDER_THRESHOLD ); + // GridItem n = getItem(nP); + // Point sP = new Point( x, y+SELECTION_DRAG_BORDER_THRESHOLD ); + // GridItem s = getItem(sP); + // + // boolean nSel = n != null && isSelected(n); + // boolean sSel = s != null && isSelected(s); + // + // over = nSel != sSel; + //// inSelection = nSel ? nP : sSel ? sP : null; + // } + // } + // else + // { + // drag area is the entire selection + + if (cellSelectionEnabled) { + final Point p = new Point(x, y); + final Point cell = getCell(p); + over = cell != null && isCellSelected(cell); + // inSelection = over ? p : null; + } else { + final Point p = new Point(x, y); + final GridItem item = getItem(p); + over = item != null && isSelected(item); + // inSelection = over ? p : null; + } + } + // } + + if (over != hoveringOnSelectionDragArea) { + // if (over) + // { + // // use drag cursor only in border mode + // if (!dragOnFullSelection) + // setCursor(getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL)); + //// potentialDragStart = inSelection; + // } + // else + // { + // setCursor(null); + //// potentialDragStart = null; + // } + hoveringOnSelectionDragArea = over; + } + return over; + } + + /** + * Display a mark indicating the point at which an item will be inserted. This + * is used as a visual hint to show where a dragged item will be inserted when + * dropped on the grid. This method should not be called directly, instead + * {@link DND#FEEDBACK_INSERT_BEFORE} or {@link DND#FEEDBACK_INSERT_AFTER} + * should be set in {@link DropTargetEvent#feedback} from within a + * {@link DropTargetListener}. + * + * @param item + * the insert item. Null will clear the insertion mark. + * @param column + * the column of the cell. Null will make the insertion mark span all + * columns. + * @param before + * true places the insert mark above 'item'. false places the insert + * mark below 'item'. + * + * @exception IllegalArgumentException + *

    + *
  • ERROR_INVALID_ARGUMENT - if the item or column has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + void setInsertMark(final GridItem item, final GridColumn column, final boolean before) { + checkWidget(); + if (item != null) { + if (item.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + if (column != null) { + if (column.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + insertMarkItem = item; + insertMarkColumn = column; + insertMarkBefore = before; + redraw(); + } + + /** + * A helper method for {@link GridDropTargetEffect#dragOver(DropTargetEvent)}. + * + * @param point + * @return true if point is near the top or bottom border of the visible grid + * area + */ + boolean isInDragScrollArea(final Point point) { + final int rhw = rowHeaderVisible ? rowHeaderWidth : 0; + final int chh = columnHeadersVisible ? headerHeight : 0; + final Rectangle top = new Rectangle(rhw, chh, getClientArea().width - rhw, DRAG_SCROLL_AREA_HEIGHT); + final Rectangle bottom = new Rectangle(rhw, getClientArea().height - DRAG_SCROLL_AREA_HEIGHT, + getClientArea().width - rhw, DRAG_SCROLL_AREA_HEIGHT); + return top.contains(point) || bottom.contains(point); + } + + /** + * Clears the item at the given zero-relative index in the receiver. The text, + * icon and other attributes of the item are set to the default value. If the + * table was created with the SWT.VIRTUAL style, these attributes + * are requested again as needed. + * + * @param index + * the index of the item to clear + * @param allChildren + * true if all child items of the indexed item should be + * cleared recursively, and false otherwise + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and + * the number of elements in the list minus 1 (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SWT#VIRTUAL + * @see SWT#SetData + */ + public void clear(final int index, final boolean allChildren) { + checkWidget(); + if (index < 0 || index >= items.size()) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + + final GridItem item = getItem(index); + item.clear(allChildren); + redraw(); + } + + /** + * Clears the items in the receiver which are between the given zero-relative + * start and end indices (inclusive). The text, icon and other attributes of the + * items are set to their default values. If the table was created with the + * SWT.VIRTUAL style, these attributes are requested again as + * needed. + * + * @param start + * the start index of the item to clear + * @param end + * the end index of the item to clear + * @param allChildren + * true if all child items of the range of items should + * be cleared recursively, and false otherwise + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if either the start or end are not + * between 0 and the number of elements in the list minus 1 + * (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SWT#VIRTUAL + * @see SWT#SetData + */ + public void clear(final int start, final int end, final boolean allChildren) { + checkWidget(); + if (start > end) { + return; + } + + final int count = items.size(); + if (!(0 <= start && start <= end && end < count)) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + for (int i = start; i <= end; i++) { + final GridItem item = items.get(i); + item.clear(allChildren); + } + redraw(); + } + + /** + * Clears the items at the given zero-relative indices in the receiver. The + * text, icon and other attributes of the items are set to their default values. + * If the table was created with the SWT.VIRTUAL style, these + * attributes are requested again as needed. + * + * @param indices + * the array of indices of the items + * @param allChildren + * true if all child items of the indexed items should + * be cleared recursively, and false otherwise + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and + * the number of elements in the list minus 1 (inclusive)
  • + *
  • ERROR_NULL_ARGUMENT - if the indices array is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SWT#VIRTUAL + * @see SWT#SetData + */ + public void clear(final int[] indices, final boolean allChildren) { + checkWidget(); + if (indices == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (indices.length == 0) { + return; + } + + final int count = items.size(); + for (final int index : indices) { + if (!(0 <= index && index < count)) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + } + for (final int indice : indices) { + final GridItem item = items.get(indice); + item.clear(allChildren); + } + redraw(); + } + + /** + * Clears all the items in the receiver. The text, icon and other attributes of + * the items are set to their default values. If the table was created with the + * SWT.VIRTUAL style, these attributes are requested again as + * needed. + * + * @param allChildren + * true if all child items of each item should be + * cleared recursively, and false otherwise + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SWT#VIRTUAL + * @see SWT#SetData + */ + public void clearAll(final boolean allChildren) { + checkWidget(); + if (items.size() > 0) { + clear(0, items.size() - 1, allChildren); + } + } + + /** + * Recalculate the height of the header + */ + public void recalculateHeader() { + final int previous = getHeaderHeight(); + computeHeaderHeight(); + + if (previous != getHeaderHeight()) { + scrollValuesObsolete = true; + redraw(); + } + } + + /** + * Query the grid for all currently visible rows and columns + *

+ * This support is provisional and may change + *

+ * + * @return all currently visible rows and columns + */ + public GridVisibleRange getVisibleRange() { + // FIXME I think we should remember the topIndex in the onPaint-method + final int topIndex = getTopIndex(); + final int bottomIndex = getBottomIndex(); + final int startColumnIndex = getStartColumnIndex(); + final int endColumnIndex = getEndColumnIndex(); + + final GridVisibleRange range = new GridVisibleRange(); + range.items = new GridItem[0]; + range.columns = new GridColumn[0]; + + if (topIndex <= bottomIndex) { + if (items.size() > 0) { + range.items = new GridItem[bottomIndex - topIndex + 1]; + for (int i = topIndex; i <= bottomIndex; i++) { + range.items[i - topIndex] = items.get(i); + } + } + } + + if (startColumnIndex <= endColumnIndex) { + if (displayOrderedColumns.size() > 0) { + final List cols = new ArrayList<>(); + for (int i = startColumnIndex; i <= endColumnIndex; i++) { + final GridColumn col = displayOrderedColumns.get(i); + if (col.isVisible()) { + cols.add(col); + } + } + + range.columns = new GridColumn[cols.size()]; + cols.toArray(range.columns); + } + } + + return range; + } + + int getStartColumnIndex() { + checkWidget(); + + if (startColumnIndex != -1) { + return startColumnIndex; + } + + if (!hScroll.getVisible()) { + startColumnIndex = 0; + } + + startColumnIndex = hScroll.getSelection(); + + return startColumnIndex; + } + + int getEndColumnIndex() { + checkWidget(); + + if (endColumnIndex != -1) { + return endColumnIndex; + } + + if (displayOrderedColumns.size() == 0) { + endColumnIndex = 0; + } else if (getVisibleGridWidth() < 1) { + endColumnIndex = getStartColumnIndex(); + } else { + int x = 0; + x -= getHScrollSelectionInPixels(); + + if (rowHeaderVisible) { + // row header is actually painted later + x += rowHeaderWidth; + } + + final int startIndex = getStartColumnIndex(); + final GridColumn[] columns = new GridColumn[displayOrderedColumns.size()]; + displayOrderedColumns.toArray(columns); + + for (int i = startIndex; i < columns.length; i++) { + endColumnIndex = i; + final GridColumn column = columns[i]; + + if (column.isVisible()) { + x += column.getWidth(); + } + + if (x > getClientArea().width) { + + break; + } + } + + } + + endColumnIndex = Math.max(0, endColumnIndex); + + return endColumnIndex; + } + + void setSizeOnEveryItemImageChange(final boolean sizeOnEveryItemImageChange) { + this.sizeOnEveryItemImageChange = sizeOnEveryItemImageChange; + } + + /** + * Returns the width of the row headers. + * + * @return width of the column header row + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread + * that created the receiver
  • + *
+ */ + public int getRowHeaderWidth() { + checkWidget(); + return rowHeaderWidth; + } + + /** + * Sets the value of the auto-height feature. When enabled, this feature resizes + * the height of rows to reflect the content of cells with word-wrapping + * enabled. Cell word-wrapping is enabled via the + * GridColumn.setWordWrap(boolean) method. If column headers have word-wrapping + * enabled, this feature will also resize the height of the column headers as + * necessary. + * + * @param enabled + * Set to true to enable this feature, false (default) otherwise. + */ + public void setAutoHeight(final boolean enabled) { + if (autoHeight == enabled) { + return; + } + + checkWidget(); + autoHeight = enabled; + setRowsResizeable(false); // turn of resizing of row height since it conflicts with this property + redraw(); + } + + /** + * Returns the value of the auto-height feature, which resizes row heights and + * column header heights based on word-wrapped content. + * + * @return Returns whether or not the auto-height feature is enabled. + * @see #setAutoHeight(boolean) + */ + public boolean isAutoHeight() { + return autoHeight; + } + + /** + * Sets the value of the auto-width feature. When enabled, this feature resizes + * the width of the row headers to reflect the content of row headers. + * + * @param enabled + * Set to true to enable this feature, false (default) otherwise. + * @see #isAutoWidth() + */ + public void setAutoWidth(final boolean enabled) { + if (autoWidth == enabled) { + return; + } + + checkWidget(); + autoWidth = enabled; + redraw(); + } + + /** + * Returns the value of the auto-height feature, which resizes row header width + * based on content. + * + * @return Returns whether or not the auto-width feature is enabled. + * @see #setAutoWidth(boolean) + */ + public boolean isAutoWidth() { + return autoWidth; + } + + /** + * Sets the value of the word-wrap feature for row headers. When enabled, this + * feature will word-wrap the contents of row headers. + * + * @param enabled + * Set to true to enable this feature, false (default) otherwise. + * @see #isWordWrapHeader() + */ + public void setWordWrapHeader(final boolean enabled) { + if (wordWrapRowHeader == enabled) { + return; + } + + checkWidget(); + wordWrapRowHeader = enabled; + redraw(); + } + + /** + * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color) + */ + @Override + public void setForeground(final Color color) { + dataVisualizer.setDefaultForeground(color); + super.setForeground(color); + } + + /** + * Returns the value of the row header word-wrap feature, which word-wraps the + * content of row headers. + * + * @return Returns whether or not the row header word-wrap feature is enabled. + * @see #setWordWrapHeader(boolean) + */ + public boolean isWordWrapHeader() { + return wordWrapRowHeader; + } + + /** + * Refresh hasData {@link GridItem} state if {@link Grid} is virtual + */ + public void refreshData() { + if ((getStyle() & SWT.VIRTUAL) != 0) { + for (final GridItem item : items) { + item.setHasSetData(false); + } + } + } + + /** + * @return true if the mouse navigation is enabled on tab/shift tab + */ + public boolean isMoveOnTab() { + checkWidget(); + return moveOnTab; + } + + /** + * This param allows user to change the current selection by pressing TAB and + * SHIFT-TAB + * + * @param moveOnTab + * if true, navigation with tab key is enabled. + */ + public void setMoveOnTab(final boolean moveOnTab) { + checkWidget(); + this.moveOnTab = moveOnTab; + } + + private void computeRowHeaderWidth(final int minWidth) { + estimate(sizingGC -> {// + final int width = items.stream() // + .mapToInt(item -> rowHeaderRenderer.computeSize(sizingGC, SWT.DEFAULT, SWT.DEFAULT, item).x) // + .max() // + .orElse(minWidth); + rowHeaderWidth = width > minWidth ? width : minWidth; + }); + } + + private int estimateWithResult(final ToIntFunction function) { + final GC gc = new GC(Grid.this); + try { + return function.applyAsInt(gc); + } finally { + gc.dispose(); + } + } + + private void estimate(final Consumer consumer) { + estimateWithResult(gc -> { + consumer.accept(gc); + return 0; + }); + } + + /** + * @return true if the grid has focus + */ + public boolean isFocusOnGrid() { + checkWidget(); + return getDisplay().getFocusControl() == this; + } + + /** + * Change selection type (single or multi) + * + * @param selectionType + * the new selection type + */ + public void setSelectionType(final GridSelectionType selectionType) { + checkWidget(); + this.selectionType = selectionType; + } + + /** + * @see org.eclipse.swt.widgets.Control#addMouseListener(org.eclipse.swt.events.MouseListener) + */ + @Override + public void addMouseListener(final MouseListener sourceListener) { + checkWidget(); + if (sourceListener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + addListener(SWT.MouseUp, e -> { + sourceListener.mouseUp(new MouseEvent(e)); + }); + addListener(SWT.MouseDown, e -> { + sourceListener.mouseDown(new MouseEvent(e)); + }); + addListener(SWT.MouseDoubleClick, e -> { + if (e.doit) { + sourceListener.mouseDoubleClick(new MouseEvent(e)); + } + }); + } + + /** + * @see org.eclipse.swt.widgets.Widget#addListener(int, + * org.eclipse.swt.widgets.Listener) + */ + @Override + public void addListener(final int eventType, final Listener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (eventType == SWT.MouseDoubleClick) { + super.addListener(SWT.MouseDoubleClick, e -> { + if (e.doit) { + listener.handleEvent(e); + } + }); + } else { + super.addListener(eventType, listener); + } + + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridCellRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridCellRenderer.java index 609d5a13c..6d2ec6eed 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridCellRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridCellRenderer.java @@ -1,298 +1,298 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Rectangle; - -/** - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A - * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE - * VERSIONS. - *

- * The super class for all grid cell renderers. Contains the properties specific - * to a grid cell. - * - * @author chris.gross@us.ibm.com - */ -public abstract class GridCellRenderer extends AbstractInternalWidget { - - private int row = 0; - - private int column = 0; - - private int alignment = SWT.LEFT; - - private int verticalAlignment = SWT.TOP; - - private boolean tree = false; - - private boolean check = false; - - private boolean rowHover = false; - - private boolean columnHover = false; - - private boolean rowFocus = false; - - private boolean cellFocus = false; - - private boolean cellSelected = false; - - private boolean wordWrap = false; - - private boolean dragging = false; - - /** - * Truncation style - */ - protected int truncationStyle = SWT.CENTER; - - /** - * @return Returns the row. - */ - public int getRow() { - return row; - } - - /** - * @param row - * The row to set. - */ - public void setRow(int row) { - this.row = row; - } - - /** - * @return Returns the alignment. - */ - public int getAlignment() { - return alignment; - } - - /** - * @param alignment - * The alignment to set. - */ - public void setAlignment(int alignment) { - this.alignment = alignment; - } - - /** - * @return Returns the vertical alignment. - */ - public int getVerticalAlignment() { - return verticalAlignment; - } - - /** - * @param verticalAlignment - * The vertical alignment to set. - */ - public void setVerticalAlignment(int verticalAlignment) { - this.verticalAlignment = verticalAlignment; - } - - /** - * @return Returns the check. - */ - public boolean isCheck() { - return check; - } - - /** - * @param check - * The check to set. - */ - public void setCheck(boolean check) { - this.check = check; - } - - /** - * @return Returns the tree. - */ - public boolean isTree() { - return tree; - } - - /** - * @param tree - * The tree to set. - */ - public void setTree(boolean tree) { - this.tree = tree; - } - - /** - * @return Returns the column. - */ - public int getColumn() { - return column; - } - - /** - * @param column - * The column to set. - */ - public void setColumn(int column) { - this.column = column; - } - - /** - * @return Returns the columnHover. - */ - public boolean isColumnHover() { - return columnHover; - } - - /** - * @param columnHover - * The columnHover to set. - */ - public void setColumnHover(boolean columnHover) { - this.columnHover = columnHover; - } - - /** - * @return Returns the rowHover. - */ - public boolean isRowHover() { - return rowHover; - } - - /** - * @param rowHover - * The rowHover to set. - */ - public void setRowHover(boolean rowHover) { - this.rowHover = rowHover; - } - - /** - * @return Returns the columnFocus. - */ - public boolean isCellFocus() { - return cellFocus; - } - - /** - * @param columnFocus - * The columnFocus to set. - */ - public void setCellFocus(boolean columnFocus) { - this.cellFocus = columnFocus; - } - - /** - * @return Returns the rowFocus. - */ - public boolean isRowFocus() { - return rowFocus; - } - - /** - * @param rowFocus - * The rowFocus to set. - */ - public void setRowFocus(boolean rowFocus) { - this.rowFocus = rowFocus; - } - - /** - * @return the cellSelected - */ - public boolean isCellSelected() { - return cellSelected; - } - - /** - * @param cellSelected - * the cellSelected to set - */ - public void setCellSelected(boolean cellSelected) { - this.cellSelected = cellSelected; - } - - /** - * Returns the bounds of the text in the cell. This is used when displaying - * in-place tooltips. If null is returned here, in-place tooltips - * will not be displayed. If the preferred argument is - * true then the returned bounds should be large enough to show the - * entire text. If preferred is false then the - * returned bounds should be be relative to the current bounds. - * - * @param item - * item to calculate text bounds. - * @param preferred - * true if the preferred width of the text should be returned. - * @return bounds of the text. - */ - public Rectangle getTextBounds(GridItem item, boolean preferred) { - return null; - } - - /** - * @return the wordWrap - */ - public boolean isWordWrap() { - return wordWrap; - } - - /** - * @param wordWrap - * the wordWrap to set - */ - public void setWordWrap(boolean wordWrap) { - this.wordWrap = wordWrap; - } - - /** - * Gets the dragging state. - * - * @return Returns the dragging state. - */ - public boolean isDragging() { - return dragging; - } - - /** - * Sets the dragging state. - * - * @param dragging - * The state to set. - */ - public void setDragging(boolean dragging) { - this.dragging = dragging; - } - - /** - * Get the truncation style - * @return the truncation style. - */ - public int getTruncationStyle() { - return truncationStyle; - } - - /** - * Set the truncation style to use when cell content is too large. - * @see SWT#LEFT - * @see SWT#CENTER - * @see SWT#RIGHT - * @param truncationStyle - */ - public void setTruncationStyle(int truncationStyle) { - this.truncationStyle = truncationStyle; - } -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Rectangle; + +/** + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A + * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE + * VERSIONS. + *

+ * The super class for all grid cell renderers. Contains the properties specific + * to a grid cell. + * + * @author chris.gross@us.ibm.com + */ +public abstract class GridCellRenderer extends AbstractInternalWidget { + + private int row = 0; + + private int column = 0; + + private int alignment = SWT.LEFT; + + private int verticalAlignment = SWT.TOP; + + private boolean tree = false; + + private boolean check = false; + + private boolean rowHover = false; + + private boolean columnHover = false; + + private boolean rowFocus = false; + + private boolean cellFocus = false; + + private boolean cellSelected = false; + + private boolean wordWrap = false; + + private boolean dragging = false; + + /** + * Truncation style + */ + protected int truncationStyle = SWT.CENTER; + + /** + * @return Returns the row. + */ + public int getRow() { + return row; + } + + /** + * @param row + * The row to set. + */ + public void setRow(int row) { + this.row = row; + } + + /** + * @return Returns the alignment. + */ + public int getAlignment() { + return alignment; + } + + /** + * @param alignment + * The alignment to set. + */ + public void setAlignment(int alignment) { + this.alignment = alignment; + } + + /** + * @return Returns the vertical alignment. + */ + public int getVerticalAlignment() { + return verticalAlignment; + } + + /** + * @param verticalAlignment + * The vertical alignment to set. + */ + public void setVerticalAlignment(int verticalAlignment) { + this.verticalAlignment = verticalAlignment; + } + + /** + * @return Returns the check. + */ + public boolean isCheck() { + return check; + } + + /** + * @param check + * The check to set. + */ + public void setCheck(boolean check) { + this.check = check; + } + + /** + * @return Returns the tree. + */ + public boolean isTree() { + return tree; + } + + /** + * @param tree + * The tree to set. + */ + public void setTree(boolean tree) { + this.tree = tree; + } + + /** + * @return Returns the column. + */ + public int getColumn() { + return column; + } + + /** + * @param column + * The column to set. + */ + public void setColumn(int column) { + this.column = column; + } + + /** + * @return Returns the columnHover. + */ + public boolean isColumnHover() { + return columnHover; + } + + /** + * @param columnHover + * The columnHover to set. + */ + public void setColumnHover(boolean columnHover) { + this.columnHover = columnHover; + } + + /** + * @return Returns the rowHover. + */ + public boolean isRowHover() { + return rowHover; + } + + /** + * @param rowHover + * The rowHover to set. + */ + public void setRowHover(boolean rowHover) { + this.rowHover = rowHover; + } + + /** + * @return Returns the columnFocus. + */ + public boolean isCellFocus() { + return cellFocus; + } + + /** + * @param columnFocus + * The columnFocus to set. + */ + public void setCellFocus(boolean columnFocus) { + this.cellFocus = columnFocus; + } + + /** + * @return Returns the rowFocus. + */ + public boolean isRowFocus() { + return rowFocus; + } + + /** + * @param rowFocus + * The rowFocus to set. + */ + public void setRowFocus(boolean rowFocus) { + this.rowFocus = rowFocus; + } + + /** + * @return the cellSelected + */ + public boolean isCellSelected() { + return cellSelected; + } + + /** + * @param cellSelected + * the cellSelected to set + */ + public void setCellSelected(boolean cellSelected) { + this.cellSelected = cellSelected; + } + + /** + * Returns the bounds of the text in the cell. This is used when displaying + * in-place tooltips. If null is returned here, in-place tooltips + * will not be displayed. If the preferred argument is + * true then the returned bounds should be large enough to show the + * entire text. If preferred is false then the + * returned bounds should be be relative to the current bounds. + * + * @param item + * item to calculate text bounds. + * @param preferred + * true if the preferred width of the text should be returned. + * @return bounds of the text. + */ + public Rectangle getTextBounds(GridItem item, boolean preferred) { + return null; + } + + /** + * @return the wordWrap + */ + public boolean isWordWrap() { + return wordWrap; + } + + /** + * @param wordWrap + * the wordWrap to set + */ + public void setWordWrap(boolean wordWrap) { + this.wordWrap = wordWrap; + } + + /** + * Gets the dragging state. + * + * @return Returns the dragging state. + */ + public boolean isDragging() { + return dragging; + } + + /** + * Sets the dragging state. + * + * @param dragging + * The state to set. + */ + public void setDragging(boolean dragging) { + this.dragging = dragging; + } + + /** + * Get the truncation style + * @return the truncation style. + */ + public int getTruncationStyle() { + return truncationStyle; + } + + /** + * Set the truncation style to use when cell content is too large. + * @see SWT#LEFT + * @see SWT#CENTER + * @see SWT#RIGHT + * @param truncationStyle + */ + public void setTruncationStyle(int truncationStyle) { + this.truncationStyle = truncationStyle; + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridCellSpanManager.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridCellSpanManager.java index 6a97f6df8..8046007bc 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridCellSpanManager.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridCellSpanManager.java @@ -1,70 +1,70 @@ -/******************************************************************************* - * Copyright (c) 2009 Claes Rosell - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Claes Rosell - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.swt.graphics.Rectangle; - -class GridCellSpanManager { - List listOfCellSpanRectangles = new ArrayList<>(); - Rectangle lastUsedCellSpanRectangle = null; - - protected void addCellSpanInfo(int colIndex, int rowIndex, int colSpan, - int rowSpan) { - Rectangle rect = new Rectangle(colIndex, rowIndex, colSpan + 1, - rowSpan + 1); - this.listOfCellSpanRectangles.add(rect); - } - - private Rectangle findSpanRectangle(int columnIndex, int rowIndex) { - Iterator iter = listOfCellSpanRectangles.iterator(); - while (iter.hasNext()) { - Rectangle cellSpanRectangle = iter.next(); - if (cellSpanRectangle.contains(columnIndex, rowIndex)) { - return cellSpanRectangle; - } - } - return null; - } - - protected boolean skipCell(int columnIndex, int rowIndex) { - this.lastUsedCellSpanRectangle = this.findSpanRectangle(columnIndex, - rowIndex); - return this.lastUsedCellSpanRectangle != null; - } - - protected void consumeCell(int columnIndex, int rowIndex) { - Rectangle rectangleToConsume = null; - - if (this.lastUsedCellSpanRectangle != null - && this.lastUsedCellSpanRectangle.contains(columnIndex, - rowIndex)) { - rectangleToConsume = this.lastUsedCellSpanRectangle; - } else { - rectangleToConsume = this.findSpanRectangle(columnIndex, rowIndex); - } - - if (rectangleToConsume != null) { - if (columnIndex >= rectangleToConsume.x - + (rectangleToConsume.width - 1) - && rowIndex >= (rectangleToConsume.y - + rectangleToConsume.height - 1)) { - this.listOfCellSpanRectangles.remove(rectangleToConsume); - } - } - } -} +/******************************************************************************* + * Copyright (c) 2009 Claes Rosell + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Claes Rosell - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.swt.graphics.Rectangle; + +class GridCellSpanManager { + List listOfCellSpanRectangles = new ArrayList<>(); + Rectangle lastUsedCellSpanRectangle = null; + + protected void addCellSpanInfo(int colIndex, int rowIndex, int colSpan, + int rowSpan) { + Rectangle rect = new Rectangle(colIndex, rowIndex, colSpan + 1, + rowSpan + 1); + this.listOfCellSpanRectangles.add(rect); + } + + private Rectangle findSpanRectangle(int columnIndex, int rowIndex) { + Iterator iter = listOfCellSpanRectangles.iterator(); + while (iter.hasNext()) { + Rectangle cellSpanRectangle = iter.next(); + if (cellSpanRectangle.contains(columnIndex, rowIndex)) { + return cellSpanRectangle; + } + } + return null; + } + + protected boolean skipCell(int columnIndex, int rowIndex) { + this.lastUsedCellSpanRectangle = this.findSpanRectangle(columnIndex, + rowIndex); + return this.lastUsedCellSpanRectangle != null; + } + + protected void consumeCell(int columnIndex, int rowIndex) { + Rectangle rectangleToConsume = null; + + if (this.lastUsedCellSpanRectangle != null + && this.lastUsedCellSpanRectangle.contains(columnIndex, + rowIndex)) { + rectangleToConsume = this.lastUsedCellSpanRectangle; + } else { + rectangleToConsume = this.findSpanRectangle(columnIndex, rowIndex); + } + + if (rectangleToConsume != null) { + if (columnIndex >= rectangleToConsume.x + + (rectangleToConsume.width - 1) + && rowIndex >= (rectangleToConsume.y + + rectangleToConsume.height - 1)) { + this.listOfCellSpanRectangles.remove(rectangleToConsume); + } + } + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridColumnGroup.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridColumnGroup.java index 9f1dda143..3866f1c83 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridColumnGroup.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridColumnGroup.java @@ -1,501 +1,501 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - * mario.winterer@scch.at - bugfix in 244333 - * Marty Jones - custom header/footer font in bug 293743 - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import java.util.Vector; - -import org.eclipse.nebula.widgets.grid.internal.DefaultColumnGroupHeaderRenderer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.TreeListener; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.TypedListener; - -/** - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A PRE-RELEASE ALPHA - * VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE VERSIONS. - *

- * Instances of this class represent a column group in a grid widget. A column group header is - * displayed above grouped columns. The column group can optionally be configured to expand and - * collapse. A column group in the expanded state shows {@code GridColumn}s whose detail property - * is true. A column group in the collapsed state shows {@code GridColumn}s whose summary property - * is true. - *

- *

- *
Styles:
- *
SWT.TOGGLE
- *
Events:
- *
Expand, Collapse
- *
- * - * @author chris.gross@us.ibm.com - */ -public class GridColumnGroup extends Item -{ - - private Grid parent; - - private GridColumn[] columns = new GridColumn[] {}; - - private boolean expanded = true; - - private Font headerFont; - - /** - * Header renderer. - */ - private GridHeaderRenderer headerRenderer = new DefaultColumnGroupHeaderRenderer(); - - /** - * Constructs a new instance of this class given its parent (which must be a Table) and a style - * value describing its behavior and appearance. - * - * @param parent the parent table - * @param style the style of the group - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that - * created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • - *
- */ - public GridColumnGroup(Grid parent, int style) - { - super(parent, style); - this.parent = parent; - - init(style); - parent.newColumnGroup(this); - } - - - private void init(int style) { - headerRenderer.setDisplay(getDisplay()); - if ((getStyle() & SWT.RIGHT) == SWT.RIGHT) { - headerRenderer.setHorizontalAlignment(SWT.RIGHT); - } - - if ((getStyle() & SWT.CENTER) == SWT.CENTER) { - headerRenderer.setHorizontalAlignment(SWT.CENTER); - } - - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when an item in the receiver is expanded or collapsed - * by sending it one of the messages defined in the TreeListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see TreeListener - * @see #removeTreeListener - */ - public void addTreeListener(TreeListener listener) { - checkWidget (); - if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener (listener); - addListener (SWT.Expand, typedListener); - addListener (SWT.Collapse, typedListener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when items in the receiver are expanded or collapsed. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see TreeListener - * @see #addTreeListener - */ - public void removeTreeListener(TreeListener listener) { - checkWidget (); - if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); - removeListener (SWT.Expand, listener); - removeListener (SWT.Collapse, listener); - } - - /** - * @return the parent grid - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that - * created the receiver
  • - *
- */ - public Grid getParent() - { - checkWidget(); - return parent; - } - - int getNewColumnIndex() - { - if (columns.length == 0) - { - return -1; - } - - GridColumn lastCol = columns[columns.length - 1]; - return lastCol.index + 1; - } - - void newColumn(GridColumn column, int index) - { - GridColumn[] newAllColumns = new GridColumn[columns.length + 1]; - System.arraycopy(columns, 0, newAllColumns, 0, columns.length); - newAllColumns[newAllColumns.length - 1] = column; - columns = newAllColumns; - } - - void removeColumn(GridColumn col) - { - - if (columns.length == 0) - return; // widget is disposing - - GridColumn[] newAllColumns = new GridColumn[columns.length - 1]; - int x = 0; - for (int i = 0; i < columns.length; i++) - { - if (columns[i] != col) - { - newAllColumns[x] = columns[i]; - x ++; - } - } - columns = newAllColumns; - } - - /** - * Returns the columns within this group. - *

- * Note: This is not the actual structure used by the receiver to maintain - * its list of items, so modifying the array will not affect the receiver. - *

- * @return the columns - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that - * created the receiver
  • - *
- */ - public GridColumn[] getColumns() - { - checkWidget(); - GridColumn[] newArray = new GridColumn[columns.length]; - System.arraycopy (columns, 0, newArray, 0, columns.length); - return newArray; - } - - /** - * {@inheritDoc} - */ - @Override - public void dispose() - { - super.dispose(); - - if (parent.isDisposing()) - return; - - GridColumn[] oldColumns = columns; - columns = new GridColumn[0]; - - for (int i = 0; i < oldColumns.length; i++) { - oldColumns[i].dispose(); - } - - parent.removeColumnGroup(this); - } - - /** - * @return the header renderer. - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that - * created the receiver
  • - *
- */ - public GridHeaderRenderer getHeaderRenderer() - { - checkWidget(); - return headerRenderer; - } - - /** - * Sets the header renderer. - * - * @param headerRenderer The headerRenderer to set. - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the renderer is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that - * created the receiver
  • - *
- */ - public void setHeaderRenderer(GridHeaderRenderer headerRenderer) - { - if (headerRenderer == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - this.headerRenderer = headerRenderer; - headerRenderer.setDisplay(getDisplay()); - } - - /** - * Returns true if the receiver is expanded, false otherwise. - * - * @return the expanded attribute - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that - * created the receiver
  • - *
- */ - public boolean getExpanded() - { - checkWidget(); - return expanded; - } - - /** - * Sets the expanded state of the receiver. - * - * @param expanded the expanded to set - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that - * created the receiver
  • - *
- */ - public void setExpanded(boolean expanded) - { - checkWidget(); - - this.expanded = expanded; - - if (!expanded && getParent().getCellSelectionEnabled()) - { - Vector collapsedCols = new Vector<>(); - for (int j = 0; j < columns.length; j++) - { - if (!columns[j].isSummary()) - { - collapsedCols.add(columns[j].index); - } - } - Point[] selection = getParent().getCellSelection(); - for (int i = 0; i < selection.length; i++) - { - if (collapsedCols.contains(new Integer(selection[i].x))) - { - getParent().deselectCell(selection[i]); - } - } - - if (getParent().getFocusColumn() != null && getParent().getFocusColumn().getColumnGroup() == this) - { - getParent().updateColumnFocus(); - } - - parent.updateColumnSelection(); - } - - if (parent.getCellSelectionEnabled()) - - - parent.refreshHoverState(); - parent.setScrollValuesObsolete(); - parent.redraw(); - } - - /** - * Returns the first visible column in this column group. - * - * @return first visible column - */ - GridColumn getFirstVisibleColumn() - { - GridColumn[] cols = parent.getColumnsInOrder(); - for (int i = 0; i < cols.length; i++) - { - if (cols[i].getColumnGroup() == this && cols[i].isVisible()) - { - return cols[i]; - } - } - return null; - } - - /** - * Returns the last visible column in this column group. - * - * @return last visible column - */ - GridColumn getLastVisibleColumn() - { - GridColumn[] cols = parent.getColumnsInOrder(); - GridColumn lastVisible = null; - for (int i = 0; i < cols.length; i++) - { - if (cols[i].getColumnGroup() == this && cols[i].isVisible()) - { - lastVisible = cols[i]; - } - } - return lastVisible; - } - - Rectangle getBounds() - { - Rectangle bounds = new Rectangle(0, 0, 0, 0); - - bounds.height = parent.getGroupHeaderHeight(); - - boolean foundFirstColumnInGroup = false; - - GridColumn[] cols = parent.getColumnsInOrder(); - for (int i = 0; i < cols.length; i++) - { - if (cols[i].getColumnGroup() == this) - { - if (cols[i].isVisible()) - { - if (!foundFirstColumnInGroup) - { - bounds.x = parent.getOrigin(cols[i], null).x; - foundFirstColumnInGroup = true; - } - bounds.width += cols[i].getWidth(); - } - } - else - { - if (foundFirstColumnInGroup) - { - break; - } - } - } - - return bounds; - } - /** - * Sets whether or not text is word-wrapped in the header for this column group. If Grid.setAutoHeight(true) is set, the row height - * is adjusted to accommodate word-wrapped text. - * @param wordWrap Set to true to wrap the text, false otherwise - * @see #getHeaderWordWrap() - */ - public void setHeaderWordWrap(boolean wordWrap) - { - checkWidget(); - headerRenderer.setWordWrap(wordWrap); - parent.redraw(); - } - /** - * Returns whether or not text is word-wrapped in the header for this column group. - * @return true if the header wraps its text. - * @see GridColumn#setHeaderWordWrap(boolean) - */ - public boolean getHeaderWordWrap() - { - checkWidget(); - return headerRenderer.isWordWrap(); - } - - /** - * Returns the font that the receiver will use to paint textual information - * for the header. - * - * @return the receiver's font - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that - * created the receiver
  • - *
- */ - public Font getHeaderFont() { - checkWidget(); - - if (headerFont == null) { - return parent.getFont(); - } - return headerFont; - } - - /** - * Sets the Font to be used when displaying the Header text. - * @param font - */ - public void setHeaderFont(Font font) { - checkWidget(); - this.headerFont = font; - } - - /** - * Returns the column group header alignment. - * - * @return SWT.LEFT, SWT.RIGHT, SWT.CENTER - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getAlignment() { - checkWidget(); - return headerRenderer.getHorizontalAlignment(); - } -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + * mario.winterer@scch.at - bugfix in 244333 + * Marty Jones - custom header/footer font in bug 293743 + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import java.util.Vector; + +import org.eclipse.nebula.widgets.grid.internal.DefaultColumnGroupHeaderRenderer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.TreeListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.TypedListener; + +/** + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A PRE-RELEASE ALPHA + * VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE VERSIONS. + *

+ * Instances of this class represent a column group in a grid widget. A column group header is + * displayed above grouped columns. The column group can optionally be configured to expand and + * collapse. A column group in the expanded state shows {@code GridColumn}s whose detail property + * is true. A column group in the collapsed state shows {@code GridColumn}s whose summary property + * is true. + *

+ *

+ *
Styles:
+ *
SWT.TOGGLE
+ *
Events:
+ *
Expand, Collapse
+ *
+ * + * @author chris.gross@us.ibm.com + */ +public class GridColumnGroup extends Item +{ + + private Grid parent; + + private GridColumn[] columns = new GridColumn[] {}; + + private boolean expanded = true; + + private Font headerFont; + + /** + * Header renderer. + */ + private GridHeaderRenderer headerRenderer = new DefaultColumnGroupHeaderRenderer(); + + /** + * Constructs a new instance of this class given its parent (which must be a Table) and a style + * value describing its behavior and appearance. + * + * @param parent the parent table + * @param style the style of the group + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that + * created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • + *
+ */ + public GridColumnGroup(Grid parent, int style) + { + super(parent, style); + this.parent = parent; + + init(style); + parent.newColumnGroup(this); + } + + + private void init(int style) { + headerRenderer.setDisplay(getDisplay()); + if ((getStyle() & SWT.RIGHT) == SWT.RIGHT) { + headerRenderer.setHorizontalAlignment(SWT.RIGHT); + } + + if ((getStyle() & SWT.CENTER) == SWT.CENTER) { + headerRenderer.setHorizontalAlignment(SWT.CENTER); + } + + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when an item in the receiver is expanded or collapsed + * by sending it one of the messages defined in the TreeListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see TreeListener + * @see #removeTreeListener + */ + public void addTreeListener(TreeListener listener) { + checkWidget (); + if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener (listener); + addListener (SWT.Expand, typedListener); + addListener (SWT.Collapse, typedListener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when items in the receiver are expanded or collapsed. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see TreeListener + * @see #addTreeListener + */ + public void removeTreeListener(TreeListener listener) { + checkWidget (); + if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + removeListener (SWT.Expand, listener); + removeListener (SWT.Collapse, listener); + } + + /** + * @return the parent grid + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that + * created the receiver
  • + *
+ */ + public Grid getParent() + { + checkWidget(); + return parent; + } + + int getNewColumnIndex() + { + if (columns.length == 0) + { + return -1; + } + + GridColumn lastCol = columns[columns.length - 1]; + return lastCol.index + 1; + } + + void newColumn(GridColumn column, int index) + { + GridColumn[] newAllColumns = new GridColumn[columns.length + 1]; + System.arraycopy(columns, 0, newAllColumns, 0, columns.length); + newAllColumns[newAllColumns.length - 1] = column; + columns = newAllColumns; + } + + void removeColumn(GridColumn col) + { + + if (columns.length == 0) + return; // widget is disposing + + GridColumn[] newAllColumns = new GridColumn[columns.length - 1]; + int x = 0; + for (int i = 0; i < columns.length; i++) + { + if (columns[i] != col) + { + newAllColumns[x] = columns[i]; + x ++; + } + } + columns = newAllColumns; + } + + /** + * Returns the columns within this group. + *

+ * Note: This is not the actual structure used by the receiver to maintain + * its list of items, so modifying the array will not affect the receiver. + *

+ * @return the columns + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that + * created the receiver
  • + *
+ */ + public GridColumn[] getColumns() + { + checkWidget(); + GridColumn[] newArray = new GridColumn[columns.length]; + System.arraycopy (columns, 0, newArray, 0, columns.length); + return newArray; + } + + /** + * {@inheritDoc} + */ + @Override + public void dispose() + { + super.dispose(); + + if (parent.isDisposing()) + return; + + GridColumn[] oldColumns = columns; + columns = new GridColumn[0]; + + for (int i = 0; i < oldColumns.length; i++) { + oldColumns[i].dispose(); + } + + parent.removeColumnGroup(this); + } + + /** + * @return the header renderer. + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that + * created the receiver
  • + *
+ */ + public GridHeaderRenderer getHeaderRenderer() + { + checkWidget(); + return headerRenderer; + } + + /** + * Sets the header renderer. + * + * @param headerRenderer The headerRenderer to set. + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the renderer is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that + * created the receiver
  • + *
+ */ + public void setHeaderRenderer(GridHeaderRenderer headerRenderer) + { + if (headerRenderer == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + this.headerRenderer = headerRenderer; + headerRenderer.setDisplay(getDisplay()); + } + + /** + * Returns true if the receiver is expanded, false otherwise. + * + * @return the expanded attribute + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that + * created the receiver
  • + *
+ */ + public boolean getExpanded() + { + checkWidget(); + return expanded; + } + + /** + * Sets the expanded state of the receiver. + * + * @param expanded the expanded to set + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that + * created the receiver
  • + *
+ */ + public void setExpanded(boolean expanded) + { + checkWidget(); + + this.expanded = expanded; + + if (!expanded && getParent().getCellSelectionEnabled()) + { + Vector collapsedCols = new Vector<>(); + for (int j = 0; j < columns.length; j++) + { + if (!columns[j].isSummary()) + { + collapsedCols.add(columns[j].index); + } + } + Point[] selection = getParent().getCellSelection(); + for (int i = 0; i < selection.length; i++) + { + if (collapsedCols.contains(new Integer(selection[i].x))) + { + getParent().deselectCell(selection[i]); + } + } + + if (getParent().getFocusColumn() != null && getParent().getFocusColumn().getColumnGroup() == this) + { + getParent().updateColumnFocus(); + } + + parent.updateColumnSelection(); + } + + if (parent.getCellSelectionEnabled()) + + + parent.refreshHoverState(); + parent.setScrollValuesObsolete(); + parent.redraw(); + } + + /** + * Returns the first visible column in this column group. + * + * @return first visible column + */ + GridColumn getFirstVisibleColumn() + { + GridColumn[] cols = parent.getColumnsInOrder(); + for (int i = 0; i < cols.length; i++) + { + if (cols[i].getColumnGroup() == this && cols[i].isVisible()) + { + return cols[i]; + } + } + return null; + } + + /** + * Returns the last visible column in this column group. + * + * @return last visible column + */ + GridColumn getLastVisibleColumn() + { + GridColumn[] cols = parent.getColumnsInOrder(); + GridColumn lastVisible = null; + for (int i = 0; i < cols.length; i++) + { + if (cols[i].getColumnGroup() == this && cols[i].isVisible()) + { + lastVisible = cols[i]; + } + } + return lastVisible; + } + + Rectangle getBounds() + { + Rectangle bounds = new Rectangle(0, 0, 0, 0); + + bounds.height = parent.getGroupHeaderHeight(); + + boolean foundFirstColumnInGroup = false; + + GridColumn[] cols = parent.getColumnsInOrder(); + for (int i = 0; i < cols.length; i++) + { + if (cols[i].getColumnGroup() == this) + { + if (cols[i].isVisible()) + { + if (!foundFirstColumnInGroup) + { + bounds.x = parent.getOrigin(cols[i], null).x; + foundFirstColumnInGroup = true; + } + bounds.width += cols[i].getWidth(); + } + } + else + { + if (foundFirstColumnInGroup) + { + break; + } + } + } + + return bounds; + } + /** + * Sets whether or not text is word-wrapped in the header for this column group. If Grid.setAutoHeight(true) is set, the row height + * is adjusted to accommodate word-wrapped text. + * @param wordWrap Set to true to wrap the text, false otherwise + * @see #getHeaderWordWrap() + */ + public void setHeaderWordWrap(boolean wordWrap) + { + checkWidget(); + headerRenderer.setWordWrap(wordWrap); + parent.redraw(); + } + /** + * Returns whether or not text is word-wrapped in the header for this column group. + * @return true if the header wraps its text. + * @see GridColumn#setHeaderWordWrap(boolean) + */ + public boolean getHeaderWordWrap() + { + checkWidget(); + return headerRenderer.isWordWrap(); + } + + /** + * Returns the font that the receiver will use to paint textual information + * for the header. + * + * @return the receiver's font + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that + * created the receiver
  • + *
+ */ + public Font getHeaderFont() { + checkWidget(); + + if (headerFont == null) { + return parent.getFont(); + } + return headerFont; + } + + /** + * Sets the Font to be used when displaying the Header text. + * @param font + */ + public void setHeaderFont(Font font) { + checkWidget(); + this.headerFont = font; + } + + /** + * Returns the column group header alignment. + * + * @return SWT.LEFT, SWT.RIGHT, SWT.CENTER + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getAlignment() { + checkWidget(); + return headerRenderer.getHorizontalAlignment(); + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridDragSourceEffect.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridDragSourceEffect.java index 7582601a2..8144b4acb 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridDragSourceEffect.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridDragSourceEffect.java @@ -1,146 +1,146 @@ -package org.eclipse.nebula.widgets.grid; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.dnd.DragSourceAdapter; -import org.eclipse.swt.dnd.DragSourceEffect; -import org.eclipse.swt.dnd.DragSourceEvent; -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.Display; - - -/** - * This class provides default implementations to display a source image - * when a drag is initiated from a Grid. - * - *

Classes that wish to provide their own source image for a Grid can - * extend DragSourceAdapter class and override the DragSourceAdapter.dragStart - * method and set the field DragSourceEvent.image with their own image.

- * - * Subclasses that override any methods of this class must call the corresponding - * super method to get the default drag under effect implementation. - * - * @see DragSourceAdapter - * @see DragSourceEvent - * - * @since 3.3 - * @author mark-oliver.reiser - */ -public class GridDragSourceEffect extends DragSourceEffect { - - Image dragSourceImage = null; - - /** - * - * @param grid - */ - public GridDragSourceEffect(Grid grid) { - super(grid); - } - - /** - * This implementation of dragFinished disposes the image - * that was created in GridDragSourceEffect.dragStart. - * - * Subclasses that override this method should call super.dragFinished(event) - * to dispose the image in the default implementation. - * - * @param event the information associated with the drag finished event - */ - @Override - public void dragFinished(DragSourceEvent event) { - if (dragSourceImage != null) dragSourceImage.dispose(); - dragSourceImage = null; - } - - /** - * This implementation of dragStart will create a default - * image that will be used during the drag. The image should be disposed - * when the drag is completed in the GridDragSourceEffect.dragFinished - * method. - * - * Subclasses that override this method should call super.dragStart(event) - * to use the image from the default implementation. - * - * @param event the information associated with the drag start event - */ - @Override - public void dragStart(DragSourceEvent event) { - event.image = getDragSourceImage(event); - } - - Image getDragSourceImage(DragSourceEvent event) { - if (dragSourceImage != null) dragSourceImage.dispose(); - dragSourceImage = null; - Grid grid = (Grid) getControl(); - Display display = grid.getDisplay(); - Rectangle empty = new Rectangle(0,0,0,0); - - // Collect the currently selected items. - Point[] selection; - if(grid.getCellSelectionEnabled()){ - selection = grid.getCellSelection(); - } else { - List l = new ArrayList<>(); - GridItem[] selItems = grid.getSelection(); - for (int i = 0; i < selItems.length; i++){ - for (int j = 0; j < grid.getColumnCount() ; j++){ - if(grid.getColumn(j).isVisible()){ - l.add(new Point(j,selItems[i].getRowIndex())); - } - } - } - selection = l.toArray(new Point[l.size()]); - } - if (selection.length == 0) return null; - - Rectangle bounds=null; - for (int i = 0; i < selection.length; i++) { - GridItem item = grid.getItem(selection[i].y); - Rectangle currBounds = item.getBounds(selection[i].x); - - if(empty.equals(currBounds)){ - selection[i]=null; - }else { - if(bounds==null){ - bounds = currBounds; - }else { - bounds = bounds.union(currBounds); - } - } - } - if(bounds==null) return null; - if (bounds.width <= 0 || bounds.height <= 0) return null; - - dragSourceImage = new Image(display,bounds.width,bounds.height); - GC gc = new GC(dragSourceImage); - for (int i = 0; i < selection.length; i++) { - if(selection[i]==null) continue; - GridItem item = grid.getItem(selection[i].y); - GridColumn column = grid.getColumn(selection[i].x); - Rectangle currBounds = item.getBounds(selection[i].x); - GridCellRenderer r = column.getCellRenderer(); - r.setBounds(currBounds.x-bounds.x, currBounds.y-bounds.y, currBounds.width, currBounds.height); - gc.setClipping(currBounds.x-bounds.x-1, currBounds.y-bounds.y-1, currBounds.width+2, currBounds.height+2); - r.setColumn(selection[i].x); - r.setSelected(false); - r.setFocus(false); - r.setRowFocus(false); - r.setCellFocus(false); - r.setRowHover(false); - r.setColumnHover(false); - r.setCellSelected(false); - r.setHoverDetail(""); - r.setDragging(true); - r.paint(gc, item); - gc.setClipping((Rectangle)null); - } - gc.dispose(); - - return dragSourceImage; - } -} +package org.eclipse.nebula.widgets.grid; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.dnd.DragSourceAdapter; +import org.eclipse.swt.dnd.DragSourceEffect; +import org.eclipse.swt.dnd.DragSourceEvent; +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.Display; + + +/** + * This class provides default implementations to display a source image + * when a drag is initiated from a Grid. + * + *

Classes that wish to provide their own source image for a Grid can + * extend DragSourceAdapter class and override the DragSourceAdapter.dragStart + * method and set the field DragSourceEvent.image with their own image.

+ * + * Subclasses that override any methods of this class must call the corresponding + * super method to get the default drag under effect implementation. + * + * @see DragSourceAdapter + * @see DragSourceEvent + * + * @since 3.3 + * @author mark-oliver.reiser + */ +public class GridDragSourceEffect extends DragSourceEffect { + + Image dragSourceImage = null; + + /** + * + * @param grid + */ + public GridDragSourceEffect(Grid grid) { + super(grid); + } + + /** + * This implementation of dragFinished disposes the image + * that was created in GridDragSourceEffect.dragStart. + * + * Subclasses that override this method should call super.dragFinished(event) + * to dispose the image in the default implementation. + * + * @param event the information associated with the drag finished event + */ + @Override + public void dragFinished(DragSourceEvent event) { + if (dragSourceImage != null) dragSourceImage.dispose(); + dragSourceImage = null; + } + + /** + * This implementation of dragStart will create a default + * image that will be used during the drag. The image should be disposed + * when the drag is completed in the GridDragSourceEffect.dragFinished + * method. + * + * Subclasses that override this method should call super.dragStart(event) + * to use the image from the default implementation. + * + * @param event the information associated with the drag start event + */ + @Override + public void dragStart(DragSourceEvent event) { + event.image = getDragSourceImage(event); + } + + Image getDragSourceImage(DragSourceEvent event) { + if (dragSourceImage != null) dragSourceImage.dispose(); + dragSourceImage = null; + Grid grid = (Grid) getControl(); + Display display = grid.getDisplay(); + Rectangle empty = new Rectangle(0,0,0,0); + + // Collect the currently selected items. + Point[] selection; + if(grid.getCellSelectionEnabled()){ + selection = grid.getCellSelection(); + } else { + List l = new ArrayList<>(); + GridItem[] selItems = grid.getSelection(); + for (int i = 0; i < selItems.length; i++){ + for (int j = 0; j < grid.getColumnCount() ; j++){ + if(grid.getColumn(j).isVisible()){ + l.add(new Point(j,selItems[i].getRowIndex())); + } + } + } + selection = l.toArray(new Point[l.size()]); + } + if (selection.length == 0) return null; + + Rectangle bounds=null; + for (int i = 0; i < selection.length; i++) { + GridItem item = grid.getItem(selection[i].y); + Rectangle currBounds = item.getBounds(selection[i].x); + + if(empty.equals(currBounds)){ + selection[i]=null; + }else { + if(bounds==null){ + bounds = currBounds; + }else { + bounds = bounds.union(currBounds); + } + } + } + if(bounds==null) return null; + if (bounds.width <= 0 || bounds.height <= 0) return null; + + dragSourceImage = new Image(display,bounds.width,bounds.height); + GC gc = new GC(dragSourceImage); + for (int i = 0; i < selection.length; i++) { + if(selection[i]==null) continue; + GridItem item = grid.getItem(selection[i].y); + GridColumn column = grid.getColumn(selection[i].x); + Rectangle currBounds = item.getBounds(selection[i].x); + GridCellRenderer r = column.getCellRenderer(); + r.setBounds(currBounds.x-bounds.x, currBounds.y-bounds.y, currBounds.width, currBounds.height); + gc.setClipping(currBounds.x-bounds.x-1, currBounds.y-bounds.y-1, currBounds.width+2, currBounds.height+2); + r.setColumn(selection[i].x); + r.setSelected(false); + r.setFocus(false); + r.setRowFocus(false); + r.setCellFocus(false); + r.setRowHover(false); + r.setColumnHover(false); + r.setCellSelected(false); + r.setHoverDetail(""); + r.setDragging(true); + r.paint(gc, item); + gc.setClipping((Rectangle)null); + } + gc.dispose(); + + return dragSourceImage; + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridEditor.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridEditor.java index 1795992da..eda26128b 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridEditor.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridEditor.java @@ -1,420 +1,420 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ControlEditor; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TreeEvent; -import org.eclipse.swt.events.TreeListener; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Listener; - -/** - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A PRE-RELEASE ALPHA - * VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE VERSIONS. - *

- * - * A GridEditor is a manager for a Control that appears above a cell in a Grid - * and tracks with the moving and resizing of that cell. It can be used to - * display a text widget above a cell in a Grid so that the user can edit the - * contents of that cell. It can also be used to display a button that can - * launch a dialog for modifying the contents of the associated cell. - *

- * @see org.eclipse.swt.custom.TableEditor - */ -public class GridEditor extends ControlEditor -{ - Grid table; - - GridItem item; - - int column = -1; - - ControlListener columnListener; - - Listener resizeListener; - - private Listener columnVisibleListener; - - private Listener columnGroupListener; - - private SelectionListener scrollListener; - - private TreeListener treeListener; - - /** - * Creates a TableEditor for the specified Table. - * - * @param table the Table Control above which this editor will be displayed - */ - public GridEditor(final Grid table) - { - super(table); - this.table = table; - - treeListener = new TreeListener () { - final Runnable runnable = () -> { - if (getEditor() == null || getEditor().isDisposed()) { - return; - } - if (table.isDisposed()) { - return; - } - layout(); - getEditor().setVisible(true); - }; - @Override - public void treeCollapsed(final TreeEvent e) { - if (getEditor() == null || getEditor().isDisposed ()) { - return; - } - getEditor().setVisible(false); - e.display.asyncExec(runnable); - } - @Override - public void treeExpanded(final TreeEvent e) { - if (getEditor() == null || getEditor().isDisposed ()) { - return; - } - getEditor().setVisible(false); - e.display.asyncExec(runnable); - } - }; - table.addTreeListener(treeListener); - - columnListener = new ControlListener() - { - @Override - public void controlMoved(final ControlEvent e) - { - layout(); - } - - @Override - public void controlResized(final ControlEvent e) - { - layout(); - } - }; - - columnVisibleListener = event -> { - if (getEditor() == null || getEditor().isDisposed ()) { - return; - } - getEditor().setVisible(((GridColumn)event.widget).isVisible()); - if (getEditor().isVisible()) { - layout(); - } - }; - - resizeListener = event -> layout(); - - scrollListener = new SelectionListener() - { - @Override - public void widgetSelected(final SelectionEvent e) - { - layout(); - } - @Override - public void widgetDefaultSelected(final SelectionEvent e) - { - } - }; - - columnGroupListener = event -> { - if (getEditor() == null || getEditor().isDisposed()) { - return; - } - getEditor().setVisible(table.getColumn(getColumn()).isVisible()); - if (getEditor().isVisible()) { - layout(); - } - }; - - // The following three listeners are workarounds for - // Eclipse bug 105764 - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=105764 - table.addListener(SWT.Resize, resizeListener); - - if (table.getVerticalScrollBarProxy() != null) - { - table.getVerticalScrollBarProxy().addSelectionListener(scrollListener); - } - if (table.getHorizontalScrollBarProxy() != null) - { - table.getHorizontalScrollBarProxy().addSelectionListener(scrollListener); - } - - // To be consistent with older versions of SWT, grabVertical defaults to - // true - grabVertical = true; - } - - /** - * Returns the bounds of the editor. - * - * @return bounds of the editor. - */ - protected Rectangle computeEditorBounds() - { - if (item == null || column == -1 || item.isDisposed()) { - return new Rectangle(0, 0, 0, 0); - } - final Rectangle cell = item.getBoundsCorrected(column); - final Rectangle area = table.getClientArea(); - if (cell.x < area.x + area.width) - { - if (cell.x + cell.width > area.x + area.width) - { - cell.width = area.x + area.width - cell.x; - } - } - final Rectangle editorRect = new Rectangle(cell.x, cell.y, minimumWidth, minimumHeight); - - if (grabHorizontal) - { - editorRect.width = Math.max(cell.width, minimumWidth) - (table.getLinesVisible() ? 2 : 0); - } - - if (grabVertical) - { - editorRect.height = Math.max(cell.height, minimumHeight); - } - - if (horizontalAlignment == SWT.RIGHT) - { - editorRect.x += cell.width - editorRect.width; - } - else if (horizontalAlignment == SWT.LEFT) - { - // do nothing - cell.x is the right answer - } - else - { // default is CENTER - editorRect.x += (cell.width - editorRect.width) / 2; - } - - if (verticalAlignment == SWT.BOTTOM) - { - editorRect.y += cell.height - editorRect.height; - } - else if (verticalAlignment == SWT.TOP) - { - // do nothing - cell.y is the right answer - } - else - { // default is CENTER - editorRect.y += (cell.height - editorRect.height) / 2; - } - - final GridColumn c = table.getColumn(column); - - if( c != null && c.isTree() ) { - final int x = c.getCellRenderer().getTextBounds(item, false).x; - editorRect.x += x; - editorRect.width -= x; - } - - return editorRect; - } - - /** - * Removes all associations between the TableEditor and the cell in the - * table. The Table and the editor Control are not disposed. - */ - @Override - public void dispose() - { - if (!table.isDisposed() && column > -1 && column < table.getColumnCount()) - { - final GridColumn tableColumn = table.getColumn(column); - tableColumn.removeControlListener(columnListener); - if (tableColumn.getColumnGroup() != null){ - tableColumn.getColumnGroup().removeListener(SWT.Expand, columnGroupListener); - tableColumn.getColumnGroup().removeListener(SWT.Collapse, columnGroupListener); - } - } - - if (!table.isDisposed()) - { - table.removeListener(SWT.Resize, resizeListener); - - if (table.getVerticalScrollBarProxy() != null) { - table.getVerticalScrollBarProxy().removeSelectionListener(scrollListener); - } - - if (table.getHorizontalScrollBarProxy() != null) { - table.getHorizontalScrollBarProxy().removeSelectionListener(scrollListener); - } - } - - columnListener = null; - resizeListener = null; - table = null; - item = null; - column = -1; - super.dispose(); - } - - /** - * Returns the zero based index of the column of the cell being tracked by - * this editor. - * - * @return the zero based index of the column of the cell being tracked by - * this editor - */ - public int getColumn() - { - return column; - } - - /** - * Returns the TableItem for the row of the cell being tracked by this - * editor. - * - * @return the TableItem for the row of the cell being tracked by this - * editor - */ - public GridItem getItem() - { - return item; - } - - /** - * Sets the zero based index of the column of the cell being tracked by this - * editor. - * - * @param column the zero based index of the column of the cell being - * tracked by this editor - */ - public void setColumn(final int column) - { - final int columnCount = table.getColumnCount(); - // Separately handle the case where the table has no TableColumns. - // In this situation, there is a single default column. - if (columnCount == 0) - { - this.column = column == 0 ? 0 : -1; - layout(); - return; - } - if (this.column > -1 && this.column < columnCount) - { - final GridColumn tableColumn = table.getColumn(this.column); - tableColumn.removeControlListener(columnListener); - tableColumn.removeListener(SWT.Show, columnVisibleListener); - tableColumn.removeListener(SWT.Hide, columnVisibleListener); - this.column = -1; - } - - if (column < 0 || column >= table.getColumnCount()) { - return; - } - - this.column = column; - final GridColumn tableColumn = table.getColumn(this.column); - tableColumn.addControlListener(columnListener); - tableColumn.addListener(SWT.Show, columnVisibleListener); - tableColumn.addListener(SWT.Hide, columnVisibleListener); - if (tableColumn.getColumnGroup() != null){ - tableColumn.getColumnGroup().addListener(SWT.Expand, columnGroupListener); - tableColumn.getColumnGroup().addListener(SWT.Collapse, columnGroupListener); - } - layout(); - } - - /** - * Sets the item that this editor will function over. - * - * @param item editing item. - */ - public void setItem(final GridItem item) - { - this.item = item; - layout(); - } - - /** - * Specify the Control that is to be displayed and the cell in the table - * that it is to be positioned above. - *

- * Note: The Control provided as the editor must be created with its - * parent being the Table control specified in the TableEditor constructor. - * - * @param editor the Control that is displayed above the cell being edited - * @param item the TableItem for the row of the cell being tracked by this - * editor - * @param column the zero based index of the column of the cell being - * tracked by this editor - */ - public void setEditor(final Control editor, final GridItem item, final int column) - { - setItem(item); - setColumn(column); - setEditor(editor); - - layout(); - } - - /** - * {@inheritDoc} - */ - @Override - public void layout() - { - - if (table.isDisposed()) { - return; - } - if (item == null || item.isDisposed()) { - return; - } - final int columnCount = table.getColumnCount(); - if (columnCount == 0 && column != 0) { - return; - } - if (columnCount > 0 && (column < 0 || column >= columnCount)) { - return; - } - - boolean hadFocus = false; - - if (getEditor() == null || getEditor().isDisposed()) { - return; - } - if (getEditor().getVisible()) - { - hadFocus = getEditor().isFocusControl(); - } // this doesn't work because - // resizing the column takes the focus away - // before we get here - getEditor().setBounds(computeEditorBounds()); - if (hadFocus) - { - if (getEditor() == null || getEditor().isDisposed()) { - return; - } - getEditor().setFocus(); - } - - } - -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ControlEditor; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TreeEvent; +import org.eclipse.swt.events.TreeListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Listener; + +/** + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A PRE-RELEASE ALPHA + * VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE VERSIONS. + *

+ * + * A GridEditor is a manager for a Control that appears above a cell in a Grid + * and tracks with the moving and resizing of that cell. It can be used to + * display a text widget above a cell in a Grid so that the user can edit the + * contents of that cell. It can also be used to display a button that can + * launch a dialog for modifying the contents of the associated cell. + *

+ * @see org.eclipse.swt.custom.TableEditor + */ +public class GridEditor extends ControlEditor +{ + Grid table; + + GridItem item; + + int column = -1; + + ControlListener columnListener; + + Listener resizeListener; + + private Listener columnVisibleListener; + + private Listener columnGroupListener; + + private SelectionListener scrollListener; + + private TreeListener treeListener; + + /** + * Creates a TableEditor for the specified Table. + * + * @param table the Table Control above which this editor will be displayed + */ + public GridEditor(final Grid table) + { + super(table); + this.table = table; + + treeListener = new TreeListener () { + final Runnable runnable = () -> { + if (getEditor() == null || getEditor().isDisposed()) { + return; + } + if (table.isDisposed()) { + return; + } + layout(); + getEditor().setVisible(true); + }; + @Override + public void treeCollapsed(final TreeEvent e) { + if (getEditor() == null || getEditor().isDisposed ()) { + return; + } + getEditor().setVisible(false); + e.display.asyncExec(runnable); + } + @Override + public void treeExpanded(final TreeEvent e) { + if (getEditor() == null || getEditor().isDisposed ()) { + return; + } + getEditor().setVisible(false); + e.display.asyncExec(runnable); + } + }; + table.addTreeListener(treeListener); + + columnListener = new ControlListener() + { + @Override + public void controlMoved(final ControlEvent e) + { + layout(); + } + + @Override + public void controlResized(final ControlEvent e) + { + layout(); + } + }; + + columnVisibleListener = event -> { + if (getEditor() == null || getEditor().isDisposed ()) { + return; + } + getEditor().setVisible(((GridColumn)event.widget).isVisible()); + if (getEditor().isVisible()) { + layout(); + } + }; + + resizeListener = event -> layout(); + + scrollListener = new SelectionListener() + { + @Override + public void widgetSelected(final SelectionEvent e) + { + layout(); + } + @Override + public void widgetDefaultSelected(final SelectionEvent e) + { + } + }; + + columnGroupListener = event -> { + if (getEditor() == null || getEditor().isDisposed()) { + return; + } + getEditor().setVisible(table.getColumn(getColumn()).isVisible()); + if (getEditor().isVisible()) { + layout(); + } + }; + + // The following three listeners are workarounds for + // Eclipse bug 105764 + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=105764 + table.addListener(SWT.Resize, resizeListener); + + if (table.getVerticalScrollBarProxy() != null) + { + table.getVerticalScrollBarProxy().addSelectionListener(scrollListener); + } + if (table.getHorizontalScrollBarProxy() != null) + { + table.getHorizontalScrollBarProxy().addSelectionListener(scrollListener); + } + + // To be consistent with older versions of SWT, grabVertical defaults to + // true + grabVertical = true; + } + + /** + * Returns the bounds of the editor. + * + * @return bounds of the editor. + */ + protected Rectangle computeEditorBounds() + { + if (item == null || column == -1 || item.isDisposed()) { + return new Rectangle(0, 0, 0, 0); + } + final Rectangle cell = item.getBoundsCorrected(column); + final Rectangle area = table.getClientArea(); + if (cell.x < area.x + area.width) + { + if (cell.x + cell.width > area.x + area.width) + { + cell.width = area.x + area.width - cell.x; + } + } + final Rectangle editorRect = new Rectangle(cell.x, cell.y, minimumWidth, minimumHeight); + + if (grabHorizontal) + { + editorRect.width = Math.max(cell.width, minimumWidth) - (table.getLinesVisible() ? 2 : 0); + } + + if (grabVertical) + { + editorRect.height = Math.max(cell.height, minimumHeight); + } + + if (horizontalAlignment == SWT.RIGHT) + { + editorRect.x += cell.width - editorRect.width; + } + else if (horizontalAlignment == SWT.LEFT) + { + // do nothing - cell.x is the right answer + } + else + { // default is CENTER + editorRect.x += (cell.width - editorRect.width) / 2; + } + + if (verticalAlignment == SWT.BOTTOM) + { + editorRect.y += cell.height - editorRect.height; + } + else if (verticalAlignment == SWT.TOP) + { + // do nothing - cell.y is the right answer + } + else + { // default is CENTER + editorRect.y += (cell.height - editorRect.height) / 2; + } + + final GridColumn c = table.getColumn(column); + + if( c != null && c.isTree() ) { + final int x = c.getCellRenderer().getTextBounds(item, false).x; + editorRect.x += x; + editorRect.width -= x; + } + + return editorRect; + } + + /** + * Removes all associations between the TableEditor and the cell in the + * table. The Table and the editor Control are not disposed. + */ + @Override + public void dispose() + { + if (!table.isDisposed() && column > -1 && column < table.getColumnCount()) + { + final GridColumn tableColumn = table.getColumn(column); + tableColumn.removeControlListener(columnListener); + if (tableColumn.getColumnGroup() != null){ + tableColumn.getColumnGroup().removeListener(SWT.Expand, columnGroupListener); + tableColumn.getColumnGroup().removeListener(SWT.Collapse, columnGroupListener); + } + } + + if (!table.isDisposed()) + { + table.removeListener(SWT.Resize, resizeListener); + + if (table.getVerticalScrollBarProxy() != null) { + table.getVerticalScrollBarProxy().removeSelectionListener(scrollListener); + } + + if (table.getHorizontalScrollBarProxy() != null) { + table.getHorizontalScrollBarProxy().removeSelectionListener(scrollListener); + } + } + + columnListener = null; + resizeListener = null; + table = null; + item = null; + column = -1; + super.dispose(); + } + + /** + * Returns the zero based index of the column of the cell being tracked by + * this editor. + * + * @return the zero based index of the column of the cell being tracked by + * this editor + */ + public int getColumn() + { + return column; + } + + /** + * Returns the TableItem for the row of the cell being tracked by this + * editor. + * + * @return the TableItem for the row of the cell being tracked by this + * editor + */ + public GridItem getItem() + { + return item; + } + + /** + * Sets the zero based index of the column of the cell being tracked by this + * editor. + * + * @param column the zero based index of the column of the cell being + * tracked by this editor + */ + public void setColumn(final int column) + { + final int columnCount = table.getColumnCount(); + // Separately handle the case where the table has no TableColumns. + // In this situation, there is a single default column. + if (columnCount == 0) + { + this.column = column == 0 ? 0 : -1; + layout(); + return; + } + if (this.column > -1 && this.column < columnCount) + { + final GridColumn tableColumn = table.getColumn(this.column); + tableColumn.removeControlListener(columnListener); + tableColumn.removeListener(SWT.Show, columnVisibleListener); + tableColumn.removeListener(SWT.Hide, columnVisibleListener); + this.column = -1; + } + + if (column < 0 || column >= table.getColumnCount()) { + return; + } + + this.column = column; + final GridColumn tableColumn = table.getColumn(this.column); + tableColumn.addControlListener(columnListener); + tableColumn.addListener(SWT.Show, columnVisibleListener); + tableColumn.addListener(SWT.Hide, columnVisibleListener); + if (tableColumn.getColumnGroup() != null){ + tableColumn.getColumnGroup().addListener(SWT.Expand, columnGroupListener); + tableColumn.getColumnGroup().addListener(SWT.Collapse, columnGroupListener); + } + layout(); + } + + /** + * Sets the item that this editor will function over. + * + * @param item editing item. + */ + public void setItem(final GridItem item) + { + this.item = item; + layout(); + } + + /** + * Specify the Control that is to be displayed and the cell in the table + * that it is to be positioned above. + *

+ * Note: The Control provided as the editor must be created with its + * parent being the Table control specified in the TableEditor constructor. + * + * @param editor the Control that is displayed above the cell being edited + * @param item the TableItem for the row of the cell being tracked by this + * editor + * @param column the zero based index of the column of the cell being + * tracked by this editor + */ + public void setEditor(final Control editor, final GridItem item, final int column) + { + setItem(item); + setColumn(column); + setEditor(editor); + + layout(); + } + + /** + * {@inheritDoc} + */ + @Override + public void layout() + { + + if (table.isDisposed()) { + return; + } + if (item == null || item.isDisposed()) { + return; + } + final int columnCount = table.getColumnCount(); + if (columnCount == 0 && column != 0) { + return; + } + if (columnCount > 0 && (column < 0 || column >= columnCount)) { + return; + } + + boolean hadFocus = false; + + if (getEditor() == null || getEditor().isDisposed()) { + return; + } + if (getEditor().getVisible()) + { + hadFocus = getEditor().isFocusControl(); + } // this doesn't work because + // resizing the column takes the focus away + // before we get here + getEditor().setBounds(computeEditorBounds()); + if (hadFocus) + { + if (getEditor() == null || getEditor().isDisposed()) { + return; + } + getEditor().setFocus(); + } + + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridFooterRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridFooterRenderer.java index 1c04314cc..f97407628 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridFooterRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridFooterRenderer.java @@ -1,75 +1,75 @@ -/******************************************************************************* - * Copyright (c) 2009 BestSolution.at - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * tom.schindl@bestsolution.at - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Rectangle; - -/** - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A - * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE - * VERSIONS. - *

- * The super class for all grid header renderers. Contains the properties - * specific to a grid header. - * - * @author chris.gross@us.ibm.com - */ -public abstract class GridFooterRenderer extends AbstractInternalWidget { - - /** - * Truncation style - */ - protected int truncationStyle = SWT.CENTER; - - /** - * Returns the bounds of the text in the cell. This is used when displaying - * in-place tooltips. If null is returned here, in-place tooltips - * will not be displayed. If the preferred argument is - * true then the returned bounds should be large enough to show the - * entire text. If preferred is false then the - * returned bounds should be be relative to the current bounds. - * - * @param value - * the object being rendered. - * @param preferred - * true if the preferred width of the text should be returned. - * @return bounds of the text. - */ - public Rectangle getTextBounds(Object value, boolean preferred) { - return null; - } - - /** - * Get the truncation style - * - * @return the truncation style. - */ - public int getTruncationStyle() { - return truncationStyle; - } - - /** - * Set the truncation style to use when cell content is too large. - * - * @see SWT#LEFT - * @see SWT#CENTER - * @see SWT#RIGHT - * @param truncationStyle - */ - public void setTruncationStyle(int truncationStyle) { - this.truncationStyle = truncationStyle; - } -} +/******************************************************************************* + * Copyright (c) 2009 BestSolution.at + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * tom.schindl@bestsolution.at - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Rectangle; + +/** + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A + * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE + * VERSIONS. + *

+ * The super class for all grid header renderers. Contains the properties + * specific to a grid header. + * + * @author chris.gross@us.ibm.com + */ +public abstract class GridFooterRenderer extends AbstractInternalWidget { + + /** + * Truncation style + */ + protected int truncationStyle = SWT.CENTER; + + /** + * Returns the bounds of the text in the cell. This is used when displaying + * in-place tooltips. If null is returned here, in-place tooltips + * will not be displayed. If the preferred argument is + * true then the returned bounds should be large enough to show the + * entire text. If preferred is false then the + * returned bounds should be be relative to the current bounds. + * + * @param value + * the object being rendered. + * @param preferred + * true if the preferred width of the text should be returned. + * @return bounds of the text. + */ + public Rectangle getTextBounds(Object value, boolean preferred) { + return null; + } + + /** + * Get the truncation style + * + * @return the truncation style. + */ + public int getTruncationStyle() { + return truncationStyle; + } + + /** + * Set the truncation style to use when cell content is too large. + * + * @see SWT#LEFT + * @see SWT#CENTER + * @see SWT#RIGHT + * @param truncationStyle + */ + public void setTruncationStyle(int truncationStyle) { + this.truncationStyle = truncationStyle; + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridHeaderEditor.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridHeaderEditor.java index 1601ba00d..0075bdbcb 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridHeaderEditor.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridHeaderEditor.java @@ -1,226 +1,226 @@ -/******************************************************************************* - * Copyright (c) 2009 BestSolution.at - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * tom.schindl@bestsolution.at - initial API and implementation - * gusten__79@hotmail.com - bugfix in 257923 - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ControlEditor; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Listener; - -/** - * Manager for a Control that appears below the grid column header. Based on - * {@link GridEditor}. - */ -class GridHeaderEditor extends ControlEditor { - - private Grid table; - - private GridColumn column; - - ControlListener columnListener; - - Listener resizeListener; - - private final Listener columnVisibleListener; - - private final Listener columnGroupListener; - - private final Listener scrollListener; - - private final Listener mouseOverListener; - - /** - * Creates a TableEditor for the specified Table. - * - * @param column - * the Table Control above which this editor will be displayed - */ - GridHeaderEditor(final GridColumn column) { - super(column.getParent()); - - this.table = column.getParent(); - this.column = column; - - columnListener = new ControlListener() { - public void controlMoved(ControlEvent e) { - layout(); - e.display.asyncExec(() -> layout()); - } - - public void controlResized(ControlEvent e) { - layout(); - } - }; - - columnVisibleListener = event -> { - getEditor().setVisible(column.isVisible()); - layout(); - }; - - resizeListener = event -> layout(); - scrollListener = event -> layout(); - - columnGroupListener = event -> { - if (getEditor() == null || getEditor().isDisposed()) - return; - getEditor().setVisible(column.isVisible()); - layout(); - }; - - // Reset the mouse cursor when the mouse hovers the control - mouseOverListener = event -> { - if (table.getCursor() != null) { - // We need to reset because it could be that when we left the resizer was active - table.hoveringOnColumnResizer = false; - table.setCursor(null); - } - }; - - // The following three listeners are workarounds for - // Eclipse bug 105764 - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=105764 - table.addListener(SWT.Resize, resizeListener); - - if (table.getVerticalScrollBarProxy() != null) { - table.getVerticalScrollBarProxy().addListener(SWT.Selection,scrollListener); - } - if (table.getHorizontalScrollBarProxy() != null) { - table.getHorizontalScrollBarProxy().addListener(SWT.Selection,scrollListener); - } - - // To be consistent with older versions of SWT, grabVertical defaults to - // true - grabVertical = true; - - // initColumn(); - } - - /** - * Returns the bounds of the editor. - * - * @return bounds of the editor. - */ - protected Rectangle internalComputeBounds() { - column.getHeaderRenderer().setBounds(column.getBounds()); - return column.getHeaderRenderer().getControlBounds(column, true); - } - - /** - * Removes all associations between the TableEditor and the cell in the - * table. The Table and the editor Control are not disposed. - */ - public void dispose() { - if (!table.isDisposed() && !column.isDisposed()) { - column.removeControlListener(columnListener); - if (column.getColumnGroup() != null) { - column.getColumnGroup().removeListener(SWT.Expand,columnGroupListener); - column.getColumnGroup().removeListener(SWT.Collapse,columnGroupListener); - } - } - - if (!table.isDisposed()) { - table.removeListener(SWT.Resize, resizeListener); - - if (table.getVerticalScrollBarProxy() != null) - table.getVerticalScrollBarProxy().removeListener(SWT.Selection,scrollListener); - - if (table.getHorizontalScrollBarProxy() != null) - table.getHorizontalScrollBarProxy().removeListener(SWT.Selection,scrollListener); - } - - columnListener = null; - resizeListener = null; - table = null; - - if ( getEditor() != null && !getEditor().isDisposed() ) { - getEditor().dispose(); - } - - super.dispose(); - } - - /** - * Sets the zero based index of the column of the cell being tracked by this - * editor. - * - * @param column - * the zero based index of the column of the cell being tracked - * by this editor - */ - void initColumn() { - - column.addControlListener(columnListener); - column.addListener(SWT.Show, columnVisibleListener); - column.addListener(SWT.Hide, columnVisibleListener); - - if (column.getColumnGroup() != null) { - column.getColumnGroup() - .addListener(SWT.Expand, columnGroupListener); - column.getColumnGroup().addListener(SWT.Collapse, - columnGroupListener); - } - layout(); - } - - /** - * {@inheritDoc} - */ - public void layout() { - if (table.isDisposed()) - return; - - boolean hadFocus = false; - if (getEditor() == null || getEditor().isDisposed() || !column.isVisible()) { - return; - } - - if (getEditor().getVisible()) { - hadFocus = getEditor().isFocusControl(); - } - - Rectangle rect = internalComputeBounds(); - if (rect == null || rect.x < 0) { - getEditor().setVisible(false); - return; - } else if (table.getItemHeaderWidth() > 0 && table.getItemHeaderWidth() > rect.x) { - getEditor().setVisible(false); - return; - } else { - getEditor().setVisible(true); - } - getEditor().setBounds(rect); - - if (hadFocus) { - if (getEditor() == null || getEditor().isDisposed()) - return; - getEditor().setFocus(); - } - } - - public void setEditor(Control editor) { - if (getEditor() != null) { - getEditor().removeListener(SWT.MouseEnter, mouseOverListener); - } - super.setEditor(editor); - - if (editor != null) { - getEditor().addListener(SWT.MouseEnter, mouseOverListener); - } - } - -} +/******************************************************************************* + * Copyright (c) 2009 BestSolution.at + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * tom.schindl@bestsolution.at - initial API and implementation + * gusten__79@hotmail.com - bugfix in 257923 + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ControlEditor; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Listener; + +/** + * Manager for a Control that appears below the grid column header. Based on + * {@link GridEditor}. + */ +class GridHeaderEditor extends ControlEditor { + + private Grid table; + + private GridColumn column; + + ControlListener columnListener; + + Listener resizeListener; + + private final Listener columnVisibleListener; + + private final Listener columnGroupListener; + + private final Listener scrollListener; + + private final Listener mouseOverListener; + + /** + * Creates a TableEditor for the specified Table. + * + * @param column + * the Table Control above which this editor will be displayed + */ + GridHeaderEditor(final GridColumn column) { + super(column.getParent()); + + this.table = column.getParent(); + this.column = column; + + columnListener = new ControlListener() { + public void controlMoved(ControlEvent e) { + layout(); + e.display.asyncExec(() -> layout()); + } + + public void controlResized(ControlEvent e) { + layout(); + } + }; + + columnVisibleListener = event -> { + getEditor().setVisible(column.isVisible()); + layout(); + }; + + resizeListener = event -> layout(); + scrollListener = event -> layout(); + + columnGroupListener = event -> { + if (getEditor() == null || getEditor().isDisposed()) + return; + getEditor().setVisible(column.isVisible()); + layout(); + }; + + // Reset the mouse cursor when the mouse hovers the control + mouseOverListener = event -> { + if (table.getCursor() != null) { + // We need to reset because it could be that when we left the resizer was active + table.hoveringOnColumnResizer = false; + table.setCursor(null); + } + }; + + // The following three listeners are workarounds for + // Eclipse bug 105764 + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=105764 + table.addListener(SWT.Resize, resizeListener); + + if (table.getVerticalScrollBarProxy() != null) { + table.getVerticalScrollBarProxy().addListener(SWT.Selection,scrollListener); + } + if (table.getHorizontalScrollBarProxy() != null) { + table.getHorizontalScrollBarProxy().addListener(SWT.Selection,scrollListener); + } + + // To be consistent with older versions of SWT, grabVertical defaults to + // true + grabVertical = true; + + // initColumn(); + } + + /** + * Returns the bounds of the editor. + * + * @return bounds of the editor. + */ + protected Rectangle internalComputeBounds() { + column.getHeaderRenderer().setBounds(column.getBounds()); + return column.getHeaderRenderer().getControlBounds(column, true); + } + + /** + * Removes all associations between the TableEditor and the cell in the + * table. The Table and the editor Control are not disposed. + */ + public void dispose() { + if (!table.isDisposed() && !column.isDisposed()) { + column.removeControlListener(columnListener); + if (column.getColumnGroup() != null) { + column.getColumnGroup().removeListener(SWT.Expand,columnGroupListener); + column.getColumnGroup().removeListener(SWT.Collapse,columnGroupListener); + } + } + + if (!table.isDisposed()) { + table.removeListener(SWT.Resize, resizeListener); + + if (table.getVerticalScrollBarProxy() != null) + table.getVerticalScrollBarProxy().removeListener(SWT.Selection,scrollListener); + + if (table.getHorizontalScrollBarProxy() != null) + table.getHorizontalScrollBarProxy().removeListener(SWT.Selection,scrollListener); + } + + columnListener = null; + resizeListener = null; + table = null; + + if ( getEditor() != null && !getEditor().isDisposed() ) { + getEditor().dispose(); + } + + super.dispose(); + } + + /** + * Sets the zero based index of the column of the cell being tracked by this + * editor. + * + * @param column + * the zero based index of the column of the cell being tracked + * by this editor + */ + void initColumn() { + + column.addControlListener(columnListener); + column.addListener(SWT.Show, columnVisibleListener); + column.addListener(SWT.Hide, columnVisibleListener); + + if (column.getColumnGroup() != null) { + column.getColumnGroup() + .addListener(SWT.Expand, columnGroupListener); + column.getColumnGroup().addListener(SWT.Collapse, + columnGroupListener); + } + layout(); + } + + /** + * {@inheritDoc} + */ + public void layout() { + if (table.isDisposed()) + return; + + boolean hadFocus = false; + if (getEditor() == null || getEditor().isDisposed() || !column.isVisible()) { + return; + } + + if (getEditor().getVisible()) { + hadFocus = getEditor().isFocusControl(); + } + + Rectangle rect = internalComputeBounds(); + if (rect == null || rect.x < 0) { + getEditor().setVisible(false); + return; + } else if (table.getItemHeaderWidth() > 0 && table.getItemHeaderWidth() > rect.x) { + getEditor().setVisible(false); + return; + } else { + getEditor().setVisible(true); + } + getEditor().setBounds(rect); + + if (hadFocus) { + if (getEditor() == null || getEditor().isDisposed()) + return; + getEditor().setFocus(); + } + } + + public void setEditor(Control editor) { + if (getEditor() != null) { + getEditor().removeListener(SWT.MouseEnter, mouseOverListener); + } + super.setEditor(editor); + + if (editor != null) { + getEditor().addListener(SWT.MouseEnter, mouseOverListener); + } + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridHeaderRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridHeaderRenderer.java index e01723d27..9840ff275 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridHeaderRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridHeaderRenderer.java @@ -1,140 +1,140 @@ -/******************************************************************************* - * Copyright (c) 2008 BestSolution.at and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * tom.schindl@bestsolution.at - initial API and implementation - * Chuck.Mastrandrea@sas.com - wordwrapping in bug 222280 - * smcduff@hotmail.com - wordwrapping in bug 222280 - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Rectangle; - -/** - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A PRE-RELEASE ALPHA - * VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE VERSIONS. - *

- * The super class for all grid header renderers. Contains the properties specific - * to a grid header. - * - * @author chris.gross@us.ibm.com - */ -public abstract class GridHeaderRenderer extends AbstractInternalWidget -{ - private boolean wordWrap = false; - private int horizontalAlignment = SWT.LEFT; - /** - * Truncation style - */ - protected int truncationStyle = SWT.CENTER; - - /** - * Returns the bounds of the text in the cell. This is used when displaying in-place tooltips. - * If null is returned here, in-place tooltips will not be displayed. If the - * preferred argument is true then the returned bounds should be large - * enough to show the entire text. If preferred is false then the - * returned bounds should be be relative to the current bounds. - * - * @param value the object being rendered. - * @param preferred true if the preferred width of the text should be returned. - * @return bounds of the text. - */ - public Rectangle getTextBounds(Object value, boolean preferred) - { - return null; - } - - /** - * Returns the bounds of the toggle within the header (typically only group headers have toggles) - * or null. - * - * @return toggle bounds or null if no toggle exists. - */ - public Rectangle getToggleBounds() - { - return null; - } - - /** - * Returns the bounds of the control to display - * - * @param value the control to display - * @param preferred if true, compute the preferred size - * @return the bounds for the control or null if no control is - * rendered - */ - protected Rectangle getControlBounds(Object value, boolean preferred) { - return null; - } - /** - * Returns whether or not text will be word-wrapped during the render - * @return the wordWrap True if word wrapping is enabled - */ - public boolean isWordWrap() - { - return wordWrap; - } - /** - * Sets whether or not text should be word-wrapped during the render - * @param wordWrap True to wrap text, false otherwise - */ - public void setWordWrap(boolean wordWrap) - { - this.wordWrap = wordWrap; - } - - /** - * Returns the header horizontal alignment. - * - * @return SWT.LEFT, SWT.RIGHT, SWT.CENTER - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getHorizontalAlignment() { - return horizontalAlignment; - } - - - /** - * Sets the header horizontal alignment. - * - * @param alignment - * The alignment to set. - */ - public void setHorizontalAlignment(int alignment) { - this.horizontalAlignment = alignment; - } - - /** - * Get the truncation style - * @return the truncation style. - */ - public int getTruncationStyle() { - return truncationStyle; - } - - /** - * Set the truncation style to use when cell content is too large. - * @see SWT#LEFT - * @see SWT#CENTER - * @see SWT#RIGHT - * @param truncationStyle - */ - public void setTruncationStyle(int truncationStyle) { - this.truncationStyle = truncationStyle; - } -} +/******************************************************************************* + * Copyright (c) 2008 BestSolution.at and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * tom.schindl@bestsolution.at - initial API and implementation + * Chuck.Mastrandrea@sas.com - wordwrapping in bug 222280 + * smcduff@hotmail.com - wordwrapping in bug 222280 + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Rectangle; + +/** + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A PRE-RELEASE ALPHA + * VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE VERSIONS. + *

+ * The super class for all grid header renderers. Contains the properties specific + * to a grid header. + * + * @author chris.gross@us.ibm.com + */ +public abstract class GridHeaderRenderer extends AbstractInternalWidget +{ + private boolean wordWrap = false; + private int horizontalAlignment = SWT.LEFT; + /** + * Truncation style + */ + protected int truncationStyle = SWT.CENTER; + + /** + * Returns the bounds of the text in the cell. This is used when displaying in-place tooltips. + * If null is returned here, in-place tooltips will not be displayed. If the + * preferred argument is true then the returned bounds should be large + * enough to show the entire text. If preferred is false then the + * returned bounds should be be relative to the current bounds. + * + * @param value the object being rendered. + * @param preferred true if the preferred width of the text should be returned. + * @return bounds of the text. + */ + public Rectangle getTextBounds(Object value, boolean preferred) + { + return null; + } + + /** + * Returns the bounds of the toggle within the header (typically only group headers have toggles) + * or null. + * + * @return toggle bounds or null if no toggle exists. + */ + public Rectangle getToggleBounds() + { + return null; + } + + /** + * Returns the bounds of the control to display + * + * @param value the control to display + * @param preferred if true, compute the preferred size + * @return the bounds for the control or null if no control is + * rendered + */ + protected Rectangle getControlBounds(Object value, boolean preferred) { + return null; + } + /** + * Returns whether or not text will be word-wrapped during the render + * @return the wordWrap True if word wrapping is enabled + */ + public boolean isWordWrap() + { + return wordWrap; + } + /** + * Sets whether or not text should be word-wrapped during the render + * @param wordWrap True to wrap text, false otherwise + */ + public void setWordWrap(boolean wordWrap) + { + this.wordWrap = wordWrap; + } + + /** + * Returns the header horizontal alignment. + * + * @return SWT.LEFT, SWT.RIGHT, SWT.CENTER + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getHorizontalAlignment() { + return horizontalAlignment; + } + + + /** + * Sets the header horizontal alignment. + * + * @param alignment + * The alignment to set. + */ + public void setHorizontalAlignment(int alignment) { + this.horizontalAlignment = alignment; + } + + /** + * Get the truncation style + * @return the truncation style. + */ + public int getTruncationStyle() { + return truncationStyle; + } + + /** + * Set the truncation style to use when cell content is too large. + * @see SWT#LEFT + * @see SWT#CENTER + * @see SWT#RIGHT + * @param truncationStyle + */ + public void setTruncationStyle(int truncationStyle) { + this.truncationStyle = truncationStyle; + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridItem.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridItem.java index d3df21717..af2cea3f6 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridItem.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridItem.java @@ -1,2134 +1,2134 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - * Claes Rosell - rowspan in bug 272384 - * Stefan Widmaier - rowspan in 304797 - * Mirko Paturzo - improvement (bug in 419928) - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -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.Event; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.TypedListener; - -/** - *

- * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A - * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE - * VERSIONS. - *

- * Instances of this class represent a selectable user interface object that - * represents an item in a grid. - *

- *

- *
Styles:
- *
(none)
- *
Events:
- *
(none)
- *
- * - * @author chris.gross@us.ibm.com - * @author Mirko Paturzo - * - * Mirko removed all collections, improve dispose performance, reduce - * used memory - */ -public class GridItem extends Item { - private static final int NO_ROW = -1; - - /** - * List of children. - */ - private List children; - - /** - * Default background color. - */ - @Deprecated - private Color defaultBackground; - - /** - * Default font. - */ - @Deprecated - private Font defaultFont; - - /** - * Default foreground color. - */ - @Deprecated - private Color defaultForeground; - - /** - * The height of this GridItem. - */ - private int height = 1; - - /** - * Is expanded? - */ - private boolean expanded = false; - - /** - * True if has children. - */ - private boolean hasChildren = false; - - /** - * Level of item in a tree. - */ - private int level = 0; - - /** - * Parent grid instance. - */ - private final Grid parent; - - /** - * Parent item (if a child item). - */ - private GridItem parentItem; - - /** - * Is visible? - */ - private boolean visible = true; - - /** - * Row header text. - */ - private String headerText = null; - - /** - * Row header image - */ - private Image headerImage = null; - - /** - * Background color of the header - */ - private Color headerBackground = null; - - /** - * Foreground color of the header - */ - public Color headerForeground = null; - - /** - * Font of the header - */ - private Font headerFont = null; - - /** - * (SWT.VIRTUAL only) Flag that specifies whether the client has already - * been sent a SWT.SetData event. - */ - private boolean hasSetData = false; - - private int row = NO_ROW; - - private final Object ROW_LOCK = new Object(); - - /** - * Creates a new instance of this class and places the item at the end of - * the grid. - * - * @param parent - * parent grid - * @param style - * item style - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- */ - public GridItem(Grid parent, int style) { - this(parent, style, NO_ROW); - } - - /** - * Creates a new instance of this class and places the item in the grid at - * the given index. - * - * @param parent - * parent grid - * @param style - * item style - * @param index - * index where to insert item - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- */ - public GridItem(Grid parent, int style, int index) { - super(parent, style, index); - - this.parent = parent; - - row = parent.newItem(this, index, true); - parent.newRootItem(this, index); - } - - /** - * @return grid row index - */ - public int getRowIndex() { - synchronized (ROW_LOCK) { - if (row != NO_ROW) - return row; - } - return parent.indexOf(this); - } - - void increaseRow() { - synchronized (ROW_LOCK) { - row++; - } - } - - void decreaseRow() { - synchronized (ROW_LOCK) { - row--; - } - } - - /** - * Creates a new instance of this class as a child node of the given - * GridItem and places the item at the end of the parents items. - * - * @param parent - * parent item - * @param style - * item style - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- */ - public GridItem(GridItem parent, int style) { - this(parent, style, NO_ROW); - } - - /** - * Creates a new instance of this class as a child node of the given Grid - * and places the item at the given index in the parent items list. - * - * @param parent - * parent item - * @param style - * item style - * @param index - * index to place item - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- */ - public GridItem(GridItem parent, int style, int index) { - super(parent, style, index); - - parentItem = parent; - this.parent = parentItem.getParent(); - - row = this.parent.newItem(this, index, false); - - level = parentItem.getLevel() + 1; - - parentItem.newItem(this, index); - - parentItem.indexOf(this); - - if (parent.isVisible() && parent.isExpanded()) { - setVisible(true); - } else { - setVisible(false); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void dispose() { - if (!parent.isDisposing()) { - parent.removeItem(this); - - if (parentItem != null) { - parentItem.remove(this); - } else { - parent.removeRootItem(this); - } - if (hasChildren) - for (int i = children.size() - 1; i >= 0; i--) { - children.get(i).dispose(); - } - } - if (parent.getDataVisualizer() != null) { - parent.getDataVisualizer().clearRow(this); - } - noRow(); - super.dispose(); - } - - /** - * Adds the listener to the collection of listeners who will be notified - * when the row is resized, by sending it one of the messages defined in the - * ControlListener interface. - *

- * Clients who wish to override the standard row resize logic should use the - * untyped listener mechanisms. The untyped Event object passed - * to an untyped listener will have its detail field populated - * with the new row height. Clients may alter this value to, for example, - * enforce minimum or maximum row sizes. Clients may also set the - * doit field to false to prevent the entire resize operation. - * - * @param listener - * the listener which should be notified - * - * @exception IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void addControlListener(ControlListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - TypedListener typedListener = new TypedListener(listener); - addListener(SWT.Resize, typedListener); - } - - /** - * Removes the listener from the collection of listeners who will be - * notified when the row is resized. - * - * @param listener - * the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void removeControlListener(ControlListener listener) { - checkWidget(); - if (listener == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - removeListener(SWT.Resize, listener); - } - - /** - * Fires the given event type on the parent Grid instance. This method - * should only be called from within a cell renderer. Any other use is not - * intended. - * - * @param eventId - * SWT event constant - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void fireEvent(int eventId) { - checkWidget(); - - Event e = new Event(); - e.display = getDisplay(); - e.widget = this; - e.item = this; - e.type = eventId; - - getParent().notifyListeners(eventId, e); - } - - /** - * Fires the appropriate events in response to a user checking/unchecking an - * item. Checking an item fires both a selection event (with event.detail of - * SWT.CHECK) if the checkbox is in the first column and the seperate check - * listener (all columns). This method manages that behavior. This method - * should only be called from within a cell renderer. Any other use is not - * intended. - * - * @param column - * the column where the checkbox resides - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void fireCheckEvent(int column) { - checkWidget(); - - Event selectionEvent = new Event(); - selectionEvent.display = getDisplay(); - selectionEvent.widget = this; - selectionEvent.item = this; - selectionEvent.type = SWT.Selection; - selectionEvent.detail = SWT.CHECK; - selectionEvent.index = column; - - getParent().notifyListeners(SWT.Selection, selectionEvent); - } - - /** - * Returns the receiver's background color. - * - * @return the background color - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getBackground() { - checkWidget(); - - if (defaultBackground == null) { - return parent.getBackground(); - } - return defaultBackground; - } - - /** - * Returns the background color at the given column index in the receiver. - * - * @param index - * the column index - * @return the background color - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getBackground(int index) { - checkWidget(); - - handleVirtual(); - - return parent.getDataVisualizer().getBackground(this, index); - - } - - /** - * Returns a rectangle describing the receiver's size and location relative - * to its parent at a column in the table. - * - * @param columnIndex - * the index that specifies the column - * @return the receiver's bounding column rectangle - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Rectangle getBounds(int columnIndex) { - checkWidget(); - - final Point origin = parent.getOrigin(parent.getColumn(columnIndex), this); - final Point cellSize = this.getCellSize(columnIndex); - return new Rectangle(origin.x, origin.y, cellSize.x, cellSize.y); - } - - /** - * Returns a rectangle describing the receiver's size and location relative - * to its parent at a column in the table. - * Handle not visible items. - * - * @param columnIndex - * the index that specifies the column - * @return the receiver's bounding column rectangle - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Rectangle getBoundsCorrected(final int columnIndex) { - checkWidget(); - - // HACK: The -1000,-1000 xy coordinates below are a hack to deal with - // GridEditor issues. In - // normal SWT Table, when an editor is created on Table and its - // positioned in the header area - // the header overlays the editor. Because Grid (header and everything) - // is drawn on one - // composite, when an editor is positioned in the header area the editor - // overlays the header. - // So to fix this, when the editor is anywhere its not supposed to be - // seen (the editor - // coordinates are determined by this getBounds) we position it out in - // timbuktu. - if (!isVisible()) - return new Rectangle(-1000, -1000, 0, 0); - - if (!parent.isShown(this)) - return new Rectangle(-1000, -1000, 0, 0); - - Point origin = parent.getOrigin(parent.getColumn(columnIndex), this); - - if (origin.x < 0 && parent.isRowHeaderVisible()) - return new Rectangle(-1000, -1000, 0, 0); - - Point cellSize = this.getCellSize(columnIndex); - - return new Rectangle(origin.x, origin.y, cellSize.x, cellSize.y); - } - - /** - * - * @param columnIndex - * @return width and height - */ - protected Point getCellSize(int columnIndex) { - /* width */ - int width = 0; - - int span = getColumnSpan(columnIndex); - - int[] columnOrder = parent.getColumnOrder(); - int visualColumnIndex = columnIndex; - for (int i = 0; i < columnOrder.length; i++) { - if (columnOrder[i] == columnIndex) { - visualColumnIndex = i; - break; - } - } - - for (int i = 0; i <= span; i++) { - if (visualColumnIndex + i >= columnOrder.length) { - break; - } - int nextColumnIndex = columnOrder[visualColumnIndex + i]; - width += parent.getColumn(nextColumnIndex).getWidth(); - } - - /* height */ - int indexOfCurrentItem = parent.getIndexOfItem(this); - - GridItem item = parent.getItem(indexOfCurrentItem); - int height = item.getHeight(); - span = getRowSpan(columnIndex); - - int itemCount = parent.getItemCount(); - - for (int i = 1; i <= span; i++) { - /* We will probably need another escape condition here */ - if (itemCount <= indexOfCurrentItem + i) { - break; - } - - item = parent.getItem(indexOfCurrentItem + i); - if (item.isVisible()) { - height += item.getHeight() + 1; - } - } - - return new Point(width, height); - } - - /** - * Returns the checked state at the first column in the receiver. - * - * @return the checked state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean getChecked() { - checkWidget(); - return parent.getDataVisualizer().getChecked(this, 0); - } - - /** - * Returns the checked state at the given column index in the receiver. - * - * @param index - * the column index - * @return the checked state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean getChecked(int index) { - checkWidget(); - - handleVirtual(); - - return parent.getDataVisualizer().getChecked(this, index); - } - - /** - * Returns the column span for the given column index in the receiver. - * - * @param index - * the column index - * @return the number of columns spanned (0 equals no columns spanned) - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getColumnSpan(int index) { - checkWidget(); - return parent.getDataVisualizer().getColumnSpan(this, index); - } - - /** - * Returns the row span for the given column index in the receiver. - * - * @param index - * the row index - * @return the number of row spanned (0 equals no row spanned) - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getRowSpan(int index) { - checkWidget(); - - return parent.getDataVisualizer().getRowSpan(this, index); - } - - /** - * Returns the font that the receiver will use to paint textual information - * for this item. - * - * @return the receiver's font - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Font getFont() { - if (defaultFont == null) { - return parent.getFont(); - } - return defaultFont; - } - - /** - * Returns the font that the receiver will use to paint textual information - * for the specified cell in this item. - * - * @param index - * the column index - * @return the receiver's font - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Font getFont(int index) { - checkWidget(); - - handleVirtual(); - - return parent.getDataVisualizer().getFont(this, index); - } - - /** - * Returns the foreground color that the receiver will use to draw. - * - * @return the receiver's foreground color - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getForeground() { - if (defaultForeground == null) { - return parent.getForeground(); - } - return defaultForeground; - } - - /** - * Returns the foreground color at the given column index in the receiver. - * - * @param index - * the column index - * @return the foreground color - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getForeground(int index) { - checkWidget(); - - handleVirtual(); - - return parent.getDataVisualizer().getForeground(this, index); - } - - /** - * Returns true if the first column in the receiver is grayed, - * and false otherwise. When the GridColumn does not have the - * CHECK style, return false. - * - * @return the grayed state of the checkbox - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean getGrayed() { - return getGrayed(0); - } - - /** - * Returns true if the column at the given index in the - * receiver is grayed, and false otherwise. When the GridColumn does not - * have the CHECK style, return false. - * - * @param index - * the column index - * @return the grayed state of the checkbox - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean getGrayed(int index) { - checkWidget(); - - handleVirtual(); - - return parent.getDataVisualizer().getGrayed(this, index); - } - - /** - * Returns the height of this GridItem. - * - * @return height of this GridItem - */ - public int getHeight() { - checkWidget(); - return height; - } - - /** - * {@inheritDoc} - */ - @Override - public Image getImage() { - checkWidget(); - return parent.getDataVisualizer().getImage(this, 0); - } - - /** - * Returns the image stored at the given column index in the receiver, or - * null if the image has not been set or if the column does not exist. - * - * @param index - * the column index - * @return the image stored at the given column index in the receiver - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Image getImage(int index) { - checkWidget(); - - handleVirtual(); - - return parent.getDataVisualizer().getImage(this, index); - } - - /** - * Returns the item at the given, zero-relative index in the receiver. - * Throws an exception if the index is out of range. - * - * @param index - * the index of the item to return - * @return the item at the given index - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and - * the number of elements in the list minus 1 (inclusive)
  • - *
- * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public GridItem getItem(int index) { - checkWidget(); - if (!hasChildren) - throw new IllegalArgumentException("GridItem has no children!"); - return children.get(index); - } - - /** - * Returns the number of items contained in the receiver that are direct - * item children of the receiver. - * - * @return the number of items - * - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getItemCount() { - checkWidget(); - if (!hasChildren) - return 0; - return children.size(); - } - - /** - * Searches the receiver's list starting at the first item (index 0) until - * an item is found that is equal to the argument, and returns the index of - * that item. If no item is found, returns -1. - * - * @param item - * the search item - * @return the index of the item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed - *
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int indexOf(GridItem item) { - checkWidget(); - if (item == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (item.isDisposed()) - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (!hasChildren) - throw new IllegalArgumentException("GridItem has no children!"); - - return children.indexOf(item); - } - - /** - * Returns a (possibly empty) array of GridItems which are the - * direct item children of the receiver. - *

- * Note: This is not the actual structure used by the receiver to maintain - * its list of items, so modifying the array will not affect the receiver. - *

- * - * @return the receiver's items - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public GridItem[] getItems() { - if (!hasChildren) - return new GridItem[0]; - return children.toArray(new GridItem[children.size()]); - } - - /** - * Returns the level of this item in the tree. - * - * @return the level of the item in the tree - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getLevel() { - checkWidget(); - return level; - } - - /** - * Returns the receiver's parent, which must be a Grid. - * - * @return the receiver's parent - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Grid getParent() { - checkWidget(); - return parent; - } - - /** - * Returns the receiver's parent item, which must be a GridItem - * or null when the receiver is a root. - * - * @return the receiver's parent item - * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public GridItem getParentItem() { - checkWidget(); - return parentItem; - } - - /** - * {@inheritDoc} - */ - @Override - public String getText() { - checkWidget(); - return parent.getDataVisualizer().getText(this, 0); - } - - /** - * Returns the text stored at the given column index in the receiver, or - * empty string if the text has not been set. - * - * @param index - * the column index - * @return the text stored at the given column index in the receiver - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public String getText(int index) { - checkWidget(); - - handleVirtual(); - - return parent.getDataVisualizer().getText(this, index); - } - - /** - * Returns true if this item has children. - * - * @return true if this item has children - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean hasChildren() { - checkWidget(); - return hasChildren; - } - - /** - * Returns true if the receiver is expanded, and false - * otherwise. - *

- * - * @return the expanded state - * @throws SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean isExpanded() { - checkWidget(); - return expanded; - } - - /** - * Sets the receiver's background color to the color specified by the - * argument, or to the default system color for the item if the argument is - * null. - * - * @param background - * the new color (or null) - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setBackground(Color background) { - checkWidget(); - - if (background != null && background.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - for (int i = 0; i < getParent().getColumnCount(); i++) { - setBackground(i, background); - } - defaultBackground = background; - parent.redraw(); - } - - /** - * Sets the background color at the given column index in the receiver to - * the color specified by the argument, or to the default system color for - * the item if the argument is null. - * - * @param index - * the column index - * @param background - * the new color (or null) - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setBackground(int index, Color background) { - checkWidget(); - if (background != null && background.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - parent.getDataVisualizer().setBackground(this, index, background); - parent.redraw(); - } - - /** - * Sets the checked state at the first column in the receiver. - * - * @param checked - * the new checked state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setChecked(boolean checked) { - checkWidget(); - parent.getDataVisualizer().setChecked(this, 0, checked); - parent.redraw(); - } - - /** - * Sets the checked state at the given column index in the receiver. - * - * @param index - * the column index - * @param checked - * the new checked state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setChecked(int index, boolean checked) { - checkWidget(); - parent.getDataVisualizer().setChecked(this, index, checked); - parent.redraw(); - } - - /** - * Sets the column spanning for the column at the given index to span the - * given number of subsequent columns. - * - * @param index - * column index that should span - * @param span - * number of subsequent columns to span - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setColumnSpan(int index, int span) { - checkWidget(); - parent.getDataVisualizer().setColumnSpan(this, index, span); - parent.setHasSpanning(true); - parent.redraw(); - } - - /** - * Sets the row spanning for the row at the given index to span the given - * number of subsequent rows. - * - * @param index - * row index that should span - * @param span - * number of subsequent rows to span - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setRowSpan(int index, int span) { - checkWidget(); - parent.getDataVisualizer().setRowSpan(this, index, span); - parent.setHasSpanning(true); - parent.redraw(); - } - - /** - * Sets the expanded state of the receiver. - *

- * - * @param expanded - * the new expanded state - * @throws SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setExpanded(boolean expanded) { - checkWidget(); - this.expanded = expanded; - - // We must unselect any items that are becoming invisible - // and thus if we change the selection we have to fire a selection event - boolean unselected = doUnselect(expanded); - - this.getParent().topIndex = NO_ROW; - this.getParent().bottomIndex = NO_ROW; - this.getParent().setScrollValuesObsolete(); - - if (unselected) { - Event e = new Event(); - e.item = this; - getParent().notifyListeners(SWT.Selection, e); - } - if (getParent().getFocusItem() != null && !getParent().getFocusItem().isVisible()) { - getParent().setFocusItem(this); - } - - if (getParent().getCellSelectionEnabled()) { - getParent().updateColumnSelection(); - } - } - - private boolean doUnselect(boolean expanded) { - boolean unselected = false; - - if (hasChildren) - for (GridItem item : children) { - item.setVisible(expanded && visible); - if (!expanded) { - if (!getParent().getCellSelectionEnabled()) { - if (getParent().isSelected(item)) { - unselected = true; - getParent().deselect(item.getRowIndex()); - } - if (deselectChildren(item)) { - unselected = true; - } - } else { - if (deselectCells(item)) { - unselected = true; - } - } - } - } - return unselected; - } - - private boolean deselectCells(GridItem item) { - boolean flag = false; - - int index = item.getRowIndex(); - - GridColumn[] columns = getParent().getColumns(); - - for (int i = 0; i < columns.length; i++) { - Point cell = new Point(columns[i].index, index); - if (getParent().isCellSelected(cell)) { - flag = true; - getParent().deselectCell(cell); - } - } - - GridItem[] kids = item.getItems(); - for (int i = 0; i < kids.length; i++) { - if (deselectCells(kids[i])) { - flag = true; - } - } - - return flag; - } - - /** - * Deselects the given item's children recursively. - * - * @param item - * item to deselect children. - * @return true if an item was deselected - */ - private boolean deselectChildren(GridItem item) { - boolean flag = false; - GridItem[] kids = item.getItems(); - for (int i = 0; i < kids.length; i++) { - if (getParent().isSelected(kids[i])) { - flag = true; - } - getParent().deselect(kids[i].getRowIndex()); - if (deselectChildren(kids[i])) { - flag = true; - } - } - return flag; - } - - /** - * Sets the font that the receiver will use to paint textual information for - * this item to the font specified by the argument, or to the default font - * for that kind of control if the argument is null. - * - * @param f - * the new font (or null) - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setFont(Font f) { - checkWidget(); - if (f != null && f.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - defaultFont = f; - parent.redraw(); - } - - /** - * Sets the font that the receiver will use to paint textual information for - * the specified cell in this item to the font specified by the argument, or - * to the default font for that kind of control if the argument is null. - * - * @param index - * the column index - * @param font - * the new font (or null) - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setFont(int index, Font font) { - checkWidget(); - if (font != null && font.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - parent.getDataVisualizer().setFont(this, index, font); - parent.redraw(); - } - - /** - * Sets the receiver's foreground color to the color specified by the - * argument, or to the default system color for the item if the argument is - * null. - * - * @param foreground - * the new color (or null) - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @throws SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setForeground(Color foreground) { - checkWidget(); - if (foreground != null && foreground.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - for (int i = 0; i < getParent().getColumnCount(); i++) { - setForeground(i, foreground); - } - defaultForeground = foreground; - parent.redraw(); - } - - /** - * Sets the foreground color at the given column index in the receiver to - * the color specified by the argument, or to the default system color for - * the item if the argument is null. - * - * @param index - * the column index - * @param foreground - * the new color (or null) - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setForeground(int index, Color foreground) { - checkWidget(); - if (foreground != null && foreground.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - parent.getDataVisualizer().setForeground(this, index, foreground); - parent.redraw(); - } - - /** - * Sets the grayed state of the checkbox for the first column. This state - * change only applies if the GridColumn was created with the SWT.CHECK - * style. - * - * @param grayed - * the new grayed state of the checkbox; - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setGrayed(boolean grayed) { - checkWidget(); - parent.getDataVisualizer().setGrayed(this, 0, grayed); - parent.redraw(); - } - - /** - * Sets the grayed state of the checkbox for the given column index. This - * state change only applies if the GridColumn was created with the - * SWT.CHECK style. - * - * @param index - * the column index - * @param grayed - * the new grayed state of the checkbox; - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setGrayed(int index, boolean grayed) { - checkWidget(); - parent.getDataVisualizer().setGrayed(this, index, grayed); - parent.redraw(); - } - - /** - * Sets the height of this GridItem. - * - * @param newHeight - * new height in pixels - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setHeight(int newHeight) { - checkWidget(); - if (newHeight < 1) - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - height = newHeight; - parent.hasDifferingHeights = true; - if (isVisible()) { - int myIndex = this.getRowIndex(); - // note: cannot use Grid#isShown() here, because that returns false - // for partially shown items - if (parent.getTopIndex() <= myIndex && myIndex <= parent.getBottomIndex()) - parent.bottomIndex = NO_ROW; - } - parent.setScrollValuesObsolete(); - parent.redraw(); - } - - /** - * Sets this GridItem to its preferred height. - * - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void pack() { - checkWidget(); - - int maxPrefHeight = 2; - GridColumn[] columns = parent.getColumns(); - GC gc = new GC(parent); - for (int cnt = 0; cnt < columns.length; cnt++) { - if (!columns[cnt].isVisible()) - continue; // invisible columns do not affect item/row height - - GridCellRenderer renderer = columns[cnt].getCellRenderer(); - - renderer.setAlignment(columns[cnt].getAlignment()); - renderer.setCheck(columns[cnt].isCheck()); - renderer.setColumn(cnt); - renderer.setTree(columns[cnt].isTree()); - renderer.setWordWrap(columns[cnt].getWordWrap()); - - Point size = renderer.computeSize(gc, columns[cnt].getWidth(), SWT.DEFAULT, this); - if (size != null) - maxPrefHeight = Math.max(maxPrefHeight, size.y); - } - gc.dispose(); - - setHeight(maxPrefHeight); - } - - /** - * {@inheritDoc} - */ - @Override - public void setImage(Image image) { - parent.getDataVisualizer().setImage(this, 0, image); - parent.redraw(); - } - - /** - * Sets the receiver's image at a column. - * - * @param index - * the column index - * @param image - * the new image - * @throws IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed - *
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setImage(int index, Image image) { - checkWidget(); - if (image != null && image.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - parent.getDataVisualizer().setImage(this, index, image); - - parent.imageSetOnItem(index, this); - - parent.redraw(); - } - - /** - * Sets the receiver's text at a column. - * - * @param index - * the column index - * @param text - * the new text - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the text is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setText(int index, String text) { - checkWidget(); - if (text == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - parent.getDataVisualizer().setText(this, index, text); - parent.redraw(); - } - - /** - * {@inheritDoc} - */ - @Override - public void setText(String string) { - parent.getDataVisualizer().setText(this, 0, string); - parent.redraw(); - } - - /** - * Removes the given child item from the list of children. - * - * @param child - * child to remove - */ - private void remove(GridItem child) { - if (!hasChildren) - throw new IllegalArgumentException("GridItem has no children!"); - children.remove(child); - parent.getDataVisualizer().clearRow(child); - hasChildren = !children.isEmpty(); - } - - /** - * Returns true if the item is visible because its parent items are all - * expanded. This method does not determine if the item is in the currently - * visible range. - * - * @return Returns the visible. - */ - public boolean isVisible() { - return visible; - } - - /** - * Creates a new child item in this item at the given index. - * - * @param item - * new child item - * @param index - * index - */ - void newItem(GridItem item, int index) { - setHasChildren(true); - if (children == null) - children = new ArrayList<>(); - if (index == NO_ROW) { - children.add(item); - } else { - children.add(index, item); - } - } - - /** - * Sets whether this item has children. - * - * @param hasChildren - * true if this item has children - */ - void setHasChildren(boolean hasChildren) { - this.hasChildren = hasChildren; - } - - /** - * Sets the visible state of this item. The visible state is determined by - * the expansion state of all of its parent items. If all parent items are - * expanded it is visible. - * - * @param visible - * The visible to set. - */ - void setVisible(boolean visible) { - if (this.visible == visible) { - return; - } - - this.visible = visible; - - if (visible) { - parent.updateVisibleItems(1); - } else { - parent.updateVisibleItems(NO_ROW); - } - - if (hasChildren) { - boolean childrenVisible = visible; - if (visible) { - childrenVisible = expanded; - } - for (GridItem item : children) { - item.setVisible(childrenVisible); - } - } - } - - /** - * Returns the receiver's row header text. If the text is null - * the row header will display the row number. - * - * @return the text stored for the row header or code null if - * the default has to be displayed - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public String getHeaderText() { - checkWidget(); - - // handleVirtual(); - - return headerText; - } - - /** - * Returns the receiver's row header image. - * - * @return the image stored for the header or null if none has - * to be displayed - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Image getHeaderImage() { - checkWidget(); - return headerImage; - } - - /** - * Returns the receiver's row header background color - * - * @return the color or null if none - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getHeaderBackground() { - checkWidget(); - return headerBackground; - } - - /** - * Returns the receiver's row header foreground color - * - * @return the color or null if none - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getHeaderForeground() { - checkWidget(); - return headerForeground; - } - - /** - * Returns the receiver's row header font - * - * @return the font or null if none - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Font getHeaderFont() { - checkWidget(); - return headerFont; - } - - /** - * Sets the receiver's row header text. If the text is null the - * row header will display the row number. - * - * @param text - * the new text - * @throws IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the text is null
  • - *
- * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setHeaderText(String text) { - checkWidget(); - // if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (text != headerText) { - GC gc = new GC(parent); - - int oldWidth = headerText == null ? 0 - : parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).x; - - this.headerText = text; - - int newWidth = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).x; - - gc.dispose(); - - parent.recalculateRowHeaderWidth(this, oldWidth, newWidth); - } - parent.redraw(); - } - - /** - * Sets the receiver's row header image. If the image is null - * none is shown in the header - * - * @param image - * the new image - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setHeaderImage(Image image) { - checkWidget(); - // if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (image != headerImage) { - GC gc = new GC(parent); - - int oldWidth = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).x; - int oldHeight = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).y; - - this.headerImage = image; - - int newWidth = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).x; - int newHeight = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).y; - - gc.dispose(); - - parent.recalculateRowHeaderWidth(this, oldWidth, newWidth); - parent.recalculateRowHeaderHeight(this, oldHeight, newHeight); - } - parent.redraw(); - } - - /** - * Set the new header background - * - * @param headerBackground - * the color or null - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setHeaderBackground(Color headerBackground) { - checkWidget(); - this.headerBackground = headerBackground; - parent.redraw(); - } - - /** - * Set the new header foreground - * - * @param headerForeground - * the color or null - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setHeaderForeground(Color headerForeground) { - checkWidget(); - this.headerForeground = headerForeground; - parent.redraw(); - } - - /** - * Set the new header font - * - * @param headerFont - * the font or null - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setHeaderFont(Font headerFont) { - checkWidget(); - this.headerFont=headerFont; - parent.redraw(); - } - - /** - * Returns the checkable state at the given column index in the receiver. If - * the column at the given index is not checkable then this will return - * false regardless of the individual cell's checkable state. - * - * @param index - * the column index - * @return the checked state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean getCheckable(int index) { - checkWidget(); - - if (!parent.getColumn(index).getCheckable()) - return false; - - return parent.getDataVisualizer().getCheckable(this, index); - } - - /** - * Sets the checkable state at the given column index in the receiver. A - * checkbox which is uncheckable will not be modifiable by the user but - * still make be modified programmatically. If the column at the given index - * is not checkable then individual cell will not be checkable regardless. - * - * @param index - * the column index - * @param checked - * the new checked state - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setCheckable(int index, boolean checked) { - checkWidget(); - parent.getDataVisualizer().setCheckable(this, index, checked); - } - - /** - * Returns the tooltip for the given cell. - * - * @param index - * the column index - * @return the tooltip - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public String getToolTipText(int index) { - checkWidget(); - - handleVirtual(); - - return parent.getDataVisualizer().getToolTipText(this, index); - } - - /** - * Sets the tooltip for the given column index. - * - * @param index - * the column index - * @param tooltip - * the tooltip text - * @throws org.eclipse.swt.SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed - *
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setToolTipText(int index, String tooltip) { - checkWidget(); - parent.getDataVisualizer().setToolTipText(this, index, tooltip); - } - - void columnAdded(int index) { - hasSetData = false; - } - - private void handleVirtual() { - if ((getParent().getStyle() & SWT.VIRTUAL) != 0 && !hasSetData) { - hasSetData = true; - Event event = new Event(); - event.item = this; - if (parentItem == null) { - event.index = getRowIndex(); - } else { - event.index = parentItem.indexOf(this); - } - getParent().notifyListeners(SWT.SetData, event); - } - } - - /** - * Sets the initial item height for this item. - * - * @param height - * initial height. - */ - void initializeHeight(int height) { - this.height = height; - } - - void setHasSetData(boolean hasSetData) { - this.hasSetData = hasSetData; - } - - /** - * Clears all properties of this item and resets values to their defaults. - * - * @param allChildren - * true if all child items should be cleared - * recursively, and false otherwise - */ - void clear(boolean allChildren) { - - defaultForeground = null; - defaultBackground = null; - defaultFont = null; - - hasSetData = false; - headerText = null; - headerImage = null; - headerBackground = null; - headerForeground = null; - - // Recursively clear children if requested. - if (allChildren && hasChildren) { - for (int i = children.size() - 1; i >= 0; i--) { - children.get(i).clear(true); - } - } - - } - - /** - * this method call only super.dispose, nothing else.. - */ - public void disposeOnly() { - if (hasChildren) - for (int i = children.size() - 1; i >= 0; i--) { - children.get(i).disposeOnly(); - } - if (parent.getDataVisualizer() != null) { - parent.getDataVisualizer().clearRow(this); - } - noRow(); - super.dispose(); - } - - private void noRow() { - synchronized (ROW_LOCK) { - row = NO_ROW; - } - } -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + * Claes Rosell - rowspan in bug 272384 + * Stefan Widmaier - rowspan in 304797 + * Mirko Paturzo - improvement (bug in 419928) + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +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.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.TypedListener; + +/** + *

+ * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A + * PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE + * VERSIONS. + *

+ * Instances of this class represent a selectable user interface object that + * represents an item in a grid. + *

+ *

+ *
Styles:
+ *
(none)
+ *
Events:
+ *
(none)
+ *
+ * + * @author chris.gross@us.ibm.com + * @author Mirko Paturzo + * + * Mirko removed all collections, improve dispose performance, reduce + * used memory + */ +public class GridItem extends Item { + private static final int NO_ROW = -1; + + /** + * List of children. + */ + private List children; + + /** + * Default background color. + */ + @Deprecated + private Color defaultBackground; + + /** + * Default font. + */ + @Deprecated + private Font defaultFont; + + /** + * Default foreground color. + */ + @Deprecated + private Color defaultForeground; + + /** + * The height of this GridItem. + */ + private int height = 1; + + /** + * Is expanded? + */ + private boolean expanded = false; + + /** + * True if has children. + */ + private boolean hasChildren = false; + + /** + * Level of item in a tree. + */ + private int level = 0; + + /** + * Parent grid instance. + */ + private final Grid parent; + + /** + * Parent item (if a child item). + */ + private GridItem parentItem; + + /** + * Is visible? + */ + private boolean visible = true; + + /** + * Row header text. + */ + private String headerText = null; + + /** + * Row header image + */ + private Image headerImage = null; + + /** + * Background color of the header + */ + private Color headerBackground = null; + + /** + * Foreground color of the header + */ + public Color headerForeground = null; + + /** + * Font of the header + */ + private Font headerFont = null; + + /** + * (SWT.VIRTUAL only) Flag that specifies whether the client has already + * been sent a SWT.SetData event. + */ + private boolean hasSetData = false; + + private int row = NO_ROW; + + private final Object ROW_LOCK = new Object(); + + /** + * Creates a new instance of this class and places the item at the end of + * the grid. + * + * @param parent + * parent grid + * @param style + * item style + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ */ + public GridItem(Grid parent, int style) { + this(parent, style, NO_ROW); + } + + /** + * Creates a new instance of this class and places the item in the grid at + * the given index. + * + * @param parent + * parent grid + * @param style + * item style + * @param index + * index where to insert item + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ */ + public GridItem(Grid parent, int style, int index) { + super(parent, style, index); + + this.parent = parent; + + row = parent.newItem(this, index, true); + parent.newRootItem(this, index); + } + + /** + * @return grid row index + */ + public int getRowIndex() { + synchronized (ROW_LOCK) { + if (row != NO_ROW) + return row; + } + return parent.indexOf(this); + } + + void increaseRow() { + synchronized (ROW_LOCK) { + row++; + } + } + + void decreaseRow() { + synchronized (ROW_LOCK) { + row--; + } + } + + /** + * Creates a new instance of this class as a child node of the given + * GridItem and places the item at the end of the parents items. + * + * @param parent + * parent item + * @param style + * item style + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ */ + public GridItem(GridItem parent, int style) { + this(parent, style, NO_ROW); + } + + /** + * Creates a new instance of this class as a child node of the given Grid + * and places the item at the given index in the parent items list. + * + * @param parent + * parent item + * @param style + * item style + * @param index + * index to place item + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ */ + public GridItem(GridItem parent, int style, int index) { + super(parent, style, index); + + parentItem = parent; + this.parent = parentItem.getParent(); + + row = this.parent.newItem(this, index, false); + + level = parentItem.getLevel() + 1; + + parentItem.newItem(this, index); + + parentItem.indexOf(this); + + if (parent.isVisible() && parent.isExpanded()) { + setVisible(true); + } else { + setVisible(false); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void dispose() { + if (!parent.isDisposing()) { + parent.removeItem(this); + + if (parentItem != null) { + parentItem.remove(this); + } else { + parent.removeRootItem(this); + } + if (hasChildren) + for (int i = children.size() - 1; i >= 0; i--) { + children.get(i).dispose(); + } + } + if (parent.getDataVisualizer() != null) { + parent.getDataVisualizer().clearRow(this); + } + noRow(); + super.dispose(); + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the row is resized, by sending it one of the messages defined in the + * ControlListener interface. + *

+ * Clients who wish to override the standard row resize logic should use the + * untyped listener mechanisms. The untyped Event object passed + * to an untyped listener will have its detail field populated + * with the new row height. Clients may alter this value to, for example, + * enforce minimum or maximum row sizes. Clients may also set the + * doit field to false to prevent the entire resize operation. + * + * @param listener + * the listener which should be notified + * + * @exception IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void addControlListener(ControlListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener(listener); + addListener(SWT.Resize, typedListener); + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the row is resized. + * + * @param listener + * the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void removeControlListener(ControlListener listener) { + checkWidget(); + if (listener == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + removeListener(SWT.Resize, listener); + } + + /** + * Fires the given event type on the parent Grid instance. This method + * should only be called from within a cell renderer. Any other use is not + * intended. + * + * @param eventId + * SWT event constant + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void fireEvent(int eventId) { + checkWidget(); + + Event e = new Event(); + e.display = getDisplay(); + e.widget = this; + e.item = this; + e.type = eventId; + + getParent().notifyListeners(eventId, e); + } + + /** + * Fires the appropriate events in response to a user checking/unchecking an + * item. Checking an item fires both a selection event (with event.detail of + * SWT.CHECK) if the checkbox is in the first column and the seperate check + * listener (all columns). This method manages that behavior. This method + * should only be called from within a cell renderer. Any other use is not + * intended. + * + * @param column + * the column where the checkbox resides + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void fireCheckEvent(int column) { + checkWidget(); + + Event selectionEvent = new Event(); + selectionEvent.display = getDisplay(); + selectionEvent.widget = this; + selectionEvent.item = this; + selectionEvent.type = SWT.Selection; + selectionEvent.detail = SWT.CHECK; + selectionEvent.index = column; + + getParent().notifyListeners(SWT.Selection, selectionEvent); + } + + /** + * Returns the receiver's background color. + * + * @return the background color + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getBackground() { + checkWidget(); + + if (defaultBackground == null) { + return parent.getBackground(); + } + return defaultBackground; + } + + /** + * Returns the background color at the given column index in the receiver. + * + * @param index + * the column index + * @return the background color + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getBackground(int index) { + checkWidget(); + + handleVirtual(); + + return parent.getDataVisualizer().getBackground(this, index); + + } + + /** + * Returns a rectangle describing the receiver's size and location relative + * to its parent at a column in the table. + * + * @param columnIndex + * the index that specifies the column + * @return the receiver's bounding column rectangle + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Rectangle getBounds(int columnIndex) { + checkWidget(); + + final Point origin = parent.getOrigin(parent.getColumn(columnIndex), this); + final Point cellSize = this.getCellSize(columnIndex); + return new Rectangle(origin.x, origin.y, cellSize.x, cellSize.y); + } + + /** + * Returns a rectangle describing the receiver's size and location relative + * to its parent at a column in the table. + * Handle not visible items. + * + * @param columnIndex + * the index that specifies the column + * @return the receiver's bounding column rectangle + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Rectangle getBoundsCorrected(final int columnIndex) { + checkWidget(); + + // HACK: The -1000,-1000 xy coordinates below are a hack to deal with + // GridEditor issues. In + // normal SWT Table, when an editor is created on Table and its + // positioned in the header area + // the header overlays the editor. Because Grid (header and everything) + // is drawn on one + // composite, when an editor is positioned in the header area the editor + // overlays the header. + // So to fix this, when the editor is anywhere its not supposed to be + // seen (the editor + // coordinates are determined by this getBounds) we position it out in + // timbuktu. + if (!isVisible()) + return new Rectangle(-1000, -1000, 0, 0); + + if (!parent.isShown(this)) + return new Rectangle(-1000, -1000, 0, 0); + + Point origin = parent.getOrigin(parent.getColumn(columnIndex), this); + + if (origin.x < 0 && parent.isRowHeaderVisible()) + return new Rectangle(-1000, -1000, 0, 0); + + Point cellSize = this.getCellSize(columnIndex); + + return new Rectangle(origin.x, origin.y, cellSize.x, cellSize.y); + } + + /** + * + * @param columnIndex + * @return width and height + */ + protected Point getCellSize(int columnIndex) { + /* width */ + int width = 0; + + int span = getColumnSpan(columnIndex); + + int[] columnOrder = parent.getColumnOrder(); + int visualColumnIndex = columnIndex; + for (int i = 0; i < columnOrder.length; i++) { + if (columnOrder[i] == columnIndex) { + visualColumnIndex = i; + break; + } + } + + for (int i = 0; i <= span; i++) { + if (visualColumnIndex + i >= columnOrder.length) { + break; + } + int nextColumnIndex = columnOrder[visualColumnIndex + i]; + width += parent.getColumn(nextColumnIndex).getWidth(); + } + + /* height */ + int indexOfCurrentItem = parent.getIndexOfItem(this); + + GridItem item = parent.getItem(indexOfCurrentItem); + int height = item.getHeight(); + span = getRowSpan(columnIndex); + + int itemCount = parent.getItemCount(); + + for (int i = 1; i <= span; i++) { + /* We will probably need another escape condition here */ + if (itemCount <= indexOfCurrentItem + i) { + break; + } + + item = parent.getItem(indexOfCurrentItem + i); + if (item.isVisible()) { + height += item.getHeight() + 1; + } + } + + return new Point(width, height); + } + + /** + * Returns the checked state at the first column in the receiver. + * + * @return the checked state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean getChecked() { + checkWidget(); + return parent.getDataVisualizer().getChecked(this, 0); + } + + /** + * Returns the checked state at the given column index in the receiver. + * + * @param index + * the column index + * @return the checked state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean getChecked(int index) { + checkWidget(); + + handleVirtual(); + + return parent.getDataVisualizer().getChecked(this, index); + } + + /** + * Returns the column span for the given column index in the receiver. + * + * @param index + * the column index + * @return the number of columns spanned (0 equals no columns spanned) + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getColumnSpan(int index) { + checkWidget(); + return parent.getDataVisualizer().getColumnSpan(this, index); + } + + /** + * Returns the row span for the given column index in the receiver. + * + * @param index + * the row index + * @return the number of row spanned (0 equals no row spanned) + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getRowSpan(int index) { + checkWidget(); + + return parent.getDataVisualizer().getRowSpan(this, index); + } + + /** + * Returns the font that the receiver will use to paint textual information + * for this item. + * + * @return the receiver's font + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Font getFont() { + if (defaultFont == null) { + return parent.getFont(); + } + return defaultFont; + } + + /** + * Returns the font that the receiver will use to paint textual information + * for the specified cell in this item. + * + * @param index + * the column index + * @return the receiver's font + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Font getFont(int index) { + checkWidget(); + + handleVirtual(); + + return parent.getDataVisualizer().getFont(this, index); + } + + /** + * Returns the foreground color that the receiver will use to draw. + * + * @return the receiver's foreground color + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getForeground() { + if (defaultForeground == null) { + return parent.getForeground(); + } + return defaultForeground; + } + + /** + * Returns the foreground color at the given column index in the receiver. + * + * @param index + * the column index + * @return the foreground color + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getForeground(int index) { + checkWidget(); + + handleVirtual(); + + return parent.getDataVisualizer().getForeground(this, index); + } + + /** + * Returns true if the first column in the receiver is grayed, + * and false otherwise. When the GridColumn does not have the + * CHECK style, return false. + * + * @return the grayed state of the checkbox + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean getGrayed() { + return getGrayed(0); + } + + /** + * Returns true if the column at the given index in the + * receiver is grayed, and false otherwise. When the GridColumn does not + * have the CHECK style, return false. + * + * @param index + * the column index + * @return the grayed state of the checkbox + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean getGrayed(int index) { + checkWidget(); + + handleVirtual(); + + return parent.getDataVisualizer().getGrayed(this, index); + } + + /** + * Returns the height of this GridItem. + * + * @return height of this GridItem + */ + public int getHeight() { + checkWidget(); + return height; + } + + /** + * {@inheritDoc} + */ + @Override + public Image getImage() { + checkWidget(); + return parent.getDataVisualizer().getImage(this, 0); + } + + /** + * Returns the image stored at the given column index in the receiver, or + * null if the image has not been set or if the column does not exist. + * + * @param index + * the column index + * @return the image stored at the given column index in the receiver + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Image getImage(int index) { + checkWidget(); + + handleVirtual(); + + return parent.getDataVisualizer().getImage(this, index); + } + + /** + * Returns the item at the given, zero-relative index in the receiver. + * Throws an exception if the index is out of range. + * + * @param index + * the index of the item to return + * @return the item at the given index + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and + * the number of elements in the list minus 1 (inclusive)
  • + *
+ * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public GridItem getItem(int index) { + checkWidget(); + if (!hasChildren) + throw new IllegalArgumentException("GridItem has no children!"); + return children.get(index); + } + + /** + * Returns the number of items contained in the receiver that are direct + * item children of the receiver. + * + * @return the number of items + * + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getItemCount() { + checkWidget(); + if (!hasChildren) + return 0; + return children.size(); + } + + /** + * Searches the receiver's list starting at the first item (index 0) until + * an item is found that is equal to the argument, and returns the index of + * that item. If no item is found, returns -1. + * + * @param item + * the search item + * @return the index of the item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed + *
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int indexOf(GridItem item) { + checkWidget(); + if (item == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (item.isDisposed()) + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (!hasChildren) + throw new IllegalArgumentException("GridItem has no children!"); + + return children.indexOf(item); + } + + /** + * Returns a (possibly empty) array of GridItems which are the + * direct item children of the receiver. + *

+ * Note: This is not the actual structure used by the receiver to maintain + * its list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the receiver's items + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public GridItem[] getItems() { + if (!hasChildren) + return new GridItem[0]; + return children.toArray(new GridItem[children.size()]); + } + + /** + * Returns the level of this item in the tree. + * + * @return the level of the item in the tree + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getLevel() { + checkWidget(); + return level; + } + + /** + * Returns the receiver's parent, which must be a Grid. + * + * @return the receiver's parent + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Grid getParent() { + checkWidget(); + return parent; + } + + /** + * Returns the receiver's parent item, which must be a GridItem + * or null when the receiver is a root. + * + * @return the receiver's parent item + * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public GridItem getParentItem() { + checkWidget(); + return parentItem; + } + + /** + * {@inheritDoc} + */ + @Override + public String getText() { + checkWidget(); + return parent.getDataVisualizer().getText(this, 0); + } + + /** + * Returns the text stored at the given column index in the receiver, or + * empty string if the text has not been set. + * + * @param index + * the column index + * @return the text stored at the given column index in the receiver + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getText(int index) { + checkWidget(); + + handleVirtual(); + + return parent.getDataVisualizer().getText(this, index); + } + + /** + * Returns true if this item has children. + * + * @return true if this item has children + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean hasChildren() { + checkWidget(); + return hasChildren; + } + + /** + * Returns true if the receiver is expanded, and false + * otherwise. + *

+ * + * @return the expanded state + * @throws SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean isExpanded() { + checkWidget(); + return expanded; + } + + /** + * Sets the receiver's background color to the color specified by the + * argument, or to the default system color for the item if the argument is + * null. + * + * @param background + * the new color (or null) + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setBackground(Color background) { + checkWidget(); + + if (background != null && background.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + for (int i = 0; i < getParent().getColumnCount(); i++) { + setBackground(i, background); + } + defaultBackground = background; + parent.redraw(); + } + + /** + * Sets the background color at the given column index in the receiver to + * the color specified by the argument, or to the default system color for + * the item if the argument is null. + * + * @param index + * the column index + * @param background + * the new color (or null) + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setBackground(int index, Color background) { + checkWidget(); + if (background != null && background.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + parent.getDataVisualizer().setBackground(this, index, background); + parent.redraw(); + } + + /** + * Sets the checked state at the first column in the receiver. + * + * @param checked + * the new checked state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setChecked(boolean checked) { + checkWidget(); + parent.getDataVisualizer().setChecked(this, 0, checked); + parent.redraw(); + } + + /** + * Sets the checked state at the given column index in the receiver. + * + * @param index + * the column index + * @param checked + * the new checked state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setChecked(int index, boolean checked) { + checkWidget(); + parent.getDataVisualizer().setChecked(this, index, checked); + parent.redraw(); + } + + /** + * Sets the column spanning for the column at the given index to span the + * given number of subsequent columns. + * + * @param index + * column index that should span + * @param span + * number of subsequent columns to span + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setColumnSpan(int index, int span) { + checkWidget(); + parent.getDataVisualizer().setColumnSpan(this, index, span); + parent.setHasSpanning(true); + parent.redraw(); + } + + /** + * Sets the row spanning for the row at the given index to span the given + * number of subsequent rows. + * + * @param index + * row index that should span + * @param span + * number of subsequent rows to span + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setRowSpan(int index, int span) { + checkWidget(); + parent.getDataVisualizer().setRowSpan(this, index, span); + parent.setHasSpanning(true); + parent.redraw(); + } + + /** + * Sets the expanded state of the receiver. + *

+ * + * @param expanded + * the new expanded state + * @throws SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setExpanded(boolean expanded) { + checkWidget(); + this.expanded = expanded; + + // We must unselect any items that are becoming invisible + // and thus if we change the selection we have to fire a selection event + boolean unselected = doUnselect(expanded); + + this.getParent().topIndex = NO_ROW; + this.getParent().bottomIndex = NO_ROW; + this.getParent().setScrollValuesObsolete(); + + if (unselected) { + Event e = new Event(); + e.item = this; + getParent().notifyListeners(SWT.Selection, e); + } + if (getParent().getFocusItem() != null && !getParent().getFocusItem().isVisible()) { + getParent().setFocusItem(this); + } + + if (getParent().getCellSelectionEnabled()) { + getParent().updateColumnSelection(); + } + } + + private boolean doUnselect(boolean expanded) { + boolean unselected = false; + + if (hasChildren) + for (GridItem item : children) { + item.setVisible(expanded && visible); + if (!expanded) { + if (!getParent().getCellSelectionEnabled()) { + if (getParent().isSelected(item)) { + unselected = true; + getParent().deselect(item.getRowIndex()); + } + if (deselectChildren(item)) { + unselected = true; + } + } else { + if (deselectCells(item)) { + unselected = true; + } + } + } + } + return unselected; + } + + private boolean deselectCells(GridItem item) { + boolean flag = false; + + int index = item.getRowIndex(); + + GridColumn[] columns = getParent().getColumns(); + + for (int i = 0; i < columns.length; i++) { + Point cell = new Point(columns[i].index, index); + if (getParent().isCellSelected(cell)) { + flag = true; + getParent().deselectCell(cell); + } + } + + GridItem[] kids = item.getItems(); + for (int i = 0; i < kids.length; i++) { + if (deselectCells(kids[i])) { + flag = true; + } + } + + return flag; + } + + /** + * Deselects the given item's children recursively. + * + * @param item + * item to deselect children. + * @return true if an item was deselected + */ + private boolean deselectChildren(GridItem item) { + boolean flag = false; + GridItem[] kids = item.getItems(); + for (int i = 0; i < kids.length; i++) { + if (getParent().isSelected(kids[i])) { + flag = true; + } + getParent().deselect(kids[i].getRowIndex()); + if (deselectChildren(kids[i])) { + flag = true; + } + } + return flag; + } + + /** + * Sets the font that the receiver will use to paint textual information for + * this item to the font specified by the argument, or to the default font + * for that kind of control if the argument is null. + * + * @param f + * the new font (or null) + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setFont(Font f) { + checkWidget(); + if (f != null && f.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + defaultFont = f; + parent.redraw(); + } + + /** + * Sets the font that the receiver will use to paint textual information for + * the specified cell in this item to the font specified by the argument, or + * to the default font for that kind of control if the argument is null. + * + * @param index + * the column index + * @param font + * the new font (or null) + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setFont(int index, Font font) { + checkWidget(); + if (font != null && font.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + parent.getDataVisualizer().setFont(this, index, font); + parent.redraw(); + } + + /** + * Sets the receiver's foreground color to the color specified by the + * argument, or to the default system color for the item if the argument is + * null. + * + * @param foreground + * the new color (or null) + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @throws SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setForeground(Color foreground) { + checkWidget(); + if (foreground != null && foreground.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + for (int i = 0; i < getParent().getColumnCount(); i++) { + setForeground(i, foreground); + } + defaultForeground = foreground; + parent.redraw(); + } + + /** + * Sets the foreground color at the given column index in the receiver to + * the color specified by the argument, or to the default system color for + * the item if the argument is null. + * + * @param index + * the column index + * @param foreground + * the new color (or null) + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setForeground(int index, Color foreground) { + checkWidget(); + if (foreground != null && foreground.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + parent.getDataVisualizer().setForeground(this, index, foreground); + parent.redraw(); + } + + /** + * Sets the grayed state of the checkbox for the first column. This state + * change only applies if the GridColumn was created with the SWT.CHECK + * style. + * + * @param grayed + * the new grayed state of the checkbox; + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setGrayed(boolean grayed) { + checkWidget(); + parent.getDataVisualizer().setGrayed(this, 0, grayed); + parent.redraw(); + } + + /** + * Sets the grayed state of the checkbox for the given column index. This + * state change only applies if the GridColumn was created with the + * SWT.CHECK style. + * + * @param index + * the column index + * @param grayed + * the new grayed state of the checkbox; + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setGrayed(int index, boolean grayed) { + checkWidget(); + parent.getDataVisualizer().setGrayed(this, index, grayed); + parent.redraw(); + } + + /** + * Sets the height of this GridItem. + * + * @param newHeight + * new height in pixels + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setHeight(int newHeight) { + checkWidget(); + if (newHeight < 1) + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + height = newHeight; + parent.hasDifferingHeights = true; + if (isVisible()) { + int myIndex = this.getRowIndex(); + // note: cannot use Grid#isShown() here, because that returns false + // for partially shown items + if (parent.getTopIndex() <= myIndex && myIndex <= parent.getBottomIndex()) + parent.bottomIndex = NO_ROW; + } + parent.setScrollValuesObsolete(); + parent.redraw(); + } + + /** + * Sets this GridItem to its preferred height. + * + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void pack() { + checkWidget(); + + int maxPrefHeight = 2; + GridColumn[] columns = parent.getColumns(); + GC gc = new GC(parent); + for (int cnt = 0; cnt < columns.length; cnt++) { + if (!columns[cnt].isVisible()) + continue; // invisible columns do not affect item/row height + + GridCellRenderer renderer = columns[cnt].getCellRenderer(); + + renderer.setAlignment(columns[cnt].getAlignment()); + renderer.setCheck(columns[cnt].isCheck()); + renderer.setColumn(cnt); + renderer.setTree(columns[cnt].isTree()); + renderer.setWordWrap(columns[cnt].getWordWrap()); + + Point size = renderer.computeSize(gc, columns[cnt].getWidth(), SWT.DEFAULT, this); + if (size != null) + maxPrefHeight = Math.max(maxPrefHeight, size.y); + } + gc.dispose(); + + setHeight(maxPrefHeight); + } + + /** + * {@inheritDoc} + */ + @Override + public void setImage(Image image) { + parent.getDataVisualizer().setImage(this, 0, image); + parent.redraw(); + } + + /** + * Sets the receiver's image at a column. + * + * @param index + * the column index + * @param image + * the new image + * @throws IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been disposed + *
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setImage(int index, Image image) { + checkWidget(); + if (image != null && image.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + parent.getDataVisualizer().setImage(this, index, image); + + parent.imageSetOnItem(index, this); + + parent.redraw(); + } + + /** + * Sets the receiver's text at a column. + * + * @param index + * the column index + * @param text + * the new text + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the text is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setText(int index, String text) { + checkWidget(); + if (text == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + parent.getDataVisualizer().setText(this, index, text); + parent.redraw(); + } + + /** + * {@inheritDoc} + */ + @Override + public void setText(String string) { + parent.getDataVisualizer().setText(this, 0, string); + parent.redraw(); + } + + /** + * Removes the given child item from the list of children. + * + * @param child + * child to remove + */ + private void remove(GridItem child) { + if (!hasChildren) + throw new IllegalArgumentException("GridItem has no children!"); + children.remove(child); + parent.getDataVisualizer().clearRow(child); + hasChildren = !children.isEmpty(); + } + + /** + * Returns true if the item is visible because its parent items are all + * expanded. This method does not determine if the item is in the currently + * visible range. + * + * @return Returns the visible. + */ + public boolean isVisible() { + return visible; + } + + /** + * Creates a new child item in this item at the given index. + * + * @param item + * new child item + * @param index + * index + */ + void newItem(GridItem item, int index) { + setHasChildren(true); + if (children == null) + children = new ArrayList<>(); + if (index == NO_ROW) { + children.add(item); + } else { + children.add(index, item); + } + } + + /** + * Sets whether this item has children. + * + * @param hasChildren + * true if this item has children + */ + void setHasChildren(boolean hasChildren) { + this.hasChildren = hasChildren; + } + + /** + * Sets the visible state of this item. The visible state is determined by + * the expansion state of all of its parent items. If all parent items are + * expanded it is visible. + * + * @param visible + * The visible to set. + */ + void setVisible(boolean visible) { + if (this.visible == visible) { + return; + } + + this.visible = visible; + + if (visible) { + parent.updateVisibleItems(1); + } else { + parent.updateVisibleItems(NO_ROW); + } + + if (hasChildren) { + boolean childrenVisible = visible; + if (visible) { + childrenVisible = expanded; + } + for (GridItem item : children) { + item.setVisible(childrenVisible); + } + } + } + + /** + * Returns the receiver's row header text. If the text is null + * the row header will display the row number. + * + * @return the text stored for the row header or code null if + * the default has to be displayed + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getHeaderText() { + checkWidget(); + + // handleVirtual(); + + return headerText; + } + + /** + * Returns the receiver's row header image. + * + * @return the image stored for the header or null if none has + * to be displayed + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Image getHeaderImage() { + checkWidget(); + return headerImage; + } + + /** + * Returns the receiver's row header background color + * + * @return the color or null if none + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getHeaderBackground() { + checkWidget(); + return headerBackground; + } + + /** + * Returns the receiver's row header foreground color + * + * @return the color or null if none + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getHeaderForeground() { + checkWidget(); + return headerForeground; + } + + /** + * Returns the receiver's row header font + * + * @return the font or null if none + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Font getHeaderFont() { + checkWidget(); + return headerFont; + } + + /** + * Sets the receiver's row header text. If the text is null the + * row header will display the row number. + * + * @param text + * the new text + * @throws IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the text is null
  • + *
+ * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setHeaderText(String text) { + checkWidget(); + // if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (text != headerText) { + GC gc = new GC(parent); + + int oldWidth = headerText == null ? 0 + : parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).x; + + this.headerText = text; + + int newWidth = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).x; + + gc.dispose(); + + parent.recalculateRowHeaderWidth(this, oldWidth, newWidth); + } + parent.redraw(); + } + + /** + * Sets the receiver's row header image. If the image is null + * none is shown in the header + * + * @param image + * the new image + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setHeaderImage(Image image) { + checkWidget(); + // if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (image != headerImage) { + GC gc = new GC(parent); + + int oldWidth = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).x; + int oldHeight = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).y; + + this.headerImage = image; + + int newWidth = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).x; + int newHeight = parent.getRowHeaderRenderer().computeSize(gc, SWT.DEFAULT, SWT.DEFAULT, this).y; + + gc.dispose(); + + parent.recalculateRowHeaderWidth(this, oldWidth, newWidth); + parent.recalculateRowHeaderHeight(this, oldHeight, newHeight); + } + parent.redraw(); + } + + /** + * Set the new header background + * + * @param headerBackground + * the color or null + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setHeaderBackground(Color headerBackground) { + checkWidget(); + this.headerBackground = headerBackground; + parent.redraw(); + } + + /** + * Set the new header foreground + * + * @param headerForeground + * the color or null + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setHeaderForeground(Color headerForeground) { + checkWidget(); + this.headerForeground = headerForeground; + parent.redraw(); + } + + /** + * Set the new header font + * + * @param headerFont + * the font or null + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setHeaderFont(Font headerFont) { + checkWidget(); + this.headerFont=headerFont; + parent.redraw(); + } + + /** + * Returns the checkable state at the given column index in the receiver. If + * the column at the given index is not checkable then this will return + * false regardless of the individual cell's checkable state. + * + * @param index + * the column index + * @return the checked state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean getCheckable(int index) { + checkWidget(); + + if (!parent.getColumn(index).getCheckable()) + return false; + + return parent.getDataVisualizer().getCheckable(this, index); + } + + /** + * Sets the checkable state at the given column index in the receiver. A + * checkbox which is uncheckable will not be modifiable by the user but + * still make be modified programmatically. If the column at the given index + * is not checkable then individual cell will not be checkable regardless. + * + * @param index + * the column index + * @param checked + * the new checked state + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setCheckable(int index, boolean checked) { + checkWidget(); + parent.getDataVisualizer().setCheckable(this, index, checked); + } + + /** + * Returns the tooltip for the given cell. + * + * @param index + * the column index + * @return the tooltip + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getToolTipText(int index) { + checkWidget(); + + handleVirtual(); + + return parent.getDataVisualizer().getToolTipText(this, index); + } + + /** + * Sets the tooltip for the given column index. + * + * @param index + * the column index + * @param tooltip + * the tooltip text + * @throws org.eclipse.swt.SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed + *
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setToolTipText(int index, String tooltip) { + checkWidget(); + parent.getDataVisualizer().setToolTipText(this, index, tooltip); + } + + void columnAdded(int index) { + hasSetData = false; + } + + private void handleVirtual() { + if ((getParent().getStyle() & SWT.VIRTUAL) != 0 && !hasSetData) { + hasSetData = true; + Event event = new Event(); + event.item = this; + if (parentItem == null) { + event.index = getRowIndex(); + } else { + event.index = parentItem.indexOf(this); + } + getParent().notifyListeners(SWT.SetData, event); + } + } + + /** + * Sets the initial item height for this item. + * + * @param height + * initial height. + */ + void initializeHeight(int height) { + this.height = height; + } + + void setHasSetData(boolean hasSetData) { + this.hasSetData = hasSetData; + } + + /** + * Clears all properties of this item and resets values to their defaults. + * + * @param allChildren + * true if all child items should be cleared + * recursively, and false otherwise + */ + void clear(boolean allChildren) { + + defaultForeground = null; + defaultBackground = null; + defaultFont = null; + + hasSetData = false; + headerText = null; + headerImage = null; + headerBackground = null; + headerForeground = null; + + // Recursively clear children if requested. + if (allChildren && hasChildren) { + for (int i = children.size() - 1; i >= 0; i--) { + children.get(i).clear(true); + } + } + + } + + /** + * this method call only super.dispose, nothing else.. + */ + public void disposeOnly() { + if (hasChildren) + for (int i = children.size() - 1; i >= 0; i--) { + children.get(i).disposeOnly(); + } + if (parent.getDataVisualizer() != null) { + parent.getDataVisualizer().clearRow(this); + } + noRow(); + super.dispose(); + } + + private void noRow() { + synchronized (ROW_LOCK) { + row = NO_ROW; + } + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridSelectionType.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridSelectionType.java index 62d60bdf6..7fe7ad29d 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridSelectionType.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridSelectionType.java @@ -1,28 +1,28 @@ -/******************************************************************************* - * Copyright (c) 2019 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -/** - * Selection type for the grid object - */ -public enum GridSelectionType { - /** - * Only one row or cell can be selected - */ - SINGLE, - /** - * Allow multiple selections - */ - MULTI -} +/******************************************************************************* + * Copyright (c) 2019 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +/** + * Selection type for the grid object + */ +public enum GridSelectionType { + /** + * Only one row or cell can be selected + */ + SINGLE, + /** + * Allow multiple selections + */ + MULTI +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridUtils.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridUtils.java index 4bf503b94..69886f332 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridUtils.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridUtils.java @@ -1,179 +1,179 @@ -/******************************************************************************* - * Copyright (c) 2014 Mirko Paturzo (Exeura srl). - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Mirko Paturzo - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid; - -import java.io.OutputStream; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * Some tools for Grid. - * - * @author Mirko Paturzo - */ -public class GridUtils -{ - - private static final String INDET_PROPERTY = "{http://xml.apache.org/xslt}indent-amount"; - private static final String INDENT_VALUE = "2"; - private static final String INDENT_ACCEPTED_VALUE = "yes"; - - /** - * Tags in xml - */ - private static final String GRID_TAG = "grid"; - private static final String HEADER_TAG = "header"; - private static final String COLUMN_TAG = "column"; - private static final String CHILDREN_TAG = "children"; - private static final String ROWS_TAG = "rows"; - private static final String ROW_TAG = "row"; - private static final String ID_TAG = "id"; - - /** - * This method export a grid into a outputstream using xml. - * SWT Main thread is required for the export. - * Full supports for Grid Table. - * Grid Tree only visible items was exported. - * - * @param grid the grid who will be export to xml. - * @param outputStream used for the export. - * @throws ParserConfigurationException - * @throws TransformerException - */ - public static void gridToXml(Grid grid, OutputStream outputStream) throws ParserConfigurationException, - TransformerException - { - - DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); - String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; - try { - docFactory.setFeature(FEATURE, true); - } catch (ParserConfigurationException e) { - throw new IllegalStateException("ParserConfigurationException was thrown. The feature '" - + FEATURE + "' is not supported by your XML processor.", e); - } - DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); - - final Document doc = docBuilder.newDocument(); - - Element rootElement = doc.createElement(GRID_TAG); - doc.appendChild(rootElement); - - GridColumn[] columnsArray = grid.getColumns(); - - Element header = doc.createElement(HEADER_TAG); - rootElement.appendChild(header); - - for (int column = 0; column < columnsArray.length; column++) - { - - Element columnElement = doc.createElement(COLUMN_TAG); - columnElement.appendChild(doc.createTextNode(columnsArray[column].getText())); - header.appendChild(columnElement); - Attr columnNumber = doc.createAttribute(ID_TAG); - columnNumber.setValue(Integer.toString(column)); - columnElement.setAttributeNode(columnNumber); - - } - - GridItem[] itemsList = grid.getItems(); - - DataVisualizer dataVisualizer = grid.getDataVisualizer(); - - Element rowsElement = doc.createElement(ROWS_TAG); - rootElement.appendChild(rowsElement); - writeChildren(doc, rowsElement, columnsArray, itemsList, dataVisualizer, 0); - - // write the content into xml file - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - Transformer transformer = transformerFactory.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, INDENT_ACCEPTED_VALUE); - transformer.setOutputProperty(INDET_PROPERTY, INDENT_VALUE); - DOMSource source = new DOMSource(doc); - StreamResult result = new StreamResult(outputStream); - - // Output to console for testing - // StreamResult result = new StreamResult(System.out); - transformer.transform(source, result); - - } - - private static void writeChildren(Document doc, Element rootElement, GridColumn[] columnsList, - GridItem[] itemsArray, DataVisualizer dataVisualizer, int level) - { - for (int row = 0; row < itemsArray.length; row++) - { - GridItem gridItem = itemsArray[row]; - - if (gridItem.isVisible() && gridItem.getLevel() == level) - { - Element rowElement = writeGridItemInformation(doc, rootElement, columnsList, dataVisualizer, gridItem); - - GridItem[] items = gridItem.getItems(); - if (items.length > 0) - { - Element childrenElement = doc.createElement(CHILDREN_TAG); - rowElement.appendChild(childrenElement); - writeChildren(doc, childrenElement, columnsList, items, - gridItem.getParent().getDataVisualizer(), level + 1); - } - } - } - } - - private static Element writeGridItemInformation(Document doc, Element rootElement, GridColumn[] columnsList, - DataVisualizer dataVisualizer, GridItem item) - { - Element rowElement = doc.createElement(ROW_TAG); - rootElement.appendChild(rowElement); - // Attr rowNumber = doc.createAttribute("id"); - // rowNumber.setValue(Integer.toString(item.getRowIndex())); - // rowElement.setAttributeNode(rowNumber); - - for (int column = 0; column < columnsList.length; column++) - { - - String text = dataVisualizer.getText(item, column); - - if (text != null) - { - Element columnElement = doc.createElement(COLUMN_TAG); - columnElement.appendChild(doc.createTextNode(text)); - rowElement.appendChild(columnElement); - Attr columnNumber = doc.createAttribute(ID_TAG); - columnNumber.setValue(Integer.toString(column)); - columnElement.setAttributeNode(columnNumber); - } - - } - - return rowElement; - } -} +/******************************************************************************* + * Copyright (c) 2014 Mirko Paturzo (Exeura srl). + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Mirko Paturzo - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid; + +import java.io.OutputStream; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * Some tools for Grid. + * + * @author Mirko Paturzo + */ +public class GridUtils +{ + + private static final String INDET_PROPERTY = "{http://xml.apache.org/xslt}indent-amount"; + private static final String INDENT_VALUE = "2"; + private static final String INDENT_ACCEPTED_VALUE = "yes"; + + /** + * Tags in xml + */ + private static final String GRID_TAG = "grid"; + private static final String HEADER_TAG = "header"; + private static final String COLUMN_TAG = "column"; + private static final String CHILDREN_TAG = "children"; + private static final String ROWS_TAG = "rows"; + private static final String ROW_TAG = "row"; + private static final String ID_TAG = "id"; + + /** + * This method export a grid into a outputstream using xml. + * SWT Main thread is required for the export. + * Full supports for Grid Table. + * Grid Tree only visible items was exported. + * + * @param grid the grid who will be export to xml. + * @param outputStream used for the export. + * @throws ParserConfigurationException + * @throws TransformerException + */ + public static void gridToXml(Grid grid, OutputStream outputStream) throws ParserConfigurationException, + TransformerException + { + + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; + try { + docFactory.setFeature(FEATURE, true); + } catch (ParserConfigurationException e) { + throw new IllegalStateException("ParserConfigurationException was thrown. The feature '" + + FEATURE + "' is not supported by your XML processor.", e); + } + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + + final Document doc = docBuilder.newDocument(); + + Element rootElement = doc.createElement(GRID_TAG); + doc.appendChild(rootElement); + + GridColumn[] columnsArray = grid.getColumns(); + + Element header = doc.createElement(HEADER_TAG); + rootElement.appendChild(header); + + for (int column = 0; column < columnsArray.length; column++) + { + + Element columnElement = doc.createElement(COLUMN_TAG); + columnElement.appendChild(doc.createTextNode(columnsArray[column].getText())); + header.appendChild(columnElement); + Attr columnNumber = doc.createAttribute(ID_TAG); + columnNumber.setValue(Integer.toString(column)); + columnElement.setAttributeNode(columnNumber); + + } + + GridItem[] itemsList = grid.getItems(); + + DataVisualizer dataVisualizer = grid.getDataVisualizer(); + + Element rowsElement = doc.createElement(ROWS_TAG); + rootElement.appendChild(rowsElement); + writeChildren(doc, rowsElement, columnsArray, itemsList, dataVisualizer, 0); + + // write the content into xml file + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, INDENT_ACCEPTED_VALUE); + transformer.setOutputProperty(INDET_PROPERTY, INDENT_VALUE); + DOMSource source = new DOMSource(doc); + StreamResult result = new StreamResult(outputStream); + + // Output to console for testing + // StreamResult result = new StreamResult(System.out); + transformer.transform(source, result); + + } + + private static void writeChildren(Document doc, Element rootElement, GridColumn[] columnsList, + GridItem[] itemsArray, DataVisualizer dataVisualizer, int level) + { + for (int row = 0; row < itemsArray.length; row++) + { + GridItem gridItem = itemsArray[row]; + + if (gridItem.isVisible() && gridItem.getLevel() == level) + { + Element rowElement = writeGridItemInformation(doc, rootElement, columnsList, dataVisualizer, gridItem); + + GridItem[] items = gridItem.getItems(); + if (items.length > 0) + { + Element childrenElement = doc.createElement(CHILDREN_TAG); + rowElement.appendChild(childrenElement); + writeChildren(doc, childrenElement, columnsList, items, + gridItem.getParent().getDataVisualizer(), level + 1); + } + } + } + } + + private static Element writeGridItemInformation(Document doc, Element rootElement, GridColumn[] columnsList, + DataVisualizer dataVisualizer, GridItem item) + { + Element rowElement = doc.createElement(ROW_TAG); + rootElement.appendChild(rowElement); + // Attr rowNumber = doc.createAttribute("id"); + // rowNumber.setValue(Integer.toString(item.getRowIndex())); + // rowElement.setAttributeNode(rowNumber); + + for (int column = 0; column < columnsList.length; column++) + { + + String text = dataVisualizer.getText(item, column); + + if (text != null) + { + Element columnElement = doc.createElement(COLUMN_TAG); + columnElement.appendChild(doc.createTextNode(text)); + rowElement.appendChild(columnElement); + Attr columnNumber = doc.createAttribute(ID_TAG); + columnNumber.setValue(Integer.toString(column)); + columnElement.setAttributeNode(columnNumber); + } + + } + + return rowElement; + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridVisibleRangeSupport.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridVisibleRangeSupport.java index 3d8c3579b..37790c45b 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridVisibleRangeSupport.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/GridVisibleRangeSupport.java @@ -1,183 +1,183 @@ -package org.eclipse.nebula.widgets.grid; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.EventObject; -import java.util.Iterator; - -import org.eclipse.nebula.widgets.grid.Grid.GridVisibleRange; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Listener; - -/** - * This support class adds the possibility to get informed when the visual range - * in the grid is modified. E.g. to implement clever resource management - *

- * This support is provisional and may change - *

- */ -public class GridVisibleRangeSupport { - private Collection rangeChangeListener; - private Grid grid; - private GridVisibleRange oldRange = new GridVisibleRange(); - - private Listener paintListener = event -> calculateChange(); - - /** - * Listener notified when the visible range changes - */ - @FunctionalInterface - public interface VisibleRangeChangedListener { - /** - * Method called when range is changed - * - * @param event - * the event holding informations about the change - */ - public void rangeChanged(RangeChangedEvent event); - } - - /** - * Event informing about the change - */ - public static class RangeChangedEvent extends EventObject { - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Rows new in the visible range - */ - public GridItem[] addedRows; - - /** - * Rows removed from the range - */ - public GridItem[] removedRows; - - /** - * Columns added to the range - */ - public GridColumn[] addedColumns; - - /** - * Columns removed from the range - */ - public GridColumn[] removedColumns; - - /** - * The current visible range - */ - public GridVisibleRange visibleRange; - - RangeChangedEvent(Grid grid, GridVisibleRange visibleRange) { - super(grid); - this.visibleRange = visibleRange; - } - - } - - private GridVisibleRangeSupport(Grid grid) { - this.grid = grid; - this.grid.setSizeOnEveryItemImageChange(true); - // FIXME Maybe better to listen to resize, ... ? - grid.addListener(SWT.Paint, paintListener); - } - - /** - * Add a listener who is informed when the range is changed - * - * @param listener - * the listener to add - */ - public void addRangeChangeListener(VisibleRangeChangedListener listener) { - if (rangeChangeListener == null) { - rangeChangeListener = new ArrayList<>(); - } - rangeChangeListener.add(listener); - } - - /** - * Remove the listener from the ones informed when the range is changed - * - * @param listener - */ - public void removeRangeChangeListener(VisibleRangeChangedListener listener) { - if (rangeChangeListener != null) { - rangeChangeListener.remove(listener); - if (rangeChangeListener.size() == 0) { - rangeChangeListener = null; - } - } - } - - private void calculateChange() { - // FIXME Add back - if (rangeChangeListener == null) { - return; - } - GridVisibleRange range = grid.getVisibleRange(); - - ArrayList lOrigItems = new ArrayList<>(); - lOrigItems.addAll(Arrays.asList(oldRange.getItems())); - - ArrayList lNewItems = new ArrayList<>(); - lNewItems.addAll(Arrays.asList(range.getItems())); - - Iterator newItemsIterator = lNewItems.iterator(); - while (newItemsIterator.hasNext()) { - if (lOrigItems.remove(newItemsIterator.next())) { - newItemsIterator.remove(); - } - } - - ArrayList lOrigColumns = new ArrayList<>(); - lOrigColumns.addAll(Arrays.asList(oldRange.getColumns())); - - ArrayList lNewColumns = new ArrayList<>(); - lNewColumns.addAll(Arrays.asList(range.getColumns())); - - Iterator newColumnsIterator = lNewColumns.iterator(); - while (newColumnsIterator.hasNext()) { - if (lOrigColumns.remove(newColumnsIterator.next())) { - newColumnsIterator.remove(); - } - } - - if (lOrigItems.size() != 0 || lNewItems.size() != 0 || lOrigColumns.size() != 0 || lNewColumns.size() != 0) { - RangeChangedEvent evt = new RangeChangedEvent(grid, range); - evt.addedRows = new GridItem[lNewItems.size()]; - lNewItems.toArray(evt.addedRows); - - evt.removedRows = new GridItem[lOrigItems.size()]; - lOrigItems.toArray(evt.removedRows); - - evt.addedColumns = new GridColumn[lNewColumns.size()]; - lNewColumns.toArray(evt.addedColumns); - - evt.removedColumns = new GridColumn[lOrigColumns.size()]; - lNewColumns.toArray(evt.removedColumns); - Iterator rangeChangeIterator = rangeChangeListener.iterator(); - - while (rangeChangeIterator.hasNext()) { - rangeChangeIterator.next().rangeChanged(evt); - } - } - - oldRange = range; - } - - /** - * Create a range support for the given grid instance - * - * @param grid - * the grid instance the range support is created for - * @return the created range support - */ - public static GridVisibleRangeSupport createFor(Grid grid) { - return new GridVisibleRangeSupport(grid); - } - -} +package org.eclipse.nebula.widgets.grid; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.EventObject; +import java.util.Iterator; + +import org.eclipse.nebula.widgets.grid.Grid.GridVisibleRange; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Listener; + +/** + * This support class adds the possibility to get informed when the visual range + * in the grid is modified. E.g. to implement clever resource management + *

+ * This support is provisional and may change + *

+ */ +public class GridVisibleRangeSupport { + private Collection rangeChangeListener; + private Grid grid; + private GridVisibleRange oldRange = new GridVisibleRange(); + + private Listener paintListener = event -> calculateChange(); + + /** + * Listener notified when the visible range changes + */ + @FunctionalInterface + public interface VisibleRangeChangedListener { + /** + * Method called when range is changed + * + * @param event + * the event holding informations about the change + */ + public void rangeChanged(RangeChangedEvent event); + } + + /** + * Event informing about the change + */ + public static class RangeChangedEvent extends EventObject { + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Rows new in the visible range + */ + public GridItem[] addedRows; + + /** + * Rows removed from the range + */ + public GridItem[] removedRows; + + /** + * Columns added to the range + */ + public GridColumn[] addedColumns; + + /** + * Columns removed from the range + */ + public GridColumn[] removedColumns; + + /** + * The current visible range + */ + public GridVisibleRange visibleRange; + + RangeChangedEvent(Grid grid, GridVisibleRange visibleRange) { + super(grid); + this.visibleRange = visibleRange; + } + + } + + private GridVisibleRangeSupport(Grid grid) { + this.grid = grid; + this.grid.setSizeOnEveryItemImageChange(true); + // FIXME Maybe better to listen to resize, ... ? + grid.addListener(SWT.Paint, paintListener); + } + + /** + * Add a listener who is informed when the range is changed + * + * @param listener + * the listener to add + */ + public void addRangeChangeListener(VisibleRangeChangedListener listener) { + if (rangeChangeListener == null) { + rangeChangeListener = new ArrayList<>(); + } + rangeChangeListener.add(listener); + } + + /** + * Remove the listener from the ones informed when the range is changed + * + * @param listener + */ + public void removeRangeChangeListener(VisibleRangeChangedListener listener) { + if (rangeChangeListener != null) { + rangeChangeListener.remove(listener); + if (rangeChangeListener.size() == 0) { + rangeChangeListener = null; + } + } + } + + private void calculateChange() { + // FIXME Add back + if (rangeChangeListener == null) { + return; + } + GridVisibleRange range = grid.getVisibleRange(); + + ArrayList lOrigItems = new ArrayList<>(); + lOrigItems.addAll(Arrays.asList(oldRange.getItems())); + + ArrayList lNewItems = new ArrayList<>(); + lNewItems.addAll(Arrays.asList(range.getItems())); + + Iterator newItemsIterator = lNewItems.iterator(); + while (newItemsIterator.hasNext()) { + if (lOrigItems.remove(newItemsIterator.next())) { + newItemsIterator.remove(); + } + } + + ArrayList lOrigColumns = new ArrayList<>(); + lOrigColumns.addAll(Arrays.asList(oldRange.getColumns())); + + ArrayList lNewColumns = new ArrayList<>(); + lNewColumns.addAll(Arrays.asList(range.getColumns())); + + Iterator newColumnsIterator = lNewColumns.iterator(); + while (newColumnsIterator.hasNext()) { + if (lOrigColumns.remove(newColumnsIterator.next())) { + newColumnsIterator.remove(); + } + } + + if (lOrigItems.size() != 0 || lNewItems.size() != 0 || lOrigColumns.size() != 0 || lNewColumns.size() != 0) { + RangeChangedEvent evt = new RangeChangedEvent(grid, range); + evt.addedRows = new GridItem[lNewItems.size()]; + lNewItems.toArray(evt.addedRows); + + evt.removedRows = new GridItem[lOrigItems.size()]; + lOrigItems.toArray(evt.removedRows); + + evt.addedColumns = new GridColumn[lNewColumns.size()]; + lNewColumns.toArray(evt.addedColumns); + + evt.removedColumns = new GridColumn[lOrigColumns.size()]; + lNewColumns.toArray(evt.removedColumns); + Iterator rangeChangeIterator = rangeChangeListener.iterator(); + + while (rangeChangeIterator.hasNext()) { + rangeChangeIterator.next().rangeChanged(evt); + } + } + + oldRange = range; + } + + /** + * Create a range support for the given grid instance + * + * @param grid + * the grid instance the range support is created for + * @return the created range support + */ + public static GridVisibleRangeSupport createFor(Grid grid) { + return new GridVisibleRangeSupport(grid); + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/Win7RendererSupport.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/Win7RendererSupport.java index a71426687..682d2babb 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/Win7RendererSupport.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/Win7RendererSupport.java @@ -1,130 +1,130 @@ -package org.eclipse.nebula.widgets.grid; - -import org.eclipse.nebula.widgets.grid.internal.win7.Win7ColumnGroupHeaderRenderer; -import org.eclipse.nebula.widgets.grid.internal.win7.Win7EmptyColumnHeaderRenderer; -import org.eclipse.nebula.widgets.grid.internal.win7.Win7GridColumnHeaderRenderer; -import org.eclipse.nebula.widgets.grid.internal.win7.Win7PaletteProvider; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; - -/** - * Support class for adding Win7 column header rendering to a given grid. - */ -public class Win7RendererSupport { - - private Win7PaletteProvider palette; - private Win7GridColumnHeaderRenderer headerRenderer; - private Win7EmptyColumnHeaderRenderer emptyHeaderRenderer; - private Win7ColumnGroupHeaderRenderer groupHeaderRenderer; - private Grid grid; - - /** - * @param agrid - * - */ - private Win7RendererSupport(Grid agrid) { - this.grid = agrid; - this.palette = new Win7PaletteProvider(); - grid.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - grid.removeDisposeListener(this); - if (palette != null) { - palette.dispose(); - } - headerRenderer = null; - emptyHeaderRenderer = null; - groupHeaderRenderer = null; - } - }); - } - - /** - * @param grid - * @return {@link Win7RendererSupport} - */ - public static Win7RendererSupport create(Grid grid) { - return new Win7RendererSupport(grid); - } - - /** - * Decorate a single column header - * - * @param col - * @return {@link Win7RendererSupport} - */ - public Win7RendererSupport decorateColumnHeader(GridColumn col) { - if (headerRenderer == null) { - headerRenderer = new Win7GridColumnHeaderRenderer(palette); - } - col.setHeaderRenderer(headerRenderer); - return this; - } - - /** - * Decorate an array of column headers - * - * @param cols - * @return {@link Win7RendererSupport} - */ - public Win7RendererSupport decorateColumnHeaders(GridColumn[] cols) { - for (int i = 0; i < cols.length; i++) { - decorateColumnHeader(cols[i]); - } - return this; - } - - /** - * Decorate a single grid column group header - * - * @param group - * @return {@link Win7RendererSupport} - */ - public Win7RendererSupport decorateColumnGroupHeader(GridColumnGroup group) { - if (groupHeaderRenderer == null) { - groupHeaderRenderer = new Win7ColumnGroupHeaderRenderer(palette); - } - group.setHeaderRenderer(groupHeaderRenderer); - decorateColumnHeaders(group.getColumns()); - return this; - } - - /** - * Decorate an array of grid column group headers - * - * @param groups - * @return {@link Win7RendererSupport} - */ - public Win7RendererSupport decorateColumnGroupHeaders(GridColumnGroup[] groups) { - for (int i = 0; i < groups.length; i++) { - decorateColumnGroupHeader(groups[i]); - } - return this; - } - - /** - * Decorate the empty column header - * - * @return {@link Win7RendererSupport} - */ - public Win7RendererSupport decorateEmptyColumnHeader() { - if (emptyHeaderRenderer == null) { - emptyHeaderRenderer = new Win7EmptyColumnHeaderRenderer(palette); - } - grid.setEmptyColumnHeaderRenderer(emptyHeaderRenderer); - return this; - } - - /** - * Decorate all column headers, all column header groups and the empty column - * header. - * - * @return {@link Win7RendererSupport} - */ - public Win7RendererSupport decorate() { - decorateEmptyColumnHeader(); - decorateColumnGroupHeaders(grid.getColumnGroups()); - decorateColumnHeaders(grid.getColumns()); - return this; - } - +package org.eclipse.nebula.widgets.grid; + +import org.eclipse.nebula.widgets.grid.internal.win7.Win7ColumnGroupHeaderRenderer; +import org.eclipse.nebula.widgets.grid.internal.win7.Win7EmptyColumnHeaderRenderer; +import org.eclipse.nebula.widgets.grid.internal.win7.Win7GridColumnHeaderRenderer; +import org.eclipse.nebula.widgets.grid.internal.win7.Win7PaletteProvider; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; + +/** + * Support class for adding Win7 column header rendering to a given grid. + */ +public class Win7RendererSupport { + + private Win7PaletteProvider palette; + private Win7GridColumnHeaderRenderer headerRenderer; + private Win7EmptyColumnHeaderRenderer emptyHeaderRenderer; + private Win7ColumnGroupHeaderRenderer groupHeaderRenderer; + private Grid grid; + + /** + * @param agrid + * + */ + private Win7RendererSupport(Grid agrid) { + this.grid = agrid; + this.palette = new Win7PaletteProvider(); + grid.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + grid.removeDisposeListener(this); + if (palette != null) { + palette.dispose(); + } + headerRenderer = null; + emptyHeaderRenderer = null; + groupHeaderRenderer = null; + } + }); + } + + /** + * @param grid + * @return {@link Win7RendererSupport} + */ + public static Win7RendererSupport create(Grid grid) { + return new Win7RendererSupport(grid); + } + + /** + * Decorate a single column header + * + * @param col + * @return {@link Win7RendererSupport} + */ + public Win7RendererSupport decorateColumnHeader(GridColumn col) { + if (headerRenderer == null) { + headerRenderer = new Win7GridColumnHeaderRenderer(palette); + } + col.setHeaderRenderer(headerRenderer); + return this; + } + + /** + * Decorate an array of column headers + * + * @param cols + * @return {@link Win7RendererSupport} + */ + public Win7RendererSupport decorateColumnHeaders(GridColumn[] cols) { + for (int i = 0; i < cols.length; i++) { + decorateColumnHeader(cols[i]); + } + return this; + } + + /** + * Decorate a single grid column group header + * + * @param group + * @return {@link Win7RendererSupport} + */ + public Win7RendererSupport decorateColumnGroupHeader(GridColumnGroup group) { + if (groupHeaderRenderer == null) { + groupHeaderRenderer = new Win7ColumnGroupHeaderRenderer(palette); + } + group.setHeaderRenderer(groupHeaderRenderer); + decorateColumnHeaders(group.getColumns()); + return this; + } + + /** + * Decorate an array of grid column group headers + * + * @param groups + * @return {@link Win7RendererSupport} + */ + public Win7RendererSupport decorateColumnGroupHeaders(GridColumnGroup[] groups) { + for (int i = 0; i < groups.length; i++) { + decorateColumnGroupHeader(groups[i]); + } + return this; + } + + /** + * Decorate the empty column header + * + * @return {@link Win7RendererSupport} + */ + public Win7RendererSupport decorateEmptyColumnHeader() { + if (emptyHeaderRenderer == null) { + emptyHeaderRenderer = new Win7EmptyColumnHeaderRenderer(palette); + } + grid.setEmptyColumnHeaderRenderer(emptyHeaderRenderer); + return this; + } + + /** + * Decorate all column headers, all column header groups and the empty column + * header. + * + * @return {@link Win7RendererSupport} + */ + public Win7RendererSupport decorate() { + decorateEmptyColumnHeader(); + decorateColumnGroupHeaders(grid.getColumnGroups()); + decorateColumnHeaders(grid.getColumns()); + return this; + } + } \ No newline at end of file diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnFooterRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnFooterRenderer.java index 76ae6203d..60594f4fd 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnFooterRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnFooterRenderer.java @@ -1,197 +1,197 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - * Marty Jones - custom header/footer font in bug 293743 - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid.internal; - -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.GridFooterRenderer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; - -/** - * The column footer renderer. - * - * @author Tom Schindl - tom.schindl@bestsolution.at - * @since 2.0.0 - */ -public class DefaultColumnFooterRenderer extends GridFooterRenderer -{ - - int leftMargin = 6; - - int rightMargin = 6; - - int topMargin = 3; - - int bottomMargin = 3; - - int arrowMargin = 6; - - int imageSpacing = 3; - - /** - * {@inheritDoc} - */ - public Point computeSize(GC gc, int wHint, int hHint, Object value) - { - GridColumn column = (GridColumn)value; - - gc.setFont(column.getFooterFont()); - - int x = 0; - - x += leftMargin; - - x += gc.stringExtent(column.getText()).x + rightMargin; - - int y = 0; - - y += topMargin; - - y += gc.getFontMetrics().getHeight(); - - y += bottomMargin; - - if (column.getFooterImage() != null) - { - x += column.getFooterImage().getBounds().width + imageSpacing; - - y = Math.max(y, topMargin + column.getFooterImage().getBounds().height + bottomMargin); - } - - return new Point(x, y); - } - - /** - * {@inheritDoc} - */ - public void paint(GC gc, Object value) - { - GridColumn column = (GridColumn)value; - - // set the font to be used to display the text. - gc.setFont(column.getFooterFont()); - - gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - - gc.fillRectangle(getBounds().x, getBounds().y, getBounds().width, - getBounds().height); - - gc.drawLine(getBounds().x, getBounds().y, getBounds().x - + getBounds().width, getBounds().y); - - int x = leftMargin; - - if (column.getFooterImage() != null) - { - gc.drawImage(column.getFooterImage(), getBounds().x + x, - getBounds().y + getBounds().height - bottomMargin - column.getFooterImage().getBounds().height); - x += column.getFooterImage().getBounds().width + imageSpacing; - } - - int width = getBounds().width - x; - - if (column.getSort() == SWT.NONE) - { - width -= rightMargin; - } - - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - - int y = getBounds().y + getBounds().height - bottomMargin - gc.getFontMetrics().getHeight(); - - String text = TextUtils.getShortStr(gc, column.getFooterText(), width, truncationStyle); - - if (column.getAlignment() == SWT.RIGHT) - { - int len = gc.stringExtent(text).x; - if (len < width) - { - x += width - len; - } - } - else if (column.getAlignment() == SWT.CENTER) - { - int len = gc.stringExtent(text).x; - if (len < width) - { - x += (width - len) / 2; - } - } - - - gc.drawString(text, getBounds().x + x, - y,true); - - } - - /** - * {@inheritDoc} - */ - public boolean notify(int event, Point point, Object value) - { - return false; - } - - /** - * {@inheritDoc} - */ - public Rectangle getTextBounds(Object value, boolean preferred) - { - GridColumn column = (GridColumn)value; - - int x = leftMargin; - - if (column.getImage() != null) - { - x += column.getImage().getBounds().width + imageSpacing; - } - - - - GC gc = new GC(column.getParent()); - gc.setFont(column.getFooterFont()); - int y = getBounds().height - bottomMargin - gc.getFontMetrics().getHeight(); - - Rectangle bounds = new Rectangle(x,y,0,0); - - Point p = gc.stringExtent(column.getText()); - - bounds.height = p.y; - - if (preferred) - { - bounds.width = p.x; - } - else - { - int width = getBounds().width - x; - if (column.getSort() == SWT.NONE) - { - width -= rightMargin; - } - - bounds.width = width; - } - - - gc.dispose(); - - return bounds; - } -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + * Marty Jones - custom header/footer font in bug 293743 + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid.internal; + +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.nebula.widgets.grid.GridFooterRenderer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; + +/** + * The column footer renderer. + * + * @author Tom Schindl - tom.schindl@bestsolution.at + * @since 2.0.0 + */ +public class DefaultColumnFooterRenderer extends GridFooterRenderer +{ + + int leftMargin = 6; + + int rightMargin = 6; + + int topMargin = 3; + + int bottomMargin = 3; + + int arrowMargin = 6; + + int imageSpacing = 3; + + /** + * {@inheritDoc} + */ + public Point computeSize(GC gc, int wHint, int hHint, Object value) + { + GridColumn column = (GridColumn)value; + + gc.setFont(column.getFooterFont()); + + int x = 0; + + x += leftMargin; + + x += gc.stringExtent(column.getText()).x + rightMargin; + + int y = 0; + + y += topMargin; + + y += gc.getFontMetrics().getHeight(); + + y += bottomMargin; + + if (column.getFooterImage() != null) + { + x += column.getFooterImage().getBounds().width + imageSpacing; + + y = Math.max(y, topMargin + column.getFooterImage().getBounds().height + bottomMargin); + } + + return new Point(x, y); + } + + /** + * {@inheritDoc} + */ + public void paint(GC gc, Object value) + { + GridColumn column = (GridColumn)value; + + // set the font to be used to display the text. + gc.setFont(column.getFooterFont()); + + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + + gc.fillRectangle(getBounds().x, getBounds().y, getBounds().width, + getBounds().height); + + gc.drawLine(getBounds().x, getBounds().y, getBounds().x + + getBounds().width, getBounds().y); + + int x = leftMargin; + + if (column.getFooterImage() != null) + { + gc.drawImage(column.getFooterImage(), getBounds().x + x, + getBounds().y + getBounds().height - bottomMargin - column.getFooterImage().getBounds().height); + x += column.getFooterImage().getBounds().width + imageSpacing; + } + + int width = getBounds().width - x; + + if (column.getSort() == SWT.NONE) + { + width -= rightMargin; + } + + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + + int y = getBounds().y + getBounds().height - bottomMargin - gc.getFontMetrics().getHeight(); + + String text = TextUtils.getShortStr(gc, column.getFooterText(), width, truncationStyle); + + if (column.getAlignment() == SWT.RIGHT) + { + int len = gc.stringExtent(text).x; + if (len < width) + { + x += width - len; + } + } + else if (column.getAlignment() == SWT.CENTER) + { + int len = gc.stringExtent(text).x; + if (len < width) + { + x += (width - len) / 2; + } + } + + + gc.drawString(text, getBounds().x + x, + y,true); + + } + + /** + * {@inheritDoc} + */ + public boolean notify(int event, Point point, Object value) + { + return false; + } + + /** + * {@inheritDoc} + */ + public Rectangle getTextBounds(Object value, boolean preferred) + { + GridColumn column = (GridColumn)value; + + int x = leftMargin; + + if (column.getImage() != null) + { + x += column.getImage().getBounds().width + imageSpacing; + } + + + + GC gc = new GC(column.getParent()); + gc.setFont(column.getFooterFont()); + int y = getBounds().height - bottomMargin - gc.getFontMetrics().getHeight(); + + Rectangle bounds = new Rectangle(x,y,0,0); + + Point p = gc.stringExtent(column.getText()); + + bounds.height = p.y; + + if (preferred) + { + bounds.width = p.x; + } + else + { + int width = getBounds().width - x; + if (column.getSort() == SWT.NONE) + { + width -= rightMargin; + } + + bounds.width = width; + } + + + gc.dispose(); + + return bounds; + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnGroupHeaderRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnGroupHeaderRenderer.java index e8d656312..41143c1b5 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnGroupHeaderRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnGroupHeaderRenderer.java @@ -1,319 +1,319 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - * Chuck.Mastrandrea@sas.com - wordwrapping in bug 222280 - * smcduff@hotmail.com - wordwrapping in bug 222280 - * Marty Jones - custom header/footer font in bug 293743 - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid.internal; - -import org.eclipse.nebula.widgets.grid.GridColumnGroup; -import org.eclipse.nebula.widgets.grid.GridHeaderRenderer; -import org.eclipse.nebula.widgets.grid.IInternalWidget; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.graphics.TextLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; - -/** - * The column group header renderer in Grid. - * - * @author chris.gross@us.ibm.com - * @since 2.0.0 - */ -public class DefaultColumnGroupHeaderRenderer extends GridHeaderRenderer -{ - int leftMargin = 6; - - int rightMargin = 6; - - int topMargin = 3; - - int bottomMargin = 3; - - int imageSpacing = 3; - - private ExpandToggleRenderer toggleRenderer = new ExpandToggleRenderer(); - - private TextLayout textLayout; - - /** - * {@inheritDoc} - */ - public void paint(GC gc, Object value) - { - GridColumnGroup group = (GridColumnGroup)value; - - // set the font to be used to display the text. - gc.setFont(group.getHeaderFont()); - - if (isSelected()) - { - gc.setBackground(group.getParent().getCellHeaderSelectionBackground()); - } - else - { - gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - } - - gc.fillRectangle(getBounds().x, getBounds().y, getBounds().width + 1, - getBounds().height + 1); - - int x = leftMargin; - - if (group.getImage() != null) - { - gc.drawImage(group.getImage(), getBounds().x + x, getBounds().y + topMargin); - x += group.getImage().getBounds().width + imageSpacing; - } - - int width = getBounds().width - x - rightMargin; - if ((group.getStyle() & SWT.TOGGLE) != 0) - { - width -= toggleRenderer.getSize().x; - } - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - - String text = group.getText(); - if (!isWordWrap()) - { - text = TextUtils.getShortStr(gc, text, width,truncationStyle); - } - - if (getHorizontalAlignment() == SWT.RIGHT) - { - int len = gc.stringExtent(text).x; - if (len < width) - { - x += width - len; - } - } - else if (getHorizontalAlignment() == SWT.CENTER) - { - int len = gc.stringExtent(text).x; - if (len < width) - { - x += (width - len) / 2; - } - } - - if (!isWordWrap()) - { - gc.drawString(text, getBounds().x + x,getBounds().y + topMargin); - } - else - { - getTextLayout(gc, group); - textLayout.setWidth(width < 1 ? 1 : width); - textLayout.setText(text); - - if (group.getParent().isAutoHeight()) - { - group.getParent().recalculateHeader(); - } - - textLayout.draw(gc, getBounds().x + x, getBounds().y + topMargin); - } - - if ((group.getStyle() & SWT.TOGGLE) != 0) - { - toggleRenderer.setHover(isHover() && getHoverDetail().equals("toggle")); - toggleRenderer.setExpanded(group.getExpanded()); - toggleRenderer.setBounds(getToggleBounds()); - toggleRenderer.paint(gc, null); - } - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); - - gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - gc.drawLine(getBounds().x, getBounds().y + getBounds().height - 1, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - - } - - /** - * {@inheritDoc} - */ - public Point computeSize(GC gc, int wHint, int hHint, Object value) - { - GridColumnGroup group = (GridColumnGroup)value; - - gc.setFont(group.getHeaderFont()); - - int x = leftMargin; - int y = topMargin + gc.getFontMetrics().getHeight() + bottomMargin; - - - if (group.getImage() != null) - { - x += group.getImage().getBounds().width + imageSpacing; - - y = Math.max(y, topMargin + group.getImage().getBounds().height + bottomMargin); - } - - if (!isWordWrap()) - { - x += gc.stringExtent(group.getText()).x + rightMargin; - } - else - { - int toggleWidth = 0; - if ((group.getStyle() & SWT.TOGGLE) != 0) - toggleWidth = toggleRenderer.getSize().x; - - int plainTextWidth; - if (wHint == SWT.DEFAULT) - plainTextWidth = getBounds().width - x - rightMargin - toggleWidth; - else - plainTextWidth = wHint - x - rightMargin - toggleWidth; - - getTextLayout(gc, group); - textLayout.setText(group.getText()); - textLayout.setWidth(plainTextWidth < 1 ? 1 : plainTextWidth); - - x += plainTextWidth + rightMargin; - - int textHeight = topMargin; - textHeight += textLayout.getBounds().height; - textHeight += bottomMargin; - - y = Math.max(y, textHeight); - } - return new Point(x, y); - } - - /** - * {@inheritDoc} - */ - public boolean notify(int event, Point point, Object value) - { - GridColumnGroup group = (GridColumnGroup)value; - - if ((group.getStyle() & SWT.TOGGLE) != 0) - { - if (event == IInternalWidget.LeftMouseButtonDown) - { - if (getToggleBounds().contains(point)) - { - group.setExpanded(!group.getExpanded()); - - if (group.getExpanded()) - { - group.notifyListeners(SWT.Expand,new Event()); - } - else - { - group.notifyListeners(SWT.Collapse,new Event()); - } - return true; - } - } - else - { - if (getToggleBounds().contains(point)) - { - setHoverDetail("toggle"); - return true; - } - } - } - - return false; - } - - /** - * {@inheritDoc} - */ - public Rectangle getToggleBounds() - { - int x = getBounds().x + getBounds().width - toggleRenderer.getBounds().width - rightMargin; - int y = getBounds().y + (getBounds().height - toggleRenderer.getBounds().height) / 2; - - return new Rectangle(x, y, toggleRenderer.getBounds().width, - toggleRenderer.getBounds().height); - } - - /** - * {@inheritDoc} - */ - public void setDisplay(Display display) - { - super.setDisplay(display); - toggleRenderer.setDisplay(display); - } - - /** - * {@inheritDoc} - */ - public Rectangle getTextBounds(Object value, boolean preferred) - { - GridColumnGroup group = (GridColumnGroup)value; - - int x = leftMargin; - - if (group.getImage() != null) - { - x += group.getImage().getBounds().width + imageSpacing; - } - - Rectangle bounds = new Rectangle(x, topMargin, 0, 0); - - GC gc = new GC(group.getParent()); - gc.setFont(group.getHeaderFont()); - - Point p = gc.stringExtent(group.getText()); - - bounds.height = p.y; - - if (preferred) - { - bounds.width = p.x; - } - else - { - int width = getBounds().width - x - rightMargin; - if ((group.getStyle() & SWT.TOGGLE) != 0) - { - width -= toggleRenderer.getSize().x; - } - bounds.width = width; - } - - gc.dispose(); - return bounds; - } - - private void getTextLayout(GC gc, GridColumnGroup group) - { - if (textLayout == null) - { - textLayout = new TextLayout(gc.getDevice()); - textLayout.setFont(gc.getFont()); - group.getParent().addDisposeListener(new DisposeListener() - { - public void widgetDisposed(DisposeEvent e) - { - textLayout.dispose(); - } - }); - } - } -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + * Chuck.Mastrandrea@sas.com - wordwrapping in bug 222280 + * smcduff@hotmail.com - wordwrapping in bug 222280 + * Marty Jones - custom header/footer font in bug 293743 + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid.internal; + +import org.eclipse.nebula.widgets.grid.GridColumnGroup; +import org.eclipse.nebula.widgets.grid.GridHeaderRenderer; +import org.eclipse.nebula.widgets.grid.IInternalWidget; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; + +/** + * The column group header renderer in Grid. + * + * @author chris.gross@us.ibm.com + * @since 2.0.0 + */ +public class DefaultColumnGroupHeaderRenderer extends GridHeaderRenderer +{ + int leftMargin = 6; + + int rightMargin = 6; + + int topMargin = 3; + + int bottomMargin = 3; + + int imageSpacing = 3; + + private ExpandToggleRenderer toggleRenderer = new ExpandToggleRenderer(); + + private TextLayout textLayout; + + /** + * {@inheritDoc} + */ + public void paint(GC gc, Object value) + { + GridColumnGroup group = (GridColumnGroup)value; + + // set the font to be used to display the text. + gc.setFont(group.getHeaderFont()); + + if (isSelected()) + { + gc.setBackground(group.getParent().getCellHeaderSelectionBackground()); + } + else + { + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + } + + gc.fillRectangle(getBounds().x, getBounds().y, getBounds().width + 1, + getBounds().height + 1); + + int x = leftMargin; + + if (group.getImage() != null) + { + gc.drawImage(group.getImage(), getBounds().x + x, getBounds().y + topMargin); + x += group.getImage().getBounds().width + imageSpacing; + } + + int width = getBounds().width - x - rightMargin; + if ((group.getStyle() & SWT.TOGGLE) != 0) + { + width -= toggleRenderer.getSize().x; + } + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + + String text = group.getText(); + if (!isWordWrap()) + { + text = TextUtils.getShortStr(gc, text, width,truncationStyle); + } + + if (getHorizontalAlignment() == SWT.RIGHT) + { + int len = gc.stringExtent(text).x; + if (len < width) + { + x += width - len; + } + } + else if (getHorizontalAlignment() == SWT.CENTER) + { + int len = gc.stringExtent(text).x; + if (len < width) + { + x += (width - len) / 2; + } + } + + if (!isWordWrap()) + { + gc.drawString(text, getBounds().x + x,getBounds().y + topMargin); + } + else + { + getTextLayout(gc, group); + textLayout.setWidth(width < 1 ? 1 : width); + textLayout.setText(text); + + if (group.getParent().isAutoHeight()) + { + group.getParent().recalculateHeader(); + } + + textLayout.draw(gc, getBounds().x + x, getBounds().y + topMargin); + } + + if ((group.getStyle() & SWT.TOGGLE) != 0) + { + toggleRenderer.setHover(isHover() && getHoverDetail().equals("toggle")); + toggleRenderer.setExpanded(group.getExpanded()); + toggleRenderer.setBounds(getToggleBounds()); + toggleRenderer.paint(gc, null); + } + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); + + gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x + + getBounds().width - 1, + getBounds().y + getBounds().height - 1); + gc.drawLine(getBounds().x, getBounds().y + getBounds().height - 1, getBounds().x + + getBounds().width - 1, + getBounds().y + getBounds().height - 1); + + } + + /** + * {@inheritDoc} + */ + public Point computeSize(GC gc, int wHint, int hHint, Object value) + { + GridColumnGroup group = (GridColumnGroup)value; + + gc.setFont(group.getHeaderFont()); + + int x = leftMargin; + int y = topMargin + gc.getFontMetrics().getHeight() + bottomMargin; + + + if (group.getImage() != null) + { + x += group.getImage().getBounds().width + imageSpacing; + + y = Math.max(y, topMargin + group.getImage().getBounds().height + bottomMargin); + } + + if (!isWordWrap()) + { + x += gc.stringExtent(group.getText()).x + rightMargin; + } + else + { + int toggleWidth = 0; + if ((group.getStyle() & SWT.TOGGLE) != 0) + toggleWidth = toggleRenderer.getSize().x; + + int plainTextWidth; + if (wHint == SWT.DEFAULT) + plainTextWidth = getBounds().width - x - rightMargin - toggleWidth; + else + plainTextWidth = wHint - x - rightMargin - toggleWidth; + + getTextLayout(gc, group); + textLayout.setText(group.getText()); + textLayout.setWidth(plainTextWidth < 1 ? 1 : plainTextWidth); + + x += plainTextWidth + rightMargin; + + int textHeight = topMargin; + textHeight += textLayout.getBounds().height; + textHeight += bottomMargin; + + y = Math.max(y, textHeight); + } + return new Point(x, y); + } + + /** + * {@inheritDoc} + */ + public boolean notify(int event, Point point, Object value) + { + GridColumnGroup group = (GridColumnGroup)value; + + if ((group.getStyle() & SWT.TOGGLE) != 0) + { + if (event == IInternalWidget.LeftMouseButtonDown) + { + if (getToggleBounds().contains(point)) + { + group.setExpanded(!group.getExpanded()); + + if (group.getExpanded()) + { + group.notifyListeners(SWT.Expand,new Event()); + } + else + { + group.notifyListeners(SWT.Collapse,new Event()); + } + return true; + } + } + else + { + if (getToggleBounds().contains(point)) + { + setHoverDetail("toggle"); + return true; + } + } + } + + return false; + } + + /** + * {@inheritDoc} + */ + public Rectangle getToggleBounds() + { + int x = getBounds().x + getBounds().width - toggleRenderer.getBounds().width - rightMargin; + int y = getBounds().y + (getBounds().height - toggleRenderer.getBounds().height) / 2; + + return new Rectangle(x, y, toggleRenderer.getBounds().width, + toggleRenderer.getBounds().height); + } + + /** + * {@inheritDoc} + */ + public void setDisplay(Display display) + { + super.setDisplay(display); + toggleRenderer.setDisplay(display); + } + + /** + * {@inheritDoc} + */ + public Rectangle getTextBounds(Object value, boolean preferred) + { + GridColumnGroup group = (GridColumnGroup)value; + + int x = leftMargin; + + if (group.getImage() != null) + { + x += group.getImage().getBounds().width + imageSpacing; + } + + Rectangle bounds = new Rectangle(x, topMargin, 0, 0); + + GC gc = new GC(group.getParent()); + gc.setFont(group.getHeaderFont()); + + Point p = gc.stringExtent(group.getText()); + + bounds.height = p.y; + + if (preferred) + { + bounds.width = p.x; + } + else + { + int width = getBounds().width - x - rightMargin; + if ((group.getStyle() & SWT.TOGGLE) != 0) + { + width -= toggleRenderer.getSize().x; + } + bounds.width = width; + } + + gc.dispose(); + return bounds; + } + + private void getTextLayout(GC gc, GridColumnGroup group) + { + if (textLayout == null) + { + textLayout = new TextLayout(gc.getDevice()); + textLayout.setFont(gc.getFont()); + group.getParent().addDisposeListener(new DisposeListener() + { + public void widgetDisposed(DisposeEvent e) + { + textLayout.dispose(); + } + }); + } + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnHeaderRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnHeaderRenderer.java index de7f11781..2c53fb7ce 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnHeaderRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultColumnHeaderRenderer.java @@ -1,426 +1,426 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - * Chuck.Mastrandrea@sas.com - wordwrapping in bug 222280 - * smcduff@hotmail.com - wordwrapping in bug 222280 - * Marty Jones - custom header/footer font in bug 293743 - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid.internal; - -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.GridHeaderRenderer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.graphics.TextLayout; -import org.eclipse.swt.widgets.Display; - -/** - * The column header renderer. - * - * @author chris.gross@us.ibm.com - * @since 2.0.0 - */ -public class DefaultColumnHeaderRenderer extends GridHeaderRenderer -{ - - int leftMargin = 6; - - int rightMargin = 6; - - int topMargin = 3; - - int bottomMargin = 3; - - int arrowMargin = 6; - - int imageSpacing = 3; - - private SortArrowRenderer arrowRenderer = new SortArrowRenderer(); - - private TextLayout textLayout; - - /** - * {@inheritDoc} - */ - public Point computeSize(GC gc, int wHint, int hHint, Object value) - { - GridColumn column = (GridColumn)value; - - gc.setFont(column.getHeaderFont()); - - int x = leftMargin; - int y = topMargin + gc.getFontMetrics().getHeight() + bottomMargin; - - - if (column.getImage() != null) - { - x += column.getImage().getBounds().width + imageSpacing; - - y = Math.max(y, topMargin + column.getImage().getBounds().height + bottomMargin); - } - if (!isWordWrap()) - { - x += gc.stringExtent(column.getText()).x + rightMargin; - } - else - { - int plainTextWidth; - if (wHint == SWT.DEFAULT) - plainTextWidth = getBounds().width - x - rightMargin; - else - plainTextWidth = wHint - x - rightMargin; - - getTextLayout(gc, column); - textLayout.setText(column.getText()); - textLayout.setWidth(plainTextWidth < 1 ? 1 : plainTextWidth); - - x += plainTextWidth + rightMargin; - - int textHeight = topMargin; - textHeight += textLayout.getBounds().height; - textHeight += bottomMargin; - - y = Math.max(y, textHeight); - } - - - y += computeControlSize(column).y; - - return new Point(x, y); - } - - /** - * {@inheritDoc} - */ - public void paint(GC gc, Object value) - { - GridColumn column = (GridColumn)value; - - // set the font to be used to display the text. - gc.setFont(column.getHeaderFont()); - - boolean flat = (column.getParent().getCellSelectionEnabled() && !column.getMoveable()); - - boolean drawSelected = ((isMouseDown() && isHover())); - - gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - - if (flat && isSelected()) - { - gc.setBackground(column.getParent().getCellHeaderSelectionBackground()); - } - - gc.fillRectangle(getBounds().x, getBounds().y, getBounds().width, - getBounds().height); - - int pushedDrawingOffset = 0; - if (drawSelected) - { - pushedDrawingOffset = 1; - } - - int x = leftMargin; - - if (column.getImage() != null) - { - int y = bottomMargin; - - if( column.getHeaderControl() == null ) { - y = getBounds().y + pushedDrawingOffset + getBounds().height - bottomMargin - column.getImage().getBounds().height; - } - - gc.drawImage(column.getImage(), getBounds().x + x + pushedDrawingOffset, y); - x += column.getImage().getBounds().width + imageSpacing; - } - - int width = getBounds().width - x; - - if (column.getSort() == SWT.NONE) - { - width -= rightMargin; - } - else - { - width -= arrowMargin + arrowRenderer.getSize().x + arrowMargin; - } - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - - int y = bottomMargin; - - if( column.getHeaderControl() == null ) { - y = getBounds().y + getBounds().height - bottomMargin - - gc.getFontMetrics().getHeight(); - } else { - y = getBounds().y + getBounds().height - bottomMargin - gc.getFontMetrics().getHeight() - computeControlSize(column).y; - } - - String text = column.getText(); - - if (!isWordWrap()) - { - text = TextUtils.getShortStr(gc, text, width,truncationStyle); - } - - if (column.getAlignment() == SWT.RIGHT) - { - int len = gc.stringExtent(text).x; - if (len < width) - { - x += width - len; - } - } - else if (column.getAlignment() == SWT.CENTER) - { - int len = gc.stringExtent(text).x; - if (len < width) - { - x += (width - len) / 2; - } - } - - - if (!isWordWrap()) { - gc.drawString(text, getBounds().x + x + pushedDrawingOffset, - y + pushedDrawingOffset,true); - } - else - { - getTextLayout(gc, column); - textLayout.setWidth(width < 1 ? 1 : width); - textLayout.setText(text); - y -= textLayout.getBounds().height; - - // remove the first line shift - y+=gc.getFontMetrics().getHeight(); - - if (column.getParent().isAutoHeight()) - { - column.getParent().recalculateHeader(); - } - - textLayout.draw(gc, getBounds().x + x + pushedDrawingOffset, y + pushedDrawingOffset); - } - - if (column.getSort() != SWT.NONE) - { - if( column.getHeaderControl() == null ) { - y = getBounds().y - + ((getBounds().height - arrowRenderer.getBounds().height) / 2) - + 1; - } else { - y = getBounds().y - + ((getBounds().height - computeControlSize(column).y - arrowRenderer.getBounds().height) / 2) - + 1; - } - - arrowRenderer.setSelected(column.getSort() == SWT.DOWN); - if (drawSelected) - { - arrowRenderer - .setLocation( - getBounds().x + getBounds().width - arrowMargin - - arrowRenderer.getBounds().width + 1,y - ); - } - else - { - if( column.getHeaderControl() == null ) { - y = getBounds().y - + ((getBounds().height - arrowRenderer.getBounds().height) / 2); - } else { - y = getBounds().y - + ((getBounds().height - computeControlSize(column).y - arrowRenderer.getBounds().height) / 2); - } - arrowRenderer - .setLocation( - getBounds().x + getBounds().width - arrowMargin - - arrowRenderer.getBounds().width,y); - } - arrowRenderer.paint(gc, null); - } - - if (!flat) - { - - if (drawSelected) - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - } - else - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); - } - - gc.drawLine(getBounds().x, getBounds().y, getBounds().x + getBounds().width - 1, - getBounds().y); - gc.drawLine(getBounds().x, getBounds().y, getBounds().x, getBounds().y + getBounds().height - - 1); - - if (!drawSelected) - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); - gc.drawLine(getBounds().x + 1, getBounds().y + 1, - getBounds().x + getBounds().width - 2, getBounds().y + 1); - gc.drawLine(getBounds().x + 1, getBounds().y + 1, getBounds().x + 1, - getBounds().y + getBounds().height - 2); - } - - if (drawSelected) - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - } - else - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); - } - gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - gc.drawLine(getBounds().x, getBounds().y + getBounds().height - 1, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - - if (!drawSelected) - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - gc.drawLine(getBounds().x + getBounds().width - 2, getBounds().y + 1, - getBounds().x + getBounds().width - 2, getBounds().y + getBounds().height - - 2); - gc.drawLine(getBounds().x + 1, getBounds().y + getBounds().height - 2, - getBounds().x + getBounds().width - 2, getBounds().y + getBounds().height - - 2); - } - - } - else - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); - - gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - gc.drawLine(getBounds().x, getBounds().y + getBounds().height - 1, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - } - - - } - - /** - * {@inheritDoc} - */ - public void setDisplay(Display display) - { - super.setDisplay(display); - arrowRenderer.setDisplay(display); - } - - /** - * {@inheritDoc} - */ - public boolean notify(int event, Point point, Object value) - { - return false; - } - - /** - * {@inheritDoc} - */ - public Rectangle getTextBounds(Object value, boolean preferred) - { - GridColumn column = (GridColumn)value; - - int x = leftMargin; - - if (column.getImage() != null) - { - x += column.getImage().getBounds().width + imageSpacing; - } - - - - GC gc = new GC(column.getParent()); - gc.setFont(column.getParent().getFont()); - int y = getBounds().height - bottomMargin - gc.getFontMetrics().getHeight(); - - Rectangle bounds = new Rectangle(x,y,0,0); - - Point p = gc.stringExtent(column.getText()); - - bounds.height = p.y; - - if (preferred) - { - bounds.width = p.x; - } - else - { - int width = getBounds().width - x; - if (column.getSort() == SWT.NONE) - { - width -= rightMargin; - } - else - { - width -= arrowMargin + arrowRenderer.getSize().x + arrowMargin; - } - bounds.width = width; - } - - - gc.dispose(); - - return bounds; - } - - /** - * @see org.eclipse.nebula.widgets.grid.GridHeaderRenderer#getControlBounds(java.lang.Object, boolean) - */ - protected Rectangle getControlBounds(Object value, boolean preferred) { - Rectangle bounds = getBounds(); - GridColumn column = (GridColumn) value; - Point controlSize = computeControlSize(column); - - int y = getBounds().y + getBounds().height - bottomMargin - controlSize.y; - - return new Rectangle(bounds.x+3,y,bounds.width-6,controlSize.y); - } - - private Point computeControlSize(GridColumn column) { - if( column.getHeaderControl() != null ) { - return column.getHeaderControl().computeSize(SWT.DEFAULT, SWT.DEFAULT); - } - return new Point(0,0); - } - - private void getTextLayout(GC gc, GridColumn column) - { - if (textLayout == null) - { - textLayout = new TextLayout(gc.getDevice()); - textLayout.setFont(gc.getFont()); - column.getParent().addDisposeListener(new DisposeListener() - { - public void widgetDisposed(DisposeEvent e) - { - textLayout.dispose(); - } - }); - } - } -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + * Chuck.Mastrandrea@sas.com - wordwrapping in bug 222280 + * smcduff@hotmail.com - wordwrapping in bug 222280 + * Marty Jones - custom header/footer font in bug 293743 + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid.internal; + +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.nebula.widgets.grid.GridHeaderRenderer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.widgets.Display; + +/** + * The column header renderer. + * + * @author chris.gross@us.ibm.com + * @since 2.0.0 + */ +public class DefaultColumnHeaderRenderer extends GridHeaderRenderer +{ + + int leftMargin = 6; + + int rightMargin = 6; + + int topMargin = 3; + + int bottomMargin = 3; + + int arrowMargin = 6; + + int imageSpacing = 3; + + private SortArrowRenderer arrowRenderer = new SortArrowRenderer(); + + private TextLayout textLayout; + + /** + * {@inheritDoc} + */ + public Point computeSize(GC gc, int wHint, int hHint, Object value) + { + GridColumn column = (GridColumn)value; + + gc.setFont(column.getHeaderFont()); + + int x = leftMargin; + int y = topMargin + gc.getFontMetrics().getHeight() + bottomMargin; + + + if (column.getImage() != null) + { + x += column.getImage().getBounds().width + imageSpacing; + + y = Math.max(y, topMargin + column.getImage().getBounds().height + bottomMargin); + } + if (!isWordWrap()) + { + x += gc.stringExtent(column.getText()).x + rightMargin; + } + else + { + int plainTextWidth; + if (wHint == SWT.DEFAULT) + plainTextWidth = getBounds().width - x - rightMargin; + else + plainTextWidth = wHint - x - rightMargin; + + getTextLayout(gc, column); + textLayout.setText(column.getText()); + textLayout.setWidth(plainTextWidth < 1 ? 1 : plainTextWidth); + + x += plainTextWidth + rightMargin; + + int textHeight = topMargin; + textHeight += textLayout.getBounds().height; + textHeight += bottomMargin; + + y = Math.max(y, textHeight); + } + + + y += computeControlSize(column).y; + + return new Point(x, y); + } + + /** + * {@inheritDoc} + */ + public void paint(GC gc, Object value) + { + GridColumn column = (GridColumn)value; + + // set the font to be used to display the text. + gc.setFont(column.getHeaderFont()); + + boolean flat = (column.getParent().getCellSelectionEnabled() && !column.getMoveable()); + + boolean drawSelected = ((isMouseDown() && isHover())); + + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + + if (flat && isSelected()) + { + gc.setBackground(column.getParent().getCellHeaderSelectionBackground()); + } + + gc.fillRectangle(getBounds().x, getBounds().y, getBounds().width, + getBounds().height); + + int pushedDrawingOffset = 0; + if (drawSelected) + { + pushedDrawingOffset = 1; + } + + int x = leftMargin; + + if (column.getImage() != null) + { + int y = bottomMargin; + + if( column.getHeaderControl() == null ) { + y = getBounds().y + pushedDrawingOffset + getBounds().height - bottomMargin - column.getImage().getBounds().height; + } + + gc.drawImage(column.getImage(), getBounds().x + x + pushedDrawingOffset, y); + x += column.getImage().getBounds().width + imageSpacing; + } + + int width = getBounds().width - x; + + if (column.getSort() == SWT.NONE) + { + width -= rightMargin; + } + else + { + width -= arrowMargin + arrowRenderer.getSize().x + arrowMargin; + } + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + + int y = bottomMargin; + + if( column.getHeaderControl() == null ) { + y = getBounds().y + getBounds().height - bottomMargin + - gc.getFontMetrics().getHeight(); + } else { + y = getBounds().y + getBounds().height - bottomMargin - gc.getFontMetrics().getHeight() - computeControlSize(column).y; + } + + String text = column.getText(); + + if (!isWordWrap()) + { + text = TextUtils.getShortStr(gc, text, width,truncationStyle); + } + + if (column.getAlignment() == SWT.RIGHT) + { + int len = gc.stringExtent(text).x; + if (len < width) + { + x += width - len; + } + } + else if (column.getAlignment() == SWT.CENTER) + { + int len = gc.stringExtent(text).x; + if (len < width) + { + x += (width - len) / 2; + } + } + + + if (!isWordWrap()) { + gc.drawString(text, getBounds().x + x + pushedDrawingOffset, + y + pushedDrawingOffset,true); + } + else + { + getTextLayout(gc, column); + textLayout.setWidth(width < 1 ? 1 : width); + textLayout.setText(text); + y -= textLayout.getBounds().height; + + // remove the first line shift + y+=gc.getFontMetrics().getHeight(); + + if (column.getParent().isAutoHeight()) + { + column.getParent().recalculateHeader(); + } + + textLayout.draw(gc, getBounds().x + x + pushedDrawingOffset, y + pushedDrawingOffset); + } + + if (column.getSort() != SWT.NONE) + { + if( column.getHeaderControl() == null ) { + y = getBounds().y + + ((getBounds().height - arrowRenderer.getBounds().height) / 2) + + 1; + } else { + y = getBounds().y + + ((getBounds().height - computeControlSize(column).y - arrowRenderer.getBounds().height) / 2) + + 1; + } + + arrowRenderer.setSelected(column.getSort() == SWT.DOWN); + if (drawSelected) + { + arrowRenderer + .setLocation( + getBounds().x + getBounds().width - arrowMargin + - arrowRenderer.getBounds().width + 1,y + ); + } + else + { + if( column.getHeaderControl() == null ) { + y = getBounds().y + + ((getBounds().height - arrowRenderer.getBounds().height) / 2); + } else { + y = getBounds().y + + ((getBounds().height - computeControlSize(column).y - arrowRenderer.getBounds().height) / 2); + } + arrowRenderer + .setLocation( + getBounds().x + getBounds().width - arrowMargin + - arrowRenderer.getBounds().width,y); + } + arrowRenderer.paint(gc, null); + } + + if (!flat) + { + + if (drawSelected) + { + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + } + else + { + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); + } + + gc.drawLine(getBounds().x, getBounds().y, getBounds().x + getBounds().width - 1, + getBounds().y); + gc.drawLine(getBounds().x, getBounds().y, getBounds().x, getBounds().y + getBounds().height + - 1); + + if (!drawSelected) + { + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); + gc.drawLine(getBounds().x + 1, getBounds().y + 1, + getBounds().x + getBounds().width - 2, getBounds().y + 1); + gc.drawLine(getBounds().x + 1, getBounds().y + 1, getBounds().x + 1, + getBounds().y + getBounds().height - 2); + } + + if (drawSelected) + { + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + } + else + { + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); + } + gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x + + getBounds().width - 1, + getBounds().y + getBounds().height - 1); + gc.drawLine(getBounds().x, getBounds().y + getBounds().height - 1, getBounds().x + + getBounds().width - 1, + getBounds().y + getBounds().height - 1); + + if (!drawSelected) + { + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + gc.drawLine(getBounds().x + getBounds().width - 2, getBounds().y + 1, + getBounds().x + getBounds().width - 2, getBounds().y + getBounds().height + - 2); + gc.drawLine(getBounds().x + 1, getBounds().y + getBounds().height - 2, + getBounds().x + getBounds().width - 2, getBounds().y + getBounds().height + - 2); + } + + } + else + { + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); + + gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x + + getBounds().width - 1, + getBounds().y + getBounds().height - 1); + gc.drawLine(getBounds().x, getBounds().y + getBounds().height - 1, getBounds().x + + getBounds().width - 1, + getBounds().y + getBounds().height - 1); + } + + + } + + /** + * {@inheritDoc} + */ + public void setDisplay(Display display) + { + super.setDisplay(display); + arrowRenderer.setDisplay(display); + } + + /** + * {@inheritDoc} + */ + public boolean notify(int event, Point point, Object value) + { + return false; + } + + /** + * {@inheritDoc} + */ + public Rectangle getTextBounds(Object value, boolean preferred) + { + GridColumn column = (GridColumn)value; + + int x = leftMargin; + + if (column.getImage() != null) + { + x += column.getImage().getBounds().width + imageSpacing; + } + + + + GC gc = new GC(column.getParent()); + gc.setFont(column.getParent().getFont()); + int y = getBounds().height - bottomMargin - gc.getFontMetrics().getHeight(); + + Rectangle bounds = new Rectangle(x,y,0,0); + + Point p = gc.stringExtent(column.getText()); + + bounds.height = p.y; + + if (preferred) + { + bounds.width = p.x; + } + else + { + int width = getBounds().width - x; + if (column.getSort() == SWT.NONE) + { + width -= rightMargin; + } + else + { + width -= arrowMargin + arrowRenderer.getSize().x + arrowMargin; + } + bounds.width = width; + } + + + gc.dispose(); + + return bounds; + } + + /** + * @see org.eclipse.nebula.widgets.grid.GridHeaderRenderer#getControlBounds(java.lang.Object, boolean) + */ + protected Rectangle getControlBounds(Object value, boolean preferred) { + Rectangle bounds = getBounds(); + GridColumn column = (GridColumn) value; + Point controlSize = computeControlSize(column); + + int y = getBounds().y + getBounds().height - bottomMargin - controlSize.y; + + return new Rectangle(bounds.x+3,y,bounds.width-6,controlSize.y); + } + + private Point computeControlSize(GridColumn column) { + if( column.getHeaderControl() != null ) { + return column.getHeaderControl().computeSize(SWT.DEFAULT, SWT.DEFAULT); + } + return new Point(0,0); + } + + private void getTextLayout(GC gc, GridColumn column) + { + if (textLayout == null) + { + textLayout = new TextLayout(gc.getDevice()); + textLayout.setFont(gc.getFont()); + column.getParent().addDisposeListener(new DisposeListener() + { + public void widgetDisposed(DisposeEvent e) + { + textLayout.dispose(); + } + }); + } + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultRowHeaderRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultRowHeaderRenderer.java index 947136d7a..af65e29c4 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultRowHeaderRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/DefaultRowHeaderRenderer.java @@ -1,319 +1,319 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - * Chuck.Mastrandrea@sas.com - wordwrapping in bug 222280 - * smcduff@hotmail.com - wordwrapping in bug 222280 - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid.internal; - -import org.eclipse.nebula.widgets.grid.AbstractRenderer; -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.GridItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.TextLayout; - -/** - * The row header renderer. - * - * @author chris.gross@us.ibm.com - * @since 2.0.0 - */ -public class DefaultRowHeaderRenderer extends AbstractRenderer -{ - - int leftMargin = 6; - - int rightMargin = 8; - - int topMargin = 3; - - int bottomMargin = 3; - - private TextLayout textLayout; - - private int truncationStyle =SWT.CENTER; - - - /** - * {@inheritDoc} - */ - @Override - public void paint(GC gc, Object value) - { - GridItem item = (GridItem) value; - - String text = getHeaderText(item); - - if (getHeaderFont(item) == null) { - gc.setFont(item.getParent().getFont()); - } else { - gc.setFont(getHeaderFont(item)); - } - - Color background = getHeaderBackground(item); - if( background == null ) { - background = getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); - } - gc.setBackground(background); - - if (isSelected() && item.getParent().getCellSelectionEnabled()) - { - gc.setBackground(item.getParent().getCellHeaderSelectionBackground()); - } - - gc.fillRectangle(getBounds().x, getBounds().y, getBounds().width, getBounds().height + 1); - - if (!item.getParent().getCellSelectionEnabled()) - { - if (isSelected()) - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - } - else - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); - } - - - - gc.drawLine(getBounds().x, getBounds().y, getBounds().x + getBounds().width - 1, - getBounds().y); - gc.drawLine(getBounds().x, getBounds().y, getBounds().x, getBounds().y + getBounds().height - - 1); - - if (!isSelected()) - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); - gc.drawLine(getBounds().x + 1, getBounds().y + 1, - getBounds().x + getBounds().width - 2, getBounds().y + 1); - gc.drawLine(getBounds().x + 1, getBounds().y + 1, getBounds().x + 1, - getBounds().y + getBounds().height - 2); - } - - if (isSelected()) - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - } - else - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); - } - gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - gc.drawLine(getBounds().x, getBounds().y + getBounds().height - 1, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - - if (!isSelected()) - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - gc.drawLine(getBounds().x + getBounds().width - 2, getBounds().y + 1, - getBounds().x + getBounds().width - 2, getBounds().y + getBounds().height - - 2); - gc.drawLine(getBounds().x + 1, getBounds().y + getBounds().height - 2, - getBounds().x + getBounds().width - 2, getBounds().y + getBounds().height - - 2); - } - } - else - { - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); - - gc.drawLine(getBounds().x + getBounds().width - 1, getBounds().y, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - gc.drawLine(getBounds().x, getBounds().y + getBounds().height - 1, getBounds().x - + getBounds().width - 1, - getBounds().y + getBounds().height - 1); - } - - int x = leftMargin; - - Image image = getHeaderImage(item); - - if( image != null ) { - if( isSelected() && !item.getParent().getCellSelectionEnabled() ) { - gc.drawImage(image, x + 1, getBounds().y + 1 + (getBounds().height - image.getBounds().height)/2); - x += 1; - } else { - gc.drawImage(image, x, getBounds().y + (getBounds().height - image.getBounds().height)/2); - } - x += image.getBounds().width + 5; - } - - int width = getBounds().width - x; - - width -= rightMargin; - - Color foreground = getHeaderForeground(item); - if( foreground == null ) { - foreground = getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND); - } - - gc.setForeground(foreground); - - - int y = getBounds().y; - int selectionOffset = 0; - if (isSelected() && !item.getParent().getCellSelectionEnabled()) - { - selectionOffset = 1; - } - - if (!item.getParent().isWordWrapHeader()) - { - y += (getBounds().height - gc.stringExtent(text).y) / 2; - gc.drawString(TextUtils.getShortStr(gc, text, width, truncationStyle), getBounds().x + x + selectionOffset, y + selectionOffset, true); - } - else - { - getTextLayout(gc, item); - textLayout.setWidth(width < 1 ? 1 : width); - textLayout.setText(text); - - if (item.getParent().isAutoHeight()) - { - // Look through all columns to get the max height needed for this item - int columnCount = item.getParent().getColumnCount(); - int maxHeight = textLayout.getBounds().height + topMargin + bottomMargin; - for (int i=0; ihandleEvent()
message. The event - * type is one of the event constants defined in class SWT. - * - * @param eventType the type of event to listen for - * @param listener the listener which should be notified when the event occurs - * - * @exception IllegalArgumentException
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see Listener - * @see SWT - * @see #removeListener(int, Listener) - */ - public void addListener(int eventType, Listener listener); - - /** - * Removes the listener from the collection of listeners who will - * be notified when an event of the given type occurs. The event - * type is one of the event constants defined in class SWT. - * - * @param eventType the type of event to listen for - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see Listener - * @see SWT - * @see #addListener - */ - public void removeListener(int eventType, Listener listener); -} +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid.internal; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; + +/** + * Used by Grid to externalize the scrollbars from the table itself. + * + * @author chris.gross@us.ibm.com + * @version 1.0.0 + */ +public interface IScrollBarProxy +{ + + /** + * Returns the scrollbar's visibility. + * + * @return true if the scrollbar is visible. + */ + public boolean getVisible(); + + /** + * Sets the scrollbar's visibility. + * + * @param visible visibilty + */ + public void setVisible(boolean visible); + + /** + * Returns the selection. + * + * @return the selection. + */ + public int getSelection(); + + /** + * Sets the selection. + * + * @param selection selection to set + */ + public void setSelection(int selection); + + /** + * Sets the receiver's selection, minimum value, maximum value, thumb, + * increment and page increment all at once. + * + * @param selection selection + * @param min minimum + * @param max maximum + * @param thumb thumb + * @param increment increment + * @param pageIncrement page increment + */ + public void setValues(int selection, int min, int max, int thumb, int increment, + int pageIncrement); + + + /** + * @param e + */ + public void handleMouseWheel(Event e); + + /** + * @param min + */ + public void setMinimum(int min); + + /** + * @return min + */ + public int getMinimum(); + + /** + * @param max + */ + public void setMaximum(int max); + + /** + * @return max + */ + public int getMaximum(); + + /** + * @param thumb + */ + public void setThumb(int thumb); + + /** + * @return thumb + */ + public int getThumb(); + + /** + * @param increment + */ + public void setIncrement(int increment); + + /** + * @return increment + */ + public int getIncrement(); + + /** + * @param page + */ + public void setPageIncrement(int page); + + /** + * @return page increment + */ + public int getPageIncrement(); + + /** + * @param listener + */ + public void addSelectionListener(SelectionListener listener); + + /** + * @param listener + */ + public void removeSelectionListener(SelectionListener listener); + + /** + * Adds the listener to the collection of listeners who will + * be notified when an event of the given type occurs. When the + * event does occur in the widget, the listener is notified by + * sending it the handleEvent() message. The event + * type is one of the event constants defined in class SWT. + * + * @param eventType the type of event to listen for + * @param listener the listener which should be notified when the event occurs + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see Listener + * @see SWT + * @see #removeListener(int, Listener) + */ + public void addListener(int eventType, Listener listener); + + /** + * Removes the listener from the collection of listeners who will + * be notified when an event of the given type occurs. The event + * type is one of the event constants defined in class SWT. + * + * @param eventType the type of event to listen for + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see Listener + * @see SWT + * @see #addListener + */ + public void removeListener(int eventType, Listener listener); +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/NullScrollBarProxy.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/NullScrollBarProxy.java index a720bd7c1..26584890f 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/NullScrollBarProxy.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/NullScrollBarProxy.java @@ -1,145 +1,145 @@ -package org.eclipse.nebula.widgets.grid.internal; - -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; - -/** - * A null-op scrollbar proxy. Used when the grid is not showing scrollbars. - * - * @author chris.gross@us.ibm.com - * @since 2.0.0 - */ -public class NullScrollBarProxy implements IScrollBarProxy { - - /** - * {@inheritDoc} - */ - public boolean getVisible() { - return false; - } - - /** - * {@inheritDoc} - */ - public void setVisible(boolean visible) { - } - - /** - * {@inheritDoc} - */ - public int getSelection() { - return 0; - } - - /** - * {@inheritDoc} - */ - public void setSelection(int selection) { - } - - /** - * {@inheritDoc} - */ - public void setValues(int selection, int min, int max, int thumb, int increment, int pageIncrement) { - } - - /** - * {@inheritDoc} - */ - public void handleMouseWheel(Event e) { - } - - /** - * {@inheritDoc} - */ - public void setMinimum(int min) { - } - - /** - * {@inheritDoc} - */ - public int getMinimum() { - return 0; - } - - /** - * {@inheritDoc} - */ - public void setMaximum(int max) { - } - - /** - * {@inheritDoc} - */ - public int getMaximum() { - return 0; - } - - /** - * {@inheritDoc} - */ - public void setThumb(int thumb) { - } - - /** - * {@inheritDoc} - */ - public int getThumb() { - return 0; - } - - /** - * {@inheritDoc} - */ - public void setIncrement(int increment) { - } - - /** - * {@inheritDoc} - */ - public int getIncrement() { - return 0; - } - - /** - * {@inheritDoc} - */ - public void setPageIncrement(int page) { - } - - /** - * {@inheritDoc} - */ - public int getPageIncrement() { - return 0; - } - - /** - * {@inheritDoc} - */ - public void addSelectionListener(SelectionListener listener) { - } - - /** - * {@inheritDoc} - */ - public void removeSelectionListener(SelectionListener listener) { - - } - - /** - * @see org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy#addListener(int, org.eclipse.swt.widgets.Listener) - */ - @Override - public void addListener(int eventType, Listener listener) { - } - - /** - * @see org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy#removeListener(int, org.eclipse.swt.widgets.Listener) - */ - @Override - public void removeListener(int eventType, Listener listener) { - } - -} +package org.eclipse.nebula.widgets.grid.internal; + +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; + +/** + * A null-op scrollbar proxy. Used when the grid is not showing scrollbars. + * + * @author chris.gross@us.ibm.com + * @since 2.0.0 + */ +public class NullScrollBarProxy implements IScrollBarProxy { + + /** + * {@inheritDoc} + */ + public boolean getVisible() { + return false; + } + + /** + * {@inheritDoc} + */ + public void setVisible(boolean visible) { + } + + /** + * {@inheritDoc} + */ + public int getSelection() { + return 0; + } + + /** + * {@inheritDoc} + */ + public void setSelection(int selection) { + } + + /** + * {@inheritDoc} + */ + public void setValues(int selection, int min, int max, int thumb, int increment, int pageIncrement) { + } + + /** + * {@inheritDoc} + */ + public void handleMouseWheel(Event e) { + } + + /** + * {@inheritDoc} + */ + public void setMinimum(int min) { + } + + /** + * {@inheritDoc} + */ + public int getMinimum() { + return 0; + } + + /** + * {@inheritDoc} + */ + public void setMaximum(int max) { + } + + /** + * {@inheritDoc} + */ + public int getMaximum() { + return 0; + } + + /** + * {@inheritDoc} + */ + public void setThumb(int thumb) { + } + + /** + * {@inheritDoc} + */ + public int getThumb() { + return 0; + } + + /** + * {@inheritDoc} + */ + public void setIncrement(int increment) { + } + + /** + * {@inheritDoc} + */ + public int getIncrement() { + return 0; + } + + /** + * {@inheritDoc} + */ + public void setPageIncrement(int page) { + } + + /** + * {@inheritDoc} + */ + public int getPageIncrement() { + return 0; + } + + /** + * {@inheritDoc} + */ + public void addSelectionListener(SelectionListener listener) { + } + + /** + * {@inheritDoc} + */ + public void removeSelectionListener(SelectionListener listener) { + + } + + /** + * @see org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy#addListener(int, org.eclipse.swt.widgets.Listener) + */ + @Override + public void addListener(int eventType, Listener listener) { + } + + /** + * @see org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy#removeListener(int, org.eclipse.swt.widgets.Listener) + */ + @Override + public void removeListener(int eventType, Listener listener) { + } + +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/ScrollBarProxyAdapter.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/ScrollBarProxyAdapter.java index d64438775..b91a7173c 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/ScrollBarProxyAdapter.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/ScrollBarProxyAdapter.java @@ -1,172 +1,172 @@ -package org.eclipse.nebula.widgets.grid.internal; - -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ScrollBar; - -/** - * Adapts a normal scrollbar to the IScrollBar proxy. - * - * @author chris.gross@us.ibm.com - * @since 2.0.0 - */ -public class ScrollBarProxyAdapter implements IScrollBarProxy { - /** - * Delegates to this scrollbar. - */ - private ScrollBar scrollBar; - - /** - * Contructs this adapter by delegating to the given scroll bar. - * - * @param scrollBar - * delegate - */ - public ScrollBarProxyAdapter(ScrollBar scrollBar) { - super(); - this.scrollBar = scrollBar; - } - - /** - * {@inheritDoc} - */ - public int getIncrement() { - return scrollBar.getIncrement(); - } - - /** - * {@inheritDoc} - */ - public int getMaximum() { - return scrollBar.getMaximum(); - } - - /** - * {@inheritDoc} - */ - public int getMinimum() { - return scrollBar.getMinimum(); - } - - /** - * {@inheritDoc} - */ - public int getPageIncrement() { - return scrollBar.getPageIncrement(); - } - - /** - * {@inheritDoc} - */ - public int getSelection() { - return scrollBar.getSelection(); - } - - /** - * {@inheritDoc} - */ - public int getThumb() { - return scrollBar.getThumb(); - } - - /** - * {@inheritDoc} - */ - public boolean getVisible() { - return scrollBar.getVisible(); - } - - /** - * {@inheritDoc} - */ - public void setIncrement(int value) { - scrollBar.setIncrement(value); - } - - /** - * {@inheritDoc} - */ - public void setMaximum(int value) { - scrollBar.setMaximum(value); - } - - /** - * {@inheritDoc} - */ - public void setMinimum(int value) { - scrollBar.setMinimum(value); - } - - /** - * {@inheritDoc} - */ - public void setPageIncrement(int value) { - scrollBar.setPageIncrement(value); - } - - /** - * {@inheritDoc} - */ - public void setSelection(int selection) { - scrollBar.setSelection(selection); - } - - /** - * {@inheritDoc} - */ - public void setThumb(int value) { - scrollBar.setThumb(value); - } - - /** - * {@inheritDoc} - */ - public void setValues(int selection, int minimum, int maximum, int thumb, int increment, int pageIncrement) { - scrollBar.setValues(selection, minimum, maximum, thumb, increment, pageIncrement); - } - - /** - * {@inheritDoc} - */ - public void setVisible(boolean visible) { - scrollBar.setVisible(visible); - } - - /** - * {@inheritDoc} - */ - public void handleMouseWheel(Event e) { - // do nothing - } - - /** - * {@inheritDoc} - */ - public void addSelectionListener(SelectionListener listener) { - scrollBar.addSelectionListener(listener); - } - - /** - * {@inheritDoc} - */ - public void removeSelectionListener(SelectionListener listener) { - scrollBar.removeSelectionListener(listener); - } - - /** - * @see org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy#addListener(int, org.eclipse.swt.widgets.Listener) - */ - @Override - public void addListener(int eventType, Listener listener) { - scrollBar.addListener(eventType, listener); - } - - /** - * @see org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy#removeListener(int, org.eclipse.swt.widgets.Listener) - */ - @Override - public void removeListener(int eventType, Listener listener) { - scrollBar.removeListener(eventType, listener); - } -} +package org.eclipse.nebula.widgets.grid.internal; + +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; + +/** + * Adapts a normal scrollbar to the IScrollBar proxy. + * + * @author chris.gross@us.ibm.com + * @since 2.0.0 + */ +public class ScrollBarProxyAdapter implements IScrollBarProxy { + /** + * Delegates to this scrollbar. + */ + private ScrollBar scrollBar; + + /** + * Contructs this adapter by delegating to the given scroll bar. + * + * @param scrollBar + * delegate + */ + public ScrollBarProxyAdapter(ScrollBar scrollBar) { + super(); + this.scrollBar = scrollBar; + } + + /** + * {@inheritDoc} + */ + public int getIncrement() { + return scrollBar.getIncrement(); + } + + /** + * {@inheritDoc} + */ + public int getMaximum() { + return scrollBar.getMaximum(); + } + + /** + * {@inheritDoc} + */ + public int getMinimum() { + return scrollBar.getMinimum(); + } + + /** + * {@inheritDoc} + */ + public int getPageIncrement() { + return scrollBar.getPageIncrement(); + } + + /** + * {@inheritDoc} + */ + public int getSelection() { + return scrollBar.getSelection(); + } + + /** + * {@inheritDoc} + */ + public int getThumb() { + return scrollBar.getThumb(); + } + + /** + * {@inheritDoc} + */ + public boolean getVisible() { + return scrollBar.getVisible(); + } + + /** + * {@inheritDoc} + */ + public void setIncrement(int value) { + scrollBar.setIncrement(value); + } + + /** + * {@inheritDoc} + */ + public void setMaximum(int value) { + scrollBar.setMaximum(value); + } + + /** + * {@inheritDoc} + */ + public void setMinimum(int value) { + scrollBar.setMinimum(value); + } + + /** + * {@inheritDoc} + */ + public void setPageIncrement(int value) { + scrollBar.setPageIncrement(value); + } + + /** + * {@inheritDoc} + */ + public void setSelection(int selection) { + scrollBar.setSelection(selection); + } + + /** + * {@inheritDoc} + */ + public void setThumb(int value) { + scrollBar.setThumb(value); + } + + /** + * {@inheritDoc} + */ + public void setValues(int selection, int minimum, int maximum, int thumb, int increment, int pageIncrement) { + scrollBar.setValues(selection, minimum, maximum, thumb, increment, pageIncrement); + } + + /** + * {@inheritDoc} + */ + public void setVisible(boolean visible) { + scrollBar.setVisible(visible); + } + + /** + * {@inheritDoc} + */ + public void handleMouseWheel(Event e) { + // do nothing + } + + /** + * {@inheritDoc} + */ + public void addSelectionListener(SelectionListener listener) { + scrollBar.addSelectionListener(listener); + } + + /** + * {@inheritDoc} + */ + public void removeSelectionListener(SelectionListener listener) { + scrollBar.removeSelectionListener(listener); + } + + /** + * @see org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy#addListener(int, org.eclipse.swt.widgets.Listener) + */ + @Override + public void addListener(int eventType, Listener listener) { + scrollBar.addListener(eventType, listener); + } + + /** + * @see org.eclipse.nebula.widgets.grid.internal.IScrollBarProxy#removeListener(int, org.eclipse.swt.widgets.Listener) + */ + @Override + public void removeListener(int eventType, Listener listener) { + scrollBar.removeListener(eventType, listener); + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/ToggleRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/ToggleRenderer.java index 3f0ec1e49..356461887 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/ToggleRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/ToggleRenderer.java @@ -1,128 +1,128 @@ -/******************************************************************************* - * Copyright (c) 2006-2019 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * chris.gross@us.ibm.com - initial API and implementation - * laurent.caron@gmail.com - Bug 316623 - Toggle for Mac - *******************************************************************************/ -package org.eclipse.nebula.widgets.grid.internal; - -import java.util.Locale; - -import org.eclipse.nebula.widgets.grid.AbstractRenderer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Transform; - -/** - * The renderer for tree item plus/minus expand/collapse toggle. - * - * @author chris.gross@us.ibm.com - * @since 2.0.0 - */ -public class ToggleRenderer extends AbstractRenderer { - - private static final boolean IS_MAC ; - static { - final String osProperty = System.getProperty("os.name"); - if (osProperty != null) { - final String osName = osProperty.toUpperCase(Locale.getDefault()); - IS_MAC = osName.indexOf("MAC") > -1; - } else { - IS_MAC = false; - } - } - - /** - * Default constructor. - */ - public ToggleRenderer() { - if (IS_MAC) { - setSize(new Point(10, 10)); - } else { - this.setSize(9, 9); - } - } - - /** - * @see org.eclipse.nebula.widgets.grid.IRenderer#paint(org.eclipse.swt.graphics.GC, - * java.lang.Object) - */ - public void paint(GC gc, Object value) { - - if (IS_MAC) { - paintMacTwistie(gc); - } else { - paintPlusMinus(gc); - } - - } - - private void paintMacTwistie(GC gc) { - Transform transform = new Transform(gc.getDevice()); - transform.translate(getBounds().x, getBounds().y); - gc.setTransform(transform); - - Color back = gc.getBackground(); - Color fore = gc.getForeground(); - - if (!isHover()) { - gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - } else { - gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION)); - } - - gc.setBackground(gc.getForeground()); - if (isExpanded()) { - gc.drawPolygon(new int[] { 1, 3, 4, 6, 5, 6, 8, 3 }); - gc.fillPolygon(new int[] { 1, 3, 4, 6, 5, 6, 8, 3 }); - } else { - gc.drawPolygon(new int[] { 3, 1, 6, 4, 6, 5, 3, 8 }); - gc.fillPolygon(new int[] { 3, 1, 6, 4, 6, 5, 3, 8 }); - } - - if (isFocus()) { - gc.setBackground(back); - gc.setForeground(fore); - gc.drawFocus(-1, -1, 12, 12); - } - - gc.setTransform(null); - transform.dispose(); - } - - private void paintPlusMinus(GC gc) { - gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - - gc.fillRectangle(getBounds()); - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - - gc.drawRectangle(getBounds().x, getBounds().y, getBounds().width - 1, getBounds().height - 1); - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - - gc.drawLine(getBounds().x + 2, getBounds().y + 4, getBounds().x + 6, getBounds().y + 4); - - if (!isExpanded()) { - gc.drawLine(getBounds().x + 4, getBounds().y + 2, getBounds().x + 4, getBounds().y + 6); - } - } - - /** - * @see org.eclipse.nebula.widgets.grid.IRenderer#computeSize(org.eclipse.swt.graphics.GC, - * int, int, java.lang.Object) - */ - public Point computeSize(GC gc, int wHint, int hHint, Object value) { - return IS_MAC ? new Point(10, 10) : new Point(9, 9); - } -} +/******************************************************************************* + * Copyright (c) 2006-2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * chris.gross@us.ibm.com - initial API and implementation + * laurent.caron@gmail.com - Bug 316623 - Toggle for Mac + *******************************************************************************/ +package org.eclipse.nebula.widgets.grid.internal; + +import java.util.Locale; + +import org.eclipse.nebula.widgets.grid.AbstractRenderer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Transform; + +/** + * The renderer for tree item plus/minus expand/collapse toggle. + * + * @author chris.gross@us.ibm.com + * @since 2.0.0 + */ +public class ToggleRenderer extends AbstractRenderer { + + private static final boolean IS_MAC ; + static { + final String osProperty = System.getProperty("os.name"); + if (osProperty != null) { + final String osName = osProperty.toUpperCase(Locale.getDefault()); + IS_MAC = osName.indexOf("MAC") > -1; + } else { + IS_MAC = false; + } + } + + /** + * Default constructor. + */ + public ToggleRenderer() { + if (IS_MAC) { + setSize(new Point(10, 10)); + } else { + this.setSize(9, 9); + } + } + + /** + * @see org.eclipse.nebula.widgets.grid.IRenderer#paint(org.eclipse.swt.graphics.GC, + * java.lang.Object) + */ + public void paint(GC gc, Object value) { + + if (IS_MAC) { + paintMacTwistie(gc); + } else { + paintPlusMinus(gc); + } + + } + + private void paintMacTwistie(GC gc) { + Transform transform = new Transform(gc.getDevice()); + transform.translate(getBounds().x, getBounds().y); + gc.setTransform(transform); + + Color back = gc.getBackground(); + Color fore = gc.getForeground(); + + if (!isHover()) { + gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + } else { + gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION)); + } + + gc.setBackground(gc.getForeground()); + if (isExpanded()) { + gc.drawPolygon(new int[] { 1, 3, 4, 6, 5, 6, 8, 3 }); + gc.fillPolygon(new int[] { 1, 3, 4, 6, 5, 6, 8, 3 }); + } else { + gc.drawPolygon(new int[] { 3, 1, 6, 4, 6, 5, 3, 8 }); + gc.fillPolygon(new int[] { 3, 1, 6, 4, 6, 5, 3, 8 }); + } + + if (isFocus()) { + gc.setBackground(back); + gc.setForeground(fore); + gc.drawFocus(-1, -1, 12, 12); + } + + gc.setTransform(null); + transform.dispose(); + } + + private void paintPlusMinus(GC gc) { + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + + gc.fillRectangle(getBounds()); + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + + gc.drawRectangle(getBounds().x, getBounds().y, getBounds().width - 1, getBounds().height - 1); + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + + gc.drawLine(getBounds().x + 2, getBounds().y + 4, getBounds().x + 6, getBounds().y + 4); + + if (!isExpanded()) { + gc.drawLine(getBounds().x + 4, getBounds().y + 2, getBounds().x + 4, getBounds().y + 6); + } + } + + /** + * @see org.eclipse.nebula.widgets.grid.IRenderer#computeSize(org.eclipse.swt.graphics.GC, + * int, int, java.lang.Object) + */ + public Point computeSize(GC gc, int wHint, int hHint, Object value) { + return IS_MAC ? new Point(10, 10) : new Point(9, 9); + } +} diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7ColumnGroupHeaderRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7ColumnGroupHeaderRenderer.java index f5447234c..63bd36d5f 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7ColumnGroupHeaderRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7ColumnGroupHeaderRenderer.java @@ -1,124 +1,124 @@ -package org.eclipse.nebula.widgets.grid.internal.win7; - -import org.eclipse.nebula.widgets.grid.GridColumnGroup; -import org.eclipse.nebula.widgets.grid.internal.DefaultColumnGroupHeaderRenderer; -import org.eclipse.nebula.widgets.grid.internal.ExpandToggleRenderer; -import org.eclipse.nebula.widgets.grid.internal.TextUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.TextLayout; -import org.eclipse.swt.widgets.Display; - -/** - * Column group renderer which emulates a default Win7 L&F - */ -public class Win7ColumnGroupHeaderRenderer extends DefaultColumnGroupHeaderRenderer { - int leftMargin = 6; - - int rightMargin = 6; - - int topMargin = 3; - - int bottomMargin = 3; - - int imageSpacing = 3; - - private ExpandToggleRenderer toggleRenderer = new ExpandToggleRenderer(); - - private TextLayout textLayout; - - private Win7PaletteProvider palette; - - private int truncationStyle = SWT.CENTER; - - /** - * @param palette - */ - public Win7ColumnGroupHeaderRenderer(Win7PaletteProvider palette) { - this.palette = palette; - } - - /** - * {@inheritDoc} - */ - public void paint(GC gc, Object value) { - GridColumnGroup group = (GridColumnGroup) value; - - // set the font to be used to display the text. - gc.setFont(group.getHeaderFont()); - - Win7ColumnHeaderUtil.drawColumn(gc, getBounds(), palette, isHover(), isSelected(), isMouseDown()); - - int x = leftMargin; - - if (group.getImage() != null) { - gc.drawImage(group.getImage(), getBounds().x + x, getBounds().y + topMargin); - x = group.getImage().getBounds().width + imageSpacing; - } - - int width = getBounds().width - x - rightMargin; - if ((group.getStyle() & SWT.TOGGLE) != 0) { - width -= toggleRenderer.getSize().x; - } - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - if (!isWordWrap()) { - gc.drawString(TextUtils.getShortStr(gc, group.getText(), width,truncationStyle), getBounds().x + x, - getBounds().y + topMargin, true); - } else { - getTextLayout(gc, group); - textLayout.setWidth(width < 1 ? 1 : width); - textLayout.setText(group.getText()); - - if (group.getParent().isAutoHeight()) { - group.getParent().recalculateHeader(); - } - - textLayout.draw(gc, getBounds().x + x, getBounds().y + topMargin); - } - - if ((group.getStyle() & SWT.TOGGLE) != 0) { - toggleRenderer.setHover(isHover() && getHoverDetail().equals("toggle")); - toggleRenderer.setExpanded(group.getExpanded()); - toggleRenderer.setBounds(getToggleBounds()); - toggleRenderer.paint(gc, null); - } - } - - /** - * {@inheritDoc} - */ - public void setDisplay(Display display) { - super.setDisplay(display); - toggleRenderer.setDisplay(display); - palette.initializePalette(getDisplay(), Win7PaletteProvider.NORMAL_GRID_COLUMN_HEADER); - palette.initializePalette(getDisplay(), Win7PaletteProvider.HOVER_GRID_COLUMN_HEADER); - } - - private void getTextLayout(GC gc, GridColumnGroup group) { - if (textLayout == null) { - textLayout = new TextLayout(gc.getDevice()); - textLayout.setFont(gc.getFont()); - group.getParent().addListener(SWT.Dispose, e -> textLayout.dispose()); - } - } - - /** - * Get the truncation style - * @return the truncation style. - */ - public int getTruncationStyle() { - return truncationStyle; - } - - /** - * Set the truncation style to use when cell content is too large. - * @see SWT#LEFT - * @see SWT#CENTER - * @see SWT#RIGHT - * @param truncationStyle - */ - public void setTruncationStyle(int truncationStyle) { - this.truncationStyle = truncationStyle; - } +package org.eclipse.nebula.widgets.grid.internal.win7; + +import org.eclipse.nebula.widgets.grid.GridColumnGroup; +import org.eclipse.nebula.widgets.grid.internal.DefaultColumnGroupHeaderRenderer; +import org.eclipse.nebula.widgets.grid.internal.ExpandToggleRenderer; +import org.eclipse.nebula.widgets.grid.internal.TextUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.widgets.Display; + +/** + * Column group renderer which emulates a default Win7 L&F + */ +public class Win7ColumnGroupHeaderRenderer extends DefaultColumnGroupHeaderRenderer { + int leftMargin = 6; + + int rightMargin = 6; + + int topMargin = 3; + + int bottomMargin = 3; + + int imageSpacing = 3; + + private ExpandToggleRenderer toggleRenderer = new ExpandToggleRenderer(); + + private TextLayout textLayout; + + private Win7PaletteProvider palette; + + private int truncationStyle = SWT.CENTER; + + /** + * @param palette + */ + public Win7ColumnGroupHeaderRenderer(Win7PaletteProvider palette) { + this.palette = palette; + } + + /** + * {@inheritDoc} + */ + public void paint(GC gc, Object value) { + GridColumnGroup group = (GridColumnGroup) value; + + // set the font to be used to display the text. + gc.setFont(group.getHeaderFont()); + + Win7ColumnHeaderUtil.drawColumn(gc, getBounds(), palette, isHover(), isSelected(), isMouseDown()); + + int x = leftMargin; + + if (group.getImage() != null) { + gc.drawImage(group.getImage(), getBounds().x + x, getBounds().y + topMargin); + x = group.getImage().getBounds().width + imageSpacing; + } + + int width = getBounds().width - x - rightMargin; + if ((group.getStyle() & SWT.TOGGLE) != 0) { + width -= toggleRenderer.getSize().x; + } + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + if (!isWordWrap()) { + gc.drawString(TextUtils.getShortStr(gc, group.getText(), width,truncationStyle), getBounds().x + x, + getBounds().y + topMargin, true); + } else { + getTextLayout(gc, group); + textLayout.setWidth(width < 1 ? 1 : width); + textLayout.setText(group.getText()); + + if (group.getParent().isAutoHeight()) { + group.getParent().recalculateHeader(); + } + + textLayout.draw(gc, getBounds().x + x, getBounds().y + topMargin); + } + + if ((group.getStyle() & SWT.TOGGLE) != 0) { + toggleRenderer.setHover(isHover() && getHoverDetail().equals("toggle")); + toggleRenderer.setExpanded(group.getExpanded()); + toggleRenderer.setBounds(getToggleBounds()); + toggleRenderer.paint(gc, null); + } + } + + /** + * {@inheritDoc} + */ + public void setDisplay(Display display) { + super.setDisplay(display); + toggleRenderer.setDisplay(display); + palette.initializePalette(getDisplay(), Win7PaletteProvider.NORMAL_GRID_COLUMN_HEADER); + palette.initializePalette(getDisplay(), Win7PaletteProvider.HOVER_GRID_COLUMN_HEADER); + } + + private void getTextLayout(GC gc, GridColumnGroup group) { + if (textLayout == null) { + textLayout = new TextLayout(gc.getDevice()); + textLayout.setFont(gc.getFont()); + group.getParent().addListener(SWT.Dispose, e -> textLayout.dispose()); + } + } + + /** + * Get the truncation style + * @return the truncation style. + */ + public int getTruncationStyle() { + return truncationStyle; + } + + /** + * Set the truncation style to use when cell content is too large. + * @see SWT#LEFT + * @see SWT#CENTER + * @see SWT#RIGHT + * @param truncationStyle + */ + public void setTruncationStyle(int truncationStyle) { + this.truncationStyle = truncationStyle; + } } \ No newline at end of file diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7ColumnHeaderUtil.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7ColumnHeaderUtil.java index 68f9343fa..a8f68222d 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7ColumnHeaderUtil.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7ColumnHeaderUtil.java @@ -1,144 +1,144 @@ -package org.eclipse.nebula.widgets.grid.internal.win7; - -import org.eclipse.nebula.widgets.grid.internal.win7.Win7PaletteProvider.Palette; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Display; - -/** - * Utility to perform the common drawing functions for all Win7 grid columns - * headers - */ -public class Win7ColumnHeaderUtil { - - /** - * Based on the provided state (hover/selected) generate the appropriate column - * header rendering. - * - * @param graphics - * @param bounds - * @param palette - * @param hover - * indicates whether the mouse is hovering over the column header - * @param selected - * indicates whether the column is selected (mousedown) - * @param mousedown - */ - public static void drawColumn(GC graphics, Rectangle bounds, Win7PaletteProvider palette, boolean hover, - boolean selected, boolean mousedown) { - if (mousedown) { - drawColumnHeader(graphics, bounds, palette.getPalette((Display) graphics.getDevice(), - Win7PaletteProvider.MOUSEDOWN_GRID_COLUMN_HEADER)); - drawColumnSelectedTopShadow(graphics, bounds, - palette.getPalette((Display) graphics.getDevice(), Win7PaletteProvider.SHADOW_GRID_COLUMN_HEADER)); - } else if (hover) { - drawColumnHeader(graphics, bounds, - palette.getPalette((Display) graphics.getDevice(), Win7PaletteProvider.HOVER_GRID_COLUMN_HEADER)); - } else if (selected) { - drawColumnHeader(graphics, bounds, palette.getPalette((Display) graphics.getDevice(), - Win7PaletteProvider.SELECTED_GRID_COLUMN_HEADER)); - } else { - drawColumnHeader(graphics, bounds, - palette.getPalette((Display) graphics.getDevice(), Win7PaletteProvider.NORMAL_GRID_COLUMN_HEADER)); - } - } - - /** - * Draw an additional shadow for the selected column state - * - * @param graphics - * @param bounds - * @param palette - */ - protected static void drawColumnSelectedTopShadow(GC graphics, Rectangle bounds, Palette palette) { - int x = bounds.x; - int y = bounds.y; - - graphics.setForeground(palette.getColors()[0]); - graphics.drawLine(x + 1, y, x + bounds.width - 2, y); - graphics.setForeground(palette.getColors()[1]); - graphics.drawLine(x + 1, y + 1, x + bounds.width - 2, y + 1); - } - - /** - * Draw the column header based on the given colors - * - * @param graphics - * @param bounds - * @param palette - */ - protected static void drawColumnHeader(GC graphics, Rectangle bounds, Palette palette) { - int x = bounds.x; - int y = bounds.y; - - int topRectHeight = (int) Math.round((bounds.height - 3) * .45); - int bottomRectHeight = bounds.height - 3 - topRectHeight; - int bottomRectY = y + topRectHeight + 1; - - // 2 - left upper - graphics.setBackground(palette.getColors()[1]); - graphics.fillRectangle(x, y, 1, topRectHeight + 1); - - // 3 - upper fill - graphics.setBackground(palette.getColors()[2]); - graphics.fillRectangle(x + 1, y, bounds.width - 3, topRectHeight + 1); - - // 4 - right upper - graphics.setBackground(palette.getColors()[3]); - graphics.fillRectangle(x + bounds.width - 2, y, 1, topRectHeight + 1); - - // 5 - right upper gradient (shadow/highlight) - graphics.setBackground(palette.getColors()[5]); - if (palette.getColors()[4] != null) { - graphics.setForeground(palette.getColors()[4]); - graphics.fillGradientRectangle(x + bounds.width - 1, y, 1, topRectHeight + 1, true); - } else { - graphics.fillRectangle(x + bounds.width - 1, y, 1, topRectHeight + 1); - } - - // 6 - left bottom gradient (shadow/hightlight) - graphics.setBackground(palette.getColors()[7]); - if (palette.getColors()[6] != null) { - graphics.setForeground(palette.getColors()[6]); - graphics.fillGradientRectangle(x, bottomRectY, 1, bottomRectHeight, true); - } else { - graphics.fillRectangle(x, bottomRectY, 1, bottomRectHeight); - } - - // 7 - bottom fill - graphics.setBackground(palette.getColors()[9]); - if (palette.getColors()[8] != null) { - graphics.setForeground(palette.getColors()[8]); - graphics.fillGradientRectangle(x + 1, bottomRectY, bounds.width - 3, bottomRectHeight, true); - } else { - graphics.fillRectangle(x + 1, bottomRectY, bounds.width - 3, bottomRectHeight); - } - - // 8 - right bottom gradient (shadow/highlight) - graphics.setBackground(palette.getColors()[11]); - if (palette.getColors()[10] != null) { - graphics.setForeground(palette.getColors()[10]); - graphics.fillGradientRectangle(x + bounds.width - 2, bottomRectY, 1, bottomRectHeight, true); - } else { - graphics.fillRectangle(x + bounds.width - 2, bottomRectY, 1, bottomRectHeight); - } - - // 9 - right bottom cell border - graphics.setBackground(palette.getColors()[13]); - if (palette.getColors()[12] != null) { - graphics.setForeground(palette.getColors()[12]); - graphics.fillGradientRectangle(x + bounds.width - 1, bottomRectY, 1, bottomRectHeight, true); - } else { - graphics.fillRectangle(x + bounds.width - 1, bottomRectY, 1, bottomRectHeight); - } - - // 10 - bottom shadow - graphics.setForeground(palette.getColors()[14]); - graphics.drawLine(x, y + bounds.height - 2, x + bounds.width - 1, y + bounds.height - 2); - - // 11 - bottom cell border - graphics.setForeground(palette.getColors()[15]); - graphics.drawLine(x, y + bounds.height - 1, x + bounds.width - 1, y + bounds.height - 1); - } - +package org.eclipse.nebula.widgets.grid.internal.win7; + +import org.eclipse.nebula.widgets.grid.internal.win7.Win7PaletteProvider.Palette; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; + +/** + * Utility to perform the common drawing functions for all Win7 grid columns + * headers + */ +public class Win7ColumnHeaderUtil { + + /** + * Based on the provided state (hover/selected) generate the appropriate column + * header rendering. + * + * @param graphics + * @param bounds + * @param palette + * @param hover + * indicates whether the mouse is hovering over the column header + * @param selected + * indicates whether the column is selected (mousedown) + * @param mousedown + */ + public static void drawColumn(GC graphics, Rectangle bounds, Win7PaletteProvider palette, boolean hover, + boolean selected, boolean mousedown) { + if (mousedown) { + drawColumnHeader(graphics, bounds, palette.getPalette((Display) graphics.getDevice(), + Win7PaletteProvider.MOUSEDOWN_GRID_COLUMN_HEADER)); + drawColumnSelectedTopShadow(graphics, bounds, + palette.getPalette((Display) graphics.getDevice(), Win7PaletteProvider.SHADOW_GRID_COLUMN_HEADER)); + } else if (hover) { + drawColumnHeader(graphics, bounds, + palette.getPalette((Display) graphics.getDevice(), Win7PaletteProvider.HOVER_GRID_COLUMN_HEADER)); + } else if (selected) { + drawColumnHeader(graphics, bounds, palette.getPalette((Display) graphics.getDevice(), + Win7PaletteProvider.SELECTED_GRID_COLUMN_HEADER)); + } else { + drawColumnHeader(graphics, bounds, + palette.getPalette((Display) graphics.getDevice(), Win7PaletteProvider.NORMAL_GRID_COLUMN_HEADER)); + } + } + + /** + * Draw an additional shadow for the selected column state + * + * @param graphics + * @param bounds + * @param palette + */ + protected static void drawColumnSelectedTopShadow(GC graphics, Rectangle bounds, Palette palette) { + int x = bounds.x; + int y = bounds.y; + + graphics.setForeground(palette.getColors()[0]); + graphics.drawLine(x + 1, y, x + bounds.width - 2, y); + graphics.setForeground(palette.getColors()[1]); + graphics.drawLine(x + 1, y + 1, x + bounds.width - 2, y + 1); + } + + /** + * Draw the column header based on the given colors + * + * @param graphics + * @param bounds + * @param palette + */ + protected static void drawColumnHeader(GC graphics, Rectangle bounds, Palette palette) { + int x = bounds.x; + int y = bounds.y; + + int topRectHeight = (int) Math.round((bounds.height - 3) * .45); + int bottomRectHeight = bounds.height - 3 - topRectHeight; + int bottomRectY = y + topRectHeight + 1; + + // 2 - left upper + graphics.setBackground(palette.getColors()[1]); + graphics.fillRectangle(x, y, 1, topRectHeight + 1); + + // 3 - upper fill + graphics.setBackground(palette.getColors()[2]); + graphics.fillRectangle(x + 1, y, bounds.width - 3, topRectHeight + 1); + + // 4 - right upper + graphics.setBackground(palette.getColors()[3]); + graphics.fillRectangle(x + bounds.width - 2, y, 1, topRectHeight + 1); + + // 5 - right upper gradient (shadow/highlight) + graphics.setBackground(palette.getColors()[5]); + if (palette.getColors()[4] != null) { + graphics.setForeground(palette.getColors()[4]); + graphics.fillGradientRectangle(x + bounds.width - 1, y, 1, topRectHeight + 1, true); + } else { + graphics.fillRectangle(x + bounds.width - 1, y, 1, topRectHeight + 1); + } + + // 6 - left bottom gradient (shadow/hightlight) + graphics.setBackground(palette.getColors()[7]); + if (palette.getColors()[6] != null) { + graphics.setForeground(palette.getColors()[6]); + graphics.fillGradientRectangle(x, bottomRectY, 1, bottomRectHeight, true); + } else { + graphics.fillRectangle(x, bottomRectY, 1, bottomRectHeight); + } + + // 7 - bottom fill + graphics.setBackground(palette.getColors()[9]); + if (palette.getColors()[8] != null) { + graphics.setForeground(palette.getColors()[8]); + graphics.fillGradientRectangle(x + 1, bottomRectY, bounds.width - 3, bottomRectHeight, true); + } else { + graphics.fillRectangle(x + 1, bottomRectY, bounds.width - 3, bottomRectHeight); + } + + // 8 - right bottom gradient (shadow/highlight) + graphics.setBackground(palette.getColors()[11]); + if (palette.getColors()[10] != null) { + graphics.setForeground(palette.getColors()[10]); + graphics.fillGradientRectangle(x + bounds.width - 2, bottomRectY, 1, bottomRectHeight, true); + } else { + graphics.fillRectangle(x + bounds.width - 2, bottomRectY, 1, bottomRectHeight); + } + + // 9 - right bottom cell border + graphics.setBackground(palette.getColors()[13]); + if (palette.getColors()[12] != null) { + graphics.setForeground(palette.getColors()[12]); + graphics.fillGradientRectangle(x + bounds.width - 1, bottomRectY, 1, bottomRectHeight, true); + } else { + graphics.fillRectangle(x + bounds.width - 1, bottomRectY, 1, bottomRectHeight); + } + + // 10 - bottom shadow + graphics.setForeground(palette.getColors()[14]); + graphics.drawLine(x, y + bounds.height - 2, x + bounds.width - 1, y + bounds.height - 2); + + // 11 - bottom cell border + graphics.setForeground(palette.getColors()[15]); + graphics.drawLine(x, y + bounds.height - 1, x + bounds.width - 1, y + bounds.height - 1); + } + } \ No newline at end of file diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7EmptyColumnHeaderRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7EmptyColumnHeaderRenderer.java index ea19308dd..aced35708 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7EmptyColumnHeaderRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7EmptyColumnHeaderRenderer.java @@ -1,55 +1,55 @@ -package org.eclipse.nebula.widgets.grid.internal.win7; - -import org.eclipse.nebula.widgets.grid.AbstractRenderer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Display; - -/** - * Empty column header renderer which emulates a default Win7 L&F. This - * implementation does not take into account any theme(s) applied to the OS and - * only used a pre-defined set of normalColors that seem to "mostly" match the - * default theme of Win7 normalColors. - */ -public class Win7EmptyColumnHeaderRenderer extends AbstractRenderer { - - private Win7PaletteProvider palette; - - /** - * @param palette - */ - public Win7EmptyColumnHeaderRenderer(Win7PaletteProvider palette) { - this.palette = palette; - } - - /** - * {@inheritDoc} - */ - public Point computeSize(GC gc, int wHint, int hHint, Object value) { - return new Point(wHint, hHint); - } - - /** - * Set the display for the renderer - * - * @param d - * Display - */ - public void setDisplay(Display d) { - super.setDisplay(d); - palette.initializePalette(getDisplay(), Win7PaletteProvider.NORMAL_GRID_COLUMN_HEADER); - } - - /** - * {@inheritDoc} - */ - public void paint(GC gc, Object value) { - Win7ColumnHeaderUtil.drawColumn(gc, getBounds(), palette, false, false, false); - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - - } - +package org.eclipse.nebula.widgets.grid.internal.win7; + +import org.eclipse.nebula.widgets.grid.AbstractRenderer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Display; + +/** + * Empty column header renderer which emulates a default Win7 L&F. This + * implementation does not take into account any theme(s) applied to the OS and + * only used a pre-defined set of normalColors that seem to "mostly" match the + * default theme of Win7 normalColors. + */ +public class Win7EmptyColumnHeaderRenderer extends AbstractRenderer { + + private Win7PaletteProvider palette; + + /** + * @param palette + */ + public Win7EmptyColumnHeaderRenderer(Win7PaletteProvider palette) { + this.palette = palette; + } + + /** + * {@inheritDoc} + */ + public Point computeSize(GC gc, int wHint, int hHint, Object value) { + return new Point(wHint, hHint); + } + + /** + * Set the display for the renderer + * + * @param d + * Display + */ + public void setDisplay(Display d) { + super.setDisplay(d); + palette.initializePalette(getDisplay(), Win7PaletteProvider.NORMAL_GRID_COLUMN_HEADER); + } + + /** + * {@inheritDoc} + */ + public void paint(GC gc, Object value) { + Win7ColumnHeaderUtil.drawColumn(gc, getBounds(), palette, false, false, false); + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + + } + } \ No newline at end of file diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7GridColumnHeaderRenderer.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7GridColumnHeaderRenderer.java index b824eb0d5..8700cb2fa 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7GridColumnHeaderRenderer.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7GridColumnHeaderRenderer.java @@ -1,300 +1,300 @@ -package org.eclipse.nebula.widgets.grid.internal.win7; - -import org.eclipse.nebula.widgets.grid.GridColumn; -import org.eclipse.nebula.widgets.grid.internal.DefaultColumnHeaderRenderer; -import org.eclipse.nebula.widgets.grid.internal.SortArrowRenderer; -import org.eclipse.nebula.widgets.grid.internal.TextUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.graphics.TextLayout; -import org.eclipse.swt.widgets.Display; - -/** - * Column header renderer which emulates a default Win7 L&F. - * This implementation does not take into account any theme(s) applied to the OS and only used - * a pre-defined set of normalColors that seem to "mostly" match the default theme of Win7 normalColors. - */ -public class Win7GridColumnHeaderRenderer extends DefaultColumnHeaderRenderer { - - int leftMargin = 6; - - int rightMargin = 6; - - int topMargin = 3; - - int bottomMargin = 3; - - int arrowMargin = 6; - - int imageSpacing = 3; - - - private SortArrowRenderer arrowRenderer = new SortArrowRenderer(); - - private TextLayout textLayout; - - private Win7PaletteProvider palette; - - private int truncationStyle = SWT.CENTER; - - /** - * @param palette - */ - public Win7GridColumnHeaderRenderer(Win7PaletteProvider palette) { - this.palette = palette; - } - - /** - * Set the display for the renderer - * @param d Display - */ - public void setDisplay(Display d) { - super.setDisplay(d); - arrowRenderer.setDisplay(d); - palette.initializePalette(getDisplay(), Win7PaletteProvider.NORMAL_GRID_COLUMN_HEADER); - palette.initializePalette(getDisplay(), Win7PaletteProvider.HOVER_GRID_COLUMN_HEADER); - palette.initializePalette(getDisplay(), Win7PaletteProvider.MOUSEDOWN_GRID_COLUMN_HEADER); - palette.initializePalette(getDisplay(), Win7PaletteProvider.SELECTED_GRID_COLUMN_HEADER); - } - - - /** - * {@inheritDoc} - */ - public void paint(GC gc, Object value) { - GridColumn column = (GridColumn) value; - - // set the font to be used to display the text. - gc.setFont(column.getHeaderFont()); - - // workaround until the hover logic in the grid's onMouseExit is resolved - boolean isHover = isHover();// && getDisplay().getCursorControl() == column.getParent(); - boolean isMouseDown = isMouseDown() && isHover; - boolean isSelected = isSelected(); - - - Win7ColumnHeaderUtil.drawColumn(gc, getBounds(), palette, isHover, isSelected, isMouseDown); - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); - gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - - int pushedDrawingOffset = 0; - - int x = leftMargin; - - int width = getBounds().width - x; - - if (column.getSort() == SWT.NONE) { - width -= rightMargin; - } else { - width -= arrowMargin + arrowRenderer.getSize().x + arrowMargin; - } - - int y = bottomMargin; - - if (column.getHeaderControl() == null) { - y = getBounds().y + getBounds().height - bottomMargin - gc.getFontMetrics().getHeight(); - } else { - y = getBounds().y + getBounds().height - bottomMargin - gc.getFontMetrics().getHeight() - computeControlSize(column).y; - } - - String text = column.getText(); - - if (!isWordWrap()) { - text = TextUtils.getShortStr(gc, text, width,truncationStyle); - } - - if (column.getAlignment() == SWT.RIGHT) { - int len = gc.stringExtent(text).x; - if (len < width) { - x += width - len; - } - } else if (column.getAlignment() == SWT.CENTER) { - int len = gc.stringExtent(text).x; - if (len < width) { - x += (width - len) / 2; - } - } - - if (!isWordWrap()) { - gc.drawString(text, getBounds().x + x + pushedDrawingOffset, y + pushedDrawingOffset, true); - } else { - getTextLayout(gc, column); - textLayout.setWidth(width < 1 ? 1 : width); - textLayout.setText(text); - y -= textLayout.getBounds().height; - - // remove the first line shift - y = gc.getFontMetrics().getHeight(); - - if (column.getParent().isAutoHeight()) { - column.getParent().recalculateHeader(); - } - textLayout.draw(gc, getBounds().x + x + pushedDrawingOffset, y + pushedDrawingOffset); - } - - if (column.getSort() != SWT.NONE) { - if (column.getHeaderControl() == null) { - y = getBounds().y + ((getBounds().height - arrowRenderer.getBounds().height) / 2) + 1; - } else { - y = getBounds().y + ((getBounds().height - computeControlSize(column).y - arrowRenderer.getBounds().height) / 2) + 1; - } - - arrowRenderer.setSelected(column.getSort() == SWT.UP); - if (isMouseDown && isHover) { - arrowRenderer.setLocation(getBounds().x + getBounds().width - arrowMargin - arrowRenderer.getBounds().width + 1, y); - } else { - if (column.getHeaderControl() == null) { - y = getBounds().y + ((getBounds().height - arrowRenderer.getBounds().height) / 2); - } else { - y = getBounds().y + ((getBounds().height - computeControlSize(column).y - arrowRenderer.getBounds().height) / 2); - } - arrowRenderer.setLocation(getBounds().x + getBounds().width - arrowMargin - arrowRenderer.getBounds().width, y); - } - arrowRenderer.paint(gc, null); - } - } - - /** - * Draw an additional shadow for the selected column state - * @param graphics - * @param bounds - * @param colors - */ - protected static void drawColumnSelectedTopShadow(GC graphics, Rectangle bounds, Color[] colors){ - int x = bounds.x; - int y = bounds.y; - - graphics.setForeground(colors[0]); - graphics.drawLine(x+1, y+1, x+bounds.width-2, y+1); - graphics.setForeground(colors[1]); - graphics.drawLine(x+1, y+2, x+bounds.width-2, y+2); - } - - - /** - * Draw the column header based on the given colors - * @param graphics - * @param bounds - * @param colors - */ - protected static void drawColumnHeader(GC graphics, Rectangle bounds, Color[] colors){ - int x = bounds.x; - int y = bounds.y; - - int topRectHeight = (int)Math.round((bounds.height-3)*.45); - int bottomRectHeight = bounds.height-3-topRectHeight; - int bottomRectY = y+topRectHeight+1; - - //1 - top highlight - graphics.setForeground(colors[0]); - graphics.drawLine(x, y, x+bounds.width-1, y); - - //2 - left upper - graphics.setBackground(colors[1]); - graphics.fillRectangle(x, y+1, 1, topRectHeight); - - //3 - upper fill - graphics.setBackground(colors[2]); - graphics.fillRectangle(x+1, y+1, bounds.width-3, topRectHeight); - - //4 - right upper - graphics.setBackground(colors[3]); - graphics.fillRectangle(x+bounds.width-2, y+1, 1, topRectHeight); - - //5 - right upper gradient (shadow/highlight) - graphics.setBackground(colors[5]); - if ( colors[4] != null ){ - graphics.setForeground(colors[4]); - graphics.fillGradientRectangle(x+bounds.width-1, y+1, 1, topRectHeight, true); - } else { - graphics.fillRectangle(x+bounds.width-1, y+1, 1, topRectHeight); - } - - //6 - left bottom gradient (shadow/hightlight) - graphics.setBackground(colors[7]); - if ( colors[6] != null ){ - graphics.setForeground(colors[6]); - graphics.fillGradientRectangle(x, bottomRectY, 1, bottomRectHeight, true); - } else { - graphics.fillRectangle(x, bottomRectY, 1, bottomRectHeight); - } - - //7 - bottom fill - graphics.setBackground(colors[9]); - if ( colors[8] != null ){ - graphics.setForeground(colors[8]); - graphics.fillGradientRectangle(x+1, bottomRectY, bounds.width-3, bottomRectHeight, true); - } else { - graphics.fillRectangle(x+1, bottomRectY, bounds.width-3, bottomRectHeight); - } - - //8 - right bottom gradient (shadow/highlight) - graphics.setBackground(colors[11]); - if ( colors[10] != null ){ - graphics.setForeground(colors[10]); - graphics.fillGradientRectangle(x+bounds.width-2, bottomRectY, 1, bottomRectHeight, true); - } else { - graphics.fillRectangle(x+bounds.width-2, bottomRectY, 1, bottomRectHeight); - } - - //9 - right bottom cell border - graphics.setBackground(colors[13]); - if ( colors[12] != null ){ - graphics.setForeground(colors[12]); - graphics.fillGradientRectangle(x+bounds.width-1, bottomRectY, 1, bottomRectHeight, true); - } else { - graphics.fillRectangle(x+bounds.width-1, bottomRectY, 1, bottomRectHeight); - } - - //10 - bottom shadow - graphics.setForeground(colors[14]); - graphics.drawLine(x, y+bounds.height-2, x+bounds.width-1, y+bounds.height-2); - - //11 - bottom cell border - graphics.setForeground(colors[15]); - graphics.drawLine(x, y+bounds.height-1, x+bounds.width-1, y+bounds.height-1); - } - - - - private void getTextLayout(GC gc, GridColumn column) { - if (textLayout == null) { - textLayout = new TextLayout(gc.getDevice()); - textLayout.setFont(gc.getFont()); - column.getParent().addListener(SWT.Dispose, e-> - textLayout.dispose() - ); - } - textLayout.setAlignment(column.getAlignment()); - } - - private Point computeControlSize(GridColumn column) { - if (column.getHeaderControl() != null) { - return column.getHeaderControl().computeSize(SWT.DEFAULT, SWT.DEFAULT); - } - return new Point(0, 0); - } - - /** - * Get the truncation style - * @return the truncation style. - */ - public int getTruncationStyle() { - return truncationStyle; - } - - /** - * Set the truncation style to use when cell content is too large. - * @see SWT#LEFT - * @see SWT#CENTER - * @see SWT#RIGHT - * @param truncationStyle - */ - public void setTruncationStyle(int truncationStyle) { - this.truncationStyle = truncationStyle; - } +package org.eclipse.nebula.widgets.grid.internal.win7; + +import org.eclipse.nebula.widgets.grid.GridColumn; +import org.eclipse.nebula.widgets.grid.internal.DefaultColumnHeaderRenderer; +import org.eclipse.nebula.widgets.grid.internal.SortArrowRenderer; +import org.eclipse.nebula.widgets.grid.internal.TextUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.TextLayout; +import org.eclipse.swt.widgets.Display; + +/** + * Column header renderer which emulates a default Win7 L&F. + * This implementation does not take into account any theme(s) applied to the OS and only used + * a pre-defined set of normalColors that seem to "mostly" match the default theme of Win7 normalColors. + */ +public class Win7GridColumnHeaderRenderer extends DefaultColumnHeaderRenderer { + + int leftMargin = 6; + + int rightMargin = 6; + + int topMargin = 3; + + int bottomMargin = 3; + + int arrowMargin = 6; + + int imageSpacing = 3; + + + private SortArrowRenderer arrowRenderer = new SortArrowRenderer(); + + private TextLayout textLayout; + + private Win7PaletteProvider palette; + + private int truncationStyle = SWT.CENTER; + + /** + * @param palette + */ + public Win7GridColumnHeaderRenderer(Win7PaletteProvider palette) { + this.palette = palette; + } + + /** + * Set the display for the renderer + * @param d Display + */ + public void setDisplay(Display d) { + super.setDisplay(d); + arrowRenderer.setDisplay(d); + palette.initializePalette(getDisplay(), Win7PaletteProvider.NORMAL_GRID_COLUMN_HEADER); + palette.initializePalette(getDisplay(), Win7PaletteProvider.HOVER_GRID_COLUMN_HEADER); + palette.initializePalette(getDisplay(), Win7PaletteProvider.MOUSEDOWN_GRID_COLUMN_HEADER); + palette.initializePalette(getDisplay(), Win7PaletteProvider.SELECTED_GRID_COLUMN_HEADER); + } + + + /** + * {@inheritDoc} + */ + public void paint(GC gc, Object value) { + GridColumn column = (GridColumn) value; + + // set the font to be used to display the text. + gc.setFont(column.getHeaderFont()); + + // workaround until the hover logic in the grid's onMouseExit is resolved + boolean isHover = isHover();// && getDisplay().getCursorControl() == column.getParent(); + boolean isMouseDown = isMouseDown() && isHover; + boolean isSelected = isSelected(); + + + Win7ColumnHeaderUtil.drawColumn(gc, getBounds(), palette, isHover, isSelected, isMouseDown); + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + + int pushedDrawingOffset = 0; + + int x = leftMargin; + + int width = getBounds().width - x; + + if (column.getSort() == SWT.NONE) { + width -= rightMargin; + } else { + width -= arrowMargin + arrowRenderer.getSize().x + arrowMargin; + } + + int y = bottomMargin; + + if (column.getHeaderControl() == null) { + y = getBounds().y + getBounds().height - bottomMargin - gc.getFontMetrics().getHeight(); + } else { + y = getBounds().y + getBounds().height - bottomMargin - gc.getFontMetrics().getHeight() - computeControlSize(column).y; + } + + String text = column.getText(); + + if (!isWordWrap()) { + text = TextUtils.getShortStr(gc, text, width,truncationStyle); + } + + if (column.getAlignment() == SWT.RIGHT) { + int len = gc.stringExtent(text).x; + if (len < width) { + x += width - len; + } + } else if (column.getAlignment() == SWT.CENTER) { + int len = gc.stringExtent(text).x; + if (len < width) { + x += (width - len) / 2; + } + } + + if (!isWordWrap()) { + gc.drawString(text, getBounds().x + x + pushedDrawingOffset, y + pushedDrawingOffset, true); + } else { + getTextLayout(gc, column); + textLayout.setWidth(width < 1 ? 1 : width); + textLayout.setText(text); + y -= textLayout.getBounds().height; + + // remove the first line shift + y = gc.getFontMetrics().getHeight(); + + if (column.getParent().isAutoHeight()) { + column.getParent().recalculateHeader(); + } + textLayout.draw(gc, getBounds().x + x + pushedDrawingOffset, y + pushedDrawingOffset); + } + + if (column.getSort() != SWT.NONE) { + if (column.getHeaderControl() == null) { + y = getBounds().y + ((getBounds().height - arrowRenderer.getBounds().height) / 2) + 1; + } else { + y = getBounds().y + ((getBounds().height - computeControlSize(column).y - arrowRenderer.getBounds().height) / 2) + 1; + } + + arrowRenderer.setSelected(column.getSort() == SWT.UP); + if (isMouseDown && isHover) { + arrowRenderer.setLocation(getBounds().x + getBounds().width - arrowMargin - arrowRenderer.getBounds().width + 1, y); + } else { + if (column.getHeaderControl() == null) { + y = getBounds().y + ((getBounds().height - arrowRenderer.getBounds().height) / 2); + } else { + y = getBounds().y + ((getBounds().height - computeControlSize(column).y - arrowRenderer.getBounds().height) / 2); + } + arrowRenderer.setLocation(getBounds().x + getBounds().width - arrowMargin - arrowRenderer.getBounds().width, y); + } + arrowRenderer.paint(gc, null); + } + } + + /** + * Draw an additional shadow for the selected column state + * @param graphics + * @param bounds + * @param colors + */ + protected static void drawColumnSelectedTopShadow(GC graphics, Rectangle bounds, Color[] colors){ + int x = bounds.x; + int y = bounds.y; + + graphics.setForeground(colors[0]); + graphics.drawLine(x+1, y+1, x+bounds.width-2, y+1); + graphics.setForeground(colors[1]); + graphics.drawLine(x+1, y+2, x+bounds.width-2, y+2); + } + + + /** + * Draw the column header based on the given colors + * @param graphics + * @param bounds + * @param colors + */ + protected static void drawColumnHeader(GC graphics, Rectangle bounds, Color[] colors){ + int x = bounds.x; + int y = bounds.y; + + int topRectHeight = (int)Math.round((bounds.height-3)*.45); + int bottomRectHeight = bounds.height-3-topRectHeight; + int bottomRectY = y+topRectHeight+1; + + //1 - top highlight + graphics.setForeground(colors[0]); + graphics.drawLine(x, y, x+bounds.width-1, y); + + //2 - left upper + graphics.setBackground(colors[1]); + graphics.fillRectangle(x, y+1, 1, topRectHeight); + + //3 - upper fill + graphics.setBackground(colors[2]); + graphics.fillRectangle(x+1, y+1, bounds.width-3, topRectHeight); + + //4 - right upper + graphics.setBackground(colors[3]); + graphics.fillRectangle(x+bounds.width-2, y+1, 1, topRectHeight); + + //5 - right upper gradient (shadow/highlight) + graphics.setBackground(colors[5]); + if ( colors[4] != null ){ + graphics.setForeground(colors[4]); + graphics.fillGradientRectangle(x+bounds.width-1, y+1, 1, topRectHeight, true); + } else { + graphics.fillRectangle(x+bounds.width-1, y+1, 1, topRectHeight); + } + + //6 - left bottom gradient (shadow/hightlight) + graphics.setBackground(colors[7]); + if ( colors[6] != null ){ + graphics.setForeground(colors[6]); + graphics.fillGradientRectangle(x, bottomRectY, 1, bottomRectHeight, true); + } else { + graphics.fillRectangle(x, bottomRectY, 1, bottomRectHeight); + } + + //7 - bottom fill + graphics.setBackground(colors[9]); + if ( colors[8] != null ){ + graphics.setForeground(colors[8]); + graphics.fillGradientRectangle(x+1, bottomRectY, bounds.width-3, bottomRectHeight, true); + } else { + graphics.fillRectangle(x+1, bottomRectY, bounds.width-3, bottomRectHeight); + } + + //8 - right bottom gradient (shadow/highlight) + graphics.setBackground(colors[11]); + if ( colors[10] != null ){ + graphics.setForeground(colors[10]); + graphics.fillGradientRectangle(x+bounds.width-2, bottomRectY, 1, bottomRectHeight, true); + } else { + graphics.fillRectangle(x+bounds.width-2, bottomRectY, 1, bottomRectHeight); + } + + //9 - right bottom cell border + graphics.setBackground(colors[13]); + if ( colors[12] != null ){ + graphics.setForeground(colors[12]); + graphics.fillGradientRectangle(x+bounds.width-1, bottomRectY, 1, bottomRectHeight, true); + } else { + graphics.fillRectangle(x+bounds.width-1, bottomRectY, 1, bottomRectHeight); + } + + //10 - bottom shadow + graphics.setForeground(colors[14]); + graphics.drawLine(x, y+bounds.height-2, x+bounds.width-1, y+bounds.height-2); + + //11 - bottom cell border + graphics.setForeground(colors[15]); + graphics.drawLine(x, y+bounds.height-1, x+bounds.width-1, y+bounds.height-1); + } + + + + private void getTextLayout(GC gc, GridColumn column) { + if (textLayout == null) { + textLayout = new TextLayout(gc.getDevice()); + textLayout.setFont(gc.getFont()); + column.getParent().addListener(SWT.Dispose, e-> + textLayout.dispose() + ); + } + textLayout.setAlignment(column.getAlignment()); + } + + private Point computeControlSize(GridColumn column) { + if (column.getHeaderControl() != null) { + return column.getHeaderControl().computeSize(SWT.DEFAULT, SWT.DEFAULT); + } + return new Point(0, 0); + } + + /** + * Get the truncation style + * @return the truncation style. + */ + public int getTruncationStyle() { + return truncationStyle; + } + + /** + * Set the truncation style to use when cell content is too large. + * @see SWT#LEFT + * @see SWT#CENTER + * @see SWT#RIGHT + * @param truncationStyle + */ + public void setTruncationStyle(int truncationStyle) { + this.truncationStyle = truncationStyle; + } } \ No newline at end of file diff --git a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7PaletteProvider.java b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7PaletteProvider.java index 7f133fe5c..71cd16e15 100644 --- a/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7PaletteProvider.java +++ b/widgets/grid/org.eclipse.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/win7/Win7PaletteProvider.java @@ -1,241 +1,241 @@ -package org.eclipse.nebula.widgets.grid.internal.win7; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Display; - -/** - * Palette provider to provide/maintain a set of palettes - * specifically used for Win7 looknfeel - */ -public class Win7PaletteProvider { - - /** - * - */ - public static final Integer NORMAL_GRID_COLUMN_HEADER = new Integer(0); - - private static final Object[] NORMAL_GRID_COLUMN_HEADER_RGB = new Object[]{ - new Integer(SWT.COLOR_WHITE), - new Integer(SWT.COLOR_WHITE), - new Integer(SWT.COLOR_WHITE), - new Integer(SWT.COLOR_WHITE), - new RGB(242,242,242), - new RGB(239,239,239), - new RGB(251,251,252), - new RGB(247,248,249), - new RGB(247,248,250), - new RGB(241,242,244), - new RGB(252,252,253), - new RGB(251,251,252), - new RGB(231,232,234), - new RGB(222,223,225), - new RGB(213,213,213), - new RGB(251,251,251) - }; - - /** - * - */ - public static final Integer HOVER_GRID_COLUMN_HEADER = new Integer(1); - - private static final Object[] HOVER_GRID_COLUMN_HEADER_RGB = new Object[]{ - new Integer(SWT.COLOR_WHITE), - new RGB(136,203,235), - new RGB(227,247,255), - new RGB(227,247,255), - null, - new RGB(136,203,235), - null, - new RGB(105,187,227), - null, - new RGB(183,231,251), - null, - new RGB(183,231,251), - null, - new RGB(105,187,227), - new RGB(147,201,227), - new RGB(251,251,251) - }; - - /** - * - */ - public static final Integer MOUSEDOWN_GRID_COLUMN_HEADER = new Integer(3); - - private static final Object[] MOUSEDOWN_GRID_COLUMN_HEADER_RGB = new Object[]{ - new Integer(SWT.COLOR_WHITE), - new RGB(122,158,177), - new RGB(188,228,249), - new RGB(162,203,224), - null, - new RGB(122,158,177), - new RGB(80,145,175), - new RGB(77,141,173), - new RGB(141,214,247), - new RGB(138,209,245), - new RGB(114,188,223), - new RGB(110,184,220), - new RGB(80,145,175), - new RGB(77,141,173), - new RGB(147,201,227), - new RGB(251,251,251) - }; - - - /** - * - */ - public static final Integer SELECTED_GRID_COLUMN_HEADER = new Integer(3); - - private static final Object[] SELECTED_GRID_COLUMN_HEADER_RGB = new Object[]{ - new Integer(SWT.COLOR_WHITE), - new RGB(150,217,249), - new RGB(242,249,252), - new RGB(242,249,252), - null, - new RGB(150,217,249), - null, - new RGB(150,217,249), - new RGB(225,241,249), - new RGB(216,236,246), - new RGB(225,241,249), - new RGB(216,236,246), - null, - new RGB(150,217,249), - new RGB(150,217,249), - new Integer(SWT.COLOR_WHITE) - }; - - - /** - * - */ - public static final Integer SHADOW_GRID_COLUMN_HEADER = new Integer(4); - - private static final Object[] SHADOW_GRID_COLUMN_HEADER_RGB = new Object[]{ - new RGB(134,163,178), - new RGB(170,206,225) - }; - - /** - * Pool of palettes - */ - private Map palettes = new HashMap<>(); - - /** - * Dispose the - */ - public void dispose(){ - for ( Iterator it = palettes.values().iterator() ; it.hasNext() ; ){ - it.next().dispose(); - } - } - - /** - * @param display - * @param type - */ - public void initializePalette(Display display, Integer type){ - getPalette(display, type); - } - - /** - * Utility method to create/pool a Color - * @param display - * @param type - * @return Color - */ - public Palette getPalette(Display display, Integer type){ - Palette palette = palettes.get(type); - if ( palette != null ) - return palette; - - //create the palette - if ( type == NORMAL_GRID_COLUMN_HEADER ){ - return createPalette(display,type,NORMAL_GRID_COLUMN_HEADER_RGB); - } else if ( type == HOVER_GRID_COLUMN_HEADER ){ - return createPalette(display,type,HOVER_GRID_COLUMN_HEADER_RGB); - } else if ( type == MOUSEDOWN_GRID_COLUMN_HEADER ){ - return createPalette(display,type,MOUSEDOWN_GRID_COLUMN_HEADER_RGB); - } else if ( type == SHADOW_GRID_COLUMN_HEADER ){ - return createPalette(display,type,SHADOW_GRID_COLUMN_HEADER_RGB); - } else if ( type == SELECTED_GRID_COLUMN_HEADER ){ - return createPalette(display,type,SELECTED_GRID_COLUMN_HEADER_RGB); - } - return null; - } - - - /** - * @param display - * @param type - * @param def - * @return Palette - */ - protected Palette createPalette(Display display, Integer type, Object[] def){ - Color[] colors = new Color[def.length]; - for ( int i = 0 ; i < colors.length ; i++ ){ - if ( def[i] == null ){ - colors[i] = null; - } else if ( def[i] instanceof Integer ){ - colors[i] = (display==null?Display.getCurrent():display).getSystemColor(((Integer)def[i]).intValue()); - } else { - colors[i] = new Color(display, (RGB)def[i]); - } - } - return new Palette(type, colors); - } - - - /** - * - */ - public class Palette { - - private Integer type; - private Color[] colors = new Color[]{}; - - /** - * @param type - * @param colors - */ - public Palette(Integer type, Color[] colors) { - this.type = type; - this.colors = colors; - } - - /** - * @return int - */ - public Integer getType() { - return type; - } - - /** - * @return Color[] - */ - public Color[] getColors(){ - return colors; - } - - /** - * Dispose colors - */ - public void dispose(){ - if ( colors != null ){ - for ( int i = 0 ; i < colors.length ; i++ ){ - if ( colors[i] != null ) - colors[i].dispose(); - } - } - } - - } - +package org.eclipse.nebula.widgets.grid.internal.win7; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +/** + * Palette provider to provide/maintain a set of palettes + * specifically used for Win7 looknfeel + */ +public class Win7PaletteProvider { + + /** + * + */ + public static final Integer NORMAL_GRID_COLUMN_HEADER = new Integer(0); + + private static final Object[] NORMAL_GRID_COLUMN_HEADER_RGB = new Object[]{ + new Integer(SWT.COLOR_WHITE), + new Integer(SWT.COLOR_WHITE), + new Integer(SWT.COLOR_WHITE), + new Integer(SWT.COLOR_WHITE), + new RGB(242,242,242), + new RGB(239,239,239), + new RGB(251,251,252), + new RGB(247,248,249), + new RGB(247,248,250), + new RGB(241,242,244), + new RGB(252,252,253), + new RGB(251,251,252), + new RGB(231,232,234), + new RGB(222,223,225), + new RGB(213,213,213), + new RGB(251,251,251) + }; + + /** + * + */ + public static final Integer HOVER_GRID_COLUMN_HEADER = new Integer(1); + + private static final Object[] HOVER_GRID_COLUMN_HEADER_RGB = new Object[]{ + new Integer(SWT.COLOR_WHITE), + new RGB(136,203,235), + new RGB(227,247,255), + new RGB(227,247,255), + null, + new RGB(136,203,235), + null, + new RGB(105,187,227), + null, + new RGB(183,231,251), + null, + new RGB(183,231,251), + null, + new RGB(105,187,227), + new RGB(147,201,227), + new RGB(251,251,251) + }; + + /** + * + */ + public static final Integer MOUSEDOWN_GRID_COLUMN_HEADER = new Integer(3); + + private static final Object[] MOUSEDOWN_GRID_COLUMN_HEADER_RGB = new Object[]{ + new Integer(SWT.COLOR_WHITE), + new RGB(122,158,177), + new RGB(188,228,249), + new RGB(162,203,224), + null, + new RGB(122,158,177), + new RGB(80,145,175), + new RGB(77,141,173), + new RGB(141,214,247), + new RGB(138,209,245), + new RGB(114,188,223), + new RGB(110,184,220), + new RGB(80,145,175), + new RGB(77,141,173), + new RGB(147,201,227), + new RGB(251,251,251) + }; + + + /** + * + */ + public static final Integer SELECTED_GRID_COLUMN_HEADER = new Integer(3); + + private static final Object[] SELECTED_GRID_COLUMN_HEADER_RGB = new Object[]{ + new Integer(SWT.COLOR_WHITE), + new RGB(150,217,249), + new RGB(242,249,252), + new RGB(242,249,252), + null, + new RGB(150,217,249), + null, + new RGB(150,217,249), + new RGB(225,241,249), + new RGB(216,236,246), + new RGB(225,241,249), + new RGB(216,236,246), + null, + new RGB(150,217,249), + new RGB(150,217,249), + new Integer(SWT.COLOR_WHITE) + }; + + + /** + * + */ + public static final Integer SHADOW_GRID_COLUMN_HEADER = new Integer(4); + + private static final Object[] SHADOW_GRID_COLUMN_HEADER_RGB = new Object[]{ + new RGB(134,163,178), + new RGB(170,206,225) + }; + + /** + * Pool of palettes + */ + private Map palettes = new HashMap<>(); + + /** + * Dispose the + */ + public void dispose(){ + for ( Iterator it = palettes.values().iterator() ; it.hasNext() ; ){ + it.next().dispose(); + } + } + + /** + * @param display + * @param type + */ + public void initializePalette(Display display, Integer type){ + getPalette(display, type); + } + + /** + * Utility method to create/pool a Color + * @param display + * @param type + * @return Color + */ + public Palette getPalette(Display display, Integer type){ + Palette palette = palettes.get(type); + if ( palette != null ) + return palette; + + //create the palette + if ( type == NORMAL_GRID_COLUMN_HEADER ){ + return createPalette(display,type,NORMAL_GRID_COLUMN_HEADER_RGB); + } else if ( type == HOVER_GRID_COLUMN_HEADER ){ + return createPalette(display,type,HOVER_GRID_COLUMN_HEADER_RGB); + } else if ( type == MOUSEDOWN_GRID_COLUMN_HEADER ){ + return createPalette(display,type,MOUSEDOWN_GRID_COLUMN_HEADER_RGB); + } else if ( type == SHADOW_GRID_COLUMN_HEADER ){ + return createPalette(display,type,SHADOW_GRID_COLUMN_HEADER_RGB); + } else if ( type == SELECTED_GRID_COLUMN_HEADER ){ + return createPalette(display,type,SELECTED_GRID_COLUMN_HEADER_RGB); + } + return null; + } + + + /** + * @param display + * @param type + * @param def + * @return Palette + */ + protected Palette createPalette(Display display, Integer type, Object[] def){ + Color[] colors = new Color[def.length]; + for ( int i = 0 ; i < colors.length ; i++ ){ + if ( def[i] == null ){ + colors[i] = null; + } else if ( def[i] instanceof Integer ){ + colors[i] = (display==null?Display.getCurrent():display).getSystemColor(((Integer)def[i]).intValue()); + } else { + colors[i] = new Color(display, (RGB)def[i]); + } + } + return new Palette(type, colors); + } + + + /** + * + */ + public class Palette { + + private Integer type; + private Color[] colors = new Color[]{}; + + /** + * @param type + * @param colors + */ + public Palette(Integer type, Color[] colors) { + this.type = type; + this.colors = colors; + } + + /** + * @return int + */ + public Integer getType() { + return type; + } + + /** + * @return Color[] + */ + public Color[] getColors(){ + return colors; + } + + /** + * Dispose colors + */ + public void dispose(){ + if ( colors != null ){ + for ( int i = 0 ; i < colors.length ; i++ ){ + if ( colors[i] != null ) + colors[i].dispose(); + } + } + } + + } + } \ No newline at end of file diff --git a/widgets/grid/pom.xml b/widgets/grid/pom.xml index 71baa26f6..4cb399d0c 100644 --- a/widgets/grid/pom.xml +++ b/widgets/grid/pom.xml @@ -1,26 +1,26 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - nebula-parent - ../../releng/org.eclipse.nebula.nebula-parent - - - grid - 1.1.0-SNAPSHOT - pom - - - org.eclipse.nebula.widgets.grid - org.eclipse.nebula.widgets.grid.example - org.eclipse.nebula.widgets.grid.feature - org.eclipse.nebula.widgets.grid.css - org.eclipse.nebula.widgets.grid.css.feature - org.eclipse.nebula.widgets.grid.example.e4 - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + nebula-parent + ../../releng/org.eclipse.nebula.nebula-parent + + + grid + 1.1.0-SNAPSHOT + pom + + + org.eclipse.nebula.widgets.grid + org.eclipse.nebula.widgets.grid.example + org.eclipse.nebula.widgets.grid.feature + org.eclipse.nebula.widgets.grid.css + org.eclipse.nebula.widgets.grid.css.feature + org.eclipse.nebula.widgets.grid.example.e4 + + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led.feature/.project b/widgets/led/org.eclipse.nebula.widgets.led.feature/.project index 201e19bea..573e19ce6 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.feature/.project +++ b/widgets/led/org.eclipse.nebula.widgets.led.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.led.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.led.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led.feature/build.properties b/widgets/led/org.eclipse.nebula.widgets.led.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.feature/build.properties +++ b/widgets/led/org.eclipse.nebula.widgets.led.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/led/org.eclipse.nebula.widgets.led.feature/feature.properties b/widgets/led/org.eclipse.nebula.widgets.led.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.feature/feature.properties +++ b/widgets/led/org.eclipse.nebula.widgets.led.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/led/org.eclipse.nebula.widgets.led.feature/feature.xml b/widgets/led/org.eclipse.nebula.widgets.led.feature/feature.xml index 89d96d185..de729e51d 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.feature/feature.xml +++ b/widgets/led/org.eclipse.nebula.widgets.led.feature/feature.xml @@ -1,34 +1,34 @@ - - - - - LED - - - - %license - - - - - - - - - - - + + + + + LED + + + + %license + + + + + + + + + + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led.feature/pom.xml b/widgets/led/org.eclipse.nebula.widgets.led.feature/pom.xml index ec73fa59a..18b0b388f 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.feature/pom.xml +++ b/widgets/led/org.eclipse.nebula.widgets.led.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - led - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.led.feature - eclipse-feature - 1.0.0-SNAPSHOT - - Nebula Badged Label Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + led + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.led.feature + eclipse-feature + 1.0.0-SNAPSHOT + + Nebula Badged Label Feature + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led.snippets/.classpath b/widgets/led/org.eclipse.nebula.widgets.led.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.snippets/.classpath +++ b/widgets/led/org.eclipse.nebula.widgets.led.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led.snippets/.project b/widgets/led/org.eclipse.nebula.widgets.led.snippets/.project index 33205f47a..8398572c9 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.snippets/.project +++ b/widgets/led/org.eclipse.nebula.widgets.led.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.led.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.led.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/led/org.eclipse.nebula.widgets.led.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/led/org.eclipse.nebula.widgets.led.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/led/org.eclipse.nebula.widgets.led.snippets/META-INF/MANIFEST.MF b/widgets/led/org.eclipse.nebula.widgets.led.snippets/META-INF/MANIFEST.MF index f7948b4f7..c5b083b7f 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.snippets/META-INF/MANIFEST.MF +++ b/widgets/led/org.eclipse.nebula.widgets.led.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula LED Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.led.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.led;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.led.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula LED Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.led.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.led;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.led.snippets diff --git a/widgets/led/org.eclipse.nebula.widgets.led.snippets/build.properties b/widgets/led/org.eclipse.nebula.widgets.led.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.snippets/build.properties +++ b/widgets/led/org.eclipse.nebula.widgets.led.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/led/org.eclipse.nebula.widgets.led.snippets/pom.xml b/widgets/led/org.eclipse.nebula.widgets.led.snippets/pom.xml index 8ac3bcedd..63ec57294 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.snippets/pom.xml +++ b/widgets/led/org.eclipse.nebula.widgets.led.snippets/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - led - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.led.snippets - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + led + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.led.snippets + eclipse-plugin + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led.snippets/src/org/eclipse/nebula/widgets/led/LEDSnippet.java b/widgets/led/org.eclipse.nebula.widgets.led.snippets/src/org/eclipse/nebula/widgets/led/LEDSnippet.java index 6635a8f08..02cbd3eda 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led.snippets/src/org/eclipse/nebula/widgets/led/LEDSnippet.java +++ b/widgets/led/org.eclipse.nebula.widgets.led.snippets/src/org/eclipse/nebula/widgets/led/LEDSnippet.java @@ -1,203 +1,203 @@ -/******************************************************************************* - * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.led; - -import java.time.LocalDateTime; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * Snippet for the LED widget - */ -public class LEDSnippet { - private static Shell shell; - - /** - * @param args - */ - public static void main(final String[] args) { - final Display display = new Display(); - shell = new Shell(display); - shell.setText("LED Snippet"); - shell.setLayout(new GridLayout(1, true)); - shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); - - createTopPart(); - createBottomPart(); - - shell.pack(); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - display.dispose(); - - } - - private static void createTopPart() { - new Label(shell, SWT.NONE); - Composite top = new Composite(shell, SWT.NONE); - top.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); - top.setLayout(new GridLayout(2, true)); - - LED led = new LED(top, SWT.ICON); - led.setLayoutData(new GridData(GridData.END, GridData.FILL, true, true, 1, 2)); - led.setCharacter(LEDCharacter.CLEAR); - Color idleColor = new Color(shell.getDisplay(), 60, 60, 60); - led.setIdleColor(idleColor); - SWTGraphicUtil.addDisposer(led, idleColor); - - Color selectedColor = new Color(shell.getDisplay(), 255, 0, 0); - led.setSelectedColor(selectedColor); - SWTGraphicUtil.addDisposer(led, selectedColor); - - Combo combo = new Combo(top, SWT.READ_ONLY); - GridData gdCombo = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); - gdCombo.minimumWidth = 100; - combo.setLayoutData(gdCombo); - for (LEDCharacter element : LEDCharacter.values()) { - combo.add(element.name()); - } - combo.setText("CLEAR"); - combo.addListener(SWT.Selection, e -> { - LEDCharacter c = LEDCharacter.valueOf(combo.getText()); - led.setCharacter(c); - }); - - Button checkBox = new Button(top, SWT.CHECK); - checkBox.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); - checkBox.setText("Dot ?"); - checkBox.addListener(SWT.Selection, e -> { - led.setShowDot(checkBox.getSelection()); - }); - - new Label(shell, SWT.NONE); - } - - private static void createBottomPart() { - Composite bottom = new Composite(shell, SWT.NONE); - bottom.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); - bottom.setLayout(new GridLayout(8, false)); - bottom.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); - - // Date - LED day1 = new LED(bottom, SWT.NONE); - day1.setLayoutData(new GridData(GridData.END, GridData.FILL, true, false)); - - LED day2 = new LED(bottom, SWT.NONE); - day2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LEDSeparator dash1 = new LEDSeparator(bottom, SWT.NONE); - dash1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LED month1 = new LED(bottom, SWT.NONE); - month1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LED month2 = new LED(bottom, SWT.NONE); - month2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LEDSeparator dash2 = new LEDSeparator(bottom, SWT.NONE); - dash2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LED year1 = new LED(bottom, SWT.NONE); - year1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LED year2 = new LED(bottom, SWT.NONE); - year2.setLayoutData(new GridData(GridData.BEGINNING, GridData.FILL, true, false)); - - // Time - LED hour1 = new LED(bottom, SWT.NONE); - hour1.setLayoutData(new GridData(GridData.END, GridData.FILL, true, false)); - - LED hour2 = new LED(bottom, SWT.NONE); - hour2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - DotsLed dots1 = new DotsLed(bottom, SWT.NONE); - dots1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LED min1 = new LED(bottom, SWT.NONE); - min1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LED min2 = new LED(bottom, SWT.NONE); - min2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - DotsLed dots2 = new DotsLed(bottom, SWT.NONE); - dots2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LED sec1 = new LED(bottom, SWT.NONE); - sec1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - LED sec2 = new LED(bottom, SWT.NONE); - sec2.setLayoutData(new GridData(GridData.BEGINNING, GridData.FILL, true, false)); - - shell.getDisplay().timerExec(0, new Runnable() { - boolean highligtDash = false; - - @Override - public void run() { - LocalDateTime now = LocalDateTime.now(); - - day1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getDayOfMonth()))); - day2.setCharacter(LEDCharacter.getByNumber(now.getDayOfMonth() % 10)); - - month1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getMonthValue()))); - month2.setCharacter(LEDCharacter.getByNumber(now.getMonthValue() % 10)); - - year1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getYear() % 100))); - year2.setCharacter(LEDCharacter.getByNumber(now.getYear() % 10)); - - hour1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getHour()))); - hour2.setCharacter(LEDCharacter.getByNumber(now.getHour() % 10)); - - min1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getMinute()))); - min2.setCharacter(LEDCharacter.getByNumber(now.getMinute() % 10)); - - sec1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getSecond()))); - sec2.setCharacter(LEDCharacter.getByNumber(now.getSecond() % 10)); - - if (highligtDash) { - dots1.switchOn(); - dots2.switchOn(); - } else { - dots1.switchOff(); - dots2.switchOff(); - } - - highligtDash = !highligtDash; - - shell.getDisplay().timerExec(1000, this); - - } - - private int getMajorDigit(int value) { - return (value - (value % 10)) / 10; - } - - }); - - } - -} +/******************************************************************************* + * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.led; + +import java.time.LocalDateTime; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * Snippet for the LED widget + */ +public class LEDSnippet { + private static Shell shell; + + /** + * @param args + */ + public static void main(final String[] args) { + final Display display = new Display(); + shell = new Shell(display); + shell.setText("LED Snippet"); + shell.setLayout(new GridLayout(1, true)); + shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); + + createTopPart(); + createBottomPart(); + + shell.pack(); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + display.dispose(); + + } + + private static void createTopPart() { + new Label(shell, SWT.NONE); + Composite top = new Composite(shell, SWT.NONE); + top.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); + top.setLayout(new GridLayout(2, true)); + + LED led = new LED(top, SWT.ICON); + led.setLayoutData(new GridData(GridData.END, GridData.FILL, true, true, 1, 2)); + led.setCharacter(LEDCharacter.CLEAR); + Color idleColor = new Color(shell.getDisplay(), 60, 60, 60); + led.setIdleColor(idleColor); + SWTGraphicUtil.addDisposer(led, idleColor); + + Color selectedColor = new Color(shell.getDisplay(), 255, 0, 0); + led.setSelectedColor(selectedColor); + SWTGraphicUtil.addDisposer(led, selectedColor); + + Combo combo = new Combo(top, SWT.READ_ONLY); + GridData gdCombo = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); + gdCombo.minimumWidth = 100; + combo.setLayoutData(gdCombo); + for (LEDCharacter element : LEDCharacter.values()) { + combo.add(element.name()); + } + combo.setText("CLEAR"); + combo.addListener(SWT.Selection, e -> { + LEDCharacter c = LEDCharacter.valueOf(combo.getText()); + led.setCharacter(c); + }); + + Button checkBox = new Button(top, SWT.CHECK); + checkBox.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); + checkBox.setText("Dot ?"); + checkBox.addListener(SWT.Selection, e -> { + led.setShowDot(checkBox.getSelection()); + }); + + new Label(shell, SWT.NONE); + } + + private static void createBottomPart() { + Composite bottom = new Composite(shell, SWT.NONE); + bottom.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); + bottom.setLayout(new GridLayout(8, false)); + bottom.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK)); + + // Date + LED day1 = new LED(bottom, SWT.NONE); + day1.setLayoutData(new GridData(GridData.END, GridData.FILL, true, false)); + + LED day2 = new LED(bottom, SWT.NONE); + day2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LEDSeparator dash1 = new LEDSeparator(bottom, SWT.NONE); + dash1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LED month1 = new LED(bottom, SWT.NONE); + month1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LED month2 = new LED(bottom, SWT.NONE); + month2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LEDSeparator dash2 = new LEDSeparator(bottom, SWT.NONE); + dash2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LED year1 = new LED(bottom, SWT.NONE); + year1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LED year2 = new LED(bottom, SWT.NONE); + year2.setLayoutData(new GridData(GridData.BEGINNING, GridData.FILL, true, false)); + + // Time + LED hour1 = new LED(bottom, SWT.NONE); + hour1.setLayoutData(new GridData(GridData.END, GridData.FILL, true, false)); + + LED hour2 = new LED(bottom, SWT.NONE); + hour2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + DotsLed dots1 = new DotsLed(bottom, SWT.NONE); + dots1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LED min1 = new LED(bottom, SWT.NONE); + min1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LED min2 = new LED(bottom, SWT.NONE); + min2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + DotsLed dots2 = new DotsLed(bottom, SWT.NONE); + dots2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LED sec1 = new LED(bottom, SWT.NONE); + sec1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + LED sec2 = new LED(bottom, SWT.NONE); + sec2.setLayoutData(new GridData(GridData.BEGINNING, GridData.FILL, true, false)); + + shell.getDisplay().timerExec(0, new Runnable() { + boolean highligtDash = false; + + @Override + public void run() { + LocalDateTime now = LocalDateTime.now(); + + day1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getDayOfMonth()))); + day2.setCharacter(LEDCharacter.getByNumber(now.getDayOfMonth() % 10)); + + month1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getMonthValue()))); + month2.setCharacter(LEDCharacter.getByNumber(now.getMonthValue() % 10)); + + year1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getYear() % 100))); + year2.setCharacter(LEDCharacter.getByNumber(now.getYear() % 10)); + + hour1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getHour()))); + hour2.setCharacter(LEDCharacter.getByNumber(now.getHour() % 10)); + + min1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getMinute()))); + min2.setCharacter(LEDCharacter.getByNumber(now.getMinute() % 10)); + + sec1.setCharacter(LEDCharacter.getByNumber(getMajorDigit(now.getSecond()))); + sec2.setCharacter(LEDCharacter.getByNumber(now.getSecond() % 10)); + + if (highligtDash) { + dots1.switchOn(); + dots2.switchOn(); + } else { + dots1.switchOff(); + dots2.switchOff(); + } + + highligtDash = !highligtDash; + + shell.getDisplay().timerExec(1000, this); + + } + + private int getMajorDigit(int value) { + return (value - (value % 10)) / 10; + } + + }); + + } + +} diff --git a/widgets/led/org.eclipse.nebula.widgets.led/.classpath b/widgets/led/org.eclipse.nebula.widgets.led/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/.classpath +++ b/widgets/led/org.eclipse.nebula.widgets.led/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led/.project b/widgets/led/org.eclipse.nebula.widgets.led/.project index c539bdd7c..6df274ce8 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/.project +++ b/widgets/led/org.eclipse.nebula.widgets.led/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.led - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.led + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led/.settings/org.eclipse.jdt.core.prefs b/widgets/led/org.eclipse.nebula.widgets.led/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/led/org.eclipse.nebula.widgets.led/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/led/org.eclipse.nebula.widgets.led/META-INF/MANIFEST.MF b/widgets/led/org.eclipse.nebula.widgets.led/META-INF/MANIFEST.MF index 7d483a5cc..0cb3dde37 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/META-INF/MANIFEST.MF +++ b/widgets/led/org.eclipse.nebula.widgets.led/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula LED Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.led -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Export-Package: org.eclipse.nebula.widgets.led -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;visibility:=reexport, - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.led +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula LED Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.led +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Export-Package: org.eclipse.nebula.widgets.led +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;visibility:=reexport, + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.led diff --git a/widgets/led/org.eclipse.nebula.widgets.led/build.properties b/widgets/led/org.eclipse.nebula.widgets.led/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/build.properties +++ b/widgets/led/org.eclipse.nebula.widgets.led/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/led/org.eclipse.nebula.widgets.led/pom.xml b/widgets/led/org.eclipse.nebula.widgets.led/pom.xml index d673f9b4b..6f73ba0ed 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/pom.xml +++ b/widgets/led/org.eclipse.nebula.widgets.led/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - led - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.led - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + led + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.led + eclipse-plugin + + diff --git a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/BaseLED.java b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/BaseLED.java index 9f84744f9..b787c2fc3 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/BaseLED.java +++ b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/BaseLED.java @@ -1,198 +1,198 @@ -/******************************************************************************* - * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget - * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) - *******************************************************************************/ -package org.eclipse.nebula.widgets.led; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; - -/** - * Abstract class for LED and Double dots LED. - */ -public abstract class BaseLED extends Canvas { - - static final int DEFAULT_HEIGHT = 100; - static final int THIN_DEFAULT_WIDTH = 30; - protected static final int DOT_DIAMETER = 10; - - protected Color idleColor; - protected Color selectedColor; - protected GC gc; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent - * a composite control which will be the parent of the new instance - * (cannot be null) - * @param style - * the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - */ - public BaseLED(Composite parent, int style) { - super(parent, style ); - setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); - addListener(SWT.Paint, e -> onPaint(e)); - - Color defaultIdleColor = new Color(getDisplay(), 0, 29, 29); - SWTGraphicUtil.addDisposer(this, defaultIdleColor); - idleColor = defaultIdleColor; - - Color defaultSelectedColor = new Color(getDisplay(), 148, 237, 147); - SWTGraphicUtil.addDisposer(this, defaultSelectedColor); - selectedColor = defaultSelectedColor; - } - - - - private void onPaint(Event e) { - gc = e.gc; - gc.setBackground(getBackground()); - gc.fillRectangle(getClientArea()); - gc.setAdvanced(true); - gc.setAntialias(SWT.ON); - paintInternal(); - } - - /** - * Paint the widget - */ - protected abstract void paintInternal(); - - /** - * Returns the color used when the line is "off". - * - * @return the color used when the line is "off" - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getIdleColor() { - checkWidget(); - return idleColor; - } - - /** - * Sets the color used by the widget to display lines when they are "off" - * - * @param idleColor - * the new color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setIdleColor(Color idleColor) { - checkWidget(); - checkColor(idleColor); - this.idleColor = idleColor; - redraw(); - } - - private void checkColor(Color color) { - if (color == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - - /** - * Returns the color used when the line is "on". - * - * @return the color used when the line is "on" - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getSelectedColor() { - checkWidget(); - return selectedColor; - } - - /** - * Sets the color used by the widget to display lines when they are "on" - * - * @param selectedColor - * the new color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setSelectedColor(Color selectedColor) { - checkWidget(); - checkColor(selectedColor); - this.selectedColor = selectedColor; - redraw(); - } -} +/******************************************************************************* + * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget + * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) + *******************************************************************************/ +package org.eclipse.nebula.widgets.led; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; + +/** + * Abstract class for LED and Double dots LED. + */ +public abstract class BaseLED extends Canvas { + + static final int DEFAULT_HEIGHT = 100; + static final int THIN_DEFAULT_WIDTH = 30; + protected static final int DOT_DIAMETER = 10; + + protected Color idleColor; + protected Color selectedColor; + protected GC gc; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent + * a composite control which will be the parent of the new instance + * (cannot be null) + * @param style + * the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + */ + public BaseLED(Composite parent, int style) { + super(parent, style ); + setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); + addListener(SWT.Paint, e -> onPaint(e)); + + Color defaultIdleColor = new Color(getDisplay(), 0, 29, 29); + SWTGraphicUtil.addDisposer(this, defaultIdleColor); + idleColor = defaultIdleColor; + + Color defaultSelectedColor = new Color(getDisplay(), 148, 237, 147); + SWTGraphicUtil.addDisposer(this, defaultSelectedColor); + selectedColor = defaultSelectedColor; + } + + + + private void onPaint(Event e) { + gc = e.gc; + gc.setBackground(getBackground()); + gc.fillRectangle(getClientArea()); + gc.setAdvanced(true); + gc.setAntialias(SWT.ON); + paintInternal(); + } + + /** + * Paint the widget + */ + protected abstract void paintInternal(); + + /** + * Returns the color used when the line is "off". + * + * @return the color used when the line is "off" + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getIdleColor() { + checkWidget(); + return idleColor; + } + + /** + * Sets the color used by the widget to display lines when they are "off" + * + * @param idleColor + * the new color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setIdleColor(Color idleColor) { + checkWidget(); + checkColor(idleColor); + this.idleColor = idleColor; + redraw(); + } + + private void checkColor(Color color) { + if (color == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } + + /** + * Returns the color used when the line is "on". + * + * @return the color used when the line is "on" + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getSelectedColor() { + checkWidget(); + return selectedColor; + } + + /** + * Sets the color used by the widget to display lines when they are "on" + * + * @param selectedColor + * the new color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSelectedColor(Color selectedColor) { + checkWidget(); + checkColor(selectedColor); + this.selectedColor = selectedColor; + redraw(); + } +} diff --git a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/DotsLed.java b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/DotsLed.java index 4279dc088..0f34af84d 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/DotsLed.java +++ b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/DotsLed.java @@ -1,140 +1,140 @@ -/******************************************************************************* - * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget - * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) - *******************************************************************************/ -package org.eclipse.nebula.widgets.led; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; - -/** - * Instances of this class represent a non-selectable user interface object that - * displays a double-dots character like it was displayed on a LED screen. - * - *
- *
Styles:
- *
SWT.BORDER
- *
Events:
- *
(none)
- *
- */ -public class DotsLed extends BaseLED { - - private boolean areDotsLight; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent - * a composite control which will be the parent of the new instance - * (cannot be null) - * @param style - * the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - */ - public DotsLed(Composite parent, int style) { - super(parent, checkStyle(style)); - } - - private static int checkStyle(final int style) { - final int mask = SWT.BORDER; - int newStyle = style & mask; - newStyle |= SWT.DOUBLE_BUFFERED; - return newStyle; - } - - /** - * @see org.eclipse.nebula.widgets.led.BaseLED#paintInternal() - */ - @Override - protected void paintInternal() { - final Rectangle clientArea = getClientArea(); - final int x = clientArea.width / 2; - - int y = (clientArea.height - 4 * DOT_DIAMETER) / 2; - gc.setBackground(areDotsLight ? selectedColor : idleColor); - - gc.fillOval(x, y, DOT_DIAMETER, DOT_DIAMETER); - y += 2 * DOT_DIAMETER; - gc.fillOval(x, y, DOT_DIAMETER, DOT_DIAMETER); - } - - /** - * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(int wHint, int hHint, boolean changed) { - int x = (wHint == SWT.DEFAULT) ? BaseLED.THIN_DEFAULT_WIDTH : wHint; - int y = (hHint == SWT.DEFAULT) ? BaseLED.DEFAULT_HEIGHT : hHint; - return new Point(x, y); - } - - /** - * Switch on the two dots - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void switchOn() { - checkWidget(); - areDotsLight = true; - redraw(); - } - - /** - * Switch off the two dots - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void switchOff() { - checkWidget(); - areDotsLight = false; - redraw(); - } - -} +/******************************************************************************* + * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget + * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) + *******************************************************************************/ +package org.eclipse.nebula.widgets.led; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + +/** + * Instances of this class represent a non-selectable user interface object that + * displays a double-dots character like it was displayed on a LED screen. + * + *
+ *
Styles:
+ *
SWT.BORDER
+ *
Events:
+ *
(none)
+ *
+ */ +public class DotsLed extends BaseLED { + + private boolean areDotsLight; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent + * a composite control which will be the parent of the new instance + * (cannot be null) + * @param style + * the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + */ + public DotsLed(Composite parent, int style) { + super(parent, checkStyle(style)); + } + + private static int checkStyle(final int style) { + final int mask = SWT.BORDER; + int newStyle = style & mask; + newStyle |= SWT.DOUBLE_BUFFERED; + return newStyle; + } + + /** + * @see org.eclipse.nebula.widgets.led.BaseLED#paintInternal() + */ + @Override + protected void paintInternal() { + final Rectangle clientArea = getClientArea(); + final int x = clientArea.width / 2; + + int y = (clientArea.height - 4 * DOT_DIAMETER) / 2; + gc.setBackground(areDotsLight ? selectedColor : idleColor); + + gc.fillOval(x, y, DOT_DIAMETER, DOT_DIAMETER); + y += 2 * DOT_DIAMETER; + gc.fillOval(x, y, DOT_DIAMETER, DOT_DIAMETER); + } + + /** + * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(int wHint, int hHint, boolean changed) { + int x = (wHint == SWT.DEFAULT) ? BaseLED.THIN_DEFAULT_WIDTH : wHint; + int y = (hHint == SWT.DEFAULT) ? BaseLED.DEFAULT_HEIGHT : hHint; + return new Point(x, y); + } + + /** + * Switch on the two dots + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void switchOn() { + checkWidget(); + areDotsLight = true; + redraw(); + } + + /** + * Switch off the two dots + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void switchOff() { + checkWidget(); + areDotsLight = false; + redraw(); + } + +} diff --git a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LED.java b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LED.java index 7454b0cc3..1ac3ee853 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LED.java +++ b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LED.java @@ -1,195 +1,195 @@ -/******************************************************************************* - * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget - * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) - *******************************************************************************/ -package org.eclipse.nebula.widgets.led; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; - -/** - * Instances of this class represent a non-selectable user interface object that - * displays a character like it was displayed on a LED screen. - * - *
- *
Styles:
- *
SWT.BORDER
- *
SWT.ICON if the user wants to add a dot - *
Events:
- *
(none)
- *
- */ -public class LED extends BaseLED { - - private static final int DEFAULT_WIDTH = 60; - - private LEDLine[] lines; - private boolean showDot, hasDot; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent - * a composite control which will be the parent of the new instance - * (cannot be null) - * @param style - * the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - */ - public LED(Composite parent, int style) { - super(parent, checkStyle(style) | SWT.DOUBLE_BUFFERED); - initLinesConfiguration(); - hasDot = (getStyle() & SWT.ICON) == SWT.ICON; - } - - private static int checkStyle(final int style) { - final int mask = SWT.BORDER | SWT.ICON; - int newStyle = style & mask; - newStyle |= SWT.DOUBLE_BUFFERED; - return newStyle; - } - - private void initLinesConfiguration() { - lines = new LEDLine[] { new LEDLine(new int[] { 0, 5, 10, 0, 50, 0, 60, 5, 50, 10, 10, 10, 0, 5 }), // - new LEDLine(new int[] { 60, 7, 60, 48, 50, 43, 50, 12, 60, 7 }), // - new LEDLine(new int[] { 60, 52, 60, 93, 50, 88, 50, 57, 60, 52 }), // - new LEDLine(new int[] { 0, 95, 10, 90, 50, 90, 60, 95, 50, 100, 10, 100, 0, 95 }), // - new LEDLine(new int[] { 0, 52, 10, 57, 10, 88, 0, 93, 0, 52 }), // - new LEDLine(new int[] { 0, 7, 10, 12, 10, 43, 0, 48, 0, 7 }), // - new LEDLine(new int[] { 0, 50, 10, 45, 50, 45, 60, 50, 50, 55, 10, 55, 0, 50 }) }; - } - - @Override - protected void paintInternal() { - for (int i = 0; i < 7; i++) { - lines[i].paint(this); - } - if (hasDot && showDot) { - gc.setBackground(selectedColor); - Rectangle clientArea = getClientArea(); - gc.fillOval((int) (clientArea.width - DOT_DIAMETER * 1.5f) + 1, // - clientArea.height - DOT_DIAMETER, DOT_DIAMETER, DOT_DIAMETER); - } - } - - /** - * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(int wHint, int hHint, boolean changed) { - int x = (wHint == SWT.DEFAULT) ? DEFAULT_WIDTH : wHint; - if (hasDot) { - x += (int) (1.5f * DOT_DIAMETER); - } - int y = (hHint == SWT.DEFAULT) ? DEFAULT_HEIGHT : hHint; - return new Point(x, y); - } - - /** - * Returns the flag which indicates if the dot pixel in the right bottom corner - * of the widget is switched on - * - * @return true if the dot is displayed, false - * otherwise - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean isShowDot() { - checkWidget(); - return showDot; - } - - /** - * Sets the flag allowing the widget to display a dot in the right bottom corner - * of the widget - * - * @param showDot - * the new value - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setShowDot(boolean showDot) { - checkWidget(); - this.showDot = showDot; - redraw(); - } - - /** - * Sets the character to display - * - * @param character - * the character to display - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setCharacter(LEDCharacter character) { - checkWidget(); - if (character == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - for (int i = 0; i < 7; i++) { - lines[i].setSwitechOnFlag(character.isSwitchedOn(i)); - } - redraw(); - } - -} +/******************************************************************************* + * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget + * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) + *******************************************************************************/ +package org.eclipse.nebula.widgets.led; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + +/** + * Instances of this class represent a non-selectable user interface object that + * displays a character like it was displayed on a LED screen. + * + *
+ *
Styles:
+ *
SWT.BORDER
+ *
SWT.ICON if the user wants to add a dot + *
Events:
+ *
(none)
+ *
+ */ +public class LED extends BaseLED { + + private static final int DEFAULT_WIDTH = 60; + + private LEDLine[] lines; + private boolean showDot, hasDot; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent + * a composite control which will be the parent of the new instance + * (cannot be null) + * @param style + * the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + */ + public LED(Composite parent, int style) { + super(parent, checkStyle(style) | SWT.DOUBLE_BUFFERED); + initLinesConfiguration(); + hasDot = (getStyle() & SWT.ICON) == SWT.ICON; + } + + private static int checkStyle(final int style) { + final int mask = SWT.BORDER | SWT.ICON; + int newStyle = style & mask; + newStyle |= SWT.DOUBLE_BUFFERED; + return newStyle; + } + + private void initLinesConfiguration() { + lines = new LEDLine[] { new LEDLine(new int[] { 0, 5, 10, 0, 50, 0, 60, 5, 50, 10, 10, 10, 0, 5 }), // + new LEDLine(new int[] { 60, 7, 60, 48, 50, 43, 50, 12, 60, 7 }), // + new LEDLine(new int[] { 60, 52, 60, 93, 50, 88, 50, 57, 60, 52 }), // + new LEDLine(new int[] { 0, 95, 10, 90, 50, 90, 60, 95, 50, 100, 10, 100, 0, 95 }), // + new LEDLine(new int[] { 0, 52, 10, 57, 10, 88, 0, 93, 0, 52 }), // + new LEDLine(new int[] { 0, 7, 10, 12, 10, 43, 0, 48, 0, 7 }), // + new LEDLine(new int[] { 0, 50, 10, 45, 50, 45, 60, 50, 50, 55, 10, 55, 0, 50 }) }; + } + + @Override + protected void paintInternal() { + for (int i = 0; i < 7; i++) { + lines[i].paint(this); + } + if (hasDot && showDot) { + gc.setBackground(selectedColor); + Rectangle clientArea = getClientArea(); + gc.fillOval((int) (clientArea.width - DOT_DIAMETER * 1.5f) + 1, // + clientArea.height - DOT_DIAMETER, DOT_DIAMETER, DOT_DIAMETER); + } + } + + /** + * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(int wHint, int hHint, boolean changed) { + int x = (wHint == SWT.DEFAULT) ? DEFAULT_WIDTH : wHint; + if (hasDot) { + x += (int) (1.5f * DOT_DIAMETER); + } + int y = (hHint == SWT.DEFAULT) ? DEFAULT_HEIGHT : hHint; + return new Point(x, y); + } + + /** + * Returns the flag which indicates if the dot pixel in the right bottom corner + * of the widget is switched on + * + * @return true if the dot is displayed, false + * otherwise + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean isShowDot() { + checkWidget(); + return showDot; + } + + /** + * Sets the flag allowing the widget to display a dot in the right bottom corner + * of the widget + * + * @param showDot + * the new value + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setShowDot(boolean showDot) { + checkWidget(); + this.showDot = showDot; + redraw(); + } + + /** + * Sets the character to display + * + * @param character + * the character to display + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_NULL_ARGUMENT - if the argument is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setCharacter(LEDCharacter character) { + checkWidget(); + if (character == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + for (int i = 0; i < 7; i++) { + lines[i].setSwitechOnFlag(character.isSwitchedOn(i)); + } + redraw(); + } + +} diff --git a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LEDLine.java b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LEDLine.java index 237a7eb02..509dd8e13 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LEDLine.java +++ b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LEDLine.java @@ -1,37 +1,37 @@ -/******************************************************************************* - * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget - * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) - *******************************************************************************/ -package org.eclipse.nebula.widgets.led; - -import org.eclipse.swt.graphics.GC; - -class LEDLine { - private int[] coords; - private boolean switchedOn; - - LEDLine(int[] coords) { - super(); - this.coords = coords; - } - - void setSwitechOnFlag(boolean newValue) { - switchedOn = newValue; - } - - public void paint(LED led) { - GC gc = led.gc; - gc.setBackground(switchedOn ? led.selectedColor : led.idleColor); - gc.fillPolygon(coords); - } -} +/******************************************************************************* + * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget + * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) + *******************************************************************************/ +package org.eclipse.nebula.widgets.led; + +import org.eclipse.swt.graphics.GC; + +class LEDLine { + private int[] coords; + private boolean switchedOn; + + LEDLine(int[] coords) { + super(); + this.coords = coords; + } + + void setSwitechOnFlag(boolean newValue) { + switchedOn = newValue; + } + + public void paint(LED led) { + GC gc = led.gc; + gc.setBackground(switchedOn ? led.selectedColor : led.idleColor); + gc.fillPolygon(coords); + } +} diff --git a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LEDSeparator.java b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LEDSeparator.java index 31fdc54db..c4906b19e 100644 --- a/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LEDSeparator.java +++ b/widgets/led/org.eclipse.nebula.widgets.led/src/org/eclipse/nebula/widgets/led/LEDSeparator.java @@ -1,104 +1,104 @@ -/******************************************************************************* - * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget - * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) - *******************************************************************************/ -package org.eclipse.nebula.widgets.led; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; - -/** - * Instances of this class represent a non-selectable user interface object that - * displays a separator (minus sign) like it was displayed on a LED screen. - * - *
- *
Styles:
- *
SWT.BORDER
- *
Events:
- *
(none)
- *
- */ -public class LEDSeparator extends Canvas { - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent - * a composite control which will be the parent of the new instance - * (cannot be null) - * @param style - * the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - */ - public LEDSeparator(Composite parent, int style) { - super(parent, checkStyle(style)); - setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); - setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - addListener(SWT.Paint, e -> onPaint(e)); - } - - private static int checkStyle(final int style) { - final int mask = SWT.BORDER; - int newStyle = style & mask; - newStyle |= SWT.DOUBLE_BUFFERED; - return newStyle; - } - - private void onPaint(Event e) { - GC gc = e.gc; - gc.setBackground(getBackground()); - gc.fillRectangle(getClientArea()); - gc.setAdvanced(true); - gc.setAntialias(SWT.ON); - gc.setForeground(getForeground()); - gc.setLineWidth(1); - gc.drawLine(0, getClientArea().height / 2, getClientArea().width, getClientArea().height / 2); - } - - /** - * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(int wHint, int hHint, boolean changed) { - int x = (wHint == SWT.DEFAULT) ? BaseLED.THIN_DEFAULT_WIDTH : wHint; - int y = (hHint == SWT.DEFAULT) ? BaseLED.DEFAULT_HEIGHT : hHint; - return new Point(x, y); - } - -} +/******************************************************************************* + * Copyright (c) 2019 Akuiteo (http://www.akuiteo.com). + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + * Frank DELPORTE - inspiration for his LED Number Display JavaFX widget + * (https://webtechie.be/2019/10/02/led-number-display-javafx-library-published-to-maven) + *******************************************************************************/ +package org.eclipse.nebula.widgets.led; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class represent a non-selectable user interface object that + * displays a separator (minus sign) like it was displayed on a LED screen. + * + *
+ *
Styles:
+ *
SWT.BORDER
+ *
Events:
+ *
(none)
+ *
+ */ +public class LEDSeparator extends Canvas { + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent + * a composite control which will be the parent of the new instance + * (cannot be null) + * @param style + * the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + */ + public LEDSeparator(Composite parent, int style) { + super(parent, checkStyle(style)); + setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); + setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + addListener(SWT.Paint, e -> onPaint(e)); + } + + private static int checkStyle(final int style) { + final int mask = SWT.BORDER; + int newStyle = style & mask; + newStyle |= SWT.DOUBLE_BUFFERED; + return newStyle; + } + + private void onPaint(Event e) { + GC gc = e.gc; + gc.setBackground(getBackground()); + gc.fillRectangle(getClientArea()); + gc.setAdvanced(true); + gc.setAntialias(SWT.ON); + gc.setForeground(getForeground()); + gc.setLineWidth(1); + gc.drawLine(0, getClientArea().height / 2, getClientArea().width, getClientArea().height / 2); + } + + /** + * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(int wHint, int hHint, boolean changed) { + int x = (wHint == SWT.DEFAULT) ? BaseLED.THIN_DEFAULT_WIDTH : wHint; + int y = (hHint == SWT.DEFAULT) ? BaseLED.DEFAULT_HEIGHT : hHint; + return new Point(x, y); + } + +} diff --git a/widgets/led/pom.xml b/widgets/led/pom.xml index 2ff5cda19..b658fe882 100644 --- a/widgets/led/pom.xml +++ b/widgets/led/pom.xml @@ -1,23 +1,23 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - nebula-parent - ../../releng/org.eclipse.nebula.nebula-parent - - - led - pom - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.led - org.eclipse.nebula.widgets.led.feature - org.eclipse.nebula.widgets.led.snippets - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + nebula-parent + ../../releng/org.eclipse.nebula.nebula-parent + + + led + pom + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.led + org.eclipse.nebula.widgets.led.feature + org.eclipse.nebula.widgets.led.snippets + + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/.project b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/.project index 1cc480fa7..c52a5511c 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/.project +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.nebulaslider.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.nebulaslider.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/build.properties b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/build.properties +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/feature.properties b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/feature.properties +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/feature.xml b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/feature.xml index 1694c310c..71a79619a 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/feature.xml +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/feature.xml @@ -1,34 +1,34 @@ - - - - - NebulaSlider - - - - %license - - - - - - - - - - - + + + + + NebulaSlider + + + + %license + + + + + + + + + + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/pom.xml b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/pom.xml index 86d74a769..cb747a6e4 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/pom.xml +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - nebulaslider - 1.1.0-SNAPSHOT - - - org.eclipse.nebula.widgets.nebulaslider.feature - eclipse-feature - 1.1.0-SNAPSHOT - - Nebula Slider Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + nebulaslider + 1.1.0-SNAPSHOT + + + org.eclipse.nebula.widgets.nebulaslider.feature + eclipse-feature + 1.1.0-SNAPSHOT + + Nebula Slider Feature + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.classpath b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.classpath +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.project b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.project index b8f0da36e..aa21c65bc 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.project +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.nebulaslider.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.nebulaslider.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/META-INF/MANIFEST.MF b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/META-INF/MANIFEST.MF index d6ce62654..d805e8a04 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/META-INF/MANIFEST.MF +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Slider Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.nebulaslider.snippets -Bundle-Version: 1.1.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.nebulaslider, - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.nebulaslider.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Slider Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.nebulaslider.snippets +Bundle-Version: 1.1.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.nebulaslider, + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.nebulaslider.snippets diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/build.properties b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/build.properties +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/pom.xml b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/pom.xml index 867f3ca99..e1d21d86c 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/pom.xml +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - nebulaslider - 1.1.0-SNAPSHOT - - - org.eclipse.nebula.widgets.nebulaslider.snippets - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + nebulaslider + 1.1.0-SNAPSHOT + + + org.eclipse.nebula.widgets.nebulaslider.snippets + eclipse-plugin + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaCustomSliderConfiguration.java b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaCustomSliderConfiguration.java index a4e91b755..cb82c02b7 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaCustomSliderConfiguration.java +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaCustomSliderConfiguration.java @@ -1,140 +1,140 @@ -/******************************************************************************* - * Copyright (c) 2024 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.nebulaslider.snippets; - -import org.eclipse.nebula.widgets.opal.nebulaslider.NebulaSlider; -import org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; - -public class NebulaCustomSliderConfiguration extends NebularSliderDefaultConfiguration { - - public NebulaCustomSliderConfiguration(final NebulaSlider parentSlider) { - super(parentSlider); - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getBarInsideColor() - */ - @Override - public Color getBarInsideColor() { - return getAndDisposeColor(231, 225, 219); - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getBarBorderColor() - */ - @Override - public Color getBarBorderColor() { - return getAndDisposeColor(219, 211, 203); - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getBarSelectionColor() - */ - @Override - public Color getBarSelectionColor() { - return getAndDisposeColor(129, 108, 91); - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorColor() - */ - @Override - public Color getSelectorColor() { - return getAndDisposeColor(148, 130, 113); - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorColorBorder() - */ - @Override - public Color getSelectorColorBorder() { - return getAndDisposeColor(238, 234, 230); - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorTextColor() - */ - @Override - public Color getSelectorTextColor() { - return getAndDisposeColor(255, 255, 204); - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getArrowColor() - */ - @Override - public Color getArrowColor() { - return getAndDisposeColor(203, 192, 181); - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getTextFont() - */ - @Override - public Font getTextFont() { - final FontData fontData = parentSlider.getFont().getFontData()[0]; - final Font newFont = new Font(parentSlider.getDisplay(), "Arial", Math.max(fontData.getHeight(), 14), SWT.ITALIC); - parentSlider.addDisposeListener(e -> { - if (!newFont.isDisposed()) { - newFont.dispose(); - } - }); - return newFont; - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getHorizontalMargin() - */ - @Override - public int getHorizontalMargin() { - // TODO Auto-generated method stub - return super.getHorizontalMargin(); - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorWidth() - */ - @Override - public int getSelectorWidth() { - return 100; - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorHeight() - */ - @Override - public int getSelectorHeight() { - return 40; - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getBarHeight() - */ - @Override - public int getBarHeight() { - return 18; - } - - /** - * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getArrowLineWidth() - */ - @Override - public int getArrowLineWidth() { - return 5; - } - -} +/******************************************************************************* + * Copyright (c) 2024 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.nebulaslider.snippets; + +import org.eclipse.nebula.widgets.opal.nebulaslider.NebulaSlider; +import org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; + +public class NebulaCustomSliderConfiguration extends NebularSliderDefaultConfiguration { + + public NebulaCustomSliderConfiguration(final NebulaSlider parentSlider) { + super(parentSlider); + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getBarInsideColor() + */ + @Override + public Color getBarInsideColor() { + return getAndDisposeColor(231, 225, 219); + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getBarBorderColor() + */ + @Override + public Color getBarBorderColor() { + return getAndDisposeColor(219, 211, 203); + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getBarSelectionColor() + */ + @Override + public Color getBarSelectionColor() { + return getAndDisposeColor(129, 108, 91); + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorColor() + */ + @Override + public Color getSelectorColor() { + return getAndDisposeColor(148, 130, 113); + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorColorBorder() + */ + @Override + public Color getSelectorColorBorder() { + return getAndDisposeColor(238, 234, 230); + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorTextColor() + */ + @Override + public Color getSelectorTextColor() { + return getAndDisposeColor(255, 255, 204); + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getArrowColor() + */ + @Override + public Color getArrowColor() { + return getAndDisposeColor(203, 192, 181); + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getTextFont() + */ + @Override + public Font getTextFont() { + final FontData fontData = parentSlider.getFont().getFontData()[0]; + final Font newFont = new Font(parentSlider.getDisplay(), "Arial", Math.max(fontData.getHeight(), 14), SWT.ITALIC); + parentSlider.addDisposeListener(e -> { + if (!newFont.isDisposed()) { + newFont.dispose(); + } + }); + return newFont; + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getHorizontalMargin() + */ + @Override + public int getHorizontalMargin() { + // TODO Auto-generated method stub + return super.getHorizontalMargin(); + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorWidth() + */ + @Override + public int getSelectorWidth() { + return 100; + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getSelectorHeight() + */ + @Override + public int getSelectorHeight() { + return 40; + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getBarHeight() + */ + @Override + public int getBarHeight() { + return 18; + } + + /** + * @see org.eclipse.nebula.widgets.opal.nebulaslider.NebularSliderDefaultConfiguration#getArrowLineWidth() + */ + @Override + public int getArrowLineWidth() { + return 5; + } + +} diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaSliderSnippet.java b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaSliderSnippet.java index f6f1ea59d..e7054891c 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaSliderSnippet.java +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaSliderSnippet.java @@ -1,137 +1,137 @@ -/******************************************************************************* - * Copyright (c) 2018-2024 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron@gmail.com) - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.nebulaslider.snippets; - -import org.eclipse.nebula.widgets.opal.nebulaslider.NebulaSlider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * A simple snippet for the TextAssist Widget - */ -public class NebulaSliderSnippet { - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(2, false)); - shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); - - createLeftLabel(shell, "Minimum"); - final Text min = createTextWidget(shell, 0); - - createLeftLabel(shell, "Maximum"); - final Text max = createTextWidget(shell, 1000); - - createLeftLabel(shell, "Value"); - final Text value = createTextWidget(shell, 632); - - final Button update = new Button(shell, SWT.PUSH); - update.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false, 2, 1)); - update.setText("Redraw Slider"); - - final NebulaSlider slider = new NebulaSlider(shell, SWT.NONE); - slider.setMinimum(0); - slider.setMaximum(1000); - slider.setValue(632); - slider.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); - - slider.addListener(SWT.Selection, e -> { - System.out.println("New value is " + slider.getValue()); - }); - - final GridData layoutData = new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1); - layoutData.widthHint = 600; - layoutData.heightHint = 50; - slider.setLayoutData(layoutData); - - update.addListener(SWT.Selection, e -> { - int minValue = 0; - try { - minValue = Integer.valueOf(min.getText()); - } catch (final NumberFormatException nfe) { - showError(shell, "The value [" + min.getText() + "] is not a number"); - return; - } - - int maxValue = 0; - try { - maxValue = Integer.valueOf(max.getText()); - } catch (final NumberFormatException nfe) { - showError(shell, "The value [" + max.getText() + "] is not a number"); - return; - } - - if (maxValue < minValue) { - showError(shell, "The minimum is greater than the maximum"); - return; - } - // - int newValue = 0; - try { - newValue = Integer.valueOf(value.getText()); - } catch (final NumberFormatException nfe) { - showError(shell, "The value [" + value.getText() + "] is not a number"); - return; - } - if (newValue < minValue || newValue > maxValue) { - showError(shell, "The value [" + newValue + "] should be between " + minValue + " and " + maxValue); - return; - } - // - slider.setMinimum(minValue); - slider.setMaximum(maxValue); - slider.setValue(newValue); - - }); - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } - - private static void createLeftLabel(final Shell shell, final String text) { - final Label lbl = new Label(shell, SWT.NONE); - lbl.setText(text); - lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - lbl.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - } - - private static Text createTextWidget(final Shell shell, final int value) { - final Text txt = new Text(shell, SWT.BORDER); - txt.setText(String.valueOf(value)); - txt.setTextLimit(3); - final GridData gd = new GridData(GridData.FILL, GridData.CENTER, false, false); - gd.minimumWidth = 40; - txt.setLayoutData(gd); - return txt; - } - - private static void showError(final Shell shell, final String message) { - final MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK); - mb.setText("Error"); - mb.setMessage(message); - mb.open(); - } -} +/******************************************************************************* + * Copyright (c) 2018-2024 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron@gmail.com) + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.nebulaslider.snippets; + +import org.eclipse.nebula.widgets.opal.nebulaslider.NebulaSlider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * A simple snippet for the TextAssist Widget + */ +public class NebulaSliderSnippet { + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(2, false)); + shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); + + createLeftLabel(shell, "Minimum"); + final Text min = createTextWidget(shell, 0); + + createLeftLabel(shell, "Maximum"); + final Text max = createTextWidget(shell, 1000); + + createLeftLabel(shell, "Value"); + final Text value = createTextWidget(shell, 632); + + final Button update = new Button(shell, SWT.PUSH); + update.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false, 2, 1)); + update.setText("Redraw Slider"); + + final NebulaSlider slider = new NebulaSlider(shell, SWT.NONE); + slider.setMinimum(0); + slider.setMaximum(1000); + slider.setValue(632); + slider.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); + + slider.addListener(SWT.Selection, e -> { + System.out.println("New value is " + slider.getValue()); + }); + + final GridData layoutData = new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1); + layoutData.widthHint = 600; + layoutData.heightHint = 50; + slider.setLayoutData(layoutData); + + update.addListener(SWT.Selection, e -> { + int minValue = 0; + try { + minValue = Integer.valueOf(min.getText()); + } catch (final NumberFormatException nfe) { + showError(shell, "The value [" + min.getText() + "] is not a number"); + return; + } + + int maxValue = 0; + try { + maxValue = Integer.valueOf(max.getText()); + } catch (final NumberFormatException nfe) { + showError(shell, "The value [" + max.getText() + "] is not a number"); + return; + } + + if (maxValue < minValue) { + showError(shell, "The minimum is greater than the maximum"); + return; + } + // + int newValue = 0; + try { + newValue = Integer.valueOf(value.getText()); + } catch (final NumberFormatException nfe) { + showError(shell, "The value [" + value.getText() + "] is not a number"); + return; + } + if (newValue < minValue || newValue > maxValue) { + showError(shell, "The value [" + newValue + "] should be between " + minValue + " and " + maxValue); + return; + } + // + slider.setMinimum(minValue); + slider.setMaximum(maxValue); + slider.setValue(newValue); + + }); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } + + private static void createLeftLabel(final Shell shell, final String text) { + final Label lbl = new Label(shell, SWT.NONE); + lbl.setText(text); + lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + lbl.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + } + + private static Text createTextWidget(final Shell shell, final int value) { + final Text txt = new Text(shell, SWT.BORDER); + txt.setText(String.valueOf(value)); + txt.setTextLimit(3); + final GridData gd = new GridData(GridData.FILL, GridData.CENTER, false, false); + gd.minimumWidth = 40; + txt.setLayoutData(gd); + return txt; + } + + private static void showError(final Shell shell, final String message) { + final MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK); + mb.setText("Error"); + mb.setMessage(message); + mb.open(); + } +} diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaSliderSnippetOtherRenderer.java b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaSliderSnippetOtherRenderer.java index 859a1a36a..7ae45a7af 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaSliderSnippetOtherRenderer.java +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider.snippets/src/org/eclipse/nebula/widgets/opal/nebulaslider/snippets/NebulaSliderSnippetOtherRenderer.java @@ -1,138 +1,138 @@ -/******************************************************************************* - * Copyright (c) 2024 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron@gmail.com) - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.nebulaslider.snippets; - -import org.eclipse.nebula.widgets.opal.nebulaslider.NebulaSlider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * A simple snippet for the TextAssist Widget - */ -public class NebulaSliderSnippetOtherRenderer { - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(2, false)); - shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); - - createLeftLabel(shell, "Minimum"); - final Text min = createTextWidget(shell, 0); - - createLeftLabel(shell, "Maximum"); - final Text max = createTextWidget(shell, 1000); - - createLeftLabel(shell, "Value"); - final Text value = createTextWidget(shell, 632); - - final Button update = new Button(shell, SWT.PUSH); - update.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false, 2, 1)); - update.setText("Redraw Slider"); - - final NebulaSlider slider = new NebulaSlider(shell, SWT.NONE); - slider.setMinimum(0); - slider.setMaximum(1000); - slider.setValue(632); - slider.setRenderer(new NebulaCustomSliderConfiguration(slider)); - slider.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); - - slider.addListener(SWT.Selection, e -> { - System.out.println("New value is " + slider.getValue()); - }); - - final GridData layoutData = new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1); - layoutData.widthHint = 600; - layoutData.heightHint = 50; - slider.setLayoutData(layoutData); - - update.addListener(SWT.Selection, e -> { - int minValue = 0; - try { - minValue = Integer.valueOf(min.getText()); - } catch (final NumberFormatException nfe) { - showError(shell, "The value [" + min.getText() + "] is not a number"); - return; - } - - int maxValue = 0; - try { - maxValue = Integer.valueOf(max.getText()); - } catch (final NumberFormatException nfe) { - showError(shell, "The value [" + max.getText() + "] is not a number"); - return; - } - - if (maxValue < minValue) { - showError(shell, "The minimum is greater than the maximum"); - return; - } - // - int newValue = 0; - try { - newValue = Integer.valueOf(value.getText()); - } catch (final NumberFormatException nfe) { - showError(shell, "The value [" + value.getText() + "] is not a number"); - return; - } - if (newValue < minValue || newValue > maxValue) { - showError(shell, "The value [" + newValue + "] should be between " + minValue + " and " + maxValue); - return; - } - // - slider.setMinimum(minValue); - slider.setMaximum(maxValue); - slider.setValue(newValue); - - }); - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } - - private static void createLeftLabel(final Shell shell, final String text) { - final Label lbl = new Label(shell, SWT.NONE); - lbl.setText(text); - lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - lbl.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - } - - private static Text createTextWidget(final Shell shell, final int value) { - final Text txt = new Text(shell, SWT.BORDER); - txt.setText(String.valueOf(value)); - txt.setTextLimit(3); - final GridData gd = new GridData(GridData.FILL, GridData.CENTER, false, false); - gd.minimumWidth = 40; - txt.setLayoutData(gd); - return txt; - } - - private static void showError(final Shell shell, final String message) { - final MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK); - mb.setText("Error"); - mb.setMessage(message); - mb.open(); - } -} +/******************************************************************************* + * Copyright (c) 2024 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron@gmail.com) + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.nebulaslider.snippets; + +import org.eclipse.nebula.widgets.opal.nebulaslider.NebulaSlider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * A simple snippet for the TextAssist Widget + */ +public class NebulaSliderSnippetOtherRenderer { + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(2, false)); + shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); + + createLeftLabel(shell, "Minimum"); + final Text min = createTextWidget(shell, 0); + + createLeftLabel(shell, "Maximum"); + final Text max = createTextWidget(shell, 1000); + + createLeftLabel(shell, "Value"); + final Text value = createTextWidget(shell, 632); + + final Button update = new Button(shell, SWT.PUSH); + update.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false, 2, 1)); + update.setText("Redraw Slider"); + + final NebulaSlider slider = new NebulaSlider(shell, SWT.NONE); + slider.setMinimum(0); + slider.setMaximum(1000); + slider.setValue(632); + slider.setRenderer(new NebulaCustomSliderConfiguration(slider)); + slider.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); + + slider.addListener(SWT.Selection, e -> { + System.out.println("New value is " + slider.getValue()); + }); + + final GridData layoutData = new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1); + layoutData.widthHint = 600; + layoutData.heightHint = 50; + slider.setLayoutData(layoutData); + + update.addListener(SWT.Selection, e -> { + int minValue = 0; + try { + minValue = Integer.valueOf(min.getText()); + } catch (final NumberFormatException nfe) { + showError(shell, "The value [" + min.getText() + "] is not a number"); + return; + } + + int maxValue = 0; + try { + maxValue = Integer.valueOf(max.getText()); + } catch (final NumberFormatException nfe) { + showError(shell, "The value [" + max.getText() + "] is not a number"); + return; + } + + if (maxValue < minValue) { + showError(shell, "The minimum is greater than the maximum"); + return; + } + // + int newValue = 0; + try { + newValue = Integer.valueOf(value.getText()); + } catch (final NumberFormatException nfe) { + showError(shell, "The value [" + value.getText() + "] is not a number"); + return; + } + if (newValue < minValue || newValue > maxValue) { + showError(shell, "The value [" + newValue + "] should be between " + minValue + " and " + maxValue); + return; + } + // + slider.setMinimum(minValue); + slider.setMaximum(maxValue); + slider.setValue(newValue); + + }); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } + + private static void createLeftLabel(final Shell shell, final String text) { + final Label lbl = new Label(shell, SWT.NONE); + lbl.setText(text); + lbl.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + lbl.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + } + + private static Text createTextWidget(final Shell shell, final int value) { + final Text txt = new Text(shell, SWT.BORDER); + txt.setText(String.valueOf(value)); + txt.setTextLimit(3); + final GridData gd = new GridData(GridData.FILL, GridData.CENTER, false, false); + gd.minimumWidth = 40; + txt.setLayoutData(gd); + return txt; + } + + private static void showError(final Shell shell, final String message) { + final MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK); + mb.setText("Error"); + mb.setMessage(message); + mb.open(); + } +} diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.classpath b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.classpath +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.project b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.project index b91441bb0..38945745e 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.project +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.nebulaslider - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.nebulaslider + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.settings/org.eclipse.jdt.core.prefs b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/META-INF/MANIFEST.MF b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/META-INF/MANIFEST.MF index 6f089ba05..e7d8a1689 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/META-INF/MANIFEST.MF +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Slider Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.nebulaslider -Bundle-Version: 1.1.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.nebulaslider -Automatic-Module-Name: org.eclipse.nebula.widgets.nebulaslider +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Slider Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.nebulaslider +Bundle-Version: 1.1.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.nebulaslider +Automatic-Module-Name: org.eclipse.nebula.widgets.nebulaslider diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/build.properties b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/build.properties +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/pom.xml b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/pom.xml index 4372b1510..3dc5c0575 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/pom.xml +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - nebulaslider - 1.1.0-SNAPSHOT - - - org.eclipse.nebula.widgets.nebulaslider - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + nebulaslider + 1.1.0-SNAPSHOT + + + org.eclipse.nebula.widgets.nebulaslider + eclipse-plugin + + diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebulaSlider.java b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebulaSlider.java index 0823a1fb0..075cc3c37 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebulaSlider.java +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebulaSlider.java @@ -1,521 +1,521 @@ -/******************************************************************************* - * Copyright (c) 2018-2024 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.nebulaslider; - -import java.util.function.IntFunction; - -import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Widget; - -/** - * Instances of this class are selectable user interface - * objects that represent a range of positive, numeric values. - * It is like an horizontal slider - *
- *
Styles:
- *
(None)
- *
Events:
- *
Selection
- *
- */ -public class NebulaSlider extends Canvas { - - private NebulaSliderGraphicConfiguration renderer; - - private int minimum; - private int maximum; - private int value; - private int xPosition; - private int mouseDeltaX; - - private boolean moving = false; - - private IntFunction format; - - private int movingValue; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - * @see Widget#getStyle() - */ - public NebulaSlider(final Composite parent, final int style) { - super(parent, checkStyle(style) | SWT.DOUBLE_BUFFERED); - - renderer = new NebularSliderDefaultConfiguration(this); - - minimum = Integer.MIN_VALUE; - maximum = Integer.MAX_VALUE; - value = 0; - xPosition = -1; - - addPaintListener(e -> { - paintControl(e.gc); - }); - addMouseListeners(); - } - - private static int checkStyle(final int style) { - if ((style & SWT.BORDER) != 0) { - return style & ~SWT.BORDER; - } - return 0; - } - - private void paintControl(final GC gc) { - gc.setAdvanced(true); - gc.setAntialias(SWT.ON); - - if (xPosition < 0) { - // Compute xPosition - xPosition = computeXPosition(); - } - boolean enabled = isEnabled(); - drawBar(gc, enabled); - drawSelectionPart(gc, enabled); - drawSelector(gc, enabled); - } - - private void drawBar(final GC gc, boolean enabled) { - final Rectangle rect = getClientArea(); - gc.setForeground(getColor(renderer.getBarBorderColor(), enabled)); - gc.setBackground(getColor(renderer.getBarInsideColor(), enabled)); - - final int hMargin = renderer.getHorizontalMargin(); - final int selectorWidth = renderer.getSelectorWidth(); - final int barHeight = renderer.getBarHeight(); - - final int x = hMargin + selectorWidth / 2; - final int y = (rect.height - barHeight) / 2; - final int width = rect.width - hMargin * 2 - selectorWidth; - - gc.fillRoundRectangle(x, y, width, barHeight, barHeight, barHeight); - gc.drawRoundRectangle(x, y, width, barHeight, barHeight, barHeight); - } - - private void drawSelectionPart(final GC gc, boolean enabled) { - final Rectangle rect = getClientArea(); - gc.setForeground(getColor(renderer.getBarBorderColor(), enabled)); - gc.setBackground(getColor(renderer.getBarSelectionColor(), enabled)); - - final int barHeight = renderer.getBarHeight(); - - final int x = renderer.getHorizontalMargin() + renderer.getSelectorWidth() / 2; - final int y = (rect.height - barHeight) / 2; - - gc.fillRoundRectangle(x, y, xPosition, barHeight, barHeight, barHeight); - gc.drawRoundRectangle(x, y, xPosition, barHeight, barHeight, barHeight); - } - - private int computeXPosition() { - final int originalWidth = getClientArea().width - renderer.getHorizontalMargin() * 2 - renderer.getSelectorWidth(); - final float coeff = value * 1f / (maximum - minimum); - final int position = (int) (coeff * originalWidth); - return position; - } - - private void drawSelector(final GC gc, boolean enabled) { - final Rectangle rect = getClientArea(); - gc.setForeground(getColor(renderer.getSelectorColorBorder(), enabled)); - gc.setBackground(getColor(renderer.getSelectorColor(), enabled)); - - final int hMargin = renderer.getHorizontalMargin(); - - final int selectorWidth = renderer.getSelectorWidth(); - final int selectorHeight = renderer.getSelectorHeight(); - - final int y = (rect.height - selectorHeight) / 2; - - // Draw the body - gc.fillRoundRectangle(hMargin + xPosition, y, selectorWidth, selectorHeight, selectorHeight, selectorHeight); - gc.drawRoundRectangle(hMargin + xPosition, y, selectorWidth, selectorHeight, selectorHeight, selectorHeight); - - // Draw the arrows - gc.setForeground(getColor(renderer.getArrowColor(), enabled)); - gc.setLineWidth(renderer.getArrowLineWidth()); - final int baseY = y + selectorHeight / 2; - gc.drawLine(hMargin + xPosition + 10, baseY, hMargin + xPosition + 17, baseY - 7); - gc.drawLine(hMargin + xPosition + 10, baseY, hMargin + xPosition + 17, baseY + 7); - - gc.drawLine(hMargin + xPosition + selectorWidth - 10, baseY, hMargin + xPosition + selectorWidth - 17, baseY - 7); - gc.drawLine(hMargin + xPosition + selectorWidth - 10, baseY, hMargin + xPosition + selectorWidth - 17, baseY + 7); - - // And the value - gc.setForeground(getColor(renderer.getSelectorTextColor(), enabled)); - gc.setFont(renderer.getTextFont()); - final String valueAsString = stringValueOf(value); - final Point textSize = gc.textExtent(valueAsString); - - final int xText = hMargin + xPosition + selectorWidth / 2; - final int yText = y + selectorHeight / 2; - - gc.drawText(valueAsString, xText - textSize.x / 2, yText - textSize.y / 2, true); - } - - @Override - public void setBounds(int x, int y, int width, int height) { - xPosition = -1; - super.setBounds(x, y, width, height); - } - - @Override - public void setEnabled(boolean enabled) { - if(!enabled && moving) { - moving = false; - } - super.setEnabled(enabled); - } - - private Color getColor(Color color, boolean enabled) { - if(enabled) { - return color; - } - // see https://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale - int red = color.getRed(); - int green = color.getGreen(); - int blue = color.getBlue(); - if(red == green && green == blue) { - return color; - } - int g = (int)(0.299 * red + 0.587 * green + 0.114 * blue); - return new Color(g, g, g); - } - - private String stringValueOf(int value) { - if(format != null) { - return format.apply(value); - } - return String.valueOf(value); - } - - /** - * Set the format that should be used to format the given number to a string. - * - * @param format - * the format or null to use the default format. - */ - public void setLabelFormatProvider(IntFunction format) { - checkWidget(); - this.format = format; - } - - public IntFunction getLabelFormatProvider() { - checkWidget(); - return format; - } - - private void addMouseListeners() { - - addListener(SWT.MouseDown, e -> { - if(isEnabled()) { - final int selectorWidth = renderer.getSelectorWidth(); - final int selectorHeight = renderer.getSelectorHeight(); - - final int y = (getClientArea().height - selectorHeight) / 2; - final Rectangle rect = new Rectangle(xPosition + renderer.getHorizontalMargin(), y, selectorWidth, selectorHeight); - if (!rect.contains(e.x, e.y)) { - return; - } - moving = true; - movingValue = value; - mouseDeltaX = xPosition - e.x; - } - }); - - addListener(SWT.MouseUp, e -> { - moving = false; - mouseDeltaX = 0; - if(movingValue != value) { - SelectionListenerUtil.fireDefaultSelectionListeners(this, e); - } - redraw(); - }); - - addListener(SWT.MouseMove, e -> { - if (!moving) { - return; - } - - xPosition = e.x + mouseDeltaX; - if (xPosition < 0) { - xPosition = 0; - } - final int originalWidth = getClientArea().width - renderer.getHorizontalMargin() * 2 - renderer.getSelectorWidth(); - - if (xPosition > originalWidth) { - xPosition = originalWidth; - } - - // Update value - final float ratio = (float) xPosition / originalWidth; - int value = (int)Math.floor(ratio * (maximum - minimum)); - if(this.value != value) { - this.value = value; - SelectionListenerUtil.fireSelectionListeners(this, e); - } - redraw(); - - }); - } - - - - /** - * Adds the listener to the collection of listeners who will be notified when - * the control is selected by the user, by sending it one of the messages - * defined in the SelectionListener interface. - *

- * widgetDefaultSelected is not called. - *

- * - * @param listener the listener which should be notified when the control is - * selected by the user, - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.addSelectionListener(this, listener); - } - - /** - * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - return new Point(Math.max(300, wHint), Math.max(40, hHint)); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the control is selected by the user. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.removeSelectionListener(this, listener); - } - - // ----------------------- Getters & Setters - - /** - * Returns the minimum value which the receiver will allow. - * - * @return the minimum - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getMinimum() { - checkWidget(); - return minimum; - } - - /** - * Sets the minimum value. If this value is greater than the maximum, an exception is thrown - * - * @param value the new minimum - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setMinimum(final int minimum) { - checkWidget(); - if (minimum > maximum) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT, new IllegalArgumentException(String.format("Value %d is greater than the maximum value (%d)", minimum, maximum))); - } - this.minimum = minimum; - redraw(); - update(); - } - - /** - * Returns the maximum value which the receiver will allow. - * - * @return the maximum - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getMaximum() { - checkWidget(); - return maximum; - } - - /** - * Sets the maximum value. If this value is lower than the minimum, an exception is thrown - * - * @param value the new minimum - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setMaximum(final int maximum) { - checkWidget(); - if (maximum < minimum) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT, new IllegalArgumentException(String.format("Value %d is lower than the minimum value (%d)", maximum, minimum))); - } - this.maximum = maximum; - redraw(); - update(); - } - - /** - * Returns the receiver's value. - * - * @return the selection - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getValue() { - checkWidget(); - return value; - } - - /** - * Sets the receiver's value. If the value is lower to minimum or greater than the maximum, an exception is thrown - * - * @param value the new selection (must be zero or greater) - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setValue(final int value) { - checkWidget(); - if (value < minimum || value > maximum) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT, new IllegalArgumentException(String.format("Value %d is not int the range [%d - %d]", value, minimum, maximum))); - } - this.value = value; - xPosition = -1; - redraw(); - update(); - } - - /** - * Return the current renderer for this widget - * - * @return the renderer - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public NebulaSliderGraphicConfiguration getRenderer() { - checkWidget(); - return renderer; - } - - /** - * Sets the renderer for this widget - * - * @param renderer the new renderer - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setRenderer(final NebulaSliderGraphicConfiguration renderer) { - checkWidget(); - this.renderer = renderer; - redraw(); - } - -} +/******************************************************************************* + * Copyright (c) 2018-2024 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.nebulaslider; + +import java.util.function.IntFunction; + +import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Widget; + +/** + * Instances of this class are selectable user interface + * objects that represent a range of positive, numeric values. + * It is like an horizontal slider + *
+ *
Styles:
+ *
(None)
+ *
Events:
+ *
Selection
+ *
+ */ +public class NebulaSlider extends Canvas { + + private NebulaSliderGraphicConfiguration renderer; + + private int minimum; + private int maximum; + private int value; + private int xPosition; + private int mouseDeltaX; + + private boolean moving = false; + + private IntFunction format; + + private int movingValue; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + * @see Widget#getStyle() + */ + public NebulaSlider(final Composite parent, final int style) { + super(parent, checkStyle(style) | SWT.DOUBLE_BUFFERED); + + renderer = new NebularSliderDefaultConfiguration(this); + + minimum = Integer.MIN_VALUE; + maximum = Integer.MAX_VALUE; + value = 0; + xPosition = -1; + + addPaintListener(e -> { + paintControl(e.gc); + }); + addMouseListeners(); + } + + private static int checkStyle(final int style) { + if ((style & SWT.BORDER) != 0) { + return style & ~SWT.BORDER; + } + return 0; + } + + private void paintControl(final GC gc) { + gc.setAdvanced(true); + gc.setAntialias(SWT.ON); + + if (xPosition < 0) { + // Compute xPosition + xPosition = computeXPosition(); + } + boolean enabled = isEnabled(); + drawBar(gc, enabled); + drawSelectionPart(gc, enabled); + drawSelector(gc, enabled); + } + + private void drawBar(final GC gc, boolean enabled) { + final Rectangle rect = getClientArea(); + gc.setForeground(getColor(renderer.getBarBorderColor(), enabled)); + gc.setBackground(getColor(renderer.getBarInsideColor(), enabled)); + + final int hMargin = renderer.getHorizontalMargin(); + final int selectorWidth = renderer.getSelectorWidth(); + final int barHeight = renderer.getBarHeight(); + + final int x = hMargin + selectorWidth / 2; + final int y = (rect.height - barHeight) / 2; + final int width = rect.width - hMargin * 2 - selectorWidth; + + gc.fillRoundRectangle(x, y, width, barHeight, barHeight, barHeight); + gc.drawRoundRectangle(x, y, width, barHeight, barHeight, barHeight); + } + + private void drawSelectionPart(final GC gc, boolean enabled) { + final Rectangle rect = getClientArea(); + gc.setForeground(getColor(renderer.getBarBorderColor(), enabled)); + gc.setBackground(getColor(renderer.getBarSelectionColor(), enabled)); + + final int barHeight = renderer.getBarHeight(); + + final int x = renderer.getHorizontalMargin() + renderer.getSelectorWidth() / 2; + final int y = (rect.height - barHeight) / 2; + + gc.fillRoundRectangle(x, y, xPosition, barHeight, barHeight, barHeight); + gc.drawRoundRectangle(x, y, xPosition, barHeight, barHeight, barHeight); + } + + private int computeXPosition() { + final int originalWidth = getClientArea().width - renderer.getHorizontalMargin() * 2 - renderer.getSelectorWidth(); + final float coeff = value * 1f / (maximum - minimum); + final int position = (int) (coeff * originalWidth); + return position; + } + + private void drawSelector(final GC gc, boolean enabled) { + final Rectangle rect = getClientArea(); + gc.setForeground(getColor(renderer.getSelectorColorBorder(), enabled)); + gc.setBackground(getColor(renderer.getSelectorColor(), enabled)); + + final int hMargin = renderer.getHorizontalMargin(); + + final int selectorWidth = renderer.getSelectorWidth(); + final int selectorHeight = renderer.getSelectorHeight(); + + final int y = (rect.height - selectorHeight) / 2; + + // Draw the body + gc.fillRoundRectangle(hMargin + xPosition, y, selectorWidth, selectorHeight, selectorHeight, selectorHeight); + gc.drawRoundRectangle(hMargin + xPosition, y, selectorWidth, selectorHeight, selectorHeight, selectorHeight); + + // Draw the arrows + gc.setForeground(getColor(renderer.getArrowColor(), enabled)); + gc.setLineWidth(renderer.getArrowLineWidth()); + final int baseY = y + selectorHeight / 2; + gc.drawLine(hMargin + xPosition + 10, baseY, hMargin + xPosition + 17, baseY - 7); + gc.drawLine(hMargin + xPosition + 10, baseY, hMargin + xPosition + 17, baseY + 7); + + gc.drawLine(hMargin + xPosition + selectorWidth - 10, baseY, hMargin + xPosition + selectorWidth - 17, baseY - 7); + gc.drawLine(hMargin + xPosition + selectorWidth - 10, baseY, hMargin + xPosition + selectorWidth - 17, baseY + 7); + + // And the value + gc.setForeground(getColor(renderer.getSelectorTextColor(), enabled)); + gc.setFont(renderer.getTextFont()); + final String valueAsString = stringValueOf(value); + final Point textSize = gc.textExtent(valueAsString); + + final int xText = hMargin + xPosition + selectorWidth / 2; + final int yText = y + selectorHeight / 2; + + gc.drawText(valueAsString, xText - textSize.x / 2, yText - textSize.y / 2, true); + } + + @Override + public void setBounds(int x, int y, int width, int height) { + xPosition = -1; + super.setBounds(x, y, width, height); + } + + @Override + public void setEnabled(boolean enabled) { + if(!enabled && moving) { + moving = false; + } + super.setEnabled(enabled); + } + + private Color getColor(Color color, boolean enabled) { + if(enabled) { + return color; + } + // see https://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale + int red = color.getRed(); + int green = color.getGreen(); + int blue = color.getBlue(); + if(red == green && green == blue) { + return color; + } + int g = (int)(0.299 * red + 0.587 * green + 0.114 * blue); + return new Color(g, g, g); + } + + private String stringValueOf(int value) { + if(format != null) { + return format.apply(value); + } + return String.valueOf(value); + } + + /** + * Set the format that should be used to format the given number to a string. + * + * @param format + * the format or null to use the default format. + */ + public void setLabelFormatProvider(IntFunction format) { + checkWidget(); + this.format = format; + } + + public IntFunction getLabelFormatProvider() { + checkWidget(); + return format; + } + + private void addMouseListeners() { + + addListener(SWT.MouseDown, e -> { + if(isEnabled()) { + final int selectorWidth = renderer.getSelectorWidth(); + final int selectorHeight = renderer.getSelectorHeight(); + + final int y = (getClientArea().height - selectorHeight) / 2; + final Rectangle rect = new Rectangle(xPosition + renderer.getHorizontalMargin(), y, selectorWidth, selectorHeight); + if (!rect.contains(e.x, e.y)) { + return; + } + moving = true; + movingValue = value; + mouseDeltaX = xPosition - e.x; + } + }); + + addListener(SWT.MouseUp, e -> { + moving = false; + mouseDeltaX = 0; + if(movingValue != value) { + SelectionListenerUtil.fireDefaultSelectionListeners(this, e); + } + redraw(); + }); + + addListener(SWT.MouseMove, e -> { + if (!moving) { + return; + } + + xPosition = e.x + mouseDeltaX; + if (xPosition < 0) { + xPosition = 0; + } + final int originalWidth = getClientArea().width - renderer.getHorizontalMargin() * 2 - renderer.getSelectorWidth(); + + if (xPosition > originalWidth) { + xPosition = originalWidth; + } + + // Update value + final float ratio = (float) xPosition / originalWidth; + int value = (int)Math.floor(ratio * (maximum - minimum)); + if(this.value != value) { + this.value = value; + SelectionListenerUtil.fireSelectionListeners(this, e); + } + redraw(); + + }); + } + + + + /** + * Adds the listener to the collection of listeners who will be notified when + * the control is selected by the user, by sending it one of the messages + * defined in the SelectionListener interface. + *

+ * widgetDefaultSelected is not called. + *

+ * + * @param listener the listener which should be notified when the control is + * selected by the user, + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.addSelectionListener(this, listener); + } + + /** + * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + return new Point(Math.max(300, wHint), Math.max(40, hHint)); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.removeSelectionListener(this, listener); + } + + // ----------------------- Getters & Setters + + /** + * Returns the minimum value which the receiver will allow. + * + * @return the minimum + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getMinimum() { + checkWidget(); + return minimum; + } + + /** + * Sets the minimum value. If this value is greater than the maximum, an exception is thrown + * + * @param value the new minimum + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setMinimum(final int minimum) { + checkWidget(); + if (minimum > maximum) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, new IllegalArgumentException(String.format("Value %d is greater than the maximum value (%d)", minimum, maximum))); + } + this.minimum = minimum; + redraw(); + update(); + } + + /** + * Returns the maximum value which the receiver will allow. + * + * @return the maximum + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getMaximum() { + checkWidget(); + return maximum; + } + + /** + * Sets the maximum value. If this value is lower than the minimum, an exception is thrown + * + * @param value the new minimum + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setMaximum(final int maximum) { + checkWidget(); + if (maximum < minimum) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, new IllegalArgumentException(String.format("Value %d is lower than the minimum value (%d)", maximum, minimum))); + } + this.maximum = maximum; + redraw(); + update(); + } + + /** + * Returns the receiver's value. + * + * @return the selection + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public int getValue() { + checkWidget(); + return value; + } + + /** + * Sets the receiver's value. If the value is lower to minimum or greater than the maximum, an exception is thrown + * + * @param value the new selection (must be zero or greater) + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setValue(final int value) { + checkWidget(); + if (value < minimum || value > maximum) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, new IllegalArgumentException(String.format("Value %d is not int the range [%d - %d]", value, minimum, maximum))); + } + this.value = value; + xPosition = -1; + redraw(); + update(); + } + + /** + * Return the current renderer for this widget + * + * @return the renderer + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public NebulaSliderGraphicConfiguration getRenderer() { + checkWidget(); + return renderer; + } + + /** + * Sets the renderer for this widget + * + * @param renderer the new renderer + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setRenderer(final NebulaSliderGraphicConfiguration renderer) { + checkWidget(); + this.renderer = renderer; + redraw(); + } + +} diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebulaSliderGraphicConfiguration.java b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebulaSliderGraphicConfiguration.java index 7ae5c31f5..f2467bb8c 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebulaSliderGraphicConfiguration.java +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebulaSliderGraphicConfiguration.java @@ -1,48 +1,48 @@ -/******************************************************************************* - * Copyright (c) 2024 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.nebulaslider; - -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; - -/** - * Interface that describe the graphical configuration of the NebulaSlider widget - */ -public interface NebulaSliderGraphicConfiguration { - - Color getBarInsideColor(); - - Color getBarBorderColor(); - - Color getBarSelectionColor(); - - Color getSelectorColor(); - - Color getSelectorColorBorder(); - - Color getSelectorTextColor(); - - Color getArrowColor(); - - int getArrowLineWidth(); - - Font getTextFont(); - - int getHorizontalMargin(); - - int getSelectorWidth(); - - int getSelectorHeight(); - - int getBarHeight(); -} +/******************************************************************************* + * Copyright (c) 2024 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.nebulaslider; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; + +/** + * Interface that describe the graphical configuration of the NebulaSlider widget + */ +public interface NebulaSliderGraphicConfiguration { + + Color getBarInsideColor(); + + Color getBarBorderColor(); + + Color getBarSelectionColor(); + + Color getSelectorColor(); + + Color getSelectorColorBorder(); + + Color getSelectorTextColor(); + + Color getArrowColor(); + + int getArrowLineWidth(); + + Font getTextFont(); + + int getHorizontalMargin(); + + int getSelectorWidth(); + + int getSelectorHeight(); + + int getBarHeight(); +} diff --git a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebularSliderDefaultConfiguration.java b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebularSliderDefaultConfiguration.java index 2008818da..9ab98c50b 100644 --- a/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebularSliderDefaultConfiguration.java +++ b/widgets/nebulaslider/org.eclipse.nebula.widgets.nebulaslider/src/org/eclipse/nebula/widgets/opal/nebulaslider/NebularSliderDefaultConfiguration.java @@ -1,118 +1,118 @@ -/******************************************************************************* - * Copyright (c) 2024 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.nebulaslider; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; - -/** - * Default graphic configuration for the NebularSlider widget - */ -public class NebularSliderDefaultConfiguration implements NebulaSliderGraphicConfiguration { - private static final int H_MARGIN = 5; - private static final int SELECTOR_WIDTH = 78; - private static final int BAR_HEIGHT = 12; - private static final int SELECTOR_HEIGHT = 32; - protected final NebulaSlider parentSlider; - private Font font; - - public NebularSliderDefaultConfiguration(final NebulaSlider parentSlider) { - this.parentSlider = parentSlider; - } - - @Override - public Color getBarInsideColor() { - return getAndDisposeColor(225, 225, 225); - } - - @Override - public Color getBarBorderColor() { - return getAndDisposeColor(211, 211, 211); - } - - @Override - public Color getBarSelectionColor() { - return getAndDisposeColor(41, 128, 185); - } - - @Override - public Color getSelectorColor() { - return getAndDisposeColor(52, 152, 219); - } - - @Override - public Color getSelectorColorBorder() { - return getAndDisposeColor(224, 237, 245); - } - - @Override - public Color getSelectorTextColor() { - return getAndDisposeColor(255, 255, 255); - } - - @Override - public Color getArrowColor() { - return getAndDisposeColor(153, 203, 237); - } - - @Override - public Font getTextFont() { - if(font == null || font.isDisposed()) { - final FontData fontData = parentSlider.getFont().getFontData()[0]; - Font newFont = new Font(parentSlider.getDisplay(), fontData.getName(), getFontSize(fontData), SWT.BOLD); - parentSlider.addDisposeListener(e -> { - if(!newFont.isDisposed()) { - newFont.dispose(); - } - }); - this.font = newFont; - } - return font; - } - - protected int getFontSize(FontData fontData) { - return Math.max(fontData.getHeight(), 14); - } - - @Override - public int getHorizontalMargin() { - return H_MARGIN; - } - - @Override - public int getSelectorWidth() { - return SELECTOR_WIDTH; - } - - @Override - public int getSelectorHeight() { - return SELECTOR_HEIGHT; - } - - @Override - public int getBarHeight() { - return BAR_HEIGHT; - } - - protected Color getAndDisposeColor(final int r, final int g, final int b) { - return new Color(r, g, b); - } - - @Override - public int getArrowLineWidth() { - return 3; - } - -} +/******************************************************************************* + * Copyright (c) 2024 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.nebulaslider; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; + +/** + * Default graphic configuration for the NebularSlider widget + */ +public class NebularSliderDefaultConfiguration implements NebulaSliderGraphicConfiguration { + private static final int H_MARGIN = 5; + private static final int SELECTOR_WIDTH = 78; + private static final int BAR_HEIGHT = 12; + private static final int SELECTOR_HEIGHT = 32; + protected final NebulaSlider parentSlider; + private Font font; + + public NebularSliderDefaultConfiguration(final NebulaSlider parentSlider) { + this.parentSlider = parentSlider; + } + + @Override + public Color getBarInsideColor() { + return getAndDisposeColor(225, 225, 225); + } + + @Override + public Color getBarBorderColor() { + return getAndDisposeColor(211, 211, 211); + } + + @Override + public Color getBarSelectionColor() { + return getAndDisposeColor(41, 128, 185); + } + + @Override + public Color getSelectorColor() { + return getAndDisposeColor(52, 152, 219); + } + + @Override + public Color getSelectorColorBorder() { + return getAndDisposeColor(224, 237, 245); + } + + @Override + public Color getSelectorTextColor() { + return getAndDisposeColor(255, 255, 255); + } + + @Override + public Color getArrowColor() { + return getAndDisposeColor(153, 203, 237); + } + + @Override + public Font getTextFont() { + if(font == null || font.isDisposed()) { + final FontData fontData = parentSlider.getFont().getFontData()[0]; + Font newFont = new Font(parentSlider.getDisplay(), fontData.getName(), getFontSize(fontData), SWT.BOLD); + parentSlider.addDisposeListener(e -> { + if(!newFont.isDisposed()) { + newFont.dispose(); + } + }); + this.font = newFont; + } + return font; + } + + protected int getFontSize(FontData fontData) { + return Math.max(fontData.getHeight(), 14); + } + + @Override + public int getHorizontalMargin() { + return H_MARGIN; + } + + @Override + public int getSelectorWidth() { + return SELECTOR_WIDTH; + } + + @Override + public int getSelectorHeight() { + return SELECTOR_HEIGHT; + } + + @Override + public int getBarHeight() { + return BAR_HEIGHT; + } + + protected Color getAndDisposeColor(final int r, final int g, final int b) { + return new Color(r, g, b); + } + + @Override + public int getArrowLineWidth() { + return 3; + } + +} diff --git a/widgets/nebulaslider/pom.xml b/widgets/nebulaslider/pom.xml index 5db3c5531..9128b5c92 100644 --- a/widgets/nebulaslider/pom.xml +++ b/widgets/nebulaslider/pom.xml @@ -1,23 +1,23 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - nebula-parent - ../../releng/org.eclipse.nebula.nebula-parent - - - nebulaslider - pom - 1.1.0-SNAPSHOT - - - org.eclipse.nebula.widgets.nebulaslider - org.eclipse.nebula.widgets.nebulaslider.feature - org.eclipse.nebula.widgets.nebulaslider.snippets - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + nebula-parent + ../../releng/org.eclipse.nebula.nebula-parent + + + nebulaslider + pom + 1.1.0-SNAPSHOT + + + org.eclipse.nebula.widgets.nebulaslider + org.eclipse.nebula.widgets.nebulaslider.feature + org.eclipse.nebula.widgets.nebulaslider.snippets + + + diff --git a/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/NebulaToolbar.java b/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/NebulaToolbar.java index 473bb8337..edd93a60b 100644 --- a/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/NebulaToolbar.java +++ b/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/NebulaToolbar.java @@ -1,1115 +1,1115 @@ -/******************************************************************************* -* Copyright (c) 2010, Lukasz Milewski 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: -* Lukasz Milewski - Initial API and implementation -*******************************************************************************/ -package org.eclipse.nebula.widgets.nebulatoolbar; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MenuAdapter; -import org.eclipse.swt.events.MenuEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; - -/** - * Toolbar widget. Imitates Windows Vista/7 toolbar found in explorer - * application. - * - * @author Lukasz Milewski - * @since 04 June 2009 - */ -public class NebulaToolbar extends Canvas -{ - - public static final int CHEVRON = 1; - - private static final int INDENT = 3; - - public static final int MODE_SEVEN = 1; - - public static final int MODE_VISTA = 0; - - private static String CHEVRON_CHARACTERS = String.valueOf((char) 0x27EB + "" + (char) 0x27EB); - - private boolean active = false; - - private boolean buttonPushed = false; - - private boolean chevronAdded = false; - - private int chevronIndex = -1; - - private int chevronPosition = 0; - - private List hiddenItemsList = new LinkedList(); - - private ToolbarItem items[] = new ToolbarItem[]{}; - - private int itemUnderCursor = -1; - - private int mode = MODE_VISTA; - - private int rightAlignedIndex = -1; - - private int selectedItemIndex = -1; - - /** - * Parameterized constructor. - * - * @param parent Parent widget - * @param style Style - */ - public NebulaToolbar(Composite parent, int style) - { - super(parent, style | SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED); - - addInternalFocusListener(); - addInternalKeyListener(); - addInternalMouseListener(); - addInternalPaintListener(); - } - - /** - * Adds chevron item. - */ - private void addChevron() - { - chevronAdded = true; - chevronIndex = items.length; - - ToolbarItem item = new ToolbarItem(this, CHEVRON); - item.setText(CHEVRON_CHARACTERS); - item.setSelectionListener(new ChevronAction()); - } - - /** - * Adds internal focus listener. - */ - private void addInternalFocusListener() - { - addFocusListener(new FocusListener() - { - - public void focusGained(FocusEvent e) - { - active = true; - - if (selectedItemIndex >= 0) - { - items[selectedItemIndex].setSelected(active); - } - - redraw(); - } - - public void focusLost(FocusEvent e) - { - active = false; - - if (selectedItemIndex >= 0) - { - items[selectedItemIndex].setSelected(active); - } - - redraw(); - } - - }); - } - - /** - * Adds internal key listener. - */ - private void addInternalKeyListener() - { - addKeyListener(new KeyListener() - { - - public void keyPressed(KeyEvent e) - { - handleKeyPressed(e); - } - - public void keyReleased(KeyEvent e) - { - handleKeyReleased(e); - } - - }); - } - - /** - * Adds internal mouse listeners. - */ - private void addInternalMouseListener() - { - addMouseListener(new MouseAdapter() - { - - @Override - public void mouseDown(MouseEvent e) - { - handleMouseDown(e); - } - - @Override - public void mouseUp(MouseEvent e) - { - handleMouseUp(e); - } - - }); - - addMouseTrackListener(new MouseTrackAdapter() - { - - @Override - public void mouseExit(MouseEvent e) - { - handleMouseHover(e); - } - - }); - - addMouseMoveListener(new MouseMoveListener() - { - - public void mouseMove(MouseEvent e) - { - handleMouseHover(e); - } - - }); - } - - /** - * Add internal paint listener. - */ - private void addInternalPaintListener() - { - addListener(SWT.Paint, new Listener() - { - - public void handleEvent(Event e) - { - paint(e.gc); - } - - }); - } - - /** - * Add item to toolbar as last. - * - * @param item ToolbarItem - */ - public void addItem(ToolbarItem item) - { - addItem(item, getItemCount()); - } - - /** - * Add item to toolbar on specific position. - * - * @param item ToolbarItem - * @param position Position - */ - public void addItem(ToolbarItem item, int position) - { - checkWidget(); - - item.calculateSize(); - - items = addItem(items, item, position); - } - - /** - * Generates false mouse event. - * - * @return False mouse event - */ - private MouseEvent generateFalseMouseEvent() - { - if (isDisposed()) - { - return null; - } - - Point cursPos = Display.getDefault().getCursorLocation(); - Point contPos = toControl(cursPos); - - Event event = new Event(); - event.display = Display.getDefault(); - event.widget = this; - - MouseEvent mouseEvent = new MouseEvent(event); - mouseEvent.x = contPos.x; - mouseEvent.y = contPos.y; - - return mouseEvent; - } - - /** - * Returns items count. - * - * @return Items count - */ - public int getItemCount() - { - checkWidget(); - - if (items == null) - { - return 0; - } - - return items.length; - } - - /** - * Returns index of item currently under specific position. If no item - * found, -1 will be returned. - * - * @param x Left position - * @param y Top position - * @return Item index - */ - private int getItemIndexUnderCursor(int x, int y) - { - int[] visibleItems = getVisibleItems(); - int start = INDENT; - - for (int i : visibleItems) - { - ToolbarItem item = items[i]; - - int left = start; - - if (i == rightAlignedIndex) - { - left = getClientArea().width - INDENT - item.getWidth(); - } - else - { - start += item.getWidth(); - } - - int end = left + item.getWidth(); - - if (x >= left && x < end && y >= INDENT && y <= getClientArea().height - INDENT) - { - return i; - } - - } - - return -1; - } - - /** - * Returns mode of widget (Vista/7) - * - * @return Mode - */ - public int getMode() - { - return mode; - } - - /** - * Returns visibile items. - * - * @return Array of indexes - */ - private int[] getVisibleItems() - { - return getVisibleItems(false); - } - - /** - * Returns visible items, additionally can collect hidden items to list. - * - * @param collectHidden Collect hidden items - * @return Array of indexes - */ - private int[] getVisibleItems(boolean collectHidden) - { - if (items == null) - { - return null; - } - - if (collectHidden) - { - hiddenItemsList.clear(); - } - - int index = 0; - int hiddenItems = 0; - - int currentWidth = INDENT; - int maxWidth = getClientArea().width - INDENT; - - if (rightAlignedIndex != -1) - { - maxWidth -= items[rightAlignedIndex].getWidth(); - } - - if (chevronAdded) - { - maxWidth -= items[chevronIndex].getWidth(); - } - - int lastItemIndex = -1; - - List list = new ArrayList(); - - while (index < items.length) - { - ToolbarItem item = items[index]; - - if (!item.isVisible()) - { - index++; - - continue; - } - - if (rightAlignedIndex == index) - { - lastItemIndex = index; - } - else - { - currentWidth += item.getWidth(); - - if (chevronAdded && index > items.length - 4 && index < items.length - 2 && item.getStyle() != CHEVRON) - { - ToolbarItem nextItem; - - if (rightAlignedIndex == index + 1) - { - nextItem = items[index + 2]; - } - else - { - nextItem = items[index + 1]; - } - - if (nextItem.getStyle() == CHEVRON) - { - maxWidth += nextItem.getWidth(); - } - } - - if (currentWidth > maxWidth && item.getStyle() != CHEVRON) - { - if (collectHidden) - { - hiddenItemsList.add(index); - } - - index++; - hiddenItems++; - - continue; - } - - list.add(index); - } - - index++; - } - - if (hiddenItems > 0 && !chevronAdded) - { - addChevron(); - - list.add(items.length - 1); - } - else if (hiddenItems == 0 && chevronAdded) - { - removeChevron(); - - if (itemUnderCursor == chevronIndex) - { - itemUnderCursor = -1; - } - - list.remove(list.indexOf(chevronIndex)); - chevronIndex = -1; - } - - if (lastItemIndex != -1) - { - list.add(lastItemIndex); - } - - int[] result = new int[list.size()]; - - for (int i = 0; i < list.size(); i++) - { - result[i] = list.get(i); - } - - return result; - } - - /** - * Handles key pressed event - * - * @param e KeyEvent - */ - private void handleKeyPressed(KeyEvent e) - { - if (e.stateMask != 0) - { - return; - } - - int newSelectedItemIndex = -1; - int[] visibleItems = getVisibleItems(); - - if (visibleItems.length == 0) - { - return; - } - - if (selectedItemIndex == -1) - { - if (e.keyCode == SWT.ARROW_LEFT) - { - newSelectedItemIndex = visibleItems[0]; - } - else if (e.keyCode == SWT.ARROW_RIGHT) - { - newSelectedItemIndex = visibleItems[visibleItems.length - 1]; - } - } - else - { - int visibleSelectedIndex = -1; - - for (int i = 0; i < visibleItems.length; i++) - { - if (visibleItems[i] == selectedItemIndex) - { - visibleSelectedIndex = i; - } - } - - if (e.keyCode == SWT.ARROW_LEFT) - { - int newSelectedVisibleIndex = visibleSelectedIndex - 1; - - if (newSelectedVisibleIndex < 0) - { - newSelectedVisibleIndex = visibleItems.length - 1; - } - - newSelectedItemIndex = visibleItems[newSelectedVisibleIndex]; - } - else if (e.keyCode == SWT.ARROW_RIGHT) - { - int newSelectedVisibleIndex = visibleSelectedIndex + 1; - - if (newSelectedVisibleIndex > visibleItems.length - 1) - { - newSelectedVisibleIndex = 0; - } - - newSelectedItemIndex = visibleItems[newSelectedVisibleIndex]; - } - else if (e.keyCode == ' ' || e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) - { - // TODO TBD - items[selectedItemIndex].setPushedDown(true); - items[selectedItemIndex].setHovered(true); - - redraw(); - - return; - } - else - { - return; - } - } - - if (selectedItemIndex == newSelectedItemIndex) - { - return; - } - - if (selectedItemIndex >= 0) - { - items[selectedItemIndex].setSelected(false); - } - - items[newSelectedItemIndex].setSelected(true); - selectedItemIndex = newSelectedItemIndex; - - redraw(); - } - - /** - * Handles key released event. - * - * @param e KeyEvent - */ - private void handleKeyReleased(KeyEvent e) - { - if (selectedItemIndex == -1) - { - return; - } - - if (e.keyCode == ' ' || e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) - { - items[selectedItemIndex].setPushedDown(false); - items[selectedItemIndex].setHovered(false); - - redraw(); - - SelectionListener selectionListener = items[selectedItemIndex].getSelectionListener(); - - if (selectionListener == null) - { - return; - } - - Event event = new Event(); - event.widget = this; - - selectionListener.widgetSelected(new SelectionEvent(event)); - } - } - - /** - * Handles mouse down event. - * - * @param e MouseEvent - */ - private void handleMouseDown(MouseEvent e) - { - if (e.x < 0 || e.y < 0 || e.x > getClientArea().width || e.y > getClientArea().height || itemUnderCursor == -1) - { - return; - } - - if (selectedItemIndex >= 0) - { - items[selectedItemIndex].setHovered(false); - items[selectedItemIndex].setPushedDown(false); - items[selectedItemIndex].setSelected(false); - } - - buttonPushed = true; - - selectedItemIndex = getItemIndexUnderCursor(e.x, e.y); - - if (selectedItemIndex >= 0) - { - items[selectedItemIndex].setPushedDown(true); - } - - redraw(); - } - - /** - * Handles mouse hover event. - * - * @param e MouseEvent - */ - private void handleMouseHover(MouseEvent e) - { - int oldItem = itemUnderCursor; - - if (e.x < 0 || e.y < 0 || e.x > getClientArea().width || e.y > getClientArea().height) - { - itemUnderCursor = -1; - } - else - { - itemUnderCursor = getItemIndexUnderCursor(e.x, e.y); - } - - if (buttonPushed) - { - if (selectedItemIndex >= 0) - { - items[selectedItemIndex].setHovered(true); - items[selectedItemIndex].setPushedDown(selectedItemIndex == itemUnderCursor); - } - - redraw(); - - return; - } - - if (oldItem != itemUnderCursor) - { - if (oldItem >= 0) - { - items[oldItem].setHovered(false); - items[oldItem].setPushedDown(false); - } - - if (itemUnderCursor >= 0) - { - items[itemUnderCursor].setHovered(true); - - if (buttonPushed) - { - items[itemUnderCursor].setPushedDown(true); - } - } - - redraw(); - } - } - - /** - * Handles mouse up event. - * - * @param e MouseEvent - */ - private void handleMouseUp(MouseEvent e) - { - if (!buttonPushed) - { - return; - } - - buttonPushed = false; - - if (selectedItemIndex == -1) - { - return; - } - - if (selectedItemIndex != itemUnderCursor) - { - items[selectedItemIndex].setHovered(false); - } - - items[selectedItemIndex].setSelected(true); - - if (e.x < 0 || e.y < 0 || e.x > getClientArea().width || e.y > getClientArea().height || itemUnderCursor == -1) - { - if (selectedItemIndex != itemUnderCursor) - { - redraw(); - } - - return; - } - - items[selectedItemIndex].setPushedDown(false); - items[itemUnderCursor].setHovered(true); - - redraw(); - - int selectedItemIndexFromUp = getItemIndexUnderCursor(e.x, e.y); - if (selectedItemIndexFromUp != selectedItemIndex) - { - return; - } - - SelectionListener selectionListener = items[selectedItemIndex].getSelectionListener(); - - if (selectionListener == null) - { - return; - } - - Event event = new Event(); - event.widget = this; - - selectionListener.widgetSelected(new SelectionEvent(event)); - - MouseEvent newEvent = generateFalseMouseEvent(); - if (newEvent != null && getItemIndexUnderCursor(newEvent.x, newEvent.y) != selectedItemIndexFromUp) - { - items[selectedItemIndex].setHovered(false); - redraw(); - } - } - - /** - * Paint widget on graphical canvas. - * - * @param gc GC - */ - private void paint(GC gc) - { - if (mode == MODE_VISTA) - { - paintVista(gc); - } - else if (mode == MODE_SEVEN) - { - paintSeven(gc); - } - - paintItems(gc); - } - - /** - * Paint items on graphical canvas. - * - * @param gc GC - */ - private void paintItems(GC gc) - { - int[] visibleItems = getVisibleItems(); - - int x = INDENT; - int y = INDENT; - - for (int i = 0; i < visibleItems.length; i++) - { - ToolbarItem item = items[visibleItems[i]]; - - if (visibleItems[i] == rightAlignedIndex) - { - item.paint(gc, getClientArea().width - INDENT - item.getWidth(), y); - - continue; - } - - if (item.getStyle() == CHEVRON) - { - chevronPosition = x; - } - - item.paint(gc, x, y); - x += item.getWidth(); - } - } - - /** - * Paint widgets using Windows Seven mode on graphical canvas. - * - * @param gc GC - */ - private void paintSeven(GC gc) - { - Color defaultForeground = gc.getForeground(); - Color defaultBackground = gc.getBackground(); - - Rectangle rect = getClientArea(); - Device device = gc.getDevice(); - - Color c1 = new Color(device, 249, 252, 255); - Color c2 = new Color(device, 230, 240, 250); - Color c3 = new Color(device, 220, 230, 244); - Color c4 = new Color(device, 221, 233, 247); - - Color ca = new Color(device, 205, 218, 234); - Color cb = new Color(device, 160, 175, 195); - - int middle = (int) Math.ceil(rect.height / 2); - - Pattern patternBg1 = new Pattern(device, 0, 0, 0, middle, c1, c2); - gc.setBackgroundPattern(patternBg1); - gc.fillRectangle(new Rectangle(0, 0, rect.width, middle)); - gc.setBackgroundPattern(null); - - Pattern patternBg2 = new Pattern(device, 0, middle, 0, rect.height - middle, c3, c4); - gc.setBackgroundPattern(patternBg2); - gc.fillRectangle(new Rectangle(0, middle, rect.width, rect.height - middle)); - gc.setBackgroundPattern(null); - - gc.setForeground(ca); - gc.drawLine(0, rect.height - 2, rect.width - 1, rect.height - 2); - - gc.setForeground(cb); - gc.drawLine(0, rect.height - 1, rect.width - 1, rect.height - 1); - - gc.setForeground(defaultForeground); - gc.setBackground(defaultBackground); - gc.setAlpha(255); - - c1.dispose(); - c2.dispose(); - c3.dispose(); - c4.dispose(); - - ca.dispose(); - cb.dispose(); - } - - /** - * Paint widget using Windows Vista mode on graphical canvas. - * - * @param gc GC - */ - private void paintVista(GC gc) - { - Color defaultForeground = gc.getForeground(); - Color defaultBackground = gc.getBackground(); - - Rectangle rect = getClientArea(); - Device device = gc.getDevice(); - - Color c1 = new Color(device, 5, 72, 117); - Color c2 = new Color(device, 25, 108, 119); - Color c3 = new Color(device, 28, 122, 134); - Color wh = getDisplay().getSystemColor(SWT.COLOR_WHITE); - - int middle = (int) Math.ceil(rect.height / 2); - - Pattern patternBg1 = new Pattern(device, 0, 0, rect.width, middle, c1, 255, c3, 255); - gc.setBackgroundPattern(patternBg1); - gc.fillRectangle(new Rectangle(0, 0, rect.width, middle)); - gc.setBackgroundPattern(null); - - Pattern patternBg2 = new Pattern(device, 0, middle, rect.width, rect.height - middle, c1, 255, c2, 255); - gc.setBackgroundPattern(patternBg2); - gc.fillRectangle(new Rectangle(0, middle, rect.width, rect.height - middle)); - gc.setBackgroundPattern(null); - - Pattern patternTopGrad = new Pattern(device, 0, 0, 0, middle, wh, 120, wh, 50); - gc.setBackgroundPattern(patternTopGrad); - gc.fillRectangle(new Rectangle(0, 0, rect.width, middle)); - gc.setBackgroundPattern(null); - - Pattern patternBtmGrad = new Pattern(device, 0, middle + 5, 0, rect.height, c1, 0, wh, 125); - gc.setBackgroundPattern(patternBtmGrad); - gc.fillRectangle(new Rectangle(0, middle + 5, rect.width, rect.height)); - gc.setBackgroundPattern(null); - - gc.setAlpha(125); - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - gc.drawPolygon(new int[]{0, 0, rect.width - 1, 0, rect.width - 1, rect.height - 2, 0, rect.height - 2}); - - gc.setAlpha(200); - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); - gc.drawLine(0, rect.height - 1, rect.width - 1, rect.height - 1); - - gc.setForeground(defaultForeground); - gc.setBackground(defaultBackground); - gc.setAlpha(255); - - c1.dispose(); - c2.dispose(); - c3.dispose(); - - patternBg1.dispose(); - patternBg2.dispose(); - patternTopGrad.dispose(); - patternBtmGrad.dispose(); - } - - /** - * Removes chevron item. - */ - private void removeChevron() - { - removeItem(chevronIndex); - - if (selectedItemIndex == chevronIndex) - { - selectedItemIndex = -1; - } - - chevronAdded = false; - } - - /** - * Removes item on specific position. - * - * @param position Position to remove - */ - public void removeItem(int position) - { - items = removeItem(items, position); - } - - /** - * Sets widget mode. - * - * @param mode Mode - */ - public void setMode(int mode) - { - this.mode = mode; - - redraw(); - } - - /** - * Sets right-aligned item. - * - * @param index Right-aligned item index - */ - public void setRightAligned(int index) - { - rightAlignedIndex = index; - - redraw(); - } - - /** - * Chevron Action - */ - private class ChevronAction implements SelectionListener - { - - public void widgetSelected(SelectionEvent e) - { - getVisibleItems(true); - - final Menu menu = new Menu(getShell(), SWT.POP_UP); - menu.addMenuListener(new MenuAdapter() - { - - @Override - public void menuShown(MenuEvent e) - { - items[selectedItemIndex].setHovered(false); - items[selectedItemIndex].setSelected(true); - - redraw(); - } - - }); - - for (int index : hiddenItemsList) - { - ToolbarItem item = items[index]; - - MenuItem menuItem = new MenuItem(menu, SWT.PUSH); - menuItem.setText(item.getText()); - menuItem.setImage(item.getImage()); - - if (item.getSelectionListener() != null) - { - menuItem.addSelectionListener(item.getSelectionListener()); - } - } - - Point pos = toDisplay(chevronPosition, getClientArea().height); - pos.y -= 3; - - menu.setLocation(pos.x, pos.y); - menu.setVisible(true); - } - - public void widgetDefaultSelected(SelectionEvent e) - { - } - - } - - /** - * Add object to array on specific index. - * - * @param Type of objects - * @param array Array of T objects - * @param object Object - * @param index Index - * @return Modified array of T objects - */ - private T[] addItem(T[] array, T object, int index) - { - int length = 0; - - if (array == null) - { - return null; - } - - length = array.length; - - @SuppressWarnings("unchecked") - T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), length + 1); - - if (array != null) - { - System.arraycopy(array, 0, newArray, 0, length); - } - - if (index != -1) - { - for (int i = newArray.length - 2; i >= index; i--) - { - if (i >= 0) - { - newArray[i + 1] = newArray[i]; - } - } - - newArray[index] = object; - } - else - { - newArray[newArray.length - 1] = object; - } - - return newArray; - } - - /** - * Removes object from array on specific index. - * - * @param Type of objects - * @param array Array of T objects - * @param index Index - * @return Modified array of T objects - */ - private T[] removeItem(T[] array, int index) - { - if (array == null) - { - return null; - } - - @SuppressWarnings("unchecked") - T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length - 1); - - if (index > 0) - { - System.arraycopy(array, 0, newArray, 0, index); - } - - if (index + 1 < array.length) - { - System.arraycopy(array, index + 1, newArray, index, newArray.length - index); - } - - return newArray; - } - -} +/******************************************************************************* +* Copyright (c) 2010, Lukasz Milewski 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: +* Lukasz Milewski - Initial API and implementation +*******************************************************************************/ +package org.eclipse.nebula.widgets.nebulatoolbar; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MenuAdapter; +import org.eclipse.swt.events.MenuEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; + +/** + * Toolbar widget. Imitates Windows Vista/7 toolbar found in explorer + * application. + * + * @author Lukasz Milewski + * @since 04 June 2009 + */ +public class NebulaToolbar extends Canvas +{ + + public static final int CHEVRON = 1; + + private static final int INDENT = 3; + + public static final int MODE_SEVEN = 1; + + public static final int MODE_VISTA = 0; + + private static String CHEVRON_CHARACTERS = String.valueOf((char) 0x27EB + "" + (char) 0x27EB); + + private boolean active = false; + + private boolean buttonPushed = false; + + private boolean chevronAdded = false; + + private int chevronIndex = -1; + + private int chevronPosition = 0; + + private List hiddenItemsList = new LinkedList(); + + private ToolbarItem items[] = new ToolbarItem[]{}; + + private int itemUnderCursor = -1; + + private int mode = MODE_VISTA; + + private int rightAlignedIndex = -1; + + private int selectedItemIndex = -1; + + /** + * Parameterized constructor. + * + * @param parent Parent widget + * @param style Style + */ + public NebulaToolbar(Composite parent, int style) + { + super(parent, style | SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED); + + addInternalFocusListener(); + addInternalKeyListener(); + addInternalMouseListener(); + addInternalPaintListener(); + } + + /** + * Adds chevron item. + */ + private void addChevron() + { + chevronAdded = true; + chevronIndex = items.length; + + ToolbarItem item = new ToolbarItem(this, CHEVRON); + item.setText(CHEVRON_CHARACTERS); + item.setSelectionListener(new ChevronAction()); + } + + /** + * Adds internal focus listener. + */ + private void addInternalFocusListener() + { + addFocusListener(new FocusListener() + { + + public void focusGained(FocusEvent e) + { + active = true; + + if (selectedItemIndex >= 0) + { + items[selectedItemIndex].setSelected(active); + } + + redraw(); + } + + public void focusLost(FocusEvent e) + { + active = false; + + if (selectedItemIndex >= 0) + { + items[selectedItemIndex].setSelected(active); + } + + redraw(); + } + + }); + } + + /** + * Adds internal key listener. + */ + private void addInternalKeyListener() + { + addKeyListener(new KeyListener() + { + + public void keyPressed(KeyEvent e) + { + handleKeyPressed(e); + } + + public void keyReleased(KeyEvent e) + { + handleKeyReleased(e); + } + + }); + } + + /** + * Adds internal mouse listeners. + */ + private void addInternalMouseListener() + { + addMouseListener(new MouseAdapter() + { + + @Override + public void mouseDown(MouseEvent e) + { + handleMouseDown(e); + } + + @Override + public void mouseUp(MouseEvent e) + { + handleMouseUp(e); + } + + }); + + addMouseTrackListener(new MouseTrackAdapter() + { + + @Override + public void mouseExit(MouseEvent e) + { + handleMouseHover(e); + } + + }); + + addMouseMoveListener(new MouseMoveListener() + { + + public void mouseMove(MouseEvent e) + { + handleMouseHover(e); + } + + }); + } + + /** + * Add internal paint listener. + */ + private void addInternalPaintListener() + { + addListener(SWT.Paint, new Listener() + { + + public void handleEvent(Event e) + { + paint(e.gc); + } + + }); + } + + /** + * Add item to toolbar as last. + * + * @param item ToolbarItem + */ + public void addItem(ToolbarItem item) + { + addItem(item, getItemCount()); + } + + /** + * Add item to toolbar on specific position. + * + * @param item ToolbarItem + * @param position Position + */ + public void addItem(ToolbarItem item, int position) + { + checkWidget(); + + item.calculateSize(); + + items = addItem(items, item, position); + } + + /** + * Generates false mouse event. + * + * @return False mouse event + */ + private MouseEvent generateFalseMouseEvent() + { + if (isDisposed()) + { + return null; + } + + Point cursPos = Display.getDefault().getCursorLocation(); + Point contPos = toControl(cursPos); + + Event event = new Event(); + event.display = Display.getDefault(); + event.widget = this; + + MouseEvent mouseEvent = new MouseEvent(event); + mouseEvent.x = contPos.x; + mouseEvent.y = contPos.y; + + return mouseEvent; + } + + /** + * Returns items count. + * + * @return Items count + */ + public int getItemCount() + { + checkWidget(); + + if (items == null) + { + return 0; + } + + return items.length; + } + + /** + * Returns index of item currently under specific position. If no item + * found, -1 will be returned. + * + * @param x Left position + * @param y Top position + * @return Item index + */ + private int getItemIndexUnderCursor(int x, int y) + { + int[] visibleItems = getVisibleItems(); + int start = INDENT; + + for (int i : visibleItems) + { + ToolbarItem item = items[i]; + + int left = start; + + if (i == rightAlignedIndex) + { + left = getClientArea().width - INDENT - item.getWidth(); + } + else + { + start += item.getWidth(); + } + + int end = left + item.getWidth(); + + if (x >= left && x < end && y >= INDENT && y <= getClientArea().height - INDENT) + { + return i; + } + + } + + return -1; + } + + /** + * Returns mode of widget (Vista/7) + * + * @return Mode + */ + public int getMode() + { + return mode; + } + + /** + * Returns visibile items. + * + * @return Array of indexes + */ + private int[] getVisibleItems() + { + return getVisibleItems(false); + } + + /** + * Returns visible items, additionally can collect hidden items to list. + * + * @param collectHidden Collect hidden items + * @return Array of indexes + */ + private int[] getVisibleItems(boolean collectHidden) + { + if (items == null) + { + return null; + } + + if (collectHidden) + { + hiddenItemsList.clear(); + } + + int index = 0; + int hiddenItems = 0; + + int currentWidth = INDENT; + int maxWidth = getClientArea().width - INDENT; + + if (rightAlignedIndex != -1) + { + maxWidth -= items[rightAlignedIndex].getWidth(); + } + + if (chevronAdded) + { + maxWidth -= items[chevronIndex].getWidth(); + } + + int lastItemIndex = -1; + + List list = new ArrayList(); + + while (index < items.length) + { + ToolbarItem item = items[index]; + + if (!item.isVisible()) + { + index++; + + continue; + } + + if (rightAlignedIndex == index) + { + lastItemIndex = index; + } + else + { + currentWidth += item.getWidth(); + + if (chevronAdded && index > items.length - 4 && index < items.length - 2 && item.getStyle() != CHEVRON) + { + ToolbarItem nextItem; + + if (rightAlignedIndex == index + 1) + { + nextItem = items[index + 2]; + } + else + { + nextItem = items[index + 1]; + } + + if (nextItem.getStyle() == CHEVRON) + { + maxWidth += nextItem.getWidth(); + } + } + + if (currentWidth > maxWidth && item.getStyle() != CHEVRON) + { + if (collectHidden) + { + hiddenItemsList.add(index); + } + + index++; + hiddenItems++; + + continue; + } + + list.add(index); + } + + index++; + } + + if (hiddenItems > 0 && !chevronAdded) + { + addChevron(); + + list.add(items.length - 1); + } + else if (hiddenItems == 0 && chevronAdded) + { + removeChevron(); + + if (itemUnderCursor == chevronIndex) + { + itemUnderCursor = -1; + } + + list.remove(list.indexOf(chevronIndex)); + chevronIndex = -1; + } + + if (lastItemIndex != -1) + { + list.add(lastItemIndex); + } + + int[] result = new int[list.size()]; + + for (int i = 0; i < list.size(); i++) + { + result[i] = list.get(i); + } + + return result; + } + + /** + * Handles key pressed event + * + * @param e KeyEvent + */ + private void handleKeyPressed(KeyEvent e) + { + if (e.stateMask != 0) + { + return; + } + + int newSelectedItemIndex = -1; + int[] visibleItems = getVisibleItems(); + + if (visibleItems.length == 0) + { + return; + } + + if (selectedItemIndex == -1) + { + if (e.keyCode == SWT.ARROW_LEFT) + { + newSelectedItemIndex = visibleItems[0]; + } + else if (e.keyCode == SWT.ARROW_RIGHT) + { + newSelectedItemIndex = visibleItems[visibleItems.length - 1]; + } + } + else + { + int visibleSelectedIndex = -1; + + for (int i = 0; i < visibleItems.length; i++) + { + if (visibleItems[i] == selectedItemIndex) + { + visibleSelectedIndex = i; + } + } + + if (e.keyCode == SWT.ARROW_LEFT) + { + int newSelectedVisibleIndex = visibleSelectedIndex - 1; + + if (newSelectedVisibleIndex < 0) + { + newSelectedVisibleIndex = visibleItems.length - 1; + } + + newSelectedItemIndex = visibleItems[newSelectedVisibleIndex]; + } + else if (e.keyCode == SWT.ARROW_RIGHT) + { + int newSelectedVisibleIndex = visibleSelectedIndex + 1; + + if (newSelectedVisibleIndex > visibleItems.length - 1) + { + newSelectedVisibleIndex = 0; + } + + newSelectedItemIndex = visibleItems[newSelectedVisibleIndex]; + } + else if (e.keyCode == ' ' || e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) + { + // TODO TBD + items[selectedItemIndex].setPushedDown(true); + items[selectedItemIndex].setHovered(true); + + redraw(); + + return; + } + else + { + return; + } + } + + if (selectedItemIndex == newSelectedItemIndex) + { + return; + } + + if (selectedItemIndex >= 0) + { + items[selectedItemIndex].setSelected(false); + } + + items[newSelectedItemIndex].setSelected(true); + selectedItemIndex = newSelectedItemIndex; + + redraw(); + } + + /** + * Handles key released event. + * + * @param e KeyEvent + */ + private void handleKeyReleased(KeyEvent e) + { + if (selectedItemIndex == -1) + { + return; + } + + if (e.keyCode == ' ' || e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) + { + items[selectedItemIndex].setPushedDown(false); + items[selectedItemIndex].setHovered(false); + + redraw(); + + SelectionListener selectionListener = items[selectedItemIndex].getSelectionListener(); + + if (selectionListener == null) + { + return; + } + + Event event = new Event(); + event.widget = this; + + selectionListener.widgetSelected(new SelectionEvent(event)); + } + } + + /** + * Handles mouse down event. + * + * @param e MouseEvent + */ + private void handleMouseDown(MouseEvent e) + { + if (e.x < 0 || e.y < 0 || e.x > getClientArea().width || e.y > getClientArea().height || itemUnderCursor == -1) + { + return; + } + + if (selectedItemIndex >= 0) + { + items[selectedItemIndex].setHovered(false); + items[selectedItemIndex].setPushedDown(false); + items[selectedItemIndex].setSelected(false); + } + + buttonPushed = true; + + selectedItemIndex = getItemIndexUnderCursor(e.x, e.y); + + if (selectedItemIndex >= 0) + { + items[selectedItemIndex].setPushedDown(true); + } + + redraw(); + } + + /** + * Handles mouse hover event. + * + * @param e MouseEvent + */ + private void handleMouseHover(MouseEvent e) + { + int oldItem = itemUnderCursor; + + if (e.x < 0 || e.y < 0 || e.x > getClientArea().width || e.y > getClientArea().height) + { + itemUnderCursor = -1; + } + else + { + itemUnderCursor = getItemIndexUnderCursor(e.x, e.y); + } + + if (buttonPushed) + { + if (selectedItemIndex >= 0) + { + items[selectedItemIndex].setHovered(true); + items[selectedItemIndex].setPushedDown(selectedItemIndex == itemUnderCursor); + } + + redraw(); + + return; + } + + if (oldItem != itemUnderCursor) + { + if (oldItem >= 0) + { + items[oldItem].setHovered(false); + items[oldItem].setPushedDown(false); + } + + if (itemUnderCursor >= 0) + { + items[itemUnderCursor].setHovered(true); + + if (buttonPushed) + { + items[itemUnderCursor].setPushedDown(true); + } + } + + redraw(); + } + } + + /** + * Handles mouse up event. + * + * @param e MouseEvent + */ + private void handleMouseUp(MouseEvent e) + { + if (!buttonPushed) + { + return; + } + + buttonPushed = false; + + if (selectedItemIndex == -1) + { + return; + } + + if (selectedItemIndex != itemUnderCursor) + { + items[selectedItemIndex].setHovered(false); + } + + items[selectedItemIndex].setSelected(true); + + if (e.x < 0 || e.y < 0 || e.x > getClientArea().width || e.y > getClientArea().height || itemUnderCursor == -1) + { + if (selectedItemIndex != itemUnderCursor) + { + redraw(); + } + + return; + } + + items[selectedItemIndex].setPushedDown(false); + items[itemUnderCursor].setHovered(true); + + redraw(); + + int selectedItemIndexFromUp = getItemIndexUnderCursor(e.x, e.y); + if (selectedItemIndexFromUp != selectedItemIndex) + { + return; + } + + SelectionListener selectionListener = items[selectedItemIndex].getSelectionListener(); + + if (selectionListener == null) + { + return; + } + + Event event = new Event(); + event.widget = this; + + selectionListener.widgetSelected(new SelectionEvent(event)); + + MouseEvent newEvent = generateFalseMouseEvent(); + if (newEvent != null && getItemIndexUnderCursor(newEvent.x, newEvent.y) != selectedItemIndexFromUp) + { + items[selectedItemIndex].setHovered(false); + redraw(); + } + } + + /** + * Paint widget on graphical canvas. + * + * @param gc GC + */ + private void paint(GC gc) + { + if (mode == MODE_VISTA) + { + paintVista(gc); + } + else if (mode == MODE_SEVEN) + { + paintSeven(gc); + } + + paintItems(gc); + } + + /** + * Paint items on graphical canvas. + * + * @param gc GC + */ + private void paintItems(GC gc) + { + int[] visibleItems = getVisibleItems(); + + int x = INDENT; + int y = INDENT; + + for (int i = 0; i < visibleItems.length; i++) + { + ToolbarItem item = items[visibleItems[i]]; + + if (visibleItems[i] == rightAlignedIndex) + { + item.paint(gc, getClientArea().width - INDENT - item.getWidth(), y); + + continue; + } + + if (item.getStyle() == CHEVRON) + { + chevronPosition = x; + } + + item.paint(gc, x, y); + x += item.getWidth(); + } + } + + /** + * Paint widgets using Windows Seven mode on graphical canvas. + * + * @param gc GC + */ + private void paintSeven(GC gc) + { + Color defaultForeground = gc.getForeground(); + Color defaultBackground = gc.getBackground(); + + Rectangle rect = getClientArea(); + Device device = gc.getDevice(); + + Color c1 = new Color(device, 249, 252, 255); + Color c2 = new Color(device, 230, 240, 250); + Color c3 = new Color(device, 220, 230, 244); + Color c4 = new Color(device, 221, 233, 247); + + Color ca = new Color(device, 205, 218, 234); + Color cb = new Color(device, 160, 175, 195); + + int middle = (int) Math.ceil(rect.height / 2); + + Pattern patternBg1 = new Pattern(device, 0, 0, 0, middle, c1, c2); + gc.setBackgroundPattern(patternBg1); + gc.fillRectangle(new Rectangle(0, 0, rect.width, middle)); + gc.setBackgroundPattern(null); + + Pattern patternBg2 = new Pattern(device, 0, middle, 0, rect.height - middle, c3, c4); + gc.setBackgroundPattern(patternBg2); + gc.fillRectangle(new Rectangle(0, middle, rect.width, rect.height - middle)); + gc.setBackgroundPattern(null); + + gc.setForeground(ca); + gc.drawLine(0, rect.height - 2, rect.width - 1, rect.height - 2); + + gc.setForeground(cb); + gc.drawLine(0, rect.height - 1, rect.width - 1, rect.height - 1); + + gc.setForeground(defaultForeground); + gc.setBackground(defaultBackground); + gc.setAlpha(255); + + c1.dispose(); + c2.dispose(); + c3.dispose(); + c4.dispose(); + + ca.dispose(); + cb.dispose(); + } + + /** + * Paint widget using Windows Vista mode on graphical canvas. + * + * @param gc GC + */ + private void paintVista(GC gc) + { + Color defaultForeground = gc.getForeground(); + Color defaultBackground = gc.getBackground(); + + Rectangle rect = getClientArea(); + Device device = gc.getDevice(); + + Color c1 = new Color(device, 5, 72, 117); + Color c2 = new Color(device, 25, 108, 119); + Color c3 = new Color(device, 28, 122, 134); + Color wh = getDisplay().getSystemColor(SWT.COLOR_WHITE); + + int middle = (int) Math.ceil(rect.height / 2); + + Pattern patternBg1 = new Pattern(device, 0, 0, rect.width, middle, c1, 255, c3, 255); + gc.setBackgroundPattern(patternBg1); + gc.fillRectangle(new Rectangle(0, 0, rect.width, middle)); + gc.setBackgroundPattern(null); + + Pattern patternBg2 = new Pattern(device, 0, middle, rect.width, rect.height - middle, c1, 255, c2, 255); + gc.setBackgroundPattern(patternBg2); + gc.fillRectangle(new Rectangle(0, middle, rect.width, rect.height - middle)); + gc.setBackgroundPattern(null); + + Pattern patternTopGrad = new Pattern(device, 0, 0, 0, middle, wh, 120, wh, 50); + gc.setBackgroundPattern(patternTopGrad); + gc.fillRectangle(new Rectangle(0, 0, rect.width, middle)); + gc.setBackgroundPattern(null); + + Pattern patternBtmGrad = new Pattern(device, 0, middle + 5, 0, rect.height, c1, 0, wh, 125); + gc.setBackgroundPattern(patternBtmGrad); + gc.fillRectangle(new Rectangle(0, middle + 5, rect.width, rect.height)); + gc.setBackgroundPattern(null); + + gc.setAlpha(125); + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + gc.drawPolygon(new int[]{0, 0, rect.width - 1, 0, rect.width - 1, rect.height - 2, 0, rect.height - 2}); + + gc.setAlpha(200); + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); + gc.drawLine(0, rect.height - 1, rect.width - 1, rect.height - 1); + + gc.setForeground(defaultForeground); + gc.setBackground(defaultBackground); + gc.setAlpha(255); + + c1.dispose(); + c2.dispose(); + c3.dispose(); + + patternBg1.dispose(); + patternBg2.dispose(); + patternTopGrad.dispose(); + patternBtmGrad.dispose(); + } + + /** + * Removes chevron item. + */ + private void removeChevron() + { + removeItem(chevronIndex); + + if (selectedItemIndex == chevronIndex) + { + selectedItemIndex = -1; + } + + chevronAdded = false; + } + + /** + * Removes item on specific position. + * + * @param position Position to remove + */ + public void removeItem(int position) + { + items = removeItem(items, position); + } + + /** + * Sets widget mode. + * + * @param mode Mode + */ + public void setMode(int mode) + { + this.mode = mode; + + redraw(); + } + + /** + * Sets right-aligned item. + * + * @param index Right-aligned item index + */ + public void setRightAligned(int index) + { + rightAlignedIndex = index; + + redraw(); + } + + /** + * Chevron Action + */ + private class ChevronAction implements SelectionListener + { + + public void widgetSelected(SelectionEvent e) + { + getVisibleItems(true); + + final Menu menu = new Menu(getShell(), SWT.POP_UP); + menu.addMenuListener(new MenuAdapter() + { + + @Override + public void menuShown(MenuEvent e) + { + items[selectedItemIndex].setHovered(false); + items[selectedItemIndex].setSelected(true); + + redraw(); + } + + }); + + for (int index : hiddenItemsList) + { + ToolbarItem item = items[index]; + + MenuItem menuItem = new MenuItem(menu, SWT.PUSH); + menuItem.setText(item.getText()); + menuItem.setImage(item.getImage()); + + if (item.getSelectionListener() != null) + { + menuItem.addSelectionListener(item.getSelectionListener()); + } + } + + Point pos = toDisplay(chevronPosition, getClientArea().height); + pos.y -= 3; + + menu.setLocation(pos.x, pos.y); + menu.setVisible(true); + } + + public void widgetDefaultSelected(SelectionEvent e) + { + } + + } + + /** + * Add object to array on specific index. + * + * @param Type of objects + * @param array Array of T objects + * @param object Object + * @param index Index + * @return Modified array of T objects + */ + private T[] addItem(T[] array, T object, int index) + { + int length = 0; + + if (array == null) + { + return null; + } + + length = array.length; + + @SuppressWarnings("unchecked") + T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), length + 1); + + if (array != null) + { + System.arraycopy(array, 0, newArray, 0, length); + } + + if (index != -1) + { + for (int i = newArray.length - 2; i >= index; i--) + { + if (i >= 0) + { + newArray[i + 1] = newArray[i]; + } + } + + newArray[index] = object; + } + else + { + newArray[newArray.length - 1] = object; + } + + return newArray; + } + + /** + * Removes object from array on specific index. + * + * @param Type of objects + * @param array Array of T objects + * @param index Index + * @return Modified array of T objects + */ + private T[] removeItem(T[] array, int index) + { + if (array == null) + { + return null; + } + + @SuppressWarnings("unchecked") + T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length - 1); + + if (index > 0) + { + System.arraycopy(array, 0, newArray, 0, index); + } + + if (index + 1 < array.length) + { + System.arraycopy(array, index + 1, newArray, index, newArray.length - index); + } + + return newArray; + } + +} diff --git a/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/ToolbarItem.java b/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/ToolbarItem.java index 06ec29bb5..e12c0d96f 100644 --- a/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/ToolbarItem.java +++ b/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/ToolbarItem.java @@ -1,640 +1,640 @@ -/******************************************************************************* - * Copyright (c) 2010, Lukasz Milewski 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: Lukasz Milewski - Initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.nebulatoolbar; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Widget; - -/** - * Default ToolbarItem implementation. Draw item using two different styles, - * Vista and 7. - * - * @author Lukasz Milewski - * @since 25 May 2009 - */ -public class ToolbarItem extends Item -{ - - protected SelectionListener selectionListener; - - protected boolean hovered = false; - - protected Image image; - - protected Menu menu; - - private NebulaToolbar parent; - - protected boolean pushedDown = false; - - protected boolean selected = false; - - protected int style; - - protected String text = ""; - - protected String tooltip = ""; - - protected int width; - - /** - * Parameterized constructor with all fields. - * - * @param parent Parent widget, should be NebulaToolbar - * @param action Selection listener - * @param text Text - * @param tooltip Tooltip text - * @param image Image - * @param style Style of item - */ - public ToolbarItem(Widget parent, SelectionListener action, String text, String tooltip, Image image, int style) - { - this(parent, style); - - this.selectionListener = action; - this.text = text; - this.tooltip = tooltip; - this.image = image; - this.style = style; - - ((NebulaToolbar) parent).addItem(this); - } - - /** - * Parameterized constructor. - * - * @param parent Parent widget, should be NebulaToolbar - * @param style Style of item - */ - public ToolbarItem(Widget parent, int style) - { - super(parent, style); - - this.parent = (NebulaToolbar) parent; - this.style = style; - - ((NebulaToolbar) parent).addItem(this); - } - - /** - * Calculate size of item. - */ - public void calculateSize() - { - Image calcSizeImage = new Image(Display.getDefault(), 1, 1); - - GC gc = new GC(calcSizeImage); - gc.setAdvanced(true); - gc.setAntialias(SWT.OFF); - gc.setFont(parent.getFont()); - - width = 10; - - if (image != null) - { - width += image.getImageData().width; - } - - if (text.length() > 0) - { - width += getTextWidth(gc, text) + 9; - } - - gc.dispose(); - calcSizeImage.dispose(); - } - - /** - * Returns context menu. - * - * @return Menu - */ - public Menu getContextMenu() - { - return menu; - } - - /** - * Returns item image. - * - * @return Image - */ - public Image getImage() - { - return image; - } - - /** - * Returns SelectionListener. - * TODO should be replaced with array of listeners - * - * @return SelectionListener - */ - public SelectionListener getSelectionListener() - { - return selectionListener; - } - - /** - * Returns style of item. - * - * @return Style - */ - public int getStyle() - { - return style; - } - - /** - * Returns text of item. - * - * @return Text - */ - public String getText() - { - return text; - } - - /** - * Returns text width. - * - * @param text Text - * @return Width - */ - private int getTextWidth(GC gc, String text) - { - if (text.endsWith(" ")) - { - return gc.textExtent(text).x; - } - - return gc.textExtent(text).x; - } - - /** - * Returns tooltip text of item. - * - * @return Tooltip text - */ - public String getTooltip() - { - return tooltip; - } - - /** - * Returns width of item. - * - * @return Width - */ - public int getWidth() - { - return width; - } - - /** - * Returns hovered state of item. - * - * @return Hovered state - */ - public boolean isHovered() - { - return hovered; - } - - /** - * Returns pushed down state of item. - * - * @return Pushed down state - */ - public boolean isPushedDown() - { - return pushedDown; - } - - /** - * Returns selected state of item. - * - * @return Selected state - */ - public boolean isSelected() - { - return selected; - } - - /** - * Returns visibility of item. - * - * @return Visibility - */ - public boolean isVisible() - { - return true; - } - - /** - * Paint item on graphical canvas. - * - * @param gc GC - * @param x Left position - * @param y Top position - */ - public void paint(GC gc, int x, int y) - { - if (parent.getMode() == NebulaToolbar.MODE_VISTA) - { - paintVista(gc, x, y); - } - else - { - paintSeven(gc, x, y); - } - } - - /** - * Paint item on graphical canvas using Windows 7 style. - * - * @param gc GC - * @param x Left position - * @param y Top position - */ - private void paintSeven(GC gc, int x, int y) - { - int imageX = x + 5; - int imageY = y + 4; - - int imageWidth = 0; - - if (image != null) - { - imageWidth = image.getImageData().width; - } - - if (pushedDown) - { - imageX++; - imageY++; - } - - int textX = imageX + imageWidth + 5; - int textY = imageY; - - Color defaultForegroundColor = gc.getForeground(); - - Color darkBorder = new Color(gc.getDevice(), 179, 196, 216); - Color lightBorder = new Color(gc.getDevice(), 252, 253, 254); - - if (pushedDown) - { - darkBorder.dispose(); - darkBorder = new Color(gc.getDevice(), 181, 197, 217); - } - - if (pushedDown || hovered || selected) - { - gc.setAntialias(SWT.ON); - - gc.setForeground(darkBorder); - gc.drawRoundRectangle(x, y, width - 1, 23, 4, 4); - - if (!pushedDown) - { - gc.setForeground(lightBorder); - gc.drawRoundRectangle(x + 1, y + 1, width - 3 + (pushedDown ? 1 : 0), 21 + (pushedDown ? 1 : 0), 4, 4); - } - - if (pushedDown || hovered) - { - Color c1 = null; - Color c2 = null; - Color c3 = null; - Color c4 = null; - - if (pushedDown) - { - c1 = new Color(gc.getDevice(), 201, 212, 228); - c2 = new Color(gc.getDevice(), 216, 228, 241); - c3 = new Color(gc.getDevice(), 207, 219, 236); - c4 = new Color(gc.getDevice(), 207, 220, 237); - } - else - { - c1 = new Color(gc.getDevice(), 248, 251, 254); - c2 = new Color(gc.getDevice(), 237, 242, 250); - c3 = new Color(gc.getDevice(), 215, 228, 244); - c4 = new Color(gc.getDevice(), 193, 210, 232); - } - - int middle = y + 12; - - int pattLeft = x + 1 + (!pushedDown ? 1 : 0); - int pattTop = y + 1 + (!pushedDown ? 1 : 0); - int pattWidth = width - (2 + (!pushedDown ? 2 : 0)); - int pattHeight = y + 22 + (pushedDown ? 1 : 0); - - Pattern patternTop = new Pattern(gc.getDevice(), 0, pattTop, 0, middle, c1, c2); - Pattern patternBtm = new Pattern(gc.getDevice(), 0, middle, 0, pattHeight, c3, c4); - - gc.setBackgroundPattern(patternTop); - gc.fillRoundRectangle(pattLeft, pattTop, pattWidth, middle, 4, 4); - - gc.setBackgroundPattern(patternBtm); - gc.fillRoundRectangle(pattLeft, middle, pattWidth, pattHeight - middle, 4, 4); - gc.fillRectangle(pattLeft, middle, pattWidth, 5); - - gc.setBackgroundPattern(null); - - patternTop.dispose(); - patternBtm.dispose(); - - c1.dispose(); - c2.dispose(); - c3.dispose(); - c4.dispose(); - } - } - - if (image != null) - { - gc.drawImage(image, imageX, imageY); - } - - if (text.length() > 0) - { - Font systemFont = null; - Font defaultFont = gc.getFont(); - boolean adv = gc.getAdvanced(); - - if (style == NebulaToolbar.CHEVRON) - { - systemFont = new Font(gc.getDevice(), "System", 8, 0); // TODO change that - gc.setFont(systemFont); - gc.setAdvanced(false); - - textX -= 1; - textY -= 2; - } - - gc.setForeground(defaultForegroundColor); // TODO change that - gc.drawText(text, textX, textY, true); - - if (systemFont != null) - { - gc.setAdvanced(adv); - gc.setFont(defaultFont); - systemFont.dispose(); - } - } - - gc.setForeground(defaultForegroundColor); - - darkBorder.dispose(); - lightBorder.dispose(); - } - - /** - * Paint item on graphical canvas using Windows Vista style. - * - * @param gc GC - * @param x Left position - * @param y Top position - */ - private void paintVista(GC gc, int x, int y) - { - Display display = parent.getDisplay(); - - int imageX = x + 5; - int imageY = y + 4; - - int imageWidth = 0; - - if (image != null) - { - imageWidth = image.getImageData().width; - } - - if (pushedDown) - { - imageX++; - imageY++; - } - - int textX = imageX + imageWidth + 5; - int textY = imageY; - - int alphaTop = 75; - int alphaBottom = 5; - - int borderAlphaDark = 0; - int borderAlphaLight = 0; - - Color defaultForegroundColor = gc.getForeground(); - - Color lightBorder = display.getSystemColor(SWT.COLOR_WHITE); - - if (pushedDown) - { - borderAlphaDark = 150; - borderAlphaLight = 75; - - lightBorder = display.getSystemColor(SWT.COLOR_BLACK); - alphaTop = 75; - } - else if (hovered) - { - borderAlphaDark = 100; - borderAlphaLight = 150; - } - else if (selected) - { - borderAlphaDark = 65; - borderAlphaLight = 105; - } - - if (pushedDown || hovered || selected) - { - gc.setAntialias(SWT.ON); - - gc.setAlpha(borderAlphaDark); - gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); - gc.drawRoundRectangle(x, y, width - 1, 23, 4, 4); - - gc.setAlpha(borderAlphaLight); - gc.setForeground(lightBorder); - gc.drawRoundRectangle(x + 1, y + 1, width - 3 + (pushedDown ? 1 : 0), 21 + (pushedDown ? 1 : 0), 4, 4); - - gc.setAlpha(255); - - if (pushedDown || hovered) - { - int pattHeight = y + 22; - - if (pushedDown) - { - pattHeight = y + 16; - } - - Pattern pattern = new Pattern(gc.getDevice(), 0, y + 2, 0, pattHeight, lightBorder, alphaTop, lightBorder, alphaBottom); - - gc.setBackgroundPattern(pattern); - gc.fillRoundRectangle(x + 2, y + 2, width - 4 + (pushedDown ? 1 : 0), pattHeight - 5, 4, 4); - gc.setBackgroundPattern(null); - - pattern.dispose(); - } - } - - if (image != null) - { - gc.drawImage(image, imageX, imageY); - } - - if (text.length() > 0) - { - Font systemFont = null; - Font defaultFont = gc.getFont(); - - if (style == NebulaToolbar.CHEVRON) - { - systemFont = new Font(gc.getDevice(), "System", 8, 0); // TODO change that - gc.setFont(systemFont); - - textX -= 1; - textY -= 2; - } - - gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); - gc.drawText(text, textX, textY, true); - - if (systemFont != null) - { - gc.setFont(defaultFont); - systemFont.dispose(); - } - } - - gc.setForeground(defaultForegroundColor); - } - - /** - * Set SelectionListener - * TODO should be replaced with array of listeners - * - * @param selectionListener SelectionListener - */ - public void setSelectionListener(SelectionListener selectionListener) - { - this.selectionListener = selectionListener; - } - - /** - * Sets context menu. - * - * @param menu New context menu - */ - public void setContextMenu(Menu menu) - { - this.menu = menu; - } - - /** - * Sets hovered state of item. - * - * @param hovered New hovered state - */ - public void setHovered(boolean hovered) - { - this.hovered = hovered; - } - - /** - * Sets image. - * - * @param image New image - */ - public void setImage(Image image) - { - this.image = image; - - calculateSize(); - } - - /** - * Sets pushed down state of item. - * - * @param pushedDown New pushed down state - */ - public void setPushedDown(boolean pushedDown) - { - this.pushedDown = pushedDown; - } - - /** - * Sets selected state of item. - * - * @param selected New selected state - */ - public void setSelected(boolean selected) - { - this.selected = selected; - } - - /** - * Sets style of item. - * - * @param style New style - */ - public void setStyle(int style) - { - this.style = style; - } - - /** - * Sets text. - * - * @param text New text - */ - public void setText(String text) - { - this.text = text; - - calculateSize(); - } - - /** - * Sets tooltip text of item. - * - * @param tooltip New tooltip text - */ - public void setTooltip(String tooltip) - { - this.tooltip = tooltip; - } - - /** - * Sets visibility of item. - * TODO visibility state is not currently handled. - * - * @param visible New visibility - */ - public void setVisible(boolean visible) - { - // TODO Should and will be implemented along JFace stuff - } - -} +/******************************************************************************* + * Copyright (c) 2010, Lukasz Milewski 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: Lukasz Milewski - Initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.nebulatoolbar; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Widget; + +/** + * Default ToolbarItem implementation. Draw item using two different styles, + * Vista and 7. + * + * @author Lukasz Milewski + * @since 25 May 2009 + */ +public class ToolbarItem extends Item +{ + + protected SelectionListener selectionListener; + + protected boolean hovered = false; + + protected Image image; + + protected Menu menu; + + private NebulaToolbar parent; + + protected boolean pushedDown = false; + + protected boolean selected = false; + + protected int style; + + protected String text = ""; + + protected String tooltip = ""; + + protected int width; + + /** + * Parameterized constructor with all fields. + * + * @param parent Parent widget, should be NebulaToolbar + * @param action Selection listener + * @param text Text + * @param tooltip Tooltip text + * @param image Image + * @param style Style of item + */ + public ToolbarItem(Widget parent, SelectionListener action, String text, String tooltip, Image image, int style) + { + this(parent, style); + + this.selectionListener = action; + this.text = text; + this.tooltip = tooltip; + this.image = image; + this.style = style; + + ((NebulaToolbar) parent).addItem(this); + } + + /** + * Parameterized constructor. + * + * @param parent Parent widget, should be NebulaToolbar + * @param style Style of item + */ + public ToolbarItem(Widget parent, int style) + { + super(parent, style); + + this.parent = (NebulaToolbar) parent; + this.style = style; + + ((NebulaToolbar) parent).addItem(this); + } + + /** + * Calculate size of item. + */ + public void calculateSize() + { + Image calcSizeImage = new Image(Display.getDefault(), 1, 1); + + GC gc = new GC(calcSizeImage); + gc.setAdvanced(true); + gc.setAntialias(SWT.OFF); + gc.setFont(parent.getFont()); + + width = 10; + + if (image != null) + { + width += image.getImageData().width; + } + + if (text.length() > 0) + { + width += getTextWidth(gc, text) + 9; + } + + gc.dispose(); + calcSizeImage.dispose(); + } + + /** + * Returns context menu. + * + * @return Menu + */ + public Menu getContextMenu() + { + return menu; + } + + /** + * Returns item image. + * + * @return Image + */ + public Image getImage() + { + return image; + } + + /** + * Returns SelectionListener. + * TODO should be replaced with array of listeners + * + * @return SelectionListener + */ + public SelectionListener getSelectionListener() + { + return selectionListener; + } + + /** + * Returns style of item. + * + * @return Style + */ + public int getStyle() + { + return style; + } + + /** + * Returns text of item. + * + * @return Text + */ + public String getText() + { + return text; + } + + /** + * Returns text width. + * + * @param text Text + * @return Width + */ + private int getTextWidth(GC gc, String text) + { + if (text.endsWith(" ")) + { + return gc.textExtent(text).x; + } + + return gc.textExtent(text).x; + } + + /** + * Returns tooltip text of item. + * + * @return Tooltip text + */ + public String getTooltip() + { + return tooltip; + } + + /** + * Returns width of item. + * + * @return Width + */ + public int getWidth() + { + return width; + } + + /** + * Returns hovered state of item. + * + * @return Hovered state + */ + public boolean isHovered() + { + return hovered; + } + + /** + * Returns pushed down state of item. + * + * @return Pushed down state + */ + public boolean isPushedDown() + { + return pushedDown; + } + + /** + * Returns selected state of item. + * + * @return Selected state + */ + public boolean isSelected() + { + return selected; + } + + /** + * Returns visibility of item. + * + * @return Visibility + */ + public boolean isVisible() + { + return true; + } + + /** + * Paint item on graphical canvas. + * + * @param gc GC + * @param x Left position + * @param y Top position + */ + public void paint(GC gc, int x, int y) + { + if (parent.getMode() == NebulaToolbar.MODE_VISTA) + { + paintVista(gc, x, y); + } + else + { + paintSeven(gc, x, y); + } + } + + /** + * Paint item on graphical canvas using Windows 7 style. + * + * @param gc GC + * @param x Left position + * @param y Top position + */ + private void paintSeven(GC gc, int x, int y) + { + int imageX = x + 5; + int imageY = y + 4; + + int imageWidth = 0; + + if (image != null) + { + imageWidth = image.getImageData().width; + } + + if (pushedDown) + { + imageX++; + imageY++; + } + + int textX = imageX + imageWidth + 5; + int textY = imageY; + + Color defaultForegroundColor = gc.getForeground(); + + Color darkBorder = new Color(gc.getDevice(), 179, 196, 216); + Color lightBorder = new Color(gc.getDevice(), 252, 253, 254); + + if (pushedDown) + { + darkBorder.dispose(); + darkBorder = new Color(gc.getDevice(), 181, 197, 217); + } + + if (pushedDown || hovered || selected) + { + gc.setAntialias(SWT.ON); + + gc.setForeground(darkBorder); + gc.drawRoundRectangle(x, y, width - 1, 23, 4, 4); + + if (!pushedDown) + { + gc.setForeground(lightBorder); + gc.drawRoundRectangle(x + 1, y + 1, width - 3 + (pushedDown ? 1 : 0), 21 + (pushedDown ? 1 : 0), 4, 4); + } + + if (pushedDown || hovered) + { + Color c1 = null; + Color c2 = null; + Color c3 = null; + Color c4 = null; + + if (pushedDown) + { + c1 = new Color(gc.getDevice(), 201, 212, 228); + c2 = new Color(gc.getDevice(), 216, 228, 241); + c3 = new Color(gc.getDevice(), 207, 219, 236); + c4 = new Color(gc.getDevice(), 207, 220, 237); + } + else + { + c1 = new Color(gc.getDevice(), 248, 251, 254); + c2 = new Color(gc.getDevice(), 237, 242, 250); + c3 = new Color(gc.getDevice(), 215, 228, 244); + c4 = new Color(gc.getDevice(), 193, 210, 232); + } + + int middle = y + 12; + + int pattLeft = x + 1 + (!pushedDown ? 1 : 0); + int pattTop = y + 1 + (!pushedDown ? 1 : 0); + int pattWidth = width - (2 + (!pushedDown ? 2 : 0)); + int pattHeight = y + 22 + (pushedDown ? 1 : 0); + + Pattern patternTop = new Pattern(gc.getDevice(), 0, pattTop, 0, middle, c1, c2); + Pattern patternBtm = new Pattern(gc.getDevice(), 0, middle, 0, pattHeight, c3, c4); + + gc.setBackgroundPattern(patternTop); + gc.fillRoundRectangle(pattLeft, pattTop, pattWidth, middle, 4, 4); + + gc.setBackgroundPattern(patternBtm); + gc.fillRoundRectangle(pattLeft, middle, pattWidth, pattHeight - middle, 4, 4); + gc.fillRectangle(pattLeft, middle, pattWidth, 5); + + gc.setBackgroundPattern(null); + + patternTop.dispose(); + patternBtm.dispose(); + + c1.dispose(); + c2.dispose(); + c3.dispose(); + c4.dispose(); + } + } + + if (image != null) + { + gc.drawImage(image, imageX, imageY); + } + + if (text.length() > 0) + { + Font systemFont = null; + Font defaultFont = gc.getFont(); + boolean adv = gc.getAdvanced(); + + if (style == NebulaToolbar.CHEVRON) + { + systemFont = new Font(gc.getDevice(), "System", 8, 0); // TODO change that + gc.setFont(systemFont); + gc.setAdvanced(false); + + textX -= 1; + textY -= 2; + } + + gc.setForeground(defaultForegroundColor); // TODO change that + gc.drawText(text, textX, textY, true); + + if (systemFont != null) + { + gc.setAdvanced(adv); + gc.setFont(defaultFont); + systemFont.dispose(); + } + } + + gc.setForeground(defaultForegroundColor); + + darkBorder.dispose(); + lightBorder.dispose(); + } + + /** + * Paint item on graphical canvas using Windows Vista style. + * + * @param gc GC + * @param x Left position + * @param y Top position + */ + private void paintVista(GC gc, int x, int y) + { + Display display = parent.getDisplay(); + + int imageX = x + 5; + int imageY = y + 4; + + int imageWidth = 0; + + if (image != null) + { + imageWidth = image.getImageData().width; + } + + if (pushedDown) + { + imageX++; + imageY++; + } + + int textX = imageX + imageWidth + 5; + int textY = imageY; + + int alphaTop = 75; + int alphaBottom = 5; + + int borderAlphaDark = 0; + int borderAlphaLight = 0; + + Color defaultForegroundColor = gc.getForeground(); + + Color lightBorder = display.getSystemColor(SWT.COLOR_WHITE); + + if (pushedDown) + { + borderAlphaDark = 150; + borderAlphaLight = 75; + + lightBorder = display.getSystemColor(SWT.COLOR_BLACK); + alphaTop = 75; + } + else if (hovered) + { + borderAlphaDark = 100; + borderAlphaLight = 150; + } + else if (selected) + { + borderAlphaDark = 65; + borderAlphaLight = 105; + } + + if (pushedDown || hovered || selected) + { + gc.setAntialias(SWT.ON); + + gc.setAlpha(borderAlphaDark); + gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); + gc.drawRoundRectangle(x, y, width - 1, 23, 4, 4); + + gc.setAlpha(borderAlphaLight); + gc.setForeground(lightBorder); + gc.drawRoundRectangle(x + 1, y + 1, width - 3 + (pushedDown ? 1 : 0), 21 + (pushedDown ? 1 : 0), 4, 4); + + gc.setAlpha(255); + + if (pushedDown || hovered) + { + int pattHeight = y + 22; + + if (pushedDown) + { + pattHeight = y + 16; + } + + Pattern pattern = new Pattern(gc.getDevice(), 0, y + 2, 0, pattHeight, lightBorder, alphaTop, lightBorder, alphaBottom); + + gc.setBackgroundPattern(pattern); + gc.fillRoundRectangle(x + 2, y + 2, width - 4 + (pushedDown ? 1 : 0), pattHeight - 5, 4, 4); + gc.setBackgroundPattern(null); + + pattern.dispose(); + } + } + + if (image != null) + { + gc.drawImage(image, imageX, imageY); + } + + if (text.length() > 0) + { + Font systemFont = null; + Font defaultFont = gc.getFont(); + + if (style == NebulaToolbar.CHEVRON) + { + systemFont = new Font(gc.getDevice(), "System", 8, 0); // TODO change that + gc.setFont(systemFont); + + textX -= 1; + textY -= 2; + } + + gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); + gc.drawText(text, textX, textY, true); + + if (systemFont != null) + { + gc.setFont(defaultFont); + systemFont.dispose(); + } + } + + gc.setForeground(defaultForegroundColor); + } + + /** + * Set SelectionListener + * TODO should be replaced with array of listeners + * + * @param selectionListener SelectionListener + */ + public void setSelectionListener(SelectionListener selectionListener) + { + this.selectionListener = selectionListener; + } + + /** + * Sets context menu. + * + * @param menu New context menu + */ + public void setContextMenu(Menu menu) + { + this.menu = menu; + } + + /** + * Sets hovered state of item. + * + * @param hovered New hovered state + */ + public void setHovered(boolean hovered) + { + this.hovered = hovered; + } + + /** + * Sets image. + * + * @param image New image + */ + public void setImage(Image image) + { + this.image = image; + + calculateSize(); + } + + /** + * Sets pushed down state of item. + * + * @param pushedDown New pushed down state + */ + public void setPushedDown(boolean pushedDown) + { + this.pushedDown = pushedDown; + } + + /** + * Sets selected state of item. + * + * @param selected New selected state + */ + public void setSelected(boolean selected) + { + this.selected = selected; + } + + /** + * Sets style of item. + * + * @param style New style + */ + public void setStyle(int style) + { + this.style = style; + } + + /** + * Sets text. + * + * @param text New text + */ + public void setText(String text) + { + this.text = text; + + calculateSize(); + } + + /** + * Sets tooltip text of item. + * + * @param tooltip New tooltip text + */ + public void setTooltip(String tooltip) + { + this.tooltip = tooltip; + } + + /** + * Sets visibility of item. + * TODO visibility state is not currently handled. + * + * @param visible New visibility + */ + public void setVisible(boolean visible) + { + // TODO Should and will be implemented along JFace stuff + } + +} diff --git a/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/test/NebulaToolbarTest.java b/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/test/NebulaToolbarTest.java index 76c4e9637..7a34ca882 100644 --- a/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/test/NebulaToolbarTest.java +++ b/widgets/nebulatoolbar/src/org/eclipse/nebula/widgets/nebulatoolbar/test/NebulaToolbarTest.java @@ -1,91 +1,91 @@ -/******************************************************************************* -* Copyright (c) 2010, Lukasz Milewski 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: -* Lukasz Milewski - Initial API and implementation -*******************************************************************************/ -package org.eclipse.nebula.widgets.nebulatoolbar.test; - -import org.eclipse.nebula.widgets.nebulatoolbar.NebulaToolbar; -import org.eclipse.nebula.widgets.nebulatoolbar.ToolbarItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -public class NebulaToolbarTest -{ - - public static void main(String[] args) - { - Display display = Display.getDefault(); - - final Shell shell = new Shell(display, SWT.SHELL_TRIM); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - shell.setLayout(gridLayout); - - GridData toolbarData = new GridData(); - toolbarData.heightHint = 31; - toolbarData.grabExcessHorizontalSpace = true; - toolbarData.horizontalAlignment = SWT.FILL; - - final NebulaToolbar toolbar = new NebulaToolbar(shell, 0); - toolbar.setLayoutData(toolbarData); - - ToolbarItem item = new ToolbarItem(toolbar, 0); - item.setText("Close application"); - item.setSelectionListener(new SelectionAdapter() - { - @Override - public void widgetSelected(SelectionEvent e) - { - shell.dispose(); - } - }); - - ToolbarItem itemVista = new ToolbarItem(toolbar, 0); - itemVista.setText("Vista style"); - itemVista.setSelectionListener(new SelectionAdapter() - { - @Override - public void widgetSelected(SelectionEvent e) - { - toolbar.setMode(NebulaToolbar.MODE_VISTA); - } - }); - - ToolbarItem itemSeven = new ToolbarItem(toolbar, 0); - itemSeven.setText("Seven style"); - itemSeven.setSelectionListener(new SelectionAdapter() - { - @Override - public void widgetSelected(SelectionEvent e) - { - toolbar.setMode(NebulaToolbar.MODE_SEVEN); - } - }); - - shell.layout(); - shell.open(); - - while (!shell.isDisposed()) - { - if (!display.readAndDispatch()) - { - display.sleep(); - } - } - - display.dispose(); - } - -} +/******************************************************************************* +* Copyright (c) 2010, Lukasz Milewski 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: +* Lukasz Milewski - Initial API and implementation +*******************************************************************************/ +package org.eclipse.nebula.widgets.nebulatoolbar.test; + +import org.eclipse.nebula.widgets.nebulatoolbar.NebulaToolbar; +import org.eclipse.nebula.widgets.nebulatoolbar.ToolbarItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class NebulaToolbarTest +{ + + public static void main(String[] args) + { + Display display = Display.getDefault(); + + final Shell shell = new Shell(display, SWT.SHELL_TRIM); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + shell.setLayout(gridLayout); + + GridData toolbarData = new GridData(); + toolbarData.heightHint = 31; + toolbarData.grabExcessHorizontalSpace = true; + toolbarData.horizontalAlignment = SWT.FILL; + + final NebulaToolbar toolbar = new NebulaToolbar(shell, 0); + toolbar.setLayoutData(toolbarData); + + ToolbarItem item = new ToolbarItem(toolbar, 0); + item.setText("Close application"); + item.setSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + shell.dispose(); + } + }); + + ToolbarItem itemVista = new ToolbarItem(toolbar, 0); + itemVista.setText("Vista style"); + itemVista.setSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + toolbar.setMode(NebulaToolbar.MODE_VISTA); + } + }); + + ToolbarItem itemSeven = new ToolbarItem(toolbar, 0); + itemSeven.setText("Seven style"); + itemSeven.setSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + toolbar.setMode(NebulaToolbar.MODE_SEVEN); + } + }); + + shell.layout(); + shell.open(); + + while (!shell.isDisposed()) + { + if (!display.readAndDispatch()) + { + display.sleep(); + } + } + + display.dispose(); + } + +} diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/.project b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/.project index c5c4e38d7..3b81fb80a 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/.project +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.breadcrumb.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.breadcrumb.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/build.properties b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/build.properties +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/feature.properties b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/feature.properties +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.classpath b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.classpath +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.project b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.project index 10e5297c8..40abbf3a7 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.project +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.breadcrumb.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.breadcrumb.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/META-INF/MANIFEST.MF b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/META-INF/MANIFEST.MF index ae8296103..61d881071 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Breadcrumb Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.breadcrumb.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.breadcrumb;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.breadcrumb.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Breadcrumb Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.breadcrumb.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.breadcrumb;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.breadcrumb.snippets diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/build.properties b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/build.properties +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/src/org/eclipse/nebula/widgets/opal/breadcrumb/snippets/BreadcrumbSnippet.java b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/src/org/eclipse/nebula/widgets/opal/breadcrumb/snippets/BreadcrumbSnippet.java index 25bf78374..f630dfbd3 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/src/org/eclipse/nebula/widgets/opal/breadcrumb/snippets/BreadcrumbSnippet.java +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb.snippets/src/org/eclipse/nebula/widgets/opal/breadcrumb/snippets/BreadcrumbSnippet.java @@ -1,136 +1,136 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON. All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.breadcrumb.snippets; - -import org.eclipse.nebula.widgets.opal.breadcrumb.Breadcrumb; -import org.eclipse.nebula.widgets.opal.breadcrumb.BreadcrumbItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple snippet for the breadcrumb Widget - */ -public class BreadcrumbSnippet { - - private static Image[] images; - - /** - * @param args - */ - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setText("BreakCrumb Snippet"); - shell.setLayout(new GridLayout(2, false)); - - createImages(); - - createLabelsBreadCrumb(shell); - createButtonsBreadCrumb(shell); - createButtonsIconsBreadCrumb(shell); - createToggleButtonsBreadCrumb(shell); - - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - display.dispose(); - - } - - private static void createImages() { - images = new Image[5]; - final String[] fileNames = new String[] { "add.png", "bell.png", "feed.png", "house.png", "script.png" }; - for (int i = 0; i < 5; i++) { - final Image image = new Image(Display.getCurrent(), BreadcrumbSnippet.class.getResourceAsStream(fileNames[i])); - images[i] = image; - } - } - - private static void createLabelsBreadCrumb(final Shell shell) { - final Label label = new Label(shell, SWT.NONE); - label.setText("Label breadcrumb:"); - label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - createBreadcrumb(shell, SWT.BORDER, SWT.CENTER, false); - new Label(shell, SWT.NONE); - - createBreadcrumb(shell, SWT.NONE, SWT.CENTER, false); - } - - private static void createBreadcrumb(final Shell shell, final int breadCrumbArgument, final int itemArgument, final boolean showImages) { - final Breadcrumb bc = new Breadcrumb(shell, breadCrumbArgument); - bc.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false)); - - for (int i = 1; i < 5; i++) { - final BreadcrumbItem item = new BreadcrumbItem(bc, itemArgument); - item.setText("Label " + String.valueOf(i)); - if (showImages) { - item.setImage(images[i]); - item.setSelectionImage(images[i]); - } - item.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(final SelectionEvent e) { - System.out.println("Click !"); - } - - }); - } - } - - private static void createButtonsBreadCrumb(final Shell shell) { - final Label label = new Label(shell, SWT.NONE); - label.setText("Buttons breadcrumb:"); - label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - createBreadcrumb(shell, SWT.BORDER, SWT.CENTER | SWT.PUSH, false); - new Label(shell, SWT.NONE); - - createBreadcrumb(shell, SWT.NONE, SWT.CENTER | SWT.PUSH, false); - } - - private static void createButtonsIconsBreadCrumb(final Shell shell) { - final Label label = new Label(shell, SWT.NONE); - label.setText("Buttons breadcrumb:"); - label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - createBreadcrumb(shell, SWT.BORDER, SWT.CENTER | SWT.PUSH, true); - new Label(shell, SWT.NONE); - - createBreadcrumb(shell, SWT.NONE, SWT.CENTER | SWT.PUSH, true); - } - - private static void createToggleButtonsBreadCrumb(final Shell shell) { - final Label label = new Label(shell, SWT.NONE); - label.setText("Toggle buttons breadcrumb:"); - label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - createBreadcrumb(shell, SWT.BORDER, SWT.CENTER | SWT.TOGGLE, false); - new Label(shell, SWT.NONE); - - createBreadcrumb(shell, SWT.NONE, SWT.CENTER | SWT.TOGGLE, false); - } - -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON. All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.breadcrumb.snippets; + +import org.eclipse.nebula.widgets.opal.breadcrumb.Breadcrumb; +import org.eclipse.nebula.widgets.opal.breadcrumb.BreadcrumbItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple snippet for the breadcrumb Widget + */ +public class BreadcrumbSnippet { + + private static Image[] images; + + /** + * @param args + */ + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setText("BreakCrumb Snippet"); + shell.setLayout(new GridLayout(2, false)); + + createImages(); + + createLabelsBreadCrumb(shell); + createButtonsBreadCrumb(shell); + createButtonsIconsBreadCrumb(shell); + createToggleButtonsBreadCrumb(shell); + + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + display.dispose(); + + } + + private static void createImages() { + images = new Image[5]; + final String[] fileNames = new String[] { "add.png", "bell.png", "feed.png", "house.png", "script.png" }; + for (int i = 0; i < 5; i++) { + final Image image = new Image(Display.getCurrent(), BreadcrumbSnippet.class.getResourceAsStream(fileNames[i])); + images[i] = image; + } + } + + private static void createLabelsBreadCrumb(final Shell shell) { + final Label label = new Label(shell, SWT.NONE); + label.setText("Label breadcrumb:"); + label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + + createBreadcrumb(shell, SWT.BORDER, SWT.CENTER, false); + new Label(shell, SWT.NONE); + + createBreadcrumb(shell, SWT.NONE, SWT.CENTER, false); + } + + private static void createBreadcrumb(final Shell shell, final int breadCrumbArgument, final int itemArgument, final boolean showImages) { + final Breadcrumb bc = new Breadcrumb(shell, breadCrumbArgument); + bc.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false)); + + for (int i = 1; i < 5; i++) { + final BreadcrumbItem item = new BreadcrumbItem(bc, itemArgument); + item.setText("Label " + String.valueOf(i)); + if (showImages) { + item.setImage(images[i]); + item.setSelectionImage(images[i]); + } + item.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(final SelectionEvent e) { + System.out.println("Click !"); + } + + }); + } + } + + private static void createButtonsBreadCrumb(final Shell shell) { + final Label label = new Label(shell, SWT.NONE); + label.setText("Buttons breadcrumb:"); + label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + + createBreadcrumb(shell, SWT.BORDER, SWT.CENTER | SWT.PUSH, false); + new Label(shell, SWT.NONE); + + createBreadcrumb(shell, SWT.NONE, SWT.CENTER | SWT.PUSH, false); + } + + private static void createButtonsIconsBreadCrumb(final Shell shell) { + final Label label = new Label(shell, SWT.NONE); + label.setText("Buttons breadcrumb:"); + label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + + createBreadcrumb(shell, SWT.BORDER, SWT.CENTER | SWT.PUSH, true); + new Label(shell, SWT.NONE); + + createBreadcrumb(shell, SWT.NONE, SWT.CENTER | SWT.PUSH, true); + } + + private static void createToggleButtonsBreadCrumb(final Shell shell) { + final Label label = new Label(shell, SWT.NONE); + label.setText("Toggle buttons breadcrumb:"); + label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + + createBreadcrumb(shell, SWT.BORDER, SWT.CENTER | SWT.TOGGLE, false); + new Label(shell, SWT.NONE); + + createBreadcrumb(shell, SWT.NONE, SWT.CENTER | SWT.TOGGLE, false); + } + +} diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.classpath b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.classpath +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.project b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.project index f6b0af8f3..eb53fc704 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.project +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.breadcrumb - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.breadcrumb + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/META-INF/MANIFEST.MF b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/META-INF/MANIFEST.MF index d8599bd8e..0758ee26e 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/META-INF/MANIFEST.MF +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Breadcrumb Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.breadcrumb -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.breadcrumb -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.breadcrumb +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Breadcrumb Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.breadcrumb +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.breadcrumb +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.breadcrumb diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/build.properties b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/build.properties +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/src/org/eclipse/nebula/widgets/opal/breadcrumb/Breadcrumb.java b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/src/org/eclipse/nebula/widgets/opal/breadcrumb/Breadcrumb.java index 1c1f9a5f5..a6d42300d 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/src/org/eclipse/nebula/widgets/opal/breadcrumb/Breadcrumb.java +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/src/org/eclipse/nebula/widgets/opal/breadcrumb/Breadcrumb.java @@ -1,365 +1,365 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.breadcrumb; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Widget; - -/** - * Instances of this class support the layout of selectable bar items displayed - * in a bread crumb. - *

- * The item children that may be added to instances of this class must be of - * type BreadcrumbItem. - *

- *

- *

- *
Styles:
- *
BORDER
- *
Events:
- *
(none)
- *
- * - */ -public class Breadcrumb extends Canvas { - - private static final String IS_BUTTON_PRESSED = Breadcrumb.class.toString() + "_pressed"; - private final List items; - private static Color START_GRADIENT_COLOR = SWTGraphicUtil.getColorSafely(255, 255, 255); - private static Color END_GRADIENT_COLOR = SWTGraphicUtil.getColorSafely(224, 224, 224); - static Color BORDER_COLOR = SWTGraphicUtil.getColorSafely(128, 128, 128); - static Color BORDER_COLOR_1 = SWTGraphicUtil.getColorSafely(212, 212, 212); - static Color BORDER_COLOR_2 = SWTGraphicUtil.getColorSafely(229, 229, 229); - static Color BORDER_COLOR_3 = SWTGraphicUtil.getColorSafely(243, 243, 243); - boolean hasBorder = false; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - * @see Widget#getStyle() - */ - public Breadcrumb(final Composite parent, final int style) { - super(parent, checkStyle(style) | SWT.DOUBLE_BUFFERED); - items = new ArrayList<>(); - hasBorder = (style & SWT.BORDER) != 0; - addListeners(); - } - - private static int checkStyle(final int style) { - if ((style & SWT.BORDER) != 0) { - return style & ~SWT.BORDER; - } - return 0; - } - - private void addListeners() { - addMouseDownListener(); - addMouseUpListener(); - addMouseHoverListener(); - addPaintListener(e -> { - paintControl(e); - }); - } - - private void addMouseDownListener() { - addListener(SWT.MouseDown, event -> { - - final BreadcrumbItem item = items.stream()// - .filter(element -> element.getBounds().contains(event.x, event.y)) // - .findFirst() // - .orElse(null); - if (item == null) { - return; - } - final boolean isToggle = (item.getStyle() & SWT.TOGGLE) != 0; - final boolean isPush = (item.getStyle() & SWT.PUSH) != 0; - if (isToggle || isPush) { - item.setSelection(!item.getSelection()); - redraw(); - update(); - } - item.setData(IS_BUTTON_PRESSED, "*"); - }); - - } - - private void addMouseUpListener() { - addListener(SWT.MouseUp, event -> { - - final BreadcrumbItem item = items.stream()// - .filter(element -> element.getBounds().contains(event.x, event.y)) // - .findFirst() // - .orElse(null); - if (item == null) { - return; - } - if (item.getData(IS_BUTTON_PRESSED) == null) { - // The button was not pressed - return; - } - item.setData(IS_BUTTON_PRESSED, null); - - if ((item.getStyle() & SWT.PUSH) != 0) { - item.setSelection(false); - } - - if ((item.getStyle() & (SWT.TOGGLE | SWT.PUSH)) != 0) { - item.fireSelectionEvent(); - redraw(); - update(); - } - }); - } - - private void addMouseHoverListener() { - addListener(SWT.MouseHover, event -> { - final BreadcrumbItem item = items.stream()// - .filter(element -> element.getBounds().contains(event.x, event.y)) // - .findFirst() // - .orElse(null); - if (item == null) { - return; - } - setToolTipText(item.getTooltipText() == null ? "" : item.getTooltipText()); - }); - } - - /** - * Paint the component - * - * @param e event - */ - private void paintControl(final PaintEvent e) { - final GC gc = e.gc; - gc.setAdvanced(true); - gc.setAntialias(SWT.ON); - - final int width = getSize().x; - final int height = getSize().y; - - drawBackground(gc, width, height); - final Iterator it = items.iterator(); - int x = 0; - while (it.hasNext()) { - final BreadcrumbItem item = it.next(); - item.setGc(gc).setToolbarHeight(height).setIsLastItemOfTheBreadCrumb(!it.hasNext()); - item.drawButtonAtPosition(x); - x += item.getWidth(); - } - } - - private void drawBackground(final GC gc, final int width, final int height) { - gc.setForeground(START_GRADIENT_COLOR); - gc.setBackground(END_GRADIENT_COLOR); - gc.fillGradientRectangle(0, 0, width, height, true); - - if (hasBorder) { - gc.setForeground(BORDER_COLOR); - gc.drawRectangle(0, 0, width - 1, height - 1); - } - } - - /** - * Add an item to the toolbar - * - * @param item roundedToolItem to add - */ - void addItem(final BreadcrumbItem item) { - items.add(item); - } - - /** - * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - int width = 0, height = 0; - for (final BreadcrumbItem item : items) { - width += item.getWidth(); - height = Math.max(height, item.getHeight()); - } - return new Point(Math.max(width, wHint), Math.max(height, hHint)); - } - - /** - * Returns the item at the given, zero-relative index in the receiver. Throws an - * exception if the index is out of range. - * - * @param index the index of the item to return - * @return the item at the given index - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and - * the number of elements in the list minus 1 (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public BreadcrumbItem getItem(final int index) { - checkWidget(); - if (index < 0 || index > items.size()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return items.get(index); - } - - /** - * Returns the item at the given point in the receiver or null if no such item - * exists. The point is in the coordinate system of the receiver. - * - * @param point the point used to locate the item - * @return the item at the given point - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the point is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public BreadcrumbItem getItem(final Point point) { - checkWidget(); - final BreadcrumbItem item = items.stream()// - .filter(element -> element.getBounds().contains(point)) // - .findFirst() // - .orElse(null); - return item; - } - - /** - * Returns the number of items contained in the receiver. - * - * @return the number of items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getItemCount() { - checkWidget(); - return items.size(); - } - - /** - * Returns an array of BreadcrumbItems which are the items in the - * receiver. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * list of items, so modifying the array will not affect the receiver. - *

- * - * @return the items in the receiver - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public BreadcrumbItem[] getItems() { - checkWidget(); - return items.toArray(new BreadcrumbItem[items.size()]); - } - - /** - * Searches the receiver's list starting at the first item (index 0) until an - * item is found that is equal to the argument, and returns the index of that - * item. If no item is found, returns -1. - * - * @param item the search item - * @return the index of the item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the item has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int indexOf(final BreadcrumbItem item) { - checkWidget(); - return items.indexOf(item); - } - - /** - * Remove an item to the toolbar - * - * @param item item to remove - */ - public void removeItem(final BreadcrumbItem item) { - items.remove(item); - } - -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.breadcrumb; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Widget; + +/** + * Instances of this class support the layout of selectable bar items displayed + * in a bread crumb. + *

+ * The item children that may be added to instances of this class must be of + * type BreadcrumbItem. + *

+ *

+ *

+ *
Styles:
+ *
BORDER
+ *
Events:
+ *
(none)
+ *
+ * + */ +public class Breadcrumb extends Canvas { + + private static final String IS_BUTTON_PRESSED = Breadcrumb.class.toString() + "_pressed"; + private final List items; + private static Color START_GRADIENT_COLOR = SWTGraphicUtil.getColorSafely(255, 255, 255); + private static Color END_GRADIENT_COLOR = SWTGraphicUtil.getColorSafely(224, 224, 224); + static Color BORDER_COLOR = SWTGraphicUtil.getColorSafely(128, 128, 128); + static Color BORDER_COLOR_1 = SWTGraphicUtil.getColorSafely(212, 212, 212); + static Color BORDER_COLOR_2 = SWTGraphicUtil.getColorSafely(229, 229, 229); + static Color BORDER_COLOR_3 = SWTGraphicUtil.getColorSafely(243, 243, 243); + boolean hasBorder = false; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + * @see Widget#getStyle() + */ + public Breadcrumb(final Composite parent, final int style) { + super(parent, checkStyle(style) | SWT.DOUBLE_BUFFERED); + items = new ArrayList<>(); + hasBorder = (style & SWT.BORDER) != 0; + addListeners(); + } + + private static int checkStyle(final int style) { + if ((style & SWT.BORDER) != 0) { + return style & ~SWT.BORDER; + } + return 0; + } + + private void addListeners() { + addMouseDownListener(); + addMouseUpListener(); + addMouseHoverListener(); + addPaintListener(e -> { + paintControl(e); + }); + } + + private void addMouseDownListener() { + addListener(SWT.MouseDown, event -> { + + final BreadcrumbItem item = items.stream()// + .filter(element -> element.getBounds().contains(event.x, event.y)) // + .findFirst() // + .orElse(null); + if (item == null) { + return; + } + final boolean isToggle = (item.getStyle() & SWT.TOGGLE) != 0; + final boolean isPush = (item.getStyle() & SWT.PUSH) != 0; + if (isToggle || isPush) { + item.setSelection(!item.getSelection()); + redraw(); + update(); + } + item.setData(IS_BUTTON_PRESSED, "*"); + }); + + } + + private void addMouseUpListener() { + addListener(SWT.MouseUp, event -> { + + final BreadcrumbItem item = items.stream()// + .filter(element -> element.getBounds().contains(event.x, event.y)) // + .findFirst() // + .orElse(null); + if (item == null) { + return; + } + if (item.getData(IS_BUTTON_PRESSED) == null) { + // The button was not pressed + return; + } + item.setData(IS_BUTTON_PRESSED, null); + + if ((item.getStyle() & SWT.PUSH) != 0) { + item.setSelection(false); + } + + if ((item.getStyle() & (SWT.TOGGLE | SWT.PUSH)) != 0) { + item.fireSelectionEvent(); + redraw(); + update(); + } + }); + } + + private void addMouseHoverListener() { + addListener(SWT.MouseHover, event -> { + final BreadcrumbItem item = items.stream()// + .filter(element -> element.getBounds().contains(event.x, event.y)) // + .findFirst() // + .orElse(null); + if (item == null) { + return; + } + setToolTipText(item.getTooltipText() == null ? "" : item.getTooltipText()); + }); + } + + /** + * Paint the component + * + * @param e event + */ + private void paintControl(final PaintEvent e) { + final GC gc = e.gc; + gc.setAdvanced(true); + gc.setAntialias(SWT.ON); + + final int width = getSize().x; + final int height = getSize().y; + + drawBackground(gc, width, height); + final Iterator it = items.iterator(); + int x = 0; + while (it.hasNext()) { + final BreadcrumbItem item = it.next(); + item.setGc(gc).setToolbarHeight(height).setIsLastItemOfTheBreadCrumb(!it.hasNext()); + item.drawButtonAtPosition(x); + x += item.getWidth(); + } + } + + private void drawBackground(final GC gc, final int width, final int height) { + gc.setForeground(START_GRADIENT_COLOR); + gc.setBackground(END_GRADIENT_COLOR); + gc.fillGradientRectangle(0, 0, width, height, true); + + if (hasBorder) { + gc.setForeground(BORDER_COLOR); + gc.drawRectangle(0, 0, width - 1, height - 1); + } + } + + /** + * Add an item to the toolbar + * + * @param item roundedToolItem to add + */ + void addItem(final BreadcrumbItem item) { + items.add(item); + } + + /** + * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + int width = 0, height = 0; + for (final BreadcrumbItem item : items) { + width += item.getWidth(); + height = Math.max(height, item.getHeight()); + } + return new Point(Math.max(width, wHint), Math.max(height, hHint)); + } + + /** + * Returns the item at the given, zero-relative index in the receiver. Throws an + * exception if the index is out of range. + * + * @param index the index of the item to return + * @return the item at the given index + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and + * the number of elements in the list minus 1 (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public BreadcrumbItem getItem(final int index) { + checkWidget(); + if (index < 0 || index > items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return items.get(index); + } + + /** + * Returns the item at the given point in the receiver or null if no such item + * exists. The point is in the coordinate system of the receiver. + * + * @param point the point used to locate the item + * @return the item at the given point + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the point is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public BreadcrumbItem getItem(final Point point) { + checkWidget(); + final BreadcrumbItem item = items.stream()// + .filter(element -> element.getBounds().contains(point)) // + .findFirst() // + .orElse(null); + return item; + } + + /** + * Returns the number of items contained in the receiver. + * + * @return the number of items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getItemCount() { + checkWidget(); + return items.size(); + } + + /** + * Returns an array of BreadcrumbItems which are the items in the + * receiver. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the items in the receiver + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public BreadcrumbItem[] getItems() { + checkWidget(); + return items.toArray(new BreadcrumbItem[items.size()]); + } + + /** + * Searches the receiver's list starting at the first item (index 0) until an + * item is found that is equal to the argument, and returns the index of that + * item. If no item is found, returns -1. + * + * @param item the search item + * @return the index of the item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the item has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int indexOf(final BreadcrumbItem item) { + checkWidget(); + return items.indexOf(item); + } + + /** + * Remove an item to the toolbar + * + * @param item item to remove + */ + public void removeItem(final BreadcrumbItem item) { + items.remove(item); + } + +} diff --git a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/src/org/eclipse/nebula/widgets/opal/breadcrumb/BreadcrumbItem.java b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/src/org/eclipse/nebula/widgets/opal/breadcrumb/BreadcrumbItem.java index 6cd8dc7cb..6940a8972 100644 --- a/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/src/org/eclipse/nebula/widgets/opal/breadcrumb/BreadcrumbItem.java +++ b/widgets/opal/breadcrumb/org.eclipse.nebula.widgets.opal.breadcrumb/src/org/eclipse/nebula/widgets/opal/breadcrumb/BreadcrumbItem.java @@ -1,983 +1,983 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.breadcrumb; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -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.Event; -import org.eclipse.swt.widgets.Item; -import org.eclipse.swt.widgets.Widget; - -/** - * Instances of this class represent a selectable user interface object that - * represents an item of a breadcrumb. - *
- *
Styles:
- *
TOGGLE,PUSH,NONE
- *
Events:
- *
Selection
- *
- * - */ -public class BreadcrumbItem extends Item { - - private static final int MIN_WIDTH = 40; - private static final int MARGIN = 4; - private static Color SELECTED_COLOR = SWTGraphicUtil.getColorSafely(223, 220, 213); - - private final Breadcrumb parentBreadcrumb; - private final List selectionListeners; - private Rectangle bounds; - private boolean enabled; - private boolean selection; - private int width; - private int height; - private Image disabledImage; - private Image selectionImage; - private int alignment; - private Color textColorSelected; - private Color textColor; - private String tooltipText; - private GC gc; - private int toolbarHeight; - private boolean isLastItemOfTheBreadCrumb; - - /** - * Constructs a new instance of this class given its parent (which must be a - * Breadcrumb) and a style value describing its behavior and - * appearance. The item is added to the end of the items maintained by its - * parent. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - * @see Widget#getStyle - */ - public BreadcrumbItem(final Breadcrumb parent) { - this(parent, SWT.NONE); - } - - /** - * Constructs a new instance of this class given its parent (which must be a - * Breadcrumb) and a style value describing its behavior and - * appearance. The item is added to the end of the items maintained by its - * parent. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - * @see Widget#getStyle - */ - public BreadcrumbItem(final Breadcrumb parent, final int style) { - super(parent, checkStyle(style)); - parent.addItem(this); - parentBreadcrumb = parent; - textColor = parent.getDisplay().getSystemColor(SWT.COLOR_BLACK); - textColorSelected = parent.getDisplay().getSystemColor(SWT.COLOR_BLACK); - enabled = true; - - if ((style & SWT.LEFT) != 0) { - alignment = SWT.LEFT; - } - if ((style & SWT.CENTER) != 0) { - alignment = SWT.CENTER; - } - if ((style & SWT.RIGHT) != 0) { - alignment = SWT.RIGHT; - } - - selectionListeners = new ArrayList<>(); - width = height = -1; - } - - private static int checkStyle(int style) { - style = checkBits(style, SWT.NONE, SWT.PUSH, SWT.TOGGLE); - if ((style & (SWT.PUSH | SWT.TOGGLE)) != 0) { - return checkBits(style, SWT.CENTER, SWT.LEFT, SWT.RIGHT); - } - return style; - } - - private static int checkBits(int style, final int int0, final int int1, final int int2) { - final int mask = int0 | int1 | int2; - if ((style & mask) == 0) { - style |= int0; - } - if ((style & int0) != 0) { - style = style & ~mask | int0; - } - if ((style & int1) != 0) { - style = style & ~mask | int1; - } - if ((style & int2) != 0) { - style = style & ~mask | int2; - } - return style; - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the control is selected by the user, by sending it one of the messages - * defined in the SelectionListener interface. - *

- * widgetDefaultSelected is not called. - *

- * - * @param listener the listener which should be notified when the control is - * selected by the user, - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - selectionListeners.add(listener); - } - - /** - * @see org.eclipse.swt.widgets.Widget#dispose() - */ - @Override - public void dispose() { - getParent().removeItem(this); - bounds = null; - disabledImage = null; - selectionImage = null; - textColor = null; - textColorSelected = null; - super.dispose(); - } - - /** - * Returns a value which describes the position of the text in the receiver. The - * value will be one of LEFT, RIGHT or - * CENTER. - * - * @return the alignment - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getAlignment() { - checkWidget(); - return alignment; - } - - /** - * Returns a rectangle describing the receiver's size and location relative to - * its parent (or its display if its parent is null), unless the receiver is a - * shell. In this case, the location is relative to the display. - * - * @return the receiver's bounding rectangle - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Rectangle getBounds() { - checkWidget(); - return bounds; - } - - /** - * @return the image displayed when the button is disabled - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Image getDisabledImage() { - checkWidget(); - return disabledImage; - } - - /** - * Returns true if the receiver is enabled, and false - * otherwise. A disabled control is typically not selectable from the user - * interface and draws with an inactive or "grayed" look. - * - * @return the receiver's enabled state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see #isEnabled - */ - public boolean getEnabled() { - checkWidget(); - return enabled; - } - - /** - * Returns the whole height of the item. - * - * @return the receiver's height - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getHeight() { - checkWidget(); - if (height == -1) { - return computeDefaultSize().y; - } - return height; - } - - /** - * @return the default size of the item - */ - private Point computeDefaultSize() { - final Point sizeOfTextAndImages = computeSizeOfTextAndImages(); - return new Point(2 * MARGIN + sizeOfTextAndImages.x, 2 * MARGIN + sizeOfTextAndImages.y); - } - - /** - * Returns the receiver's parent, which must be a Breadcrumb. - * - * @return the receiver's parent - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Breadcrumb getParent() { - checkWidget(); - return parentBreadcrumb; - } - - /** - * Returns true if the receiver is selected, and false otherwise. - * - * @return the selection state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean getSelection() { - checkWidget(); - return selection; - } - - /** - * @return the image displayed when the button is selected - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Image getSelectionImage() { - checkWidget(); - return selectionImage; - } - - /** - * Returns the color of the text when the button is enabled and not selected. - * - * @return the receiver's text color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getTextColor() { - checkWidget(); - return textColor; - } - - /** - * Returns the color of the text when the button is not selected. - * - * @return the receiver's text color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - - public Color getTextColorSelected() { - checkWidget(); - return textColorSelected; - } - - /** - * Returns the receiver's tool tip text, or null if it has not been set. - * - * @return the receiver's tool tip text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public String getTooltipText() { - checkWidget(); - return tooltipText; - } - - /** - * Returns the whole width of the item. - * - * @return the receiver's height - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getWidth() { - checkWidget(); - if (width == -1) { - return Math.max(computeDefaultSize().x, MIN_WIDTH); - } - return Math.max(width, MIN_WIDTH); - } - - /** - * Returns true if the receiver is enabled, and false - * otherwise. A disabled control is typically not selectable from the user - * interface and draws with an inactive or "grayed" look. - * - * @return the receiver's enabled state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see #getEnabled - */ - public boolean isEnabled() { - checkWidget(); - return enabled; - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the control is selected by the user. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - selectionListeners.remove(listener); - } - - /** - * Controls how text will be displayed in the receiver. The argument should be - * one of LEFT, RIGHT or CENTER. - * - * @param alignment the new alignment - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setAlignment(final int alignment) { - checkWidget(); - this.alignment = alignment; - } - - /** - * Sets the receiver's size and location to the rectangular area specified by - * the argument. The x and y fields of the rectangle - * are relative to the receiver's parent (or its display if its parent is null). - *

- * Note: Attempting to set the width or height of the receiver to a negative - * number will cause that value to be set to zero instead. - *

- * - * @param rect the new bounds for the receiver - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setBounds(final Rectangle rectangle) { - checkWidget(); - if (bounds == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - bounds = new Rectangle(Math.max(0, rectangle.x), // - Math.max(0, rectangle.y), // - Math.max(0, rectangle.width), // - Math.max(0, rectangle.height)); - } - - /** - * Sets the receiver's image to the argument when this is one is disabled, which - * may be null indicating that no image should be displayed. - * - * @param image the image to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setDisabledImage(final Image image) { - checkWidget(); - disabledImage = image; - } - - /** - * Enables the receiver if the argument is true, and disables it - * otherwise. - *

- * A disabled control is typically not selectable from the user interface and - * draws with an inactive or "grayed" look. - *

- * - * @param enabled the new enabled state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setEnabled(final boolean enabled) { - checkWidget(); - this.enabled = enabled; - } - - /** - * Sets the height of the receiver. - *

- * Note: Attempting to set the width or height of the receiver to a negative - * number will cause that value to be set to zero instead. - *

- * - * @param height the new width - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setHeight(final int height) { - checkWidget(); - this.height = Math.max(height, 0); - } - - /** - * Sets the selection state of the receiver. - * - * @param selected the new selection state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setSelection(final boolean selected) { - checkWidget(); - selection = selected; - } - - /** - * Sets the receiver's image to the argument when this one is selected, which - * may be null indicating that no image should be displayed. - * - * @param image the image to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setSelectionImage(final Image image) { - checkWidget(); - selectionImage = image; - } - - /** - * Sets the receiver's text color to the argument, which may be null indicating - * that no image should be displayed. - * - * @param textColor the text color to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setTextColor(final Color textColor) { - checkWidget(); - this.textColor = textColor; - } - - /** - * Sets the receiver's text color to the argument when this one is selected, - * which may be null indicating that no image should be displayed. - * - * @param textColor the text color to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setTextColorSelected(final Color textColor) { - checkWidget(); - textColorSelected = textColor; - } - - /** - * Sets the receiver's tool tip text to the argument, which may be null - * indicating that the default tool tip for the control will be shown. For a - * control that has a default tool tip, such as the Tree control on Windows, - * setting the tool tip text to an empty string replaces the default, causing no - * tool tip text to be shown. - *

- * The mnemonic indicator (character '&') is not displayed in a tool tip. To - * display a single '&' in the tool tip, the character '&' can be - * escaped by doubling it in the string. - *

- * - * @param string the new tool tip text (or null) - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setTooltipText(final String string) { - checkWidget(); - tooltipText = string == null ? "" : string; - } - - /** - * Sets the width of the receiver. - *

- * Note: Attempting to set the width or height of the receiver to a negative - * number will cause that value to be set to zero instead. - *

- * - * @param width the new width - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setWidth(final int width) { - checkWidget(); - this.width = Math.max(0, width); - } - - // --------------------------------------------- Package visibility section - void fireSelectionEvent() { - final Event event = new Event(); - event.widget = parentBreadcrumb; - event.display = getDisplay(); - event.item = this; - event.type = SWT.Selection; - for (final SelectionListener selectionListener : selectionListeners) { - selectionListener.widgetSelected(new SelectionEvent(event)); - } - } - - void drawButtonAtPosition(final int x) { - - if (selection) { - drawBackgroundAtPosition(x); - } - if (!isLastItemOfTheBreadCrumb) { - drawTrianglesAtPosition(x); - } - - int xPosition = computeGap(); - final Image drawnedImage = drawImageAtPosition(x + xPosition); - if (drawnedImage != null) { - xPosition += drawnedImage.getBounds().width + 2 * MARGIN; - } - drawTextAtPosition(x + xPosition); - - bounds = new Rectangle(x, 0, getWidth(), toolbarHeight); - } - - private void drawBackgroundAtPosition(final int x) { - gc.setAdvanced(true); - gc.setAntialias(SWT.ON); - - gc.setForeground(SELECTED_COLOR); - gc.setBackground(SELECTED_COLOR); - - final boolean hasBorder = parentBreadcrumb.hasBorder; - final boolean isFirst = parentBreadcrumb.indexOf(this) == 0; - final int borderWidth = hasBorder ? 1 : 0; - - int leftSide; - if (isFirst) { - leftSide = 0; - } else { - leftSide = 5 + (hasBorder ? 0 : 1); - } - - final int xUpperLeft = x + borderWidth + leftSide; - final int yUpperLeft = borderWidth; - final int rectWidth = getWidth() - borderWidth - leftSide - (isLastItemOfTheBreadCrumb && hasBorder ? 1 : 0); - final int rectHeight = getHeight() - 2 * borderWidth; - gc.fillRectangle(xUpperLeft, yUpperLeft, rectWidth, rectHeight); - - if (!isFirst) { - gc.fillPolygon(new int[] { xUpperLeft - 5, yUpperLeft, // - xUpperLeft, yUpperLeft, // - xUpperLeft, yUpperLeft + toolbarHeight / 2 // - }); - gc.fillPolygon(new int[] { xUpperLeft - 5, yUpperLeft + rectHeight, // - xUpperLeft, yUpperLeft + rectHeight, // - xUpperLeft, yUpperLeft + toolbarHeight / 2 // - }); - - } - - if (!isLastItemOfTheBreadCrumb) { - gc.fillPolygon(new int[] { xUpperLeft + rectWidth, yUpperLeft + 1, // - xUpperLeft + rectWidth, yUpperLeft + getHeight(), // - xUpperLeft + rectWidth + 5, yUpperLeft + toolbarHeight / 2 // - }); - } - - gc.setClipping((Rectangle) null); - } - - private void drawTrianglesAtPosition(final int x) { - gc.setForeground(Breadcrumb.BORDER_COLOR); - drawTriangleAtPosition(x + getWidth()); - - gc.setAlpha(127); - gc.setForeground(Breadcrumb.BORDER_COLOR_1); - drawTriangleAtPosition(x + getWidth() + 1); - - gc.setForeground(Breadcrumb.BORDER_COLOR_2); - drawTriangleAtPosition(x + getWidth() + 2); - - gc.setForeground(Breadcrumb.BORDER_COLOR_3); - drawTriangleAtPosition(x + getWidth() + 3); - - gc.setAlpha(255); - if (parentBreadcrumb.hasBorder) { - gc.setForeground(Breadcrumb.BORDER_COLOR); - gc.drawLine(x + getWidth(), 0, x + getWidth() + 3, 0); - gc.drawLine(x + getWidth(), toolbarHeight - 1, x + getWidth() + 3, toolbarHeight - 1); - } - } - - private void drawTriangleAtPosition(final int x) { - gc.drawLine(x, 0, x + 5, toolbarHeight / 2); - gc.drawLine(x + 5, toolbarHeight / 2, x, toolbarHeight); - - } - - private int computeGap() { - final int widthOfTextAndImage = computeSizeOfTextAndImages().x; - switch (alignment) { - case SWT.CENTER: - return (getWidth() - widthOfTextAndImage) / 2; - case SWT.RIGHT: - return getWidth() - widthOfTextAndImage - MARGIN; - default: - return MARGIN; - } - } - - private Point computeSizeOfTextAndImages() { - int width = 0, height = 0; - final boolean textISNotEmpty = getText() != null && !getText().equals(""); - - if (textISNotEmpty) { - final GC gc = new GC(parentBreadcrumb); - gc.setFont(parentBreadcrumb.getFont()); - final Point extent = gc.stringExtent(getText()); - gc.dispose(); - width += extent.x; - height = extent.y; - } - - final Point imageSize = computeMaxWidthAndHeightForImages(getImage(), selectionImage, disabledImage); - - if (imageSize.x != -1) { - width += imageSize.x; - height = Math.max(imageSize.y, height); - if (textISNotEmpty) { - width += MARGIN * 2; - } - } - width += MARGIN; - return new Point(width, height); - } - - private Point computeMaxWidthAndHeightForImages(final Image... images) { - final Point imageSize = new Point(-1, -1); - for (final Image image : images) { - if (image == null) { - continue; - } - final Rectangle imageBounds = image.getBounds(); - imageSize.x = Math.max(imageBounds.width, imageSize.x); - imageSize.y = Math.max(imageBounds.height, imageSize.y); - } - return imageSize; - } - - private Image drawImageAtPosition(final int xPosition) { - Image image; - if (!isEnabled()) { - image = disabledImage; - } else if (selection) { - image = selectionImage; - } else { - image = getImage(); - } - - if (image == null) { - return null; - } - - final int yPosition = (toolbarHeight - image.getBounds().height) / 2; - gc.drawImage(image, (int) (xPosition + MARGIN * 1.5), yPosition); - return image; - } - - private void drawTextAtPosition(final int xPosition) { - gc.setFont(parentBreadcrumb.getFont()); - if (selection) { - gc.setForeground(textColorSelected); - } else { - gc.setForeground(textColor); - } - - final Point textSize = gc.stringExtent(getText()); - final int yPosition = (toolbarHeight - textSize.y) / 2; - - int padding; - if (parentBreadcrumb.indexOf(this) == 0 || isLastItemOfTheBreadCrumb) { - padding = 0; - } else { - padding = 5; - } - gc.drawText(getText(), xPosition + padding, yPosition, true); - } - - BreadcrumbItem setGc(final GC gc) { - this.gc = gc; - return this; - } - - BreadcrumbItem setToolbarHeight(final int toolbarHeight) { - this.toolbarHeight = toolbarHeight; - return this; - } - - BreadcrumbItem setIsLastItemOfTheBreadCrumb(final boolean isLastItemOfTheBreadCrumb) { - this.isLastItemOfTheBreadCrumb = isLastItemOfTheBreadCrumb; - return this; - } - -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.breadcrumb; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +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.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Widget; + +/** + * Instances of this class represent a selectable user interface object that + * represents an item of a breadcrumb. + *
+ *
Styles:
+ *
TOGGLE,PUSH,NONE
+ *
Events:
+ *
Selection
+ *
+ * + */ +public class BreadcrumbItem extends Item { + + private static final int MIN_WIDTH = 40; + private static final int MARGIN = 4; + private static Color SELECTED_COLOR = SWTGraphicUtil.getColorSafely(223, 220, 213); + + private final Breadcrumb parentBreadcrumb; + private final List selectionListeners; + private Rectangle bounds; + private boolean enabled; + private boolean selection; + private int width; + private int height; + private Image disabledImage; + private Image selectionImage; + private int alignment; + private Color textColorSelected; + private Color textColor; + private String tooltipText; + private GC gc; + private int toolbarHeight; + private boolean isLastItemOfTheBreadCrumb; + + /** + * Constructs a new instance of this class given its parent (which must be a + * Breadcrumb) and a style value describing its behavior and + * appearance. The item is added to the end of the items maintained by its + * parent. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + * @see Widget#getStyle + */ + public BreadcrumbItem(final Breadcrumb parent) { + this(parent, SWT.NONE); + } + + /** + * Constructs a new instance of this class given its parent (which must be a + * Breadcrumb) and a style value describing its behavior and + * appearance. The item is added to the end of the items maintained by its + * parent. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
  • + *
+ * + * @see Widget#getStyle + */ + public BreadcrumbItem(final Breadcrumb parent, final int style) { + super(parent, checkStyle(style)); + parent.addItem(this); + parentBreadcrumb = parent; + textColor = parent.getDisplay().getSystemColor(SWT.COLOR_BLACK); + textColorSelected = parent.getDisplay().getSystemColor(SWT.COLOR_BLACK); + enabled = true; + + if ((style & SWT.LEFT) != 0) { + alignment = SWT.LEFT; + } + if ((style & SWT.CENTER) != 0) { + alignment = SWT.CENTER; + } + if ((style & SWT.RIGHT) != 0) { + alignment = SWT.RIGHT; + } + + selectionListeners = new ArrayList<>(); + width = height = -1; + } + + private static int checkStyle(int style) { + style = checkBits(style, SWT.NONE, SWT.PUSH, SWT.TOGGLE); + if ((style & (SWT.PUSH | SWT.TOGGLE)) != 0) { + return checkBits(style, SWT.CENTER, SWT.LEFT, SWT.RIGHT); + } + return style; + } + + private static int checkBits(int style, final int int0, final int int1, final int int2) { + final int mask = int0 | int1 | int2; + if ((style & mask) == 0) { + style |= int0; + } + if ((style & int0) != 0) { + style = style & ~mask | int0; + } + if ((style & int1) != 0) { + style = style & ~mask | int1; + } + if ((style & int2) != 0) { + style = style & ~mask | int2; + } + return style; + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the control is selected by the user, by sending it one of the messages + * defined in the SelectionListener interface. + *

+ * widgetDefaultSelected is not called. + *

+ * + * @param listener the listener which should be notified when the control is + * selected by the user, + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + selectionListeners.add(listener); + } + + /** + * @see org.eclipse.swt.widgets.Widget#dispose() + */ + @Override + public void dispose() { + getParent().removeItem(this); + bounds = null; + disabledImage = null; + selectionImage = null; + textColor = null; + textColorSelected = null; + super.dispose(); + } + + /** + * Returns a value which describes the position of the text in the receiver. The + * value will be one of LEFT, RIGHT or + * CENTER. + * + * @return the alignment + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getAlignment() { + checkWidget(); + return alignment; + } + + /** + * Returns a rectangle describing the receiver's size and location relative to + * its parent (or its display if its parent is null), unless the receiver is a + * shell. In this case, the location is relative to the display. + * + * @return the receiver's bounding rectangle + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Rectangle getBounds() { + checkWidget(); + return bounds; + } + + /** + * @return the image displayed when the button is disabled + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Image getDisabledImage() { + checkWidget(); + return disabledImage; + } + + /** + * Returns true if the receiver is enabled, and false + * otherwise. A disabled control is typically not selectable from the user + * interface and draws with an inactive or "grayed" look. + * + * @return the receiver's enabled state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see #isEnabled + */ + public boolean getEnabled() { + checkWidget(); + return enabled; + } + + /** + * Returns the whole height of the item. + * + * @return the receiver's height + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getHeight() { + checkWidget(); + if (height == -1) { + return computeDefaultSize().y; + } + return height; + } + + /** + * @return the default size of the item + */ + private Point computeDefaultSize() { + final Point sizeOfTextAndImages = computeSizeOfTextAndImages(); + return new Point(2 * MARGIN + sizeOfTextAndImages.x, 2 * MARGIN + sizeOfTextAndImages.y); + } + + /** + * Returns the receiver's parent, which must be a Breadcrumb. + * + * @return the receiver's parent + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Breadcrumb getParent() { + checkWidget(); + return parentBreadcrumb; + } + + /** + * Returns true if the receiver is selected, and false otherwise. + * + * @return the selection state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean getSelection() { + checkWidget(); + return selection; + } + + /** + * @return the image displayed when the button is selected + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Image getSelectionImage() { + checkWidget(); + return selectionImage; + } + + /** + * Returns the color of the text when the button is enabled and not selected. + * + * @return the receiver's text color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getTextColor() { + checkWidget(); + return textColor; + } + + /** + * Returns the color of the text when the button is not selected. + * + * @return the receiver's text color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + + public Color getTextColorSelected() { + checkWidget(); + return textColorSelected; + } + + /** + * Returns the receiver's tool tip text, or null if it has not been set. + * + * @return the receiver's tool tip text + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getTooltipText() { + checkWidget(); + return tooltipText; + } + + /** + * Returns the whole width of the item. + * + * @return the receiver's height + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getWidth() { + checkWidget(); + if (width == -1) { + return Math.max(computeDefaultSize().x, MIN_WIDTH); + } + return Math.max(width, MIN_WIDTH); + } + + /** + * Returns true if the receiver is enabled, and false + * otherwise. A disabled control is typically not selectable from the user + * interface and draws with an inactive or "grayed" look. + * + * @return the receiver's enabled state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see #getEnabled + */ + public boolean isEnabled() { + checkWidget(); + return enabled; + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + selectionListeners.remove(listener); + } + + /** + * Controls how text will be displayed in the receiver. The argument should be + * one of LEFT, RIGHT or CENTER. + * + * @param alignment the new alignment + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setAlignment(final int alignment) { + checkWidget(); + this.alignment = alignment; + } + + /** + * Sets the receiver's size and location to the rectangular area specified by + * the argument. The x and y fields of the rectangle + * are relative to the receiver's parent (or its display if its parent is null). + *

+ * Note: Attempting to set the width or height of the receiver to a negative + * number will cause that value to be set to zero instead. + *

+ * + * @param rect the new bounds for the receiver + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setBounds(final Rectangle rectangle) { + checkWidget(); + if (bounds == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + bounds = new Rectangle(Math.max(0, rectangle.x), // + Math.max(0, rectangle.y), // + Math.max(0, rectangle.width), // + Math.max(0, rectangle.height)); + } + + /** + * Sets the receiver's image to the argument when this is one is disabled, which + * may be null indicating that no image should be displayed. + * + * @param image the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setDisabledImage(final Image image) { + checkWidget(); + disabledImage = image; + } + + /** + * Enables the receiver if the argument is true, and disables it + * otherwise. + *

+ * A disabled control is typically not selectable from the user interface and + * draws with an inactive or "grayed" look. + *

+ * + * @param enabled the new enabled state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setEnabled(final boolean enabled) { + checkWidget(); + this.enabled = enabled; + } + + /** + * Sets the height of the receiver. + *

+ * Note: Attempting to set the width or height of the receiver to a negative + * number will cause that value to be set to zero instead. + *

+ * + * @param height the new width + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setHeight(final int height) { + checkWidget(); + this.height = Math.max(height, 0); + } + + /** + * Sets the selection state of the receiver. + * + * @param selected the new selection state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSelection(final boolean selected) { + checkWidget(); + selection = selected; + } + + /** + * Sets the receiver's image to the argument when this one is selected, which + * may be null indicating that no image should be displayed. + * + * @param image the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSelectionImage(final Image image) { + checkWidget(); + selectionImage = image; + } + + /** + * Sets the receiver's text color to the argument, which may be null indicating + * that no image should be displayed. + * + * @param textColor the text color to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTextColor(final Color textColor) { + checkWidget(); + this.textColor = textColor; + } + + /** + * Sets the receiver's text color to the argument when this one is selected, + * which may be null indicating that no image should be displayed. + * + * @param textColor the text color to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTextColorSelected(final Color textColor) { + checkWidget(); + textColorSelected = textColor; + } + + /** + * Sets the receiver's tool tip text to the argument, which may be null + * indicating that the default tool tip for the control will be shown. For a + * control that has a default tool tip, such as the Tree control on Windows, + * setting the tool tip text to an empty string replaces the default, causing no + * tool tip text to be shown. + *

+ * The mnemonic indicator (character '&') is not displayed in a tool tip. To + * display a single '&' in the tool tip, the character '&' can be + * escaped by doubling it in the string. + *

+ * + * @param string the new tool tip text (or null) + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTooltipText(final String string) { + checkWidget(); + tooltipText = string == null ? "" : string; + } + + /** + * Sets the width of the receiver. + *

+ * Note: Attempting to set the width or height of the receiver to a negative + * number will cause that value to be set to zero instead. + *

+ * + * @param width the new width + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setWidth(final int width) { + checkWidget(); + this.width = Math.max(0, width); + } + + // --------------------------------------------- Package visibility section + void fireSelectionEvent() { + final Event event = new Event(); + event.widget = parentBreadcrumb; + event.display = getDisplay(); + event.item = this; + event.type = SWT.Selection; + for (final SelectionListener selectionListener : selectionListeners) { + selectionListener.widgetSelected(new SelectionEvent(event)); + } + } + + void drawButtonAtPosition(final int x) { + + if (selection) { + drawBackgroundAtPosition(x); + } + if (!isLastItemOfTheBreadCrumb) { + drawTrianglesAtPosition(x); + } + + int xPosition = computeGap(); + final Image drawnedImage = drawImageAtPosition(x + xPosition); + if (drawnedImage != null) { + xPosition += drawnedImage.getBounds().width + 2 * MARGIN; + } + drawTextAtPosition(x + xPosition); + + bounds = new Rectangle(x, 0, getWidth(), toolbarHeight); + } + + private void drawBackgroundAtPosition(final int x) { + gc.setAdvanced(true); + gc.setAntialias(SWT.ON); + + gc.setForeground(SELECTED_COLOR); + gc.setBackground(SELECTED_COLOR); + + final boolean hasBorder = parentBreadcrumb.hasBorder; + final boolean isFirst = parentBreadcrumb.indexOf(this) == 0; + final int borderWidth = hasBorder ? 1 : 0; + + int leftSide; + if (isFirst) { + leftSide = 0; + } else { + leftSide = 5 + (hasBorder ? 0 : 1); + } + + final int xUpperLeft = x + borderWidth + leftSide; + final int yUpperLeft = borderWidth; + final int rectWidth = getWidth() - borderWidth - leftSide - (isLastItemOfTheBreadCrumb && hasBorder ? 1 : 0); + final int rectHeight = getHeight() - 2 * borderWidth; + gc.fillRectangle(xUpperLeft, yUpperLeft, rectWidth, rectHeight); + + if (!isFirst) { + gc.fillPolygon(new int[] { xUpperLeft - 5, yUpperLeft, // + xUpperLeft, yUpperLeft, // + xUpperLeft, yUpperLeft + toolbarHeight / 2 // + }); + gc.fillPolygon(new int[] { xUpperLeft - 5, yUpperLeft + rectHeight, // + xUpperLeft, yUpperLeft + rectHeight, // + xUpperLeft, yUpperLeft + toolbarHeight / 2 // + }); + + } + + if (!isLastItemOfTheBreadCrumb) { + gc.fillPolygon(new int[] { xUpperLeft + rectWidth, yUpperLeft + 1, // + xUpperLeft + rectWidth, yUpperLeft + getHeight(), // + xUpperLeft + rectWidth + 5, yUpperLeft + toolbarHeight / 2 // + }); + } + + gc.setClipping((Rectangle) null); + } + + private void drawTrianglesAtPosition(final int x) { + gc.setForeground(Breadcrumb.BORDER_COLOR); + drawTriangleAtPosition(x + getWidth()); + + gc.setAlpha(127); + gc.setForeground(Breadcrumb.BORDER_COLOR_1); + drawTriangleAtPosition(x + getWidth() + 1); + + gc.setForeground(Breadcrumb.BORDER_COLOR_2); + drawTriangleAtPosition(x + getWidth() + 2); + + gc.setForeground(Breadcrumb.BORDER_COLOR_3); + drawTriangleAtPosition(x + getWidth() + 3); + + gc.setAlpha(255); + if (parentBreadcrumb.hasBorder) { + gc.setForeground(Breadcrumb.BORDER_COLOR); + gc.drawLine(x + getWidth(), 0, x + getWidth() + 3, 0); + gc.drawLine(x + getWidth(), toolbarHeight - 1, x + getWidth() + 3, toolbarHeight - 1); + } + } + + private void drawTriangleAtPosition(final int x) { + gc.drawLine(x, 0, x + 5, toolbarHeight / 2); + gc.drawLine(x + 5, toolbarHeight / 2, x, toolbarHeight); + + } + + private int computeGap() { + final int widthOfTextAndImage = computeSizeOfTextAndImages().x; + switch (alignment) { + case SWT.CENTER: + return (getWidth() - widthOfTextAndImage) / 2; + case SWT.RIGHT: + return getWidth() - widthOfTextAndImage - MARGIN; + default: + return MARGIN; + } + } + + private Point computeSizeOfTextAndImages() { + int width = 0, height = 0; + final boolean textISNotEmpty = getText() != null && !getText().equals(""); + + if (textISNotEmpty) { + final GC gc = new GC(parentBreadcrumb); + gc.setFont(parentBreadcrumb.getFont()); + final Point extent = gc.stringExtent(getText()); + gc.dispose(); + width += extent.x; + height = extent.y; + } + + final Point imageSize = computeMaxWidthAndHeightForImages(getImage(), selectionImage, disabledImage); + + if (imageSize.x != -1) { + width += imageSize.x; + height = Math.max(imageSize.y, height); + if (textISNotEmpty) { + width += MARGIN * 2; + } + } + width += MARGIN; + return new Point(width, height); + } + + private Point computeMaxWidthAndHeightForImages(final Image... images) { + final Point imageSize = new Point(-1, -1); + for (final Image image : images) { + if (image == null) { + continue; + } + final Rectangle imageBounds = image.getBounds(); + imageSize.x = Math.max(imageBounds.width, imageSize.x); + imageSize.y = Math.max(imageBounds.height, imageSize.y); + } + return imageSize; + } + + private Image drawImageAtPosition(final int xPosition) { + Image image; + if (!isEnabled()) { + image = disabledImage; + } else if (selection) { + image = selectionImage; + } else { + image = getImage(); + } + + if (image == null) { + return null; + } + + final int yPosition = (toolbarHeight - image.getBounds().height) / 2; + gc.drawImage(image, (int) (xPosition + MARGIN * 1.5), yPosition); + return image; + } + + private void drawTextAtPosition(final int xPosition) { + gc.setFont(parentBreadcrumb.getFont()); + if (selection) { + gc.setForeground(textColorSelected); + } else { + gc.setForeground(textColor); + } + + final Point textSize = gc.stringExtent(getText()); + final int yPosition = (toolbarHeight - textSize.y) / 2; + + int padding; + if (parentBreadcrumb.indexOf(this) == 0 || isLastItemOfTheBreadCrumb) { + padding = 0; + } else { + padding = 5; + } + gc.drawText(getText(), xPosition + padding, yPosition, true); + } + + BreadcrumbItem setGc(final GC gc) { + this.gc = gc; + return this; + } + + BreadcrumbItem setToolbarHeight(final int toolbarHeight) { + this.toolbarHeight = toolbarHeight; + return this; + } + + BreadcrumbItem setIsLastItemOfTheBreadCrumb(final boolean isLastItemOfTheBreadCrumb) { + this.isLastItemOfTheBreadCrumb = isLastItemOfTheBreadCrumb; + return this; + } + +} diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/.project b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/.project index 2bf5bb5c0..df2f600e0 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/.project +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.calculator.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.calculator.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/build.properties b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/build.properties +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/feature.properties b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/feature.properties +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.classpath b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.classpath +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.project b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.project index 431e76df9..650819a1d 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.project +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.calculator.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.calculator.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/META-INF/MANIFEST.MF b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/META-INF/MANIFEST.MF index f6b86ab26..9806733e2 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Calculator Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.calculator.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.calculator;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.calculator.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Calculator Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.calculator.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.calculator;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.calculator.snippets diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/build.properties b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/build.properties +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/src/org/eclipse/nebula/widgets/opal/calculator/snippets/CalculatorComboSnippet.java b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/src/org/eclipse/nebula/widgets/opal/calculator/snippets/CalculatorComboSnippet.java index 7ceeed048..14694b4e4 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/src/org/eclipse/nebula/widgets/opal/calculator/snippets/CalculatorComboSnippet.java +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/src/org/eclipse/nebula/widgets/opal/calculator/snippets/CalculatorComboSnippet.java @@ -1,62 +1,62 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON. - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.calculator.snippets; - -import org.eclipse.nebula.widgets.opal.calculator.CalculatorCombo; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple snippet for the CalculatorCombo Widget - */ -public class CalculatorComboSnippet { - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(2, false)); - - final Label label = new Label(shell, SWT.NONE); - label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - label.setText("Calculator combo:"); - - final CalculatorCombo combo = new CalculatorCombo(shell, SWT.NONE); - combo.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, false)); - - combo.addModifyListener(new ModifyListener() { - - @Override - public void modifyText(final ModifyEvent e) { - System.out.println("New value is " + combo.getValue()); - - } - }); - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } - -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON. + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.calculator.snippets; + +import org.eclipse.nebula.widgets.opal.calculator.CalculatorCombo; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple snippet for the CalculatorCombo Widget + */ +public class CalculatorComboSnippet { + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(2, false)); + + final Label label = new Label(shell, SWT.NONE); + label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + label.setText("Calculator combo:"); + + final CalculatorCombo combo = new CalculatorCombo(shell, SWT.NONE); + combo.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, false)); + + combo.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(final ModifyEvent e) { + System.out.println("New value is " + combo.getValue()); + + } + }); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } + +} diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/src/org/eclipse/nebula/widgets/opal/calculator/snippets/CalculatorSnippet.java b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/src/org/eclipse/nebula/widgets/opal/calculator/snippets/CalculatorSnippet.java index bb26c7503..ecdefbb7c 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/src/org/eclipse/nebula/widgets/opal/calculator/snippets/CalculatorSnippet.java +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator.snippets/src/org/eclipse/nebula/widgets/opal/calculator/snippets/CalculatorSnippet.java @@ -1,55 +1,55 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON. - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.calculator.snippets; - -import org.eclipse.nebula.widgets.opal.calculator.Calculator; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple snippet for the Calculator Widget - */ -public class CalculatorSnippet { - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new FillLayout(SWT.VERTICAL)); - - final Calculator calc = new Calculator(shell, SWT.NONE); - - calc.addModifyListener(new ModifyListener() { - - @Override - public void modifyText(final ModifyEvent e) { - System.out.println("New value is " + calc.getValue()); - - } - }); - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } - -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON. + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.calculator.snippets; + +import org.eclipse.nebula.widgets.opal.calculator.Calculator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple snippet for the Calculator Widget + */ +public class CalculatorSnippet { + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new FillLayout(SWT.VERTICAL)); + + final Calculator calc = new Calculator(shell, SWT.NONE); + + calc.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(final ModifyEvent e) { + System.out.println("New value is " + calc.getValue()); + + } + }); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } + +} diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.classpath b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.classpath +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.project b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.project index dfb4f9a0c..a6c3303ab 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.project +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.calculator - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.calculator + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/META-INF/MANIFEST.MF b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/META-INF/MANIFEST.MF index 4afb8cc1b..35a177b25 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/META-INF/MANIFEST.MF +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Calculator Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.calculator -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.calculator -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.calculator +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Calculator Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.calculator +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.calculator +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.calculator diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/build.properties b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/build.properties +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/Calculator.java b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/Calculator.java index e6a071120..8e2c959ed 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/Calculator.java +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/Calculator.java @@ -1,162 +1,162 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Laurent CARON - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.calculator; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; - -/** - * Instances of this class are calculator. - *
- *
Styles:
- *
(none)
- *
Events:
- *
(none)
- *
- * This component is inspired by Hermant - * (http://www.javabeginner.com/java-swing/java-swing-calculator) - */ -public class Calculator extends Composite { - - private final Label displayArea; - private final CalculatorButtonsComposite panel; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - */ - public Calculator(final Composite parent, final int style) { - super(parent, style); - setLayout(new GridLayout()); - displayArea = createTextArea(); - panel = new CalculatorButtonsComposite(this, SWT.NONE); - panel.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - panel.setDisplayArea(displayArea); - displayArea.addListener(SWT.KeyDown,panel.getKeyListener()); - } - - /** - * Create the text area - */ - private Label createTextArea() { - final Label text = new Label(this, SWT.BORDER | SWT.RIGHT); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false); - gd.widthHint = 150; - text.setLayoutData(gd); - text.setText("0"); - text.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - return text; - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the receiver's text is modified, by sending it one of the messages defined in - * the ModifyListener interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #removeModifyListener - */ - public void addModifyListener(final ModifyListener listener) { - checkWidget(); - panel.addModifyListener(listener); - } - - /** - * @return the value - */ - public String getValue() { - checkWidget(); - return displayArea.getText(); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the receiver's text is modified. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #addModifyListener - */ - public void removeModifyListener(final ModifyListener listener) { - checkWidget(); - panel.removeModifyListener(listener); - } - - /** - * @param value new value - * @throws NumberFormatException if value is not a valid double - * value - */ - public void setValue(final String value) { - checkWidget(); - new Double(value); - displayArea.setText(value); - } - -} +/******************************************************************************* + * Copyright (c) 2012-2017 Laurent CARON + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.calculator; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +/** + * Instances of this class are calculator. + *
+ *
Styles:
+ *
(none)
+ *
Events:
+ *
(none)
+ *
+ * This component is inspired by Hermant + * (http://www.javabeginner.com/java-swing/java-swing-calculator) + */ +public class Calculator extends Composite { + + private final Label displayArea; + private final CalculatorButtonsComposite panel; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + public Calculator(final Composite parent, final int style) { + super(parent, style); + setLayout(new GridLayout()); + displayArea = createTextArea(); + panel = new CalculatorButtonsComposite(this, SWT.NONE); + panel.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + panel.setDisplayArea(displayArea); + displayArea.addListener(SWT.KeyDown,panel.getKeyListener()); + } + + /** + * Create the text area + */ + private Label createTextArea() { + final Label text = new Label(this, SWT.BORDER | SWT.RIGHT); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false); + gd.widthHint = 150; + text.setLayoutData(gd); + text.setText("0"); + text.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + return text; + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the receiver's text is modified, by sending it one of the messages defined in + * the ModifyListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #removeModifyListener + */ + public void addModifyListener(final ModifyListener listener) { + checkWidget(); + panel.addModifyListener(listener); + } + + /** + * @return the value + */ + public String getValue() { + checkWidget(); + return displayArea.getText(); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the receiver's text is modified. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #addModifyListener + */ + public void removeModifyListener(final ModifyListener listener) { + checkWidget(); + panel.removeModifyListener(listener); + } + + /** + * @param value new value + * @throws NumberFormatException if value is not a valid double + * value + */ + public void setValue(final String value) { + checkWidget(); + new Double(value); + displayArea.setText(value); + } + +} diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorButtonsBehaviourEngine.java b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorButtonsBehaviourEngine.java index bc504094b..ea3304c97 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorButtonsBehaviourEngine.java +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorButtonsBehaviourEngine.java @@ -1,85 +1,85 @@ -/******************************************************************************* - * Copyright (c) 2012-2017 Laurent CARON - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.calculator; - -public class CalculatorButtonsBehaviourEngine { - - private final CalculatorButtonsComposite composite; - - public CalculatorButtonsBehaviourEngine(final CalculatorButtonsComposite composite) { - this.composite = composite; - } - - public void processBackSpace() { - if (composite.isReadyToEnterNewNumber()) { - return; - } - final String content = getContent(); - if (content.length() < 2) { - return; - - } - final String newContent = content.substring(0, content.length() - 2); - setContent(newContent.length() == 0 ? "0" : newContent); - composite.setReadyToEnterNewNumber(false); - } - - private String getContent() { - return composite.getDisplayArea().getText(); - } - - private void setContent(final String newContent) { - composite.getDisplayArea().setText(newContent); - composite.fireModifyListeners(); - } - - public void clearResult() { - setContent("0"); - } - - public void addDecimalPoint() { - if (composite.isReadyToEnterNewNumber()) { - return; - } - final String content = getContent(); - if (content.indexOf('.') > 0) { - return; - } - final String newContent = content + "."; - setContent(newContent); - } - - public void addDigitToDisplay(final int digit) { - final String content = getContent(); - if (composite.isReadyToEnterNewNumber()) { - setContent(String.valueOf(digit)); - return; - } - String newContent; - if (content.length() == 1) { - if (digit == 0) { - return; - } - if (getContent().equals("0")) { - newContent = String.valueOf(digit); - } else { - newContent = content + String.valueOf(digit); - } - } else { - newContent = content + String.valueOf(digit); - } - setContent(newContent); - } - -} +/******************************************************************************* + * Copyright (c) 2012-2017 Laurent CARON + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.calculator; + +public class CalculatorButtonsBehaviourEngine { + + private final CalculatorButtonsComposite composite; + + public CalculatorButtonsBehaviourEngine(final CalculatorButtonsComposite composite) { + this.composite = composite; + } + + public void processBackSpace() { + if (composite.isReadyToEnterNewNumber()) { + return; + } + final String content = getContent(); + if (content.length() < 2) { + return; + + } + final String newContent = content.substring(0, content.length() - 2); + setContent(newContent.length() == 0 ? "0" : newContent); + composite.setReadyToEnterNewNumber(false); + } + + private String getContent() { + return composite.getDisplayArea().getText(); + } + + private void setContent(final String newContent) { + composite.getDisplayArea().setText(newContent); + composite.fireModifyListeners(); + } + + public void clearResult() { + setContent("0"); + } + + public void addDecimalPoint() { + if (composite.isReadyToEnterNewNumber()) { + return; + } + final String content = getContent(); + if (content.indexOf('.') > 0) { + return; + } + final String newContent = content + "."; + setContent(newContent); + } + + public void addDigitToDisplay(final int digit) { + final String content = getContent(); + if (composite.isReadyToEnterNewNumber()) { + setContent(String.valueOf(digit)); + return; + } + String newContent; + if (content.length() == 1) { + if (digit == 0) { + return; + } + if (getContent().equals("0")) { + newContent = String.valueOf(digit); + } else { + newContent = content + String.valueOf(digit); + } + } else { + newContent = content + String.valueOf(digit); + } + setContent(newContent); + } + +} diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorButtonsComposite.java b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorButtonsComposite.java index 5659fdac5..7a448323d 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorButtonsComposite.java +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorButtonsComposite.java @@ -1,375 +1,375 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.calculator; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; - -/** - * This composite contains all buttons - */ -class CalculatorButtonsComposite extends Composite { - - private static final String LABEL_C = "C"; - private static final String LABEL_CE = "CE"; - private static final String LABEL_BACK = "Back"; - private final Color darkRedColor; - private final Color darkBlueColor; - private final CalculatorEngine engine; - private Label displayArea; - private Listener keyListener; - private final List modifyListeners; - private final CalculatorButtonsBehaviourEngine behaviourEngine; - private boolean readyToEnterNewNumber; - - /** - * Constructor - * - * @param parent parent composite - * @param style style - */ - CalculatorButtonsComposite(final Composite parent, final int style) { - super(parent, style); - setLayout(new GridLayout(5, false)); - darkRedColor = new Color(getDisplay(), 139, 0, 0); - darkBlueColor = new Color(getDisplay(), 0, 0, 139); - createButtons(); - - SWTGraphicUtil.addDisposer(this, darkBlueColor); - SWTGraphicUtil.addDisposer(this, darkRedColor); - - engine = new CalculatorEngine(this); - behaviourEngine = new CalculatorButtonsBehaviourEngine(this); - addKeyListeners(); - modifyListeners = new ArrayList(); - } - - /** - * Create all buttons - */ - private void createButtons() { - final Button buttonBackSpace = createButton(LABEL_BACK, darkRedColor); - buttonBackSpace.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false, 3, 1)); - buttonBackSpace.addListener(SWT.Selection, e -> { - behaviourEngine.processBackSpace(); - }); - - final Button buttonCe = createButton(LABEL_CE, darkRedColor); - buttonCe.addListener(SWT.Selection, e -> { - behaviourEngine.clearResult(); - }); - - final Button buttonC = createButton(LABEL_C, darkRedColor); - buttonC.addListener(SWT.Selection, e -> { - behaviourEngine.clearResult(); - engine.cancel(); - }); - - createDigitButton(7); - createDigitButton(8); - createDigitButton(9); - - final Button buttonDivide = createButton(CalculatorEngine.OPERATOR_DIVIDE, getDisplay().getSystemColor(SWT.COLOR_RED)); - buttonDivide.addListener(SWT.Selection, e -> { - engine.processOperation(CalculatorEngine.OPERATOR_DIVIDE); - }); - - final Button buttonSqrt = createButton("\u221A", darkRedColor); - buttonSqrt.addListener(SWT.Selection, e -> { - engine.processSquareRootOperation(); - }); - - createDigitButton(4); - createDigitButton(5); - createDigitButton(6); - - final Button buttonMultiply = createButton(CalculatorEngine.OPERATOR_MULTIPLY, getDisplay().getSystemColor(SWT.COLOR_RED)); - buttonMultiply.addListener(SWT.Selection, e -> { - engine.processOperation(CalculatorEngine.OPERATOR_MULTIPLY); - }); - final Button buttonInverse = createButton("1/x", darkBlueColor); - buttonInverse.addListener(SWT.Selection, e -> { - engine.processInverseOperation(); - }); - - createDigitButton(1); - createDigitButton(2); - createDigitButton(3); - - final Button buttonMinus = createButton(CalculatorEngine.OPERATOR_MINUS, getDisplay().getSystemColor(SWT.COLOR_RED)); - buttonMinus.addListener(SWT.Selection, e -> { - engine.processOperation(CalculatorEngine.OPERATOR_MINUS); - }); - - final Button buttonPercent = createButton("%", darkBlueColor); - buttonPercent.addListener(SWT.Selection, e -> { - engine.processPerCentageOperation(); - }); - - createDigitButton(0); - - final Button buttonPlusMinus = createButton("+/-", getDisplay().getSystemColor(SWT.COLOR_BLUE)); - buttonPlusMinus.addListener(SWT.Selection, e -> { - engine.processSignChange(); - }); - final Button buttonDot = createButton(".", getDisplay().getSystemColor(SWT.COLOR_BLUE)); - buttonDot.addListener(SWT.Selection, e -> { - behaviourEngine.addDecimalPoint(); - }); - - final Button buttonPlus = createButton(CalculatorEngine.OPERATOR_PLUS, getDisplay().getSystemColor(SWT.COLOR_RED)); - buttonPlus.addListener(SWT.Selection, e -> { - engine.processOperation(CalculatorEngine.OPERATOR_PLUS); - }); - - final Button buttonEquals = createButton("=", getDisplay().getSystemColor(SWT.COLOR_RED)); - buttonEquals.addListener(SWT.Selection, e -> { - engine.processEquals(); - }); - } - - private void createDigitButton(final int digit) { - final Button button = createButton(" " + digit + " ", getDisplay().getSystemColor(SWT.COLOR_BLUE)); - button.addListener(SWT.Selection, e -> { - behaviourEngine.addDigitToDisplay(digit); - }); - - } - - private Button createButton(final String label, final Color color) { - final Button button = new Button(this, SWT.PUSH | SWT.DOUBLE_BUFFERED); - button.setText(""); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false); - gd.widthHint = 30; - button.setLayoutData(gd); - - // Use a paint listener because setForeground is not working on Windows - button.addPaintListener(e -> { - e.gc.setForeground(color); - e.gc.setFont(getFont()); - final Point textSize = e.gc.textExtent(" " + label + " ", SWT.TRANSPARENT); - e.gc.drawText(" " + label + " ", (button.getBounds().width - textSize.x) / 2, (button.getBounds().height - textSize.y) / 2, true); - }); - - return button; - } - - /** - * Add key listeners - */ - private void addKeyListeners() { - keyListener = e -> { - - switch (e.character) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - behaviourEngine.addDigitToDisplay(Integer.parseInt(String.valueOf(e.character))); - return; - case '.': - behaviourEngine.addDecimalPoint(); - return; - case '+': - engine.processOperation(CalculatorEngine.OPERATOR_PLUS); - return; - case '-': - engine.processOperation(CalculatorEngine.OPERATOR_MINUS); - return; - case '*': - engine.processOperation(CalculatorEngine.OPERATOR_MULTIPLY); - return; - case '/': - engine.processOperation(CalculatorEngine.OPERATOR_DIVIDE); - return; - case '=': - engine.processEquals(); - return; - case '%': - engine.processPerCentageOperation(); - return; - - } - - switch (e.keyCode) { - case SWT.KEYPAD_0: - case SWT.KEYPAD_1: - case SWT.KEYPAD_2: - case SWT.KEYPAD_3: - case SWT.KEYPAD_4: - case SWT.KEYPAD_5: - case SWT.KEYPAD_6: - case SWT.KEYPAD_7: - case SWT.KEYPAD_8: - case SWT.KEYPAD_9: - final int digit = e.keyCode - SWT.KEYCODE_BIT - 47; - behaviourEngine.addDigitToDisplay(digit); - return; - case SWT.KEYPAD_ADD: - engine.processOperation(CalculatorEngine.OPERATOR_PLUS); - return; - case SWT.KEYPAD_SUBTRACT: - engine.processOperation(CalculatorEngine.OPERATOR_MINUS); - return; - case SWT.KEYPAD_DIVIDE: - engine.processOperation(CalculatorEngine.OPERATOR_DIVIDE); - return; - case SWT.KEYPAD_MULTIPLY: - engine.processOperation(CalculatorEngine.OPERATOR_MULTIPLY); - return; - case SWT.KEYPAD_CR: - case SWT.KEYPAD_EQUAL: - case SWT.CR: - engine.processEquals(); - return; - case SWT.BS: - behaviourEngine.processBackSpace(); - return; - case SWT.ESC: - behaviourEngine.clearResult(); - engine.cancel(); - return; - } - }; - - for (final Control control : getChildren()) { - control.addListener(SWT.KeyDown, keyListener); - } - addListener(SWT.KeyDown, keyListener); - - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the receiver's text is modified, by sending it one of the messages defined in - * the ModifyListener interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #removeModifyListener - */ - public void addModifyListener(final ModifyListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - modifyListeners.add(listener); - } - - /** - * Fire the modify listeners - */ - void fireModifyListeners() { - for (final ModifyListener listener : modifyListeners) { - final Event e = new Event(); - e.widget = this; - final ModifyEvent modifyEvent = new ModifyEvent(e); - listener.modifyText(modifyEvent); - } - } - - /** - * @return the keyListener - */ - Listener getKeyListener() { - return keyListener; - } - - /** - * @return the text - */ - Label getDisplayArea() { - return displayArea; - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the receiver's text is modified. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #addModifyListener - */ - public void removeModifyListener(final ModifyListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - modifyListeners.remove(listener); - } - - /** - * @param text the text to set - */ - void setDisplayArea(final Label text) { - displayArea = text; - } - - void setReadyToEnterNewNumber(final boolean newValue) { - readyToEnterNewNumber = newValue; - } - - boolean isReadyToEnterNewNumber() { - return readyToEnterNewNumber; - } - -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.calculator; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; + +/** + * This composite contains all buttons + */ +class CalculatorButtonsComposite extends Composite { + + private static final String LABEL_C = "C"; + private static final String LABEL_CE = "CE"; + private static final String LABEL_BACK = "Back"; + private final Color darkRedColor; + private final Color darkBlueColor; + private final CalculatorEngine engine; + private Label displayArea; + private Listener keyListener; + private final List modifyListeners; + private final CalculatorButtonsBehaviourEngine behaviourEngine; + private boolean readyToEnterNewNumber; + + /** + * Constructor + * + * @param parent parent composite + * @param style style + */ + CalculatorButtonsComposite(final Composite parent, final int style) { + super(parent, style); + setLayout(new GridLayout(5, false)); + darkRedColor = new Color(getDisplay(), 139, 0, 0); + darkBlueColor = new Color(getDisplay(), 0, 0, 139); + createButtons(); + + SWTGraphicUtil.addDisposer(this, darkBlueColor); + SWTGraphicUtil.addDisposer(this, darkRedColor); + + engine = new CalculatorEngine(this); + behaviourEngine = new CalculatorButtonsBehaviourEngine(this); + addKeyListeners(); + modifyListeners = new ArrayList(); + } + + /** + * Create all buttons + */ + private void createButtons() { + final Button buttonBackSpace = createButton(LABEL_BACK, darkRedColor); + buttonBackSpace.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false, 3, 1)); + buttonBackSpace.addListener(SWT.Selection, e -> { + behaviourEngine.processBackSpace(); + }); + + final Button buttonCe = createButton(LABEL_CE, darkRedColor); + buttonCe.addListener(SWT.Selection, e -> { + behaviourEngine.clearResult(); + }); + + final Button buttonC = createButton(LABEL_C, darkRedColor); + buttonC.addListener(SWT.Selection, e -> { + behaviourEngine.clearResult(); + engine.cancel(); + }); + + createDigitButton(7); + createDigitButton(8); + createDigitButton(9); + + final Button buttonDivide = createButton(CalculatorEngine.OPERATOR_DIVIDE, getDisplay().getSystemColor(SWT.COLOR_RED)); + buttonDivide.addListener(SWT.Selection, e -> { + engine.processOperation(CalculatorEngine.OPERATOR_DIVIDE); + }); + + final Button buttonSqrt = createButton("\u221A", darkRedColor); + buttonSqrt.addListener(SWT.Selection, e -> { + engine.processSquareRootOperation(); + }); + + createDigitButton(4); + createDigitButton(5); + createDigitButton(6); + + final Button buttonMultiply = createButton(CalculatorEngine.OPERATOR_MULTIPLY, getDisplay().getSystemColor(SWT.COLOR_RED)); + buttonMultiply.addListener(SWT.Selection, e -> { + engine.processOperation(CalculatorEngine.OPERATOR_MULTIPLY); + }); + final Button buttonInverse = createButton("1/x", darkBlueColor); + buttonInverse.addListener(SWT.Selection, e -> { + engine.processInverseOperation(); + }); + + createDigitButton(1); + createDigitButton(2); + createDigitButton(3); + + final Button buttonMinus = createButton(CalculatorEngine.OPERATOR_MINUS, getDisplay().getSystemColor(SWT.COLOR_RED)); + buttonMinus.addListener(SWT.Selection, e -> { + engine.processOperation(CalculatorEngine.OPERATOR_MINUS); + }); + + final Button buttonPercent = createButton("%", darkBlueColor); + buttonPercent.addListener(SWT.Selection, e -> { + engine.processPerCentageOperation(); + }); + + createDigitButton(0); + + final Button buttonPlusMinus = createButton("+/-", getDisplay().getSystemColor(SWT.COLOR_BLUE)); + buttonPlusMinus.addListener(SWT.Selection, e -> { + engine.processSignChange(); + }); + final Button buttonDot = createButton(".", getDisplay().getSystemColor(SWT.COLOR_BLUE)); + buttonDot.addListener(SWT.Selection, e -> { + behaviourEngine.addDecimalPoint(); + }); + + final Button buttonPlus = createButton(CalculatorEngine.OPERATOR_PLUS, getDisplay().getSystemColor(SWT.COLOR_RED)); + buttonPlus.addListener(SWT.Selection, e -> { + engine.processOperation(CalculatorEngine.OPERATOR_PLUS); + }); + + final Button buttonEquals = createButton("=", getDisplay().getSystemColor(SWT.COLOR_RED)); + buttonEquals.addListener(SWT.Selection, e -> { + engine.processEquals(); + }); + } + + private void createDigitButton(final int digit) { + final Button button = createButton(" " + digit + " ", getDisplay().getSystemColor(SWT.COLOR_BLUE)); + button.addListener(SWT.Selection, e -> { + behaviourEngine.addDigitToDisplay(digit); + }); + + } + + private Button createButton(final String label, final Color color) { + final Button button = new Button(this, SWT.PUSH | SWT.DOUBLE_BUFFERED); + button.setText(""); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false); + gd.widthHint = 30; + button.setLayoutData(gd); + + // Use a paint listener because setForeground is not working on Windows + button.addPaintListener(e -> { + e.gc.setForeground(color); + e.gc.setFont(getFont()); + final Point textSize = e.gc.textExtent(" " + label + " ", SWT.TRANSPARENT); + e.gc.drawText(" " + label + " ", (button.getBounds().width - textSize.x) / 2, (button.getBounds().height - textSize.y) / 2, true); + }); + + return button; + } + + /** + * Add key listeners + */ + private void addKeyListeners() { + keyListener = e -> { + + switch (e.character) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + behaviourEngine.addDigitToDisplay(Integer.parseInt(String.valueOf(e.character))); + return; + case '.': + behaviourEngine.addDecimalPoint(); + return; + case '+': + engine.processOperation(CalculatorEngine.OPERATOR_PLUS); + return; + case '-': + engine.processOperation(CalculatorEngine.OPERATOR_MINUS); + return; + case '*': + engine.processOperation(CalculatorEngine.OPERATOR_MULTIPLY); + return; + case '/': + engine.processOperation(CalculatorEngine.OPERATOR_DIVIDE); + return; + case '=': + engine.processEquals(); + return; + case '%': + engine.processPerCentageOperation(); + return; + + } + + switch (e.keyCode) { + case SWT.KEYPAD_0: + case SWT.KEYPAD_1: + case SWT.KEYPAD_2: + case SWT.KEYPAD_3: + case SWT.KEYPAD_4: + case SWT.KEYPAD_5: + case SWT.KEYPAD_6: + case SWT.KEYPAD_7: + case SWT.KEYPAD_8: + case SWT.KEYPAD_9: + final int digit = e.keyCode - SWT.KEYCODE_BIT - 47; + behaviourEngine.addDigitToDisplay(digit); + return; + case SWT.KEYPAD_ADD: + engine.processOperation(CalculatorEngine.OPERATOR_PLUS); + return; + case SWT.KEYPAD_SUBTRACT: + engine.processOperation(CalculatorEngine.OPERATOR_MINUS); + return; + case SWT.KEYPAD_DIVIDE: + engine.processOperation(CalculatorEngine.OPERATOR_DIVIDE); + return; + case SWT.KEYPAD_MULTIPLY: + engine.processOperation(CalculatorEngine.OPERATOR_MULTIPLY); + return; + case SWT.KEYPAD_CR: + case SWT.KEYPAD_EQUAL: + case SWT.CR: + engine.processEquals(); + return; + case SWT.BS: + behaviourEngine.processBackSpace(); + return; + case SWT.ESC: + behaviourEngine.clearResult(); + engine.cancel(); + return; + } + }; + + for (final Control control : getChildren()) { + control.addListener(SWT.KeyDown, keyListener); + } + addListener(SWT.KeyDown, keyListener); + + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the receiver's text is modified, by sending it one of the messages defined in + * the ModifyListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #removeModifyListener + */ + public void addModifyListener(final ModifyListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + modifyListeners.add(listener); + } + + /** + * Fire the modify listeners + */ + void fireModifyListeners() { + for (final ModifyListener listener : modifyListeners) { + final Event e = new Event(); + e.widget = this; + final ModifyEvent modifyEvent = new ModifyEvent(e); + listener.modifyText(modifyEvent); + } + } + + /** + * @return the keyListener + */ + Listener getKeyListener() { + return keyListener; + } + + /** + * @return the text + */ + Label getDisplayArea() { + return displayArea; + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the receiver's text is modified. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #addModifyListener + */ + public void removeModifyListener(final ModifyListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + modifyListeners.remove(listener); + } + + /** + * @param text the text to set + */ + void setDisplayArea(final Label text) { + displayArea = text; + } + + void setReadyToEnterNewNumber(final boolean newValue) { + readyToEnterNewNumber = newValue; + } + + boolean isReadyToEnterNewNumber() { + return readyToEnterNewNumber; + } + +} diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorCombo.java b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorCombo.java index 319c02214..8129ece29 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorCombo.java +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorCombo.java @@ -1,417 +1,417 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.opal.calculator; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; - -/** - * The CalculatorCombo class represents a selectable user interface object that - * combines a text field and a calculator buttons panel and issues notification - * when an the value is modified. - *

- * Note that although this class is a subclass of Composite, it - * does not make sense to add children to it, or set a layout on it. - *

- *
- *
Styles: - *
BORDER, FLAT
- *
Events: - *
Modify
- *
- * - * @see CCombo - * snippets - */ -public class CalculatorCombo extends Composite { - - private Label label; - private Button arrow; - private Shell popup; - private Listener listener, filter; - private boolean hasFocus; - private Listener keyListener; - private CalculatorButtonsComposite composite; - - /** - * Constructs a new instance of this class given its parent. - * - * @param parent a widget which will be the parent of the new instance (cannot be null) - * @param style not used - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- */ - public CalculatorCombo(final Composite parent, final int style) { - super(parent, style); - - final GridLayout gridLayout = new GridLayout(2, false); - gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginWidth = gridLayout.marginHeight = 0; - setLayout(gridLayout); - - label = new Label(this, SWT.BORDER | SWT.RIGHT); - label.setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - label.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - - arrow = new Button(this, SWT.ARROW | SWT.DOWN); - arrow.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - - listener = event -> { - if (popup == event.widget) { - handlePopupEvent(event); - return; - } - - if (arrow == event.widget) { - handleButtonEvent(event); - return; - } - - if (CalculatorCombo.this == event.widget) { - handleMultiChoiceEvent(event); - return; - } - - if (getShell() == event.widget) { - getDisplay().asyncExec(() -> { - if (isDisposed()) { - return; - } - handleFocusEvent(SWT.FocusOut); - }); - } - }; - - final int[] calculatorComboEvents = { SWT.Dispose, SWT.Move, SWT.Resize }; - for (final int calculatorComboEvent : calculatorComboEvents) { - addListener(calculatorComboEvent, listener); - } - - final int[] buttonEvents = { SWT.Selection, SWT.FocusIn }; - for (final int buttonEvent : buttonEvents) { - arrow.addListener(buttonEvent, listener); - } - - filter = event -> { - final Shell shell = ((Control) event.widget).getShell(); - if (shell == CalculatorCombo.this.getShell()) { - handleFocusEvent(SWT.FocusOut); - } - }; - - createPopupShell(); - } - - /** - * Handle a popup event - * - * @param event event to handle - */ - private void handlePopupEvent(final Event event) { - switch (event.type) { - case SWT.Paint: - final Rectangle listRect = popup.getBounds(); - final Color black = getDisplay().getSystemColor(SWT.COLOR_BLACK); - event.gc.setForeground(black); - event.gc.drawRectangle(0, 0, listRect.width - 1, listRect.height - 1); - break; - case SWT.Close: - event.doit = false; - hidePopupWindow(false); - break; - case SWT.Deactivate: - hidePopupWindow(false); - break; - case SWT.Dispose: - if (keyListener != null) { - label.removeListener(SWT.KeyDown,keyListener); - } - break; - } - } - - private void hidePopupWindow(final boolean drop) { - _displayHidePopupWindow(false); - } - - private void _displayHidePopupWindow(final boolean show) { - if (show == isPopupVisible()) { - return; - } - - if (!show) { - popup.setVisible(false); - if (!isDisposed()) { - label.setFocus(); - } - return; - } - - if (getShell() != popup.getParent()) { - popup.dispose(); - popup = null; - createPopupShell(); - } - - final Point textRect = label.toDisplay(label.getLocation().x, label.getLocation().y); - final int x = textRect.x; - final int y = textRect.y + label.getSize().y; - - popup.setLocation(x, y); - popup.setVisible(true); - popup.setFocus(); - } - - private void createPopupShell() { - popup = new Shell(getShell(), SWT.NO_TRIM | SWT.ON_TOP); - popup.setLayout(new GridLayout()); - - final int[] popupEvents = { SWT.Close, SWT.Paint, SWT.Deactivate, SWT.Dispose }; - for (final int popupEvent : popupEvents) { - popup.addListener(popupEvent, listener); - } - - composite = new CalculatorButtonsComposite(popup, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - composite.setDisplayArea(label); - keyListener = composite.getKeyListener(); - label.addListener(SWT.KeyDown, keyListener); - - popup.pack(); - } - - private void handleButtonEvent(final Event event) { - switch (event.type) { - case SWT.FocusIn: { - handleFocusEvent(SWT.FocusIn); - break; - } - case SWT.Selection: { - _displayHidePopupWindow(!isPopupVisible()); - break; - } - } - } - - private void handleFocusEvent(final int eventType) { - if (isDisposed()) { - return; - } - switch (eventType) { - case SWT.FocusIn: { - if (hasFocus) { - return; - } - hasFocus = true; - final Shell shell = getShell(); - shell.removeListener(SWT.Deactivate, listener); - shell.addListener(SWT.Deactivate, listener); - final Display display = getDisplay(); - display.removeFilter(SWT.FocusIn, filter); - display.addFilter(SWT.FocusIn, filter); - final Event e = new Event(); - notifyListeners(SWT.FocusIn, e); - break; - } - case SWT.FocusOut: { - if (!hasFocus) { - return; - } - final Control focusControl = getDisplay().getFocusControl(); - if (focusControl == arrow) { - return; - } - hasFocus = false; - final Shell shell = getShell(); - shell.removeListener(SWT.Deactivate, listener); - final Display display = getDisplay(); - display.removeFilter(SWT.FocusIn, filter); - final Event e = new Event(); - notifyListeners(SWT.FocusOut, e); - break; - } - } - } - - private boolean isPopupVisible() { - return !popup.isDisposed() && popup.getVisible(); - } - - private void handleMultiChoiceEvent(final Event event) { - switch (event.type) { - case SWT.Dispose: - if (popup != null && !popup.isDisposed()) { - popup.dispose(); - } - final Shell shell = getShell(); - shell.removeListener(SWT.Deactivate, listener); - final Display display = getDisplay(); - display.removeFilter(SWT.FocusIn, filter); - popup = null; - arrow = null; - break; - case SWT.Move: - hidePopupWindow(false); - break; - case SWT.Resize: - if (isPopupVisible()) { - hidePopupWindow(false); - } - break; - } - } - - /** - * Adds the listener to the collection of listeners who will be notified - * when the receiver's text is modified, by sending it one of the messages - * defined in the ModifyListener interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #removeModifyListener - */ - public void addModifyListener(final ModifyListener listener) { - checkWidget(); - composite.addModifyListener(listener); - } - - /** - * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - checkWidget(); - int width = 0, height = 0; - - final GC gc = new GC(label); - final int spacer = gc.stringExtent(" ").x; - final int textWidth = gc.stringExtent(label.getText()).x; - gc.dispose(); - final Point textSize = label.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); - final Point arrowSize = arrow.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); - final int borderWidth = getBorderWidth(); - - height = Math.max(textSize.y, arrowSize.y); - width = textWidth + 2 * spacer + arrowSize.x + 2 * borderWidth; - if (wHint != SWT.DEFAULT) { - width = wHint; - } - if (hHint != SWT.DEFAULT) { - height = hHint; - } - return new Point(width + 2 * borderWidth, height + 2 * borderWidth); - } - - /** - * @return the value of the combo - */ - public String getValue() { - checkWidget(); - return label.getText(); - } - - /** - * Removes the listener from the collection of listeners who will be - * notified when the receiver's text is modified. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #addModifyListener - */ - public void removeModifyListener(final ModifyListener listener) { - checkWidget(); - composite.removeModifyListener(listener); - } - - /** - * @see org.eclipse.swt.widgets.Control#setEnabled(boolean) - */ - @Override - public void setEnabled(final boolean enabled) { - checkWidget(); - arrow.setEnabled(enabled); - label.setEnabled(enabled); - super.setEnabled(enabled); - } - - /** - * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String) - */ - @Override - public void setToolTipText(final String txt) { - checkWidget(); - label.setToolTipText(txt); - } - - /** - * @param value new value - * @throws NumberFormatException if value is not a valid double - * value - */ - public void setValue(final String value) { - checkWidget(); - new Double(value); - label.setText(value); - } - -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.opal.calculator; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; + +/** + * The CalculatorCombo class represents a selectable user interface object that + * combines a text field and a calculator buttons panel and issues notification + * when an the value is modified. + *

+ * Note that although this class is a subclass of Composite, it + * does not make sense to add children to it, or set a layout on it. + *

+ *
+ *
Styles: + *
BORDER, FLAT
+ *
Events: + *
Modify
+ *
+ * + * @see CCombo + * snippets + */ +public class CalculatorCombo extends Composite { + + private Label label; + private Button arrow; + private Shell popup; + private Listener listener, filter; + private boolean hasFocus; + private Listener keyListener; + private CalculatorButtonsComposite composite; + + /** + * Constructs a new instance of this class given its parent. + * + * @param parent a widget which will be the parent of the new instance (cannot be null) + * @param style not used + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ */ + public CalculatorCombo(final Composite parent, final int style) { + super(parent, style); + + final GridLayout gridLayout = new GridLayout(2, false); + gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginWidth = gridLayout.marginHeight = 0; + setLayout(gridLayout); + + label = new Label(this, SWT.BORDER | SWT.RIGHT); + label.setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + label.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + + arrow = new Button(this, SWT.ARROW | SWT.DOWN); + arrow.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + + listener = event -> { + if (popup == event.widget) { + handlePopupEvent(event); + return; + } + + if (arrow == event.widget) { + handleButtonEvent(event); + return; + } + + if (CalculatorCombo.this == event.widget) { + handleMultiChoiceEvent(event); + return; + } + + if (getShell() == event.widget) { + getDisplay().asyncExec(() -> { + if (isDisposed()) { + return; + } + handleFocusEvent(SWT.FocusOut); + }); + } + }; + + final int[] calculatorComboEvents = { SWT.Dispose, SWT.Move, SWT.Resize }; + for (final int calculatorComboEvent : calculatorComboEvents) { + addListener(calculatorComboEvent, listener); + } + + final int[] buttonEvents = { SWT.Selection, SWT.FocusIn }; + for (final int buttonEvent : buttonEvents) { + arrow.addListener(buttonEvent, listener); + } + + filter = event -> { + final Shell shell = ((Control) event.widget).getShell(); + if (shell == CalculatorCombo.this.getShell()) { + handleFocusEvent(SWT.FocusOut); + } + }; + + createPopupShell(); + } + + /** + * Handle a popup event + * + * @param event event to handle + */ + private void handlePopupEvent(final Event event) { + switch (event.type) { + case SWT.Paint: + final Rectangle listRect = popup.getBounds(); + final Color black = getDisplay().getSystemColor(SWT.COLOR_BLACK); + event.gc.setForeground(black); + event.gc.drawRectangle(0, 0, listRect.width - 1, listRect.height - 1); + break; + case SWT.Close: + event.doit = false; + hidePopupWindow(false); + break; + case SWT.Deactivate: + hidePopupWindow(false); + break; + case SWT.Dispose: + if (keyListener != null) { + label.removeListener(SWT.KeyDown,keyListener); + } + break; + } + } + + private void hidePopupWindow(final boolean drop) { + _displayHidePopupWindow(false); + } + + private void _displayHidePopupWindow(final boolean show) { + if (show == isPopupVisible()) { + return; + } + + if (!show) { + popup.setVisible(false); + if (!isDisposed()) { + label.setFocus(); + } + return; + } + + if (getShell() != popup.getParent()) { + popup.dispose(); + popup = null; + createPopupShell(); + } + + final Point textRect = label.toDisplay(label.getLocation().x, label.getLocation().y); + final int x = textRect.x; + final int y = textRect.y + label.getSize().y; + + popup.setLocation(x, y); + popup.setVisible(true); + popup.setFocus(); + } + + private void createPopupShell() { + popup = new Shell(getShell(), SWT.NO_TRIM | SWT.ON_TOP); + popup.setLayout(new GridLayout()); + + final int[] popupEvents = { SWT.Close, SWT.Paint, SWT.Deactivate, SWT.Dispose }; + for (final int popupEvent : popupEvents) { + popup.addListener(popupEvent, listener); + } + + composite = new CalculatorButtonsComposite(popup, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + composite.setDisplayArea(label); + keyListener = composite.getKeyListener(); + label.addListener(SWT.KeyDown, keyListener); + + popup.pack(); + } + + private void handleButtonEvent(final Event event) { + switch (event.type) { + case SWT.FocusIn: { + handleFocusEvent(SWT.FocusIn); + break; + } + case SWT.Selection: { + _displayHidePopupWindow(!isPopupVisible()); + break; + } + } + } + + private void handleFocusEvent(final int eventType) { + if (isDisposed()) { + return; + } + switch (eventType) { + case SWT.FocusIn: { + if (hasFocus) { + return; + } + hasFocus = true; + final Shell shell = getShell(); + shell.removeListener(SWT.Deactivate, listener); + shell.addListener(SWT.Deactivate, listener); + final Display display = getDisplay(); + display.removeFilter(SWT.FocusIn, filter); + display.addFilter(SWT.FocusIn, filter); + final Event e = new Event(); + notifyListeners(SWT.FocusIn, e); + break; + } + case SWT.FocusOut: { + if (!hasFocus) { + return; + } + final Control focusControl = getDisplay().getFocusControl(); + if (focusControl == arrow) { + return; + } + hasFocus = false; + final Shell shell = getShell(); + shell.removeListener(SWT.Deactivate, listener); + final Display display = getDisplay(); + display.removeFilter(SWT.FocusIn, filter); + final Event e = new Event(); + notifyListeners(SWT.FocusOut, e); + break; + } + } + } + + private boolean isPopupVisible() { + return !popup.isDisposed() && popup.getVisible(); + } + + private void handleMultiChoiceEvent(final Event event) { + switch (event.type) { + case SWT.Dispose: + if (popup != null && !popup.isDisposed()) { + popup.dispose(); + } + final Shell shell = getShell(); + shell.removeListener(SWT.Deactivate, listener); + final Display display = getDisplay(); + display.removeFilter(SWT.FocusIn, filter); + popup = null; + arrow = null; + break; + case SWT.Move: + hidePopupWindow(false); + break; + case SWT.Resize: + if (isPopupVisible()) { + hidePopupWindow(false); + } + break; + } + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the receiver's text is modified, by sending it one of the messages + * defined in the ModifyListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #removeModifyListener + */ + public void addModifyListener(final ModifyListener listener) { + checkWidget(); + composite.addModifyListener(listener); + } + + /** + * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + checkWidget(); + int width = 0, height = 0; + + final GC gc = new GC(label); + final int spacer = gc.stringExtent(" ").x; + final int textWidth = gc.stringExtent(label.getText()).x; + gc.dispose(); + final Point textSize = label.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); + final Point arrowSize = arrow.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed); + final int borderWidth = getBorderWidth(); + + height = Math.max(textSize.y, arrowSize.y); + width = textWidth + 2 * spacer + arrowSize.x + 2 * borderWidth; + if (wHint != SWT.DEFAULT) { + width = wHint; + } + if (hHint != SWT.DEFAULT) { + height = hHint; + } + return new Point(width + 2 * borderWidth, height + 2 * borderWidth); + } + + /** + * @return the value of the combo + */ + public String getValue() { + checkWidget(); + return label.getText(); + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the receiver's text is modified. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #addModifyListener + */ + public void removeModifyListener(final ModifyListener listener) { + checkWidget(); + composite.removeModifyListener(listener); + } + + /** + * @see org.eclipse.swt.widgets.Control#setEnabled(boolean) + */ + @Override + public void setEnabled(final boolean enabled) { + checkWidget(); + arrow.setEnabled(enabled); + label.setEnabled(enabled); + super.setEnabled(enabled); + } + + /** + * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String) + */ + @Override + public void setToolTipText(final String txt) { + checkWidget(); + label.setToolTipText(txt); + } + + /** + * @param value new value + * @throws NumberFormatException if value is not a valid double + * value + */ + public void setValue(final String value) { + checkWidget(); + new Double(value); + label.setText(value); + } + +} diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorEngine.java b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorEngine.java index 1b9f83125..f98e3ba98 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorEngine.java +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/CalculatorEngine.java @@ -1,198 +1,198 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.calculator; - -import java.math.BigDecimal; - -import org.eclipse.nebula.widgets.opal.commons.ResourceManager; - -/** - * This is the calculator engine - */ -class CalculatorEngine { - - static final String OPERATOR_PLUS = "+"; - static final String OPERATOR_MINUS = "-"; - static final String OPERATOR_MULTIPLY = "*"; - static final String OPERATOR_DIVIDE = "/"; - - private String lastOperator; - private final CalculatorButtonsComposite composite; - private boolean error; - private Double lastNumber; - - /** - * Constructor - * - * @param calculator calculator widget associated to this engine - */ - CalculatorEngine(final CalculatorButtonsComposite composite) { - this.composite = composite; - } - - /** - * @param value value to display - */ - private void setContent(final Double value) { - composite.getDisplayArea().setText(doubleToString(value)); - composite.fireModifyListeners(); - } - - private String doubleToString(final Double d) { - if (d == null) { - return "0"; - } - // pre java 8, a value of 0 would yield "0.0" below - if (d.doubleValue() == 0) { - return "0"; - } - - if (Math.floor(d) == d) { - return Integer.toString(d.intValue()); - } - - return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString(); - } - - /** - * @return the displayed value as string - */ - private Double getContent() { - final String content = composite.getDisplayArea().getText(); - return Double.valueOf(content); - } - - /** - * Process equals operation - */ - void processEquals() { - if (error) { - return; - } - if (lastOperator == null) { - return; - } - - double result = 0; - final double content = getContent(); - - if (lastOperator.equals(OPERATOR_DIVIDE)) { - if (content == 0) { - displayErrorMessage(ResourceManager.CALCULATOR_DIVIDE_BY_ZERO); - return; - } - result = lastNumber / content; - } - - if (lastOperator.equals(OPERATOR_MULTIPLY)) { - result = lastNumber * content; - } - - if (lastOperator.equals(OPERATOR_MINUS)) { - result = lastNumber - content; - } - - if (lastOperator.equals(OPERATOR_PLUS)) { - result = lastNumber + content; - } - - setContent(result); - lastOperator = null; - lastNumber = result; - } - - /** - * @param errorMessage error message - */ - private void displayErrorMessage(final String errorMessage) { - composite.getDisplayArea().setText(ResourceManager.getLabel(errorMessage)); - lastOperator = null; - lastNumber = null; - error = true; - } - - /** - * Process 1/x operation - */ - void processInverseOperation() { - if (error) { - return; - } - processEquals(); - try { - final double result = 1d / getContent(); - setContent(result); - } catch (final Exception ex) { - displayErrorMessage(ResourceManager.CALCULATOR_DIVIDE_BY_ZERO); - } - } - - /** - * @param operator operation to process - */ - void processOperation(final String operator) { - if (error) { - return; - } - lastOperator = operator; - lastNumber = getContent(); - composite.setReadyToEnterNewNumber(true); - } - - /** - * Process percentage operation - */ - void processPerCentageOperation() { - if (error) { - return; - } - final double result = getContent(); - setContent(result / 100d); - } - - /** - * Process +/- operation - */ - void processSignChange() { - if (error) { - return; - } - final double result = getContent(); - setContent(result * -1d); - } - - /** - * Process square root operation - */ - void processSquareRootOperation() { - if (error) { - return; - } - processEquals(); - try { - final double result = Math.sqrt(getContent()); - setContent(result); - } catch (final Exception ex) { - displayErrorMessage(ResourceManager.CALCULATOR_INVALID_VALUE); - } - } - - public void cancel() { - lastOperator = null; - error = false; - composite.setReadyToEnterNewNumber(false); - lastNumber = null; - } - -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.calculator; + +import java.math.BigDecimal; + +import org.eclipse.nebula.widgets.opal.commons.ResourceManager; + +/** + * This is the calculator engine + */ +class CalculatorEngine { + + static final String OPERATOR_PLUS = "+"; + static final String OPERATOR_MINUS = "-"; + static final String OPERATOR_MULTIPLY = "*"; + static final String OPERATOR_DIVIDE = "/"; + + private String lastOperator; + private final CalculatorButtonsComposite composite; + private boolean error; + private Double lastNumber; + + /** + * Constructor + * + * @param calculator calculator widget associated to this engine + */ + CalculatorEngine(final CalculatorButtonsComposite composite) { + this.composite = composite; + } + + /** + * @param value value to display + */ + private void setContent(final Double value) { + composite.getDisplayArea().setText(doubleToString(value)); + composite.fireModifyListeners(); + } + + private String doubleToString(final Double d) { + if (d == null) { + return "0"; + } + // pre java 8, a value of 0 would yield "0.0" below + if (d.doubleValue() == 0) { + return "0"; + } + + if (Math.floor(d) == d) { + return Integer.toString(d.intValue()); + } + + return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString(); + } + + /** + * @return the displayed value as string + */ + private Double getContent() { + final String content = composite.getDisplayArea().getText(); + return Double.valueOf(content); + } + + /** + * Process equals operation + */ + void processEquals() { + if (error) { + return; + } + if (lastOperator == null) { + return; + } + + double result = 0; + final double content = getContent(); + + if (lastOperator.equals(OPERATOR_DIVIDE)) { + if (content == 0) { + displayErrorMessage(ResourceManager.CALCULATOR_DIVIDE_BY_ZERO); + return; + } + result = lastNumber / content; + } + + if (lastOperator.equals(OPERATOR_MULTIPLY)) { + result = lastNumber * content; + } + + if (lastOperator.equals(OPERATOR_MINUS)) { + result = lastNumber - content; + } + + if (lastOperator.equals(OPERATOR_PLUS)) { + result = lastNumber + content; + } + + setContent(result); + lastOperator = null; + lastNumber = result; + } + + /** + * @param errorMessage error message + */ + private void displayErrorMessage(final String errorMessage) { + composite.getDisplayArea().setText(ResourceManager.getLabel(errorMessage)); + lastOperator = null; + lastNumber = null; + error = true; + } + + /** + * Process 1/x operation + */ + void processInverseOperation() { + if (error) { + return; + } + processEquals(); + try { + final double result = 1d / getContent(); + setContent(result); + } catch (final Exception ex) { + displayErrorMessage(ResourceManager.CALCULATOR_DIVIDE_BY_ZERO); + } + } + + /** + * @param operator operation to process + */ + void processOperation(final String operator) { + if (error) { + return; + } + lastOperator = operator; + lastNumber = getContent(); + composite.setReadyToEnterNewNumber(true); + } + + /** + * Process percentage operation + */ + void processPerCentageOperation() { + if (error) { + return; + } + final double result = getContent(); + setContent(result / 100d); + } + + /** + * Process +/- operation + */ + void processSignChange() { + if (error) { + return; + } + final double result = getContent(); + setContent(result * -1d); + } + + /** + * Process square root operation + */ + void processSquareRootOperation() { + if (error) { + return; + } + processEquals(); + try { + final double result = Math.sqrt(getContent()); + setContent(result); + } catch (final Exception ex) { + displayErrorMessage(ResourceManager.CALCULATOR_INVALID_VALUE); + } + } + + public void cancel() { + lastOperator = null; + error = false; + composite.setReadyToEnterNewNumber(false); + lastNumber = null; + } + +} diff --git a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/DivideByZeroException.java b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/DivideByZeroException.java index 722d89a1c..4a2505df5 100644 --- a/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/DivideByZeroException.java +++ b/widgets/opal/calculator/org.eclipse.nebula.widgets.opal.calculator/src/org/eclipse/nebula/widgets/opal/calculator/DivideByZeroException.java @@ -1,34 +1,34 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.calculator; - -class DivideByZeroException extends Exception { - private static final long serialVersionUID = 1764265506499117961L; - - /** - * Constructor - */ - public DivideByZeroException() { - super(); - } - - /** - * Constructor - * - * @param errorMessage error message - */ - public DivideByZeroException(final String errorMessage) { - super(errorMessage); - } +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.calculator; + +class DivideByZeroException extends Exception { + private static final long serialVersionUID = 1764265506499117961L; + + /** + * Constructor + */ + public DivideByZeroException() { + super(); + } + + /** + * Constructor + * + * @param errorMessage error message + */ + public DivideByZeroException(final String errorMessage) { + super(errorMessage); + } } \ No newline at end of file diff --git a/widgets/opal/calculator/pom.xml b/widgets/opal/calculator/pom.xml index 0027d7ff2..ab31d6e74 100644 --- a/widgets/opal/calculator/pom.xml +++ b/widgets/opal/calculator/pom.xml @@ -1,22 +1,22 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - opal - - - calculator - pom - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.opal.calculator - org.eclipse.nebula.widgets.opal.calculator.feature - org.eclipse.nebula.widgets.opal.calculator.snippets - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + opal + + + calculator + pom + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.opal.calculator + org.eclipse.nebula.widgets.opal.calculator.feature + org.eclipse.nebula.widgets.opal.calculator.snippets + + + diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/.project b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/.project index 7d3aafb7e..de277084b 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/.project +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.checkboxgroup.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.checkboxgroup.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/build.properties b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/build.properties +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/feature.properties b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/feature.properties +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.classpath b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.classpath +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.project b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.project index e74d46508..b380cddc6 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.project +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.checkboxgroup.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.checkboxgroup.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/META-INF/MANIFEST.MF b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/META-INF/MANIFEST.MF index c6c3ba7ac..5e9f0ea77 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Checkbox Group Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.checkboxgroup.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.checkboxgroup;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.checkboxgroup.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Checkbox Group Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.checkboxgroup.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.checkboxgroup;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.checkboxgroup.snippets diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/build.properties b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/build.properties +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/src/org/eclipse/nebula/widgets/opal/checkboxgroup/snippets/SnippetCheckBoxGroup.java b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/src/org/eclipse/nebula/widgets/opal/checkboxgroup/snippets/SnippetCheckBoxGroup.java index 73709cd80..bd57781c2 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/src/org/eclipse/nebula/widgets/opal/checkboxgroup/snippets/SnippetCheckBoxGroup.java +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup.snippets/src/org/eclipse/nebula/widgets/opal/checkboxgroup/snippets/SnippetCheckBoxGroup.java @@ -1,92 +1,92 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.checkboxgroup.snippets; - -import org.eclipse.nebula.widgets.opal.checkboxgroup.CheckBoxGroup; -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * This snippet demonstrates the checkBoxGroup widget - * - */ -public class SnippetCheckBoxGroup { - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setBackgroundMode(SWT.INHERIT_DEFAULT); - final FillLayout layout1 = new FillLayout(SWT.VERTICAL); - layout1.marginWidth = layout1.marginHeight = 10; - shell.setLayout(layout1); - - // Displays the group - final CheckBoxGroup group = new CheckBoxGroup(shell, SWT.NONE); - group.setLayout(new GridLayout(4, false)); - group.setText("Use proxy server"); - - final Composite content = group.getContent(); - - final Label lblServer = new Label(content, SWT.NONE); - lblServer.setText("Server:"); - lblServer.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - final Text txtServer = new Text(content, SWT.NONE); - txtServer.setText("proxy.host.com"); - txtServer.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); - - final Label lblPort = new Label(content, SWT.NONE); - lblPort.setText("Port:"); - lblPort.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - final Text txtPort = new Text(content, SWT.NONE); - txtPort.setText("1234"); - txtPort.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); - - final Label lblUser = new Label(content, SWT.NONE); - lblUser.setText("User ID:"); - lblUser.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - final Text txtUser = new Text(content, SWT.NONE); - txtUser.setText("MyName"); - txtUser.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); - - final Label lblPassword = new Label(content, SWT.NONE); - lblPassword.setText("Password:"); - lblPassword.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - final Text txtPassword = new Text(content, SWT.PASSWORD); - txtPassword.setText("password"); - txtPassword.setEnabled(false); - txtPassword.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); - - // Open the shell - shell.setSize(640, 360); - SWTGraphicUtil.centerShell(shell); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.checkboxgroup.snippets; + +import org.eclipse.nebula.widgets.opal.checkboxgroup.CheckBoxGroup; +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * This snippet demonstrates the checkBoxGroup widget + * + */ +public class SnippetCheckBoxGroup { + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setBackgroundMode(SWT.INHERIT_DEFAULT); + final FillLayout layout1 = new FillLayout(SWT.VERTICAL); + layout1.marginWidth = layout1.marginHeight = 10; + shell.setLayout(layout1); + + // Displays the group + final CheckBoxGroup group = new CheckBoxGroup(shell, SWT.NONE); + group.setLayout(new GridLayout(4, false)); + group.setText("Use proxy server"); + + final Composite content = group.getContent(); + + final Label lblServer = new Label(content, SWT.NONE); + lblServer.setText("Server:"); + lblServer.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + + final Text txtServer = new Text(content, SWT.NONE); + txtServer.setText("proxy.host.com"); + txtServer.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); + + final Label lblPort = new Label(content, SWT.NONE); + lblPort.setText("Port:"); + lblPort.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + + final Text txtPort = new Text(content, SWT.NONE); + txtPort.setText("1234"); + txtPort.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); + + final Label lblUser = new Label(content, SWT.NONE); + lblUser.setText("User ID:"); + lblUser.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + + final Text txtUser = new Text(content, SWT.NONE); + txtUser.setText("MyName"); + txtUser.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); + + final Label lblPassword = new Label(content, SWT.NONE); + lblPassword.setText("Password:"); + lblPassword.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + + final Text txtPassword = new Text(content, SWT.PASSWORD); + txtPassword.setText("password"); + txtPassword.setEnabled(false); + txtPassword.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); + + // Open the shell + shell.setSize(640, 360); + SWTGraphicUtil.centerShell(shell); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } + +} diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.classpath b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.classpath +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.project b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.project index 503152947..b82733591 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.project +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.checkboxgroup - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.checkboxgroup + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/META-INF/MANIFEST.MF b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/META-INF/MANIFEST.MF index 2601bbd49..d8b820ccc 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/META-INF/MANIFEST.MF +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Checkbox Group -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.checkboxgroup -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.checkboxgroup -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.checkboxgroup +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Checkbox Group +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.checkboxgroup +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.checkboxgroup +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.checkboxgroup diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/build.properties b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/build.properties +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/src/org/eclipse/nebula/widgets/opal/checkboxgroup/CheckBoxGroup.java b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/src/org/eclipse/nebula/widgets/opal/checkboxgroup/CheckBoxGroup.java index f1a18f543..656b05bcb 100644 --- a/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/src/org/eclipse/nebula/widgets/opal/checkboxgroup/CheckBoxGroup.java +++ b/widgets/opal/checkboxgroup/org.eclipse.nebula.widgets.opal.checkboxgroup/src/org/eclipse/nebula/widgets/opal/checkboxgroup/CheckBoxGroup.java @@ -1,335 +1,335 @@ -/******************************************************************************* - * Copyright (c) 2011,2012 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API Marnix van Bochove (mgvanbochove at gmail dot com) - - * Enhancements and bug fixes - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.checkboxgroup; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Widget; - -/** - * Instances of this class provide an etched border with a title and a checkbox. - * If the checkbox is checked, the content of the composite is enabled. If the - * checkbox is unchecked, the content of the composite is disabled, thus not - * editable. - *

- *

- *
Styles:
- *
BORDER
- *
Events:
- *
(none)
- *
- */ -public class CheckBoxGroup extends Canvas implements PaintListener { - protected Button button; - private final Composite content; - - private boolean transparent = false; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a widget which will be the parent of the new instance (cannot - * be null) - * @param style the style of widget to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - * @see Composite#Composite(Composite, int) - * @see SWT#BORDER - * @see Widget#getStyle - */ - public CheckBoxGroup(final Composite parent, final int style) { - super(parent, style); - super.setLayout(new GridLayout()); - - createCheckBoxButton(); - - content = new Composite(this, style); - content.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - - addPaintListener(this); - } - - private void createCheckBoxButton() { - button = new Button(this, SWT.CHECK); - final GridData gdButton = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); - gdButton.horizontalIndent = 15; - button.setLayoutData(gdButton); - button.setSelection(true); - button.setBackground(getBackground()); - button.pack(); - - button.addListener(SWT.Selection, e -> { - e.doit = SelectionListenerUtil.fireSelectionListeners(this,e); - if (!e.doit) { - return; - } - if (button.getSelection()) { - activate(); - } else { - deactivate(); - } - }); - } - - /** - * Activate the content - */ - public void activate() { - button.setSelection(true); - SWTGraphicUtil.enableAllChildrenWidgets(content); - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the user changes the receiver's selection, by sending it one of the messages - * defined in the SelectionListener interface. - *

- * When widgetSelected is called, the item field of the event - * object is valid. If the receiver has the SWT.CHECK style and the - * check selection changes, the event object detail field contains the value - * SWT.CHECK. widgetDefaultSelected is typically - * called when an item is double-clicked. The item field of the event object is - * valid for default selection, but the detail field is not used. - *

- * - * @param listener the listener which should be notified when the user changes - * the receiver's selection - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.addSelectionListener(this, listener); - } - - /** - * Deactivate the content - */ - public void deactivate() { - button.setSelection(false); - SWTGraphicUtil.disableAllChildrenWidgets(content); - } - - /** - * @return true if the content is activated, false - * otherwise - */ - public boolean isActivated() { - return button.getSelection(); - } - - /** - * @see org.eclipse.swt.widgets.Composite#getLayout() - */ - @Override - public Layout getLayout() { - return content.getLayout(); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the user changes the receiver's selection. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.removeSelectionListener(this, listener); - } - - - - /** - * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) - */ - @Override - public void setBackground(final Color color) { - super.setBackground(color); - button.setBackground(color); - } - - /** - * @see org.eclipse.swt.widgets.Composite#setFocus() - */ - @Override - public boolean setFocus() { - return content.setFocus(); - } - - /** - * @see org.eclipse.swt.widgets.Composite#setLayout(org.eclipse.swt.widgets.Layout) - */ - @Override - public void setLayout(final Layout layout) { - content.setLayout(layout); - } - - // ------------------------------------ Getters and Setters - - /** - * @return the text of the button - */ - public String getText() { - return button.getText(); - } - - /** - * @param text the text of the button to set - */ - public void setText(final String text) { - button.setText(text); - } - - /** - * @return the font of the button - */ - @Override - public Font getFont() { - return button.getFont(); - } - - /** - * @param font the font to set - */ - @Override - public void setFont(final Font font) { - button.setFont(font); - } - - /** - * @return the content of the group - */ - public Composite getContent() { - return content; - } - - public boolean isTransparent() { - return transparent; - } - - public void setTransparent(final boolean transparent) { - this.transparent = transparent; - if (transparent) { - setBackgroundMode(SWT.INHERIT_DEFAULT); - content.setBackgroundMode(SWT.INHERIT_DEFAULT); - } - } - - @Override - public void paintControl(final PaintEvent paintEvent) { - if (paintEvent.widget == this) { - drawWidget(paintEvent.gc); - } - } - - /** - * Draws the widget - */ - private void drawWidget(final GC gc) { - final Rectangle rect = getClientArea(); - final int margin = (int) (button.getSize().y * 1.5); - final int startY = margin / 2; - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); - gc.drawRoundRectangle(1, startY, rect.width - 2, rect.height - startY - 2, 2, 2); - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); - gc.drawRoundRectangle(2, startY + 1, rect.width - 4, rect.height - startY - 4, 2, 2); - } - - /** - * Sets the selection state of the receiver - * - * @param selection the new selection state - */ - public void setSelection(boolean selection) { - if (selection) {// TODO - activate(); - } else { - deactivate(); - } - } - - /** - * Returns true if the receiver is selected, and false otherwise - * - * @return the selection state - */ - public boolean getSelection() { - return isActivated(); - } -} +/******************************************************************************* + * Copyright (c) 2011,2012 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API Marnix van Bochove (mgvanbochove at gmail dot com) - + * Enhancements and bug fixes + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.checkboxgroup; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Widget; + +/** + * Instances of this class provide an etched border with a title and a checkbox. + * If the checkbox is checked, the content of the composite is enabled. If the + * checkbox is unchecked, the content of the composite is disabled, thus not + * editable. + *

+ *

+ *
Styles:
+ *
BORDER
+ *
Events:
+ *
(none)
+ *
+ */ +public class CheckBoxGroup extends Canvas implements PaintListener { + protected Button button; + private final Composite content; + + private boolean transparent = false; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance (cannot + * be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see Composite#Composite(Composite, int) + * @see SWT#BORDER + * @see Widget#getStyle + */ + public CheckBoxGroup(final Composite parent, final int style) { + super(parent, style); + super.setLayout(new GridLayout()); + + createCheckBoxButton(); + + content = new Composite(this, style); + content.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + + addPaintListener(this); + } + + private void createCheckBoxButton() { + button = new Button(this, SWT.CHECK); + final GridData gdButton = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); + gdButton.horizontalIndent = 15; + button.setLayoutData(gdButton); + button.setSelection(true); + button.setBackground(getBackground()); + button.pack(); + + button.addListener(SWT.Selection, e -> { + e.doit = SelectionListenerUtil.fireSelectionListeners(this,e); + if (!e.doit) { + return; + } + if (button.getSelection()) { + activate(); + } else { + deactivate(); + } + }); + } + + /** + * Activate the content + */ + public void activate() { + button.setSelection(true); + SWTGraphicUtil.enableAllChildrenWidgets(content); + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the user changes the receiver's selection, by sending it one of the messages + * defined in the SelectionListener interface. + *

+ * When widgetSelected is called, the item field of the event + * object is valid. If the receiver has the SWT.CHECK style and the + * check selection changes, the event object detail field contains the value + * SWT.CHECK. widgetDefaultSelected is typically + * called when an item is double-clicked. The item field of the event object is + * valid for default selection, but the detail field is not used. + *

+ * + * @param listener the listener which should be notified when the user changes + * the receiver's selection + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.addSelectionListener(this, listener); + } + + /** + * Deactivate the content + */ + public void deactivate() { + button.setSelection(false); + SWTGraphicUtil.disableAllChildrenWidgets(content); + } + + /** + * @return true if the content is activated, false + * otherwise + */ + public boolean isActivated() { + return button.getSelection(); + } + + /** + * @see org.eclipse.swt.widgets.Composite#getLayout() + */ + @Override + public Layout getLayout() { + return content.getLayout(); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the user changes the receiver's selection. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.removeSelectionListener(this, listener); + } + + + + /** + * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) + */ + @Override + public void setBackground(final Color color) { + super.setBackground(color); + button.setBackground(color); + } + + /** + * @see org.eclipse.swt.widgets.Composite#setFocus() + */ + @Override + public boolean setFocus() { + return content.setFocus(); + } + + /** + * @see org.eclipse.swt.widgets.Composite#setLayout(org.eclipse.swt.widgets.Layout) + */ + @Override + public void setLayout(final Layout layout) { + content.setLayout(layout); + } + + // ------------------------------------ Getters and Setters + + /** + * @return the text of the button + */ + public String getText() { + return button.getText(); + } + + /** + * @param text the text of the button to set + */ + public void setText(final String text) { + button.setText(text); + } + + /** + * @return the font of the button + */ + @Override + public Font getFont() { + return button.getFont(); + } + + /** + * @param font the font to set + */ + @Override + public void setFont(final Font font) { + button.setFont(font); + } + + /** + * @return the content of the group + */ + public Composite getContent() { + return content; + } + + public boolean isTransparent() { + return transparent; + } + + public void setTransparent(final boolean transparent) { + this.transparent = transparent; + if (transparent) { + setBackgroundMode(SWT.INHERIT_DEFAULT); + content.setBackgroundMode(SWT.INHERIT_DEFAULT); + } + } + + @Override + public void paintControl(final PaintEvent paintEvent) { + if (paintEvent.widget == this) { + drawWidget(paintEvent.gc); + } + } + + /** + * Draws the widget + */ + private void drawWidget(final GC gc) { + final Rectangle rect = getClientArea(); + final int margin = (int) (button.getSize().y * 1.5); + final int startY = margin / 2; + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); + gc.drawRoundRectangle(1, startY, rect.width - 2, rect.height - startY - 2, 2, 2); + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); + gc.drawRoundRectangle(2, startY + 1, rect.width - 4, rect.height - startY - 4, 2, 2); + } + + /** + * Sets the selection state of the receiver + * + * @param selection the new selection state + */ + public void setSelection(boolean selection) { + if (selection) {// TODO + activate(); + } else { + deactivate(); + } + } + + /** + * Returns true if the receiver is selected, and false otherwise + * + * @return the selection state + */ + public boolean getSelection() { + return isActivated(); + } +} diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/.project b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/.project index 79f262791..12bff36ac 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/.project +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.columnbrowser.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.columnbrowser.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/build.properties b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/build.properties +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/feature.properties b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/feature.properties +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.classpath b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.classpath +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.project b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.project index e74c8ff5a..ed61630a9 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.project +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.columnbrowser.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.columnbrowser.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/META-INF/MANIFEST.MF b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/META-INF/MANIFEST.MF index 88b718e2e..a90e96496 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Column Browser Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.columnbrowser.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.columnbrowser;bundle-version="1.0.0", - org.eclipse.nebula.widgets.opal.dialog;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.columnbrowser.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Column Browser Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.columnbrowser.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.columnbrowser;bundle-version="1.0.0", + org.eclipse.nebula.widgets.opal.dialog;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.columnbrowser.snippets diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/build.properties b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/build.properties +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/src/org/eclipse/nebula/opal/columnbrowser/snippets/ColumnsSnippet.java b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/src/org/eclipse/nebula/opal/columnbrowser/snippets/ColumnsSnippet.java index 9512b5267..185a73c18 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/src/org/eclipse/nebula/opal/columnbrowser/snippets/ColumnsSnippet.java +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser.snippets/src/org/eclipse/nebula/opal/columnbrowser/snippets/ColumnsSnippet.java @@ -1,168 +1,168 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.opal.columnbrowser.snippets; - -import org.eclipse.nebula.widgets.opal.columnbrowser.ColumnBrowserWidget; -import org.eclipse.nebula.widgets.opal.columnbrowser.ColumnItem; -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.dialog.Dialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * This snippet demonstrates the ColumnBrowser widget - */ -public class ColumnsSnippet { - - /** - * @param args - */ - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(2, false)); - - final ColumnBrowserWidget cbw = new ColumnBrowserWidget(shell, SWT.NONE); - cbw.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1)); - - final ColumnItem item = createColors(cbw); - createSports(cbw); - - createShowSelectionButton(shell, cbw); - createForceSelection(shell, cbw, item); - - shell.setSize(640, 350); - shell.pack(); - shell.open(); - SWTGraphicUtil.centerShell(shell); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } - - private static ColumnItem createColors(final ColumnBrowserWidget cbw) { - final ColumnItem root = new ColumnItem(cbw); - root.setText("Colors"); - - final ColumnItem b = new ColumnItem(root); - b.setText("b"); - - final ColumnItem bl = new ColumnItem(b); - bl.setText("l"); - - final ColumnItem blu = new ColumnItem(bl); - blu.setText("u"); - - final ColumnItem blue = new ColumnItem(blu); - blue.setText("e"); - - final ColumnItem r = new ColumnItem(root); - r.setText("r"); - - final ColumnItem re = new ColumnItem(r); - re.setText("e"); - - final ColumnItem red = new ColumnItem(re); - red.setText("d"); - - final ColumnItem ro = new ColumnItem(r); - ro.setText("o"); - - final ColumnItem ros = new ColumnItem(ro); - ros.setText("s"); - - final ColumnItem rose = new ColumnItem(ros); - rose.setText("e"); - - final ColumnItem g = new ColumnItem(root); - g.setText("g"); - - final ColumnItem gr = new ColumnItem(g); - gr.setText("r"); - - final ColumnItem gre = new ColumnItem(gr); - gre.setText("e"); - - final ColumnItem gree = new ColumnItem(gre); - gree.setText("e"); - - final ColumnItem green = new ColumnItem(gree); - green.setText("n"); - - return green; - - } - - private static void createSports(final ColumnBrowserWidget cbw) { - final ColumnItem root = new ColumnItem(cbw); - root.setText("Sports"); - - final ColumnItem football = new ColumnItem(root); - football.setText("Football"); - - final ColumnItem rugby = new ColumnItem(root); - rugby.setText("Rugby"); - - final ColumnItem handball = new ColumnItem(root); - handball.setText("Hand Ball"); - - } - - private static void createShowSelectionButton(final Shell shell, final ColumnBrowserWidget cbw) { - final Button button = new Button(shell, SWT.PUSH); - button.setLayoutData(new GridData(GridData.END, GridData.FILL, true, false)); - button.setText("Show selection"); - - button.addSelectionListener(new SelectionAdapter() { - - /** - * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetSelected(final SelectionEvent e) { - Dialog.inform("Selection", - "You have selected " + (cbw.getSelection() == null ? "nothing" : cbw.getSelection().getText())); - } - }); - - } - - private static void createForceSelection(final Shell shell, final ColumnBrowserWidget cbw, final ColumnItem item) { - final Button button = new Button(shell, SWT.PUSH); - button.setLayoutData(new GridData(GridData.END, GridData.FILL, false, false)); - button.setText("Force selection"); - - button.addSelectionListener(new SelectionAdapter() { - - /** - * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetSelected(final SelectionEvent e) { - cbw.select(item); - } - }); - - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.opal.columnbrowser.snippets; + +import org.eclipse.nebula.widgets.opal.columnbrowser.ColumnBrowserWidget; +import org.eclipse.nebula.widgets.opal.columnbrowser.ColumnItem; +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.dialog.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * This snippet demonstrates the ColumnBrowser widget + */ +public class ColumnsSnippet { + + /** + * @param args + */ + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(2, false)); + + final ColumnBrowserWidget cbw = new ColumnBrowserWidget(shell, SWT.NONE); + cbw.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1)); + + final ColumnItem item = createColors(cbw); + createSports(cbw); + + createShowSelectionButton(shell, cbw); + createForceSelection(shell, cbw, item); + + shell.setSize(640, 350); + shell.pack(); + shell.open(); + SWTGraphicUtil.centerShell(shell); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } + + private static ColumnItem createColors(final ColumnBrowserWidget cbw) { + final ColumnItem root = new ColumnItem(cbw); + root.setText("Colors"); + + final ColumnItem b = new ColumnItem(root); + b.setText("b"); + + final ColumnItem bl = new ColumnItem(b); + bl.setText("l"); + + final ColumnItem blu = new ColumnItem(bl); + blu.setText("u"); + + final ColumnItem blue = new ColumnItem(blu); + blue.setText("e"); + + final ColumnItem r = new ColumnItem(root); + r.setText("r"); + + final ColumnItem re = new ColumnItem(r); + re.setText("e"); + + final ColumnItem red = new ColumnItem(re); + red.setText("d"); + + final ColumnItem ro = new ColumnItem(r); + ro.setText("o"); + + final ColumnItem ros = new ColumnItem(ro); + ros.setText("s"); + + final ColumnItem rose = new ColumnItem(ros); + rose.setText("e"); + + final ColumnItem g = new ColumnItem(root); + g.setText("g"); + + final ColumnItem gr = new ColumnItem(g); + gr.setText("r"); + + final ColumnItem gre = new ColumnItem(gr); + gre.setText("e"); + + final ColumnItem gree = new ColumnItem(gre); + gree.setText("e"); + + final ColumnItem green = new ColumnItem(gree); + green.setText("n"); + + return green; + + } + + private static void createSports(final ColumnBrowserWidget cbw) { + final ColumnItem root = new ColumnItem(cbw); + root.setText("Sports"); + + final ColumnItem football = new ColumnItem(root); + football.setText("Football"); + + final ColumnItem rugby = new ColumnItem(root); + rugby.setText("Rugby"); + + final ColumnItem handball = new ColumnItem(root); + handball.setText("Hand Ball"); + + } + + private static void createShowSelectionButton(final Shell shell, final ColumnBrowserWidget cbw) { + final Button button = new Button(shell, SWT.PUSH); + button.setLayoutData(new GridData(GridData.END, GridData.FILL, true, false)); + button.setText("Show selection"); + + button.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + Dialog.inform("Selection", + "You have selected " + (cbw.getSelection() == null ? "nothing" : cbw.getSelection().getText())); + } + }); + + } + + private static void createForceSelection(final Shell shell, final ColumnBrowserWidget cbw, final ColumnItem item) { + final Button button = new Button(shell, SWT.PUSH); + button.setLayoutData(new GridData(GridData.END, GridData.FILL, false, false)); + button.setText("Force selection"); + + button.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + cbw.select(item); + } + }); + + } + +} diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.classpath b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.classpath +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.project b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.project index d228e04d4..5153b21f2 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.project +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.columnbrowser - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.columnbrowser + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/META-INF/MANIFEST.MF b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/META-INF/MANIFEST.MF index 8278d1f08..0c0dd6762 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/META-INF/MANIFEST.MF +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Column Browser -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.columnbrowser -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.columnbrowser -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.columnbrowser +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Column Browser +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.columnbrowser +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.columnbrowser +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.columnbrowser diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/build.properties b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/build.properties +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/src/org/eclipse/nebula/widgets/opal/columnbrowser/ColumnBrowserWidget.java b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/src/org/eclipse/nebula/widgets/opal/columnbrowser/ColumnBrowserWidget.java index d0c45c676..1520ac907 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/src/org/eclipse/nebula/widgets/opal/columnbrowser/ColumnBrowserWidget.java +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/src/org/eclipse/nebula/widgets/opal/columnbrowser/ColumnBrowserWidget.java @@ -1,744 +1,744 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.columnbrowser; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.RowData; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; -import org.eclipse.swt.widgets.Widget; - -/** - * Instances of this class provide a data browser similar to the ones used in - * Mac OS X. Look at http://en.wikipedia.org/wiki/Miller_Columns - *

- *

- *
Styles:
- *
BORDER
- *
Events:
- *
Selection
- *
- */ -public class ColumnBrowserWidget extends ScrolledComposite { - - private final List columns; - private final Composite composite; - private final Image columnArrow; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a widget which will be the parent of the new instance (cannot - * be null) - * @param style the style of widget to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - * @see Composite#Composite(Composite, int) - * @see SWT#BORDER - * @see Widget#getStyle - */ - public ColumnBrowserWidget(final Composite parent, final int style) { - super(parent, style | SWT.H_SCROLL | SWT.V_SCROLL); - - composite = new Composite(this, SWT.NONE); - final RowLayout layout = new RowLayout(SWT.HORIZONTAL); - layout.spacing = 1; - layout.pack = false; - composite.setLayout(layout); - - columnArrow = SWTGraphicUtil.createImageFromFile("images/columnArrow.png"); - - columns = new ArrayList
(); - for (int i = 0; i < 3; i++) { - createTable(); - } - - // Store root - columns.get(0).setData(new ColumnItem(this)); - - setContent(composite); - setExpandHorizontal(true); - setExpandVertical(true); - setShowFocusedControl(true); - updateContent(); - this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - - addDisposeListener(e -> { - SWTGraphicUtil.safeDispose(columnArrow); - }); - - } - - /** - * Create a column that displays data - */ - private void createTable() { - final Table table = new Table(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); - new TableColumn(table, SWT.LEFT); - - table.setLayoutData(new RowData(150, 175)); - columns.add(table); - - addTableListeners(table); - - if (super.getBackground() != null && super.getBackground().getRed() != 240 && super.getBackground().getGreen() != 240 && super.getBackground().getBlue() != 240) { - table.setBackground(super.getBackground()); - } - table.setBackgroundImage(super.getBackgroundImage()); - table.setBackgroundMode(super.getBackgroundMode()); - table.setCursor(super.getCursor()); - table.setFont(super.getFont()); - table.setForeground(super.getForeground()); - table.setMenu(super.getMenu()); - table.setToolTipText(super.getToolTipText()); - - } - - private void addTableListeners(final Table table) { - table.addListener(SWT.Resize, event -> { - final int width = table.getSize().x; - table.getColumn(0).setWidth(width - 5); - }); - - table.addListener(SWT.Selection, event -> { - final Table tbl = (Table) event.widget; - if (tbl.getSelection() == null || tbl.getSelection().length != 1) { - return; - } - selectItem(tbl.getSelection()[0]); - }); - - final Listener paintListener = new Listener() { - @Override - public void handleEvent(final Event event) { - switch (event.type) { - case SWT.MeasureItem: { - final Rectangle rect = columnArrow.getBounds(); - event.width += rect.width; - event.height = Math.max(event.height, rect.height + 2); - break; - } - - case SWT.PaintItem: { - if (!(event.item instanceof TableItem)) { - return; - } - final TableItem item = (TableItem) event.item; - if (item.getData() == null) { - return; - } - - if (((ColumnItem) item.getData()).getItemCount() == 0) { - return; - } - - final int x = event.x + event.width; - final Rectangle rect = columnArrow.getBounds(); - final int offset = Math.max(0, (event.height - rect.height) / 2); - event.gc.drawImage(columnArrow, x, event.y + offset); - break; - } - } - } - }; - table.addListener(SWT.MeasureItem, paintListener); - table.addListener(SWT.PaintItem, paintListener); - - table.addListener(SWT.Selection, e -> { - SelectionListenerUtil.fireSelectionListeners(this,e); - }); - } - - - - /** - * Perform actions when an item is selected (ie fill the next column and force - * focus on it) - * - * @param tableItem selected item - */ - private void selectItem(final TableItem tableItem) { - final ColumnItem c = (ColumnItem) tableItem.getData(); - - if (c.getItemCount() == 0) { - return; - } - - final int selectedColumn = findSelectedColumn(tableItem); - boolean needPacking = false; - if (selectedColumn != columns.size() - 1) { - for (int i = selectedColumn + 1; i < columns.size(); i++) { - columns.get(i).setData(null); - columns.get(i).deselectAll(); - } - - int i = 0; - final Iterator
it = columns.iterator(); - while (it.hasNext()) { - final Table t = it.next(); - if (i > selectedColumn) { - t.dispose(); - it.remove(); - this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - } - i++; - } - - if (selectedColumn != columns.size() - 1) { - columns.get(selectedColumn + 1).setData(c); - } else { - createTable(); - columns.get(columns.size() - 1).setData(c); - } - needPacking = true; - - } else { - createTable(); - needPacking = true; - columns.get(columns.size() - 1).setData(c); - } - updateContent(); - if (needPacking) { - composite.pack(); - this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - } - columns.get(columns.size() - 1).forceFocus(); - } - - /** - * Find which column has been selected - * - * @param tableItem selected table item - * @return the index of the selected column - */ - private int findSelectedColumn(final TableItem tableItem) { - for (int i = 0; i < columns.size(); i++) { - if (columns.get(i).equals(tableItem.getParent())) { - return i; - } - } - return -1; - } - - /** - * Update the content of the widget - */ - void updateContent() { - if (columns == null) { - return; - } - - for (int i = 0; i < columns.size(); i++) { - - final Table table = columns.get(i); - final int index = table.getSelectionIndex(); - table.removeAll(); - if (table.getData() == null) { - continue; - } - for (final ColumnItem c : ((ColumnItem) table.getData()).getItems()) { - final TableItem item = new TableItem(table, SWT.NONE); - item.setData(c); - if (c.getText() != null) { - item.setText(c.getText()); - } - if (c.getImage() != null) { - item.setImage(c.getImage()); - } - } - table.setSelection(index); - } - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the user changes the receiver's selection, by sending it one of the messages - * defined in the SelectionListener interface. - * - * @param listener the listener which should be notified when the user changes - * the receiver's selection - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.addSelectionListener(this, listener); - } - - /** - * Clear the selection - * - * @param needPacking if true, the widget is packed - */ - public void clear(final boolean needPacking) { - final Iterator
it = columns.iterator(); - int i = 0; - while (it.hasNext()) { - final Table t = it.next(); - if (i >= 3) { - t.dispose(); - it.remove(); - } else { - if (i != 0) { - t.setData(null); - } - t.deselectAll(); - } - i++; - } - updateContent(); - if (needPacking) { - composite.pack(); - this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - } - columns.get(0).forceFocus(); - } - - /** - * Returns the ColumnItems that is currently selected in the - * receiver. - * - * @return the selected item, or null if no one is selected - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public ColumnItem getSelection() { - for (int i = columns.size() - 1; i >= 0; i--) { - final Table table = columns.get(i); - if (table == null || table.getData() == null || table.getSelection().length == 0) { - continue; - } - return (ColumnItem) table.getItem(table.getSelectionIndex()).getData(); - } - return null; - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the user changes the receiver's selection. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.removeSelectionListener(this, listener); - } - - /** - * Selects an item in the receiver. If the item was already selected, it remains - * selected. - * - * @param item the item to be selected - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed - *
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void select(final ColumnItem item) { - - final List items = new ArrayList(); - findElement(item, items); - Collections.reverse(items); - if (items.isEmpty()) { - return; - } - - clear(false); - for (int i = 3; i < items.size(); i++) { - createTable(); - } - for (int i = 0; i < items.size() - 1; i++) { - columns.get(i + 1).setData(items.get(i)); - } - updateContent(); - - for (int i = 0; i < columns.size() - 1; i++) { - final ColumnItem nextItem = (ColumnItem) columns.get(i + 1).getData(); - for (final TableItem tableItem : columns.get(i).getItems()) { - if (tableItem.getData() != null && tableItem.getData().equals(nextItem)) { - tableItem.getParent().setSelection(tableItem); - } - } - } - - composite.pack(); - this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - columns.get(columns.size() - 1).forceFocus(); - } - - /** - * Build an array that contains the hierarchy of ColumnItem from the root node - * to a given item. - * - * @param item item to find - * @param items the lists of item that composes the hierarchy - */ - private void findElement(final ColumnItem item, final List items) { - if (item == null) { - return; - } - items.add(item); - findElement(item.getParentItem(), items); - } - - /** - * Sets the receiver's background color to the color specified by the argument, - * or to the default system color for the control if the argument is null. - *

- * Note: This operation is a hint and may be overridden by the platform. For - * example, on Windows the background of a Button cannot be changed. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) - */ - @Override - public void setBackground(final Color color) { - super.setBackground(color); - for (final Table column : columns) { - column.setBackground(color); - } - } - - /** - * Sets the background drawing mode to the argument which should be one of the - * following constants defined in class SWT: - * INHERIT_NONE, INHERIT_DEFAULT, - * INHERIT_FORCE. - * - * @param mode the new background mode - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SWT - * @see org.eclipse.swt.widgets.Composite#setBackgroundMode(int) - */ - @Override - public void setBackgroundMode(final int mode) { - super.setBackgroundMode(mode); - for (final Table column : columns) { - column.setBackgroundMode(mode); - } - } - - /** - * Sets the receiver's background image to the image specified by the argument, - * or to the default system color for the control if the argument is null. The - * background image is tiled to fill the available space. - *

- * Note: This operation is a hint and may be overridden by the platform. For - * example, on Windows the background of a Button cannot be changed. - *

- * - * @param image the new image (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_INVALID_ARGUMENT - if the argument is not a - * bitmap
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see org.eclipse.swt.widgets.Control#setBackgroundImage(org.eclipse.swt.graphics.Image) - */ - @Override - public void setBackgroundImage(final Image image) { - super.setBackgroundImage(image); - for (final Table column : columns) { - column.setBackgroundImage(image); - } - } - - /** - * Sets the receiver's cursor to the cursor specified by the argument, or to the - * default cursor for that kind of control if the argument is null. - *

- * When the mouse pointer passes over a control its appearance is changed to - * match the control's cursor. - *

- * - * @param cursor the new cursor (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * @see org.eclipse.swt.widgets.Control#setCursor(org.eclipse.swt.graphics.Cursor) - */ - @Override - public void setCursor(final Cursor cursor) { - super.setCursor(cursor); - for (final Table column : columns) { - column.setCursor(cursor); - } - } - - /** - * Sets the font that the receiver will use to paint textual information to the - * font specified by the argument, or to the default font for that kind of - * control if the argument is null. - * - * @param font the new font (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font) - */ - @Override - public void setFont(final Font font) { - super.setFont(font); - for (final Table column : columns) { - column.setFont(font); - } - } - - /** - * Sets the receiver's foreground color to the color specified by the argument, - * or to the default system color for the control if the argument is null. - *

- * Note: This operation is a hint and may be overridden by the platform. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color) - */ - @Override - public void setForeground(final Color color) { - super.setForeground(color); - for (final Table column : columns) { - column.setForeground(color); - } - } - - /** - * Sets the receiver's pop up menu to the argument. All controls may optionally - * have a pop up menu that is displayed when the user requests one for the - * control. The sequence of key strokes, button presses and/or button releases - * that are used to request a pop up menu is platform specific. - *

- * Note: Disposing of a control that has a pop up menu will dispose of the menu. - * To avoid this behavior, set the menu to null before the control is disposed. - *

- * - * @param menu the new pop up menu - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu
  • - *
  • ERROR_INVALID_PARENT - if the menu is not in the same - * widget tree
  • - *
  • ERROR_INVALID_ARGUMENT - if the menu has been disposed - *
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu) - */ - @Override - public void setMenu(final Menu menu) { - super.setMenu(menu); - for (final Table column : columns) { - column.setMenu(menu); - } - } - - /** - * Sets the receiver's tool tip text to the argument, which may be null - * indicating that the default tool tip for the control will be shown. For a - * control that has a default tool tip, such as the Tree control on Windows, - * setting the tool tip text to an empty string replaces the default, causing no - * tool tip text to be shown. - *

- * The mnemonic indicator (character '&') is not displayed in a tool tip. To - * display a single '&' in the tool tip, the character '&' can be - * escaped by doubling it in the string. - *

- * - * @param string the new tool tip text (or null) - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String) - */ - @Override - public void setToolTipText(final String tooltipText) { - super.setToolTipText(tooltipText); - for (final Table column : columns) { - column.setToolTipText(tooltipText); - } - } - - /** - * @return the root item, or null if there is no data - */ - ColumnItem getRootItem() { - if (columns == null || columns.isEmpty()) { - return null; - } - return (ColumnItem) columns.get(0).getData(); - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.columnbrowser; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Widget; + +/** + * Instances of this class provide a data browser similar to the ones used in + * Mac OS X. Look at http://en.wikipedia.org/wiki/Miller_Columns + *

+ *

+ *
Styles:
+ *
BORDER
+ *
Events:
+ *
Selection
+ *
+ */ +public class ColumnBrowserWidget extends ScrolledComposite { + + private final List
columns; + private final Composite composite; + private final Image columnArrow; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance (cannot + * be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see Composite#Composite(Composite, int) + * @see SWT#BORDER + * @see Widget#getStyle + */ + public ColumnBrowserWidget(final Composite parent, final int style) { + super(parent, style | SWT.H_SCROLL | SWT.V_SCROLL); + + composite = new Composite(this, SWT.NONE); + final RowLayout layout = new RowLayout(SWT.HORIZONTAL); + layout.spacing = 1; + layout.pack = false; + composite.setLayout(layout); + + columnArrow = SWTGraphicUtil.createImageFromFile("images/columnArrow.png"); + + columns = new ArrayList
(); + for (int i = 0; i < 3; i++) { + createTable(); + } + + // Store root + columns.get(0).setData(new ColumnItem(this)); + + setContent(composite); + setExpandHorizontal(true); + setExpandVertical(true); + setShowFocusedControl(true); + updateContent(); + this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + + addDisposeListener(e -> { + SWTGraphicUtil.safeDispose(columnArrow); + }); + + } + + /** + * Create a column that displays data + */ + private void createTable() { + final Table table = new Table(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); + new TableColumn(table, SWT.LEFT); + + table.setLayoutData(new RowData(150, 175)); + columns.add(table); + + addTableListeners(table); + + if (super.getBackground() != null && super.getBackground().getRed() != 240 && super.getBackground().getGreen() != 240 && super.getBackground().getBlue() != 240) { + table.setBackground(super.getBackground()); + } + table.setBackgroundImage(super.getBackgroundImage()); + table.setBackgroundMode(super.getBackgroundMode()); + table.setCursor(super.getCursor()); + table.setFont(super.getFont()); + table.setForeground(super.getForeground()); + table.setMenu(super.getMenu()); + table.setToolTipText(super.getToolTipText()); + + } + + private void addTableListeners(final Table table) { + table.addListener(SWT.Resize, event -> { + final int width = table.getSize().x; + table.getColumn(0).setWidth(width - 5); + }); + + table.addListener(SWT.Selection, event -> { + final Table tbl = (Table) event.widget; + if (tbl.getSelection() == null || tbl.getSelection().length != 1) { + return; + } + selectItem(tbl.getSelection()[0]); + }); + + final Listener paintListener = new Listener() { + @Override + public void handleEvent(final Event event) { + switch (event.type) { + case SWT.MeasureItem: { + final Rectangle rect = columnArrow.getBounds(); + event.width += rect.width; + event.height = Math.max(event.height, rect.height + 2); + break; + } + + case SWT.PaintItem: { + if (!(event.item instanceof TableItem)) { + return; + } + final TableItem item = (TableItem) event.item; + if (item.getData() == null) { + return; + } + + if (((ColumnItem) item.getData()).getItemCount() == 0) { + return; + } + + final int x = event.x + event.width; + final Rectangle rect = columnArrow.getBounds(); + final int offset = Math.max(0, (event.height - rect.height) / 2); + event.gc.drawImage(columnArrow, x, event.y + offset); + break; + } + } + } + }; + table.addListener(SWT.MeasureItem, paintListener); + table.addListener(SWT.PaintItem, paintListener); + + table.addListener(SWT.Selection, e -> { + SelectionListenerUtil.fireSelectionListeners(this,e); + }); + } + + + + /** + * Perform actions when an item is selected (ie fill the next column and force + * focus on it) + * + * @param tableItem selected item + */ + private void selectItem(final TableItem tableItem) { + final ColumnItem c = (ColumnItem) tableItem.getData(); + + if (c.getItemCount() == 0) { + return; + } + + final int selectedColumn = findSelectedColumn(tableItem); + boolean needPacking = false; + if (selectedColumn != columns.size() - 1) { + for (int i = selectedColumn + 1; i < columns.size(); i++) { + columns.get(i).setData(null); + columns.get(i).deselectAll(); + } + + int i = 0; + final Iterator
it = columns.iterator(); + while (it.hasNext()) { + final Table t = it.next(); + if (i > selectedColumn) { + t.dispose(); + it.remove(); + this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + i++; + } + + if (selectedColumn != columns.size() - 1) { + columns.get(selectedColumn + 1).setData(c); + } else { + createTable(); + columns.get(columns.size() - 1).setData(c); + } + needPacking = true; + + } else { + createTable(); + needPacking = true; + columns.get(columns.size() - 1).setData(c); + } + updateContent(); + if (needPacking) { + composite.pack(); + this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + columns.get(columns.size() - 1).forceFocus(); + } + + /** + * Find which column has been selected + * + * @param tableItem selected table item + * @return the index of the selected column + */ + private int findSelectedColumn(final TableItem tableItem) { + for (int i = 0; i < columns.size(); i++) { + if (columns.get(i).equals(tableItem.getParent())) { + return i; + } + } + return -1; + } + + /** + * Update the content of the widget + */ + void updateContent() { + if (columns == null) { + return; + } + + for (int i = 0; i < columns.size(); i++) { + + final Table table = columns.get(i); + final int index = table.getSelectionIndex(); + table.removeAll(); + if (table.getData() == null) { + continue; + } + for (final ColumnItem c : ((ColumnItem) table.getData()).getItems()) { + final TableItem item = new TableItem(table, SWT.NONE); + item.setData(c); + if (c.getText() != null) { + item.setText(c.getText()); + } + if (c.getImage() != null) { + item.setImage(c.getImage()); + } + } + table.setSelection(index); + } + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the user changes the receiver's selection, by sending it one of the messages + * defined in the SelectionListener interface. + * + * @param listener the listener which should be notified when the user changes + * the receiver's selection + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.addSelectionListener(this, listener); + } + + /** + * Clear the selection + * + * @param needPacking if true, the widget is packed + */ + public void clear(final boolean needPacking) { + final Iterator
it = columns.iterator(); + int i = 0; + while (it.hasNext()) { + final Table t = it.next(); + if (i >= 3) { + t.dispose(); + it.remove(); + } else { + if (i != 0) { + t.setData(null); + } + t.deselectAll(); + } + i++; + } + updateContent(); + if (needPacking) { + composite.pack(); + this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + columns.get(0).forceFocus(); + } + + /** + * Returns the ColumnItems that is currently selected in the + * receiver. + * + * @return the selected item, or null if no one is selected + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public ColumnItem getSelection() { + for (int i = columns.size() - 1; i >= 0; i--) { + final Table table = columns.get(i); + if (table == null || table.getData() == null || table.getSelection().length == 0) { + continue; + } + return (ColumnItem) table.getItem(table.getSelectionIndex()).getData(); + } + return null; + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the user changes the receiver's selection. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.removeSelectionListener(this, listener); + } + + /** + * Selects an item in the receiver. If the item was already selected, it remains + * selected. + * + * @param item the item to be selected + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the item has been disposed + *
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void select(final ColumnItem item) { + + final List items = new ArrayList(); + findElement(item, items); + Collections.reverse(items); + if (items.isEmpty()) { + return; + } + + clear(false); + for (int i = 3; i < items.size(); i++) { + createTable(); + } + for (int i = 0; i < items.size() - 1; i++) { + columns.get(i + 1).setData(items.get(i)); + } + updateContent(); + + for (int i = 0; i < columns.size() - 1; i++) { + final ColumnItem nextItem = (ColumnItem) columns.get(i + 1).getData(); + for (final TableItem tableItem : columns.get(i).getItems()) { + if (tableItem.getData() != null && tableItem.getData().equals(nextItem)) { + tableItem.getParent().setSelection(tableItem); + } + } + } + + composite.pack(); + this.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + columns.get(columns.size() - 1).forceFocus(); + } + + /** + * Build an array that contains the hierarchy of ColumnItem from the root node + * to a given item. + * + * @param item item to find + * @param items the lists of item that composes the hierarchy + */ + private void findElement(final ColumnItem item, final List items) { + if (item == null) { + return; + } + items.add(item); + findElement(item.getParentItem(), items); + } + + /** + * Sets the receiver's background color to the color specified by the argument, + * or to the default system color for the control if the argument is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. For + * example, on Windows the background of a Button cannot be changed. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color) + */ + @Override + public void setBackground(final Color color) { + super.setBackground(color); + for (final Table column : columns) { + column.setBackground(color); + } + } + + /** + * Sets the background drawing mode to the argument which should be one of the + * following constants defined in class SWT: + * INHERIT_NONE, INHERIT_DEFAULT, + * INHERIT_FORCE. + * + * @param mode the new background mode + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SWT + * @see org.eclipse.swt.widgets.Composite#setBackgroundMode(int) + */ + @Override + public void setBackgroundMode(final int mode) { + super.setBackgroundMode(mode); + for (final Table column : columns) { + column.setBackgroundMode(mode); + } + } + + /** + * Sets the receiver's background image to the image specified by the argument, + * or to the default system color for the control if the argument is null. The + * background image is tiled to fill the available space. + *

+ * Note: This operation is a hint and may be overridden by the platform. For + * example, on Windows the background of a Button cannot be changed. + *

+ * + * @param image the new image (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_INVALID_ARGUMENT - if the argument is not a + * bitmap
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see org.eclipse.swt.widgets.Control#setBackgroundImage(org.eclipse.swt.graphics.Image) + */ + @Override + public void setBackgroundImage(final Image image) { + super.setBackgroundImage(image); + for (final Table column : columns) { + column.setBackgroundImage(image); + } + } + + /** + * Sets the receiver's cursor to the cursor specified by the argument, or to the + * default cursor for that kind of control if the argument is null. + *

+ * When the mouse pointer passes over a control its appearance is changed to + * match the control's cursor. + *

+ * + * @param cursor the new cursor (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setCursor(org.eclipse.swt.graphics.Cursor) + */ + @Override + public void setCursor(final Cursor cursor) { + super.setCursor(cursor); + for (final Table column : columns) { + column.setCursor(cursor); + } + } + + /** + * Sets the font that the receiver will use to paint textual information to the + * font specified by the argument, or to the default font for that kind of + * control if the argument is null. + * + * @param font the new font (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font) + */ + @Override + public void setFont(final Font font) { + super.setFont(font); + for (final Table column : columns) { + column.setFont(font); + } + } + + /** + * Sets the receiver's foreground color to the color specified by the argument, + * or to the default system color for the control if the argument is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color) + */ + @Override + public void setForeground(final Color color) { + super.setForeground(color); + for (final Table column : columns) { + column.setForeground(color); + } + } + + /** + * Sets the receiver's pop up menu to the argument. All controls may optionally + * have a pop up menu that is displayed when the user requests one for the + * control. The sequence of key strokes, button presses and/or button releases + * that are used to request a pop up menu is platform specific. + *

+ * Note: Disposing of a control that has a pop up menu will dispose of the menu. + * To avoid this behavior, set the menu to null before the control is disposed. + *

+ * + * @param menu the new pop up menu + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu
  • + *
  • ERROR_INVALID_PARENT - if the menu is not in the same + * widget tree
  • + *
  • ERROR_INVALID_ARGUMENT - if the menu has been disposed + *
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu) + */ + @Override + public void setMenu(final Menu menu) { + super.setMenu(menu); + for (final Table column : columns) { + column.setMenu(menu); + } + } + + /** + * Sets the receiver's tool tip text to the argument, which may be null + * indicating that the default tool tip for the control will be shown. For a + * control that has a default tool tip, such as the Tree control on Windows, + * setting the tool tip text to an empty string replaces the default, causing no + * tool tip text to be shown. + *

+ * The mnemonic indicator (character '&') is not displayed in a tool tip. To + * display a single '&' in the tool tip, the character '&' can be + * escaped by doubling it in the string. + *

+ * + * @param string the new tool tip text (or null) + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String) + */ + @Override + public void setToolTipText(final String tooltipText) { + super.setToolTipText(tooltipText); + for (final Table column : columns) { + column.setToolTipText(tooltipText); + } + } + + /** + * @return the root item, or null if there is no data + */ + ColumnItem getRootItem() { + if (columns == null || columns.isEmpty()) { + return null; + } + return (ColumnItem) columns.get(0).getData(); + } + +} diff --git a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/src/org/eclipse/nebula/widgets/opal/columnbrowser/ColumnItem.java b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/src/org/eclipse/nebula/widgets/opal/columnbrowser/ColumnItem.java index 02a9517cb..627cd7fee 100644 --- a/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/src/org/eclipse/nebula/widgets/opal/columnbrowser/ColumnItem.java +++ b/widgets/opal/columnbrowser/org.eclipse.nebula.widgets.opal.columnbrowser/src/org/eclipse/nebula/widgets/opal/columnbrowser/ColumnItem.java @@ -1,443 +1,443 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.columnbrowser; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.OpalItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; - -/** - * Instances of this object are items manipulated by the ColumnBrowser widget. - * ColumnItems are part of a tree structure . - * - * @see OpalItem - */ -public class ColumnItem extends OpalItem { - - private final ColumnBrowserWidget widget; - private final ColumnItem parent; - private final List children; - - /** - * Constructs a new instance of this class given its parent. The item is added - * to the end of the items maintained by its parent. - * - * @param widget the widget that will contain this item (can not be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public ColumnItem(final ColumnBrowserWidget widget) { - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - - this.widget = widget; - parent = null; - children = new ArrayList(); - - if (widget.getRootItem() != null) { - widget.getRootItem().children.add(this); - } - widget.updateContent(); - } - - /** - * Constructs a new instance of this class given its parent. The item is added - * at a given position in the items'list maintained by its parent. - * - * @param widget the widget that will contain this item (can not be null) - * @param index the position - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public ColumnItem(final ColumnBrowserWidget widget, final int index) { - - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - - this.widget = widget; - parent = null; - children = new ArrayList(); - widget.getRootItem().children.add(index, this); - widget.updateContent(); - } - - /** - * Constructs a new instance of this class given its parent. The item is added - * to the end of the items maintained by its parent. - * - * @param widget the widget that will contain this item (can not be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public ColumnItem(final ColumnItem parent) { - - if (parent == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (parent.widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - - widget = parent.widget; - this.parent = parent; - children = new ArrayList(); - parent.children.add(this); - parent.widget.updateContent(); - } - - /** - * Constructs a new instance of this class given its parent. The item is added - * at a given position in the items'list maintained by its parent. - * - * @param widget the widget that will contain this item (can not be null) - * @param index the position - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public ColumnItem(final ColumnItem parent, final int index) { - if (parent == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (parent.widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - - widget = parent.widget; - this.parent = parent; - children = new ArrayList(); - parent.children.add(index, this); - parent.widget.updateContent(); - } - - /** - * Remove a given children of this object - * - * @param item the item to remove (can not be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public void remove(final ColumnItem item) { - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - children.remove(item); - widget.updateContent(); - } - - /** - * Remove a children in a given position of this object - * - * @param index position of the children in the items'list - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public void remove(final int index) { - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - children.remove(index); - widget.updateContent(); - } - - /** - * Remove all children of this object - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public void removeAll() { - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - children.clear(); - widget.updateContent(); - } - - /** - * Returns an item located at a given position - * - * @param index position - * @return the item located at the index position - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public ColumnItem getItem(final int index) { - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - return children.get(index); - } - - /** - * @return the number of children - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public int getItemCount() { - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - return children.size(); - } - - /** - * @return all children of this item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public ColumnItem[] getItems() { - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - return children.toArray(new ColumnItem[children.size()]); - } - - /** - * @return the widget that holds this item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public ColumnBrowserWidget getParent() { - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - return widget; - } - - /** - * @return the parent item, of null if this item is the root node - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public ColumnItem getParentItem() { - if (widget == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - if (widget.isDisposed()) { - SWT.error(SWT.ERROR_WIDGET_DISPOSED); - } - return parent; - } - - /** - * Return the position of a given item in children's list - * - * @param item item to find - * @return the position of the children, or -1 if item is a not a - * children of this object - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
- */ - public int indexOf(final ColumnItem item) { - return children.indexOf(item); - } - - /** - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (parent == null ? 0 : parent.hashCode()); - result = prime * result + (widget == null ? 0 : widget.hashCode()); - return result; - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final ColumnItem other = (ColumnItem) obj; - if (children == null) { - if (other.children != null) { - return false; - } - } else if (!children.equals(other.children)) { - return false; - } - if (parent == null) { - if (other.parent != null) { - return false; - } - } else if (!parent.equals(other.parent)) { - return false; - } - if (widget == null) { - if (other.widget != null) { - return false; - } - } else if (!widget.equals(other.widget)) { - return false; - } - return true; - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.columnbrowser; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.OpalItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; + +/** + * Instances of this object are items manipulated by the ColumnBrowser widget. + * ColumnItems are part of a tree structure . + * + * @see OpalItem + */ +public class ColumnItem extends OpalItem { + + private final ColumnBrowserWidget widget; + private final ColumnItem parent; + private final List children; + + /** + * Constructs a new instance of this class given its parent. The item is added + * to the end of the items maintained by its parent. + * + * @param widget the widget that will contain this item (can not be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem(final ColumnBrowserWidget widget) { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + this.widget = widget; + parent = null; + children = new ArrayList(); + + if (widget.getRootItem() != null) { + widget.getRootItem().children.add(this); + } + widget.updateContent(); + } + + /** + * Constructs a new instance of this class given its parent. The item is added + * at a given position in the items'list maintained by its parent. + * + * @param widget the widget that will contain this item (can not be null) + * @param index the position + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem(final ColumnBrowserWidget widget, final int index) { + + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + this.widget = widget; + parent = null; + children = new ArrayList(); + widget.getRootItem().children.add(index, this); + widget.updateContent(); + } + + /** + * Constructs a new instance of this class given its parent. The item is added + * to the end of the items maintained by its parent. + * + * @param widget the widget that will contain this item (can not be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem(final ColumnItem parent) { + + if (parent == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (parent.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + widget = parent.widget; + this.parent = parent; + children = new ArrayList(); + parent.children.add(this); + parent.widget.updateContent(); + } + + /** + * Constructs a new instance of this class given its parent. The item is added + * at a given position in the items'list maintained by its parent. + * + * @param widget the widget that will contain this item (can not be null) + * @param index the position + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem(final ColumnItem parent, final int index) { + if (parent == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (parent.widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + + widget = parent.widget; + this.parent = parent; + children = new ArrayList(); + parent.children.add(index, this); + parent.widget.updateContent(); + } + + /** + * Remove a given children of this object + * + * @param item the item to remove (can not be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public void remove(final ColumnItem item) { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + children.remove(item); + widget.updateContent(); + } + + /** + * Remove a children in a given position of this object + * + * @param index position of the children in the items'list + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public void remove(final int index) { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + children.remove(index); + widget.updateContent(); + } + + /** + * Remove all children of this object + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public void removeAll() { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + children.clear(); + widget.updateContent(); + } + + /** + * Returns an item located at a given position + * + * @param index position + * @return the item located at the index position + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem getItem(final int index) { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return children.get(index); + } + + /** + * @return the number of children + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public int getItemCount() { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return children.size(); + } + + /** + * @return all children of this item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem[] getItems() { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return children.toArray(new ColumnItem[children.size()]); + } + + /** + * @return the widget that holds this item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnBrowserWidget getParent() { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return widget; + } + + /** + * @return the parent item, of null if this item is the root node + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public ColumnItem getParentItem() { + if (widget == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + if (widget.isDisposed()) { + SWT.error(SWT.ERROR_WIDGET_DISPOSED); + } + return parent; + } + + /** + * Return the position of a given item in children's list + * + * @param item item to find + * @return the position of the children, or -1 if item is a not a + * children of this object + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
+ */ + public int indexOf(final ColumnItem item) { + return children.indexOf(item); + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (parent == null ? 0 : parent.hashCode()); + result = prime * result + (widget == null ? 0 : widget.hashCode()); + return result; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ColumnItem other = (ColumnItem) obj; + if (children == null) { + if (other.children != null) { + return false; + } + } else if (!children.equals(other.children)) { + return false; + } + if (parent == null) { + if (other.parent != null) { + return false; + } + } else if (!parent.equals(other.parent)) { + return false; + } + if (widget == null) { + if (other.widget != null) { + return false; + } + } else if (!widget.equals(other.widget)) { + return false; + } + return true; + } + +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.classpath b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.classpath +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.project b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.project index 76fb6cfca..8ddc287bd 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.project +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.commons - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.commons + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/META-INF/MANIFEST.MF b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/META-INF/MANIFEST.MF index fd459e63d..2aa95f613 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/META-INF/MANIFEST.MF +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/META-INF/MANIFEST.MF @@ -1,12 +1,12 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Common Elements -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.commons -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.equinox.common, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.commons, - org.eclipse.nebula.widgets.opal.commons.resources -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.commons +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Common Elements +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.commons +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.equinox.common, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.commons, + org.eclipse.nebula.widgets.opal.commons.resources +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.commons diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/build.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/build.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/AdvancedPath.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/AdvancedPath.java index 4f4d080c4..c9fddc585 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/AdvancedPath.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/AdvancedPath.java @@ -1,162 +1,162 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Waldimiro Rossi - addRoundRectangle and addCircle methods - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.commons; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Path; - -/** - * AdvancedPath, a Path object that contains extra paths - * @see Path - */ -public class AdvancedPath extends Path { - - /** - * Contructor - * - * @param device - */ - public AdvancedPath(final Device device) { - super(device); - } - - /** - * Adds to the receiver the circle specified by x, y, radius - * - * @param x the x coordinate of the circle to add - * @param y the y coordinate of the circle to add - * @param radius the width of the radius - * - * @exception SWTException - *
    - *
  • ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
  • - *
- */ - public void addCircle(final float x, final float y, final float radius) { - if (this.isDisposed()) { - SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - } - this.addArc(x, y, radius, radius, 0, 360); - } - - /** - * Adds to the receiver the round-cornered rectangle specified by x, y, width and height. - * - * @param x the x coordinate of the rectangle to add - * @param y the y coordinate of the rectangle to add - * @param width the width of the rectangle to add - * @param height the height of the rectangle to add - * @param arcWidth the width of the arc - * @param arcHeight the height of the arc - * @exception SWTException - *
    - *
  • ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
  • - *
- */ - public void addRoundRectangle(final float x, final float y, final float width, final float height, final float arcWidth, final float arcHeight) { - if (this.isDisposed()) { - SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - } - - // Top left corner - this.cubicTo(x, y, x, y, x, y + arcHeight); - this.cubicTo(x, y, x, y, x + arcWidth, y); - - // Top right corner - this.cubicTo(x + width, y, x + width, y, x + width - arcWidth, y); - this.cubicTo(x + width, y, x + width, y, x + width, y + arcHeight); - - // Bottom right corner - this.cubicTo(x + width, y + height, x + width, y + height, x + width, y + height - arcHeight); - this.cubicTo(x + width, y + height, x + width, y + height, x + width - arcWidth, y + height); - - // Bottom left corner - this.cubicTo(x, y + height, x, y + height, x + arcWidth, y + height); - this.cubicTo(x, y + height, x, y + height, x, y + height - arcHeight); - } - - /** - * Adds to the receiver the rectangle specified by x, y, width and height.
- * This rectangle is round-cornered on the left, and straight on the right. - * - * @param x the x coordinate of the rectangle to add - * @param y the y coordinate of the rectangle to add - * @param width the width of the rectangle to add - * @param height the height of the rectangle to add - * @param arcWidth the width of the arc - * @param arcHeight the height of the arc - * @exception SWTException - *
    - *
  • ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
  • - *
- */ - public void addRoundRectangleStraightRight(final float x, final float y, final float width, final float height, final float arcWidth, final float arcHeight) { - if (this.isDisposed()) { - SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - } - - // Top left corner - this.cubicTo(x, y, x, y, x, y + arcHeight); - this.cubicTo(x, y, x, y, x + arcWidth, y); - - // Top right corner - this.lineTo(x + width, y); - - // Bottom right corner - this.lineTo(x + width, y + height); - - // Bottom left corner - this.cubicTo(x, y + height, x, y + height, x + arcWidth, y + height); - this.cubicTo(x, y + height, x, y + height, x, y + height - arcHeight); - } - - /** - * Adds to the receiver the rectangle specified by x, y, width and height.
- * This rectangle is round-cornered on the right, and straight on the left. - * - * @param x the x coordinate of the rectangle to add - * @param y the y coordinate of the rectangle to add - * @param width the width of the rectangle to add - * @param height the height of the rectangle to add - * @param arcWidth the width of the arc - * @param arcHeight the height of the arc - * @exception SWTException - *
    - *
  • ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
  • - *
- */ - public void addRoundRectangleStraightLeft(final float x, final float y, final float width, final float height, final float arcWidth, final float arcHeight) { - if (this.isDisposed()) { - SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - } - - // Top left corner - moveTo(x, y); - lineTo(x + width - arcWidth, y); - - // Top right corner - this.cubicTo(x + width, y, x + width, y, x + width - arcWidth, y); - this.cubicTo(x + width, y, x + width, y, x + width, y + arcHeight); - - // Bottom right corner - this.cubicTo(x + width, y + height, x + width, y + height, x + width, y + height - arcHeight); - this.cubicTo(x + width, y + height, x + width, y + height, x + width - arcWidth, y + height); - - // Bottom left corner - lineTo(x, y + height); - lineTo(x, y); - } -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Waldimiro Rossi - addRoundRectangle and addCircle methods + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.commons; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Path; + +/** + * AdvancedPath, a Path object that contains extra paths + * @see Path + */ +public class AdvancedPath extends Path { + + /** + * Contructor + * + * @param device + */ + public AdvancedPath(final Device device) { + super(device); + } + + /** + * Adds to the receiver the circle specified by x, y, radius + * + * @param x the x coordinate of the circle to add + * @param y the y coordinate of the circle to add + * @param radius the width of the radius + * + * @exception SWTException + *
    + *
  • ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
  • + *
+ */ + public void addCircle(final float x, final float y, final float radius) { + if (this.isDisposed()) { + SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); + } + this.addArc(x, y, radius, radius, 0, 360); + } + + /** + * Adds to the receiver the round-cornered rectangle specified by x, y, width and height. + * + * @param x the x coordinate of the rectangle to add + * @param y the y coordinate of the rectangle to add + * @param width the width of the rectangle to add + * @param height the height of the rectangle to add + * @param arcWidth the width of the arc + * @param arcHeight the height of the arc + * @exception SWTException + *
    + *
  • ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
  • + *
+ */ + public void addRoundRectangle(final float x, final float y, final float width, final float height, final float arcWidth, final float arcHeight) { + if (this.isDisposed()) { + SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); + } + + // Top left corner + this.cubicTo(x, y, x, y, x, y + arcHeight); + this.cubicTo(x, y, x, y, x + arcWidth, y); + + // Top right corner + this.cubicTo(x + width, y, x + width, y, x + width - arcWidth, y); + this.cubicTo(x + width, y, x + width, y, x + width, y + arcHeight); + + // Bottom right corner + this.cubicTo(x + width, y + height, x + width, y + height, x + width, y + height - arcHeight); + this.cubicTo(x + width, y + height, x + width, y + height, x + width - arcWidth, y + height); + + // Bottom left corner + this.cubicTo(x, y + height, x, y + height, x + arcWidth, y + height); + this.cubicTo(x, y + height, x, y + height, x, y + height - arcHeight); + } + + /** + * Adds to the receiver the rectangle specified by x, y, width and height.
+ * This rectangle is round-cornered on the left, and straight on the right. + * + * @param x the x coordinate of the rectangle to add + * @param y the y coordinate of the rectangle to add + * @param width the width of the rectangle to add + * @param height the height of the rectangle to add + * @param arcWidth the width of the arc + * @param arcHeight the height of the arc + * @exception SWTException + *
    + *
  • ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
  • + *
+ */ + public void addRoundRectangleStraightRight(final float x, final float y, final float width, final float height, final float arcWidth, final float arcHeight) { + if (this.isDisposed()) { + SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); + } + + // Top left corner + this.cubicTo(x, y, x, y, x, y + arcHeight); + this.cubicTo(x, y, x, y, x + arcWidth, y); + + // Top right corner + this.lineTo(x + width, y); + + // Bottom right corner + this.lineTo(x + width, y + height); + + // Bottom left corner + this.cubicTo(x, y + height, x, y + height, x + arcWidth, y + height); + this.cubicTo(x, y + height, x, y + height, x, y + height - arcHeight); + } + + /** + * Adds to the receiver the rectangle specified by x, y, width and height.
+ * This rectangle is round-cornered on the right, and straight on the left. + * + * @param x the x coordinate of the rectangle to add + * @param y the y coordinate of the rectangle to add + * @param width the width of the rectangle to add + * @param height the height of the rectangle to add + * @param arcWidth the width of the arc + * @param arcHeight the height of the arc + * @exception SWTException + *
    + *
  • ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
  • + *
+ */ + public void addRoundRectangleStraightLeft(final float x, final float y, final float width, final float height, final float arcWidth, final float arcHeight) { + if (this.isDisposed()) { + SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); + } + + // Top left corner + moveTo(x, y); + lineTo(x + width - arcWidth, y); + + // Top right corner + this.cubicTo(x + width, y, x + width, y, x + width - arcWidth, y); + this.cubicTo(x + width, y, x + width, y, x + width, y + arcHeight); + + // Bottom right corner + this.cubicTo(x + width, y + height, x + width, y + height, x + width, y + height - arcHeight); + this.cubicTo(x + width, y + height, x + width, y + height, x + width - arcWidth, y + height); + + // Bottom left corner + lineTo(x, y + height); + lineTo(x, y); + } +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/FileToolbox.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/FileToolbox.java index 78483b29e..2cc4a6fdd 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/FileToolbox.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/FileToolbox.java @@ -1,50 +1,50 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.commons; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; - -public class FileToolbox { - - /** - * Loads a file into a stream - * - * @param fileName file name - * @return a stream composed of this file - */ - public static InputStream getInputStream(final String fileName) { - if (fileName.startsWith("jar:")) { - URL url; - try { - url = new URL(fileName); - return url.openStream(); - } catch (final MalformedURLException e) { - throw new RuntimeException(e); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } else { - try { - return new FileInputStream(fileName); - } catch (final FileNotFoundException e) { - throw new RuntimeException(e); - } - } - } -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.commons; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +public class FileToolbox { + + /** + * Loads a file into a stream + * + * @param fileName file name + * @return a stream composed of this file + */ + public static InputStream getInputStream(final String fileName) { + if (fileName.startsWith("jar:")) { + URL url; + try { + url = new URL(fileName); + return url.openStream(); + } catch (final MalformedURLException e) { + throw new RuntimeException(e); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } else { + try { + return new FileInputStream(fileName); + } catch (final FileNotFoundException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/FixedSizeQueue.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/FixedSizeQueue.java index 8f1a0c96a..68af8fb19 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/FixedSizeQueue.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/FixedSizeQueue.java @@ -1,99 +1,99 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.commons; - -import java.util.ArrayList; -import java.util.List; - -/** - * Instance of this class are queues that have a fixed size.
- * When the queue is full, the elements are shifted and the first element is - * lost. - * - * @param Type of objects stored in this queue - */ -public class FixedSizeQueue { - private T[] buffer; - private int index; - - /** - * Constructor - * - * @param capacity initial capacity - */ - @SuppressWarnings("unchecked") - public FixedSizeQueue(final int capacity) { - this.buffer = (T[]) new Object[capacity]; - this.index = 0; - } - - /** - * Store an element in the buffer - * - * @param element element to store - */ - public void put(final T element) { - if (this.index == this.buffer.length) { - // Full - System.arraycopy(this.buffer, 1, this.buffer, 0, this.buffer.length - 1); - this.buffer[this.index - 1] = element; - } else { - this.buffer[this.index++] = element; - } - } - - /** - * @return all values stored in this queue - */ - public List getValues() { - final List list = new ArrayList(this.index); - for (int i = 0; i < this.index; i++) { - if (this.buffer[i] != null) { - list.add(this.buffer[i]); - } - } - return list; - } - - /** - * @return size of the buffer - */ - public int getSize() { - return this.index; - } - - /** - * @param newSize new size of the buffer. If newSize is lower than the actual - * size, the buffer will contain the last elements that have been - * stored - */ - @SuppressWarnings("unchecked") - public void resizeTo(int newSize) { - if (newSize < 0) { - newSize = 1; - } - if (newSize == this.buffer.length) { - return; - } - final T[] resizedBuffer = (T[]) new Object[newSize]; - if (newSize > this.buffer.length) { - System.arraycopy(this.buffer, 0, resizedBuffer, 0, this.buffer.length); - } else { - final int startPos = Math.max(0, this.index - newSize); - System.arraycopy(this.buffer, startPos, resizedBuffer, 0, newSize); - this.index = newSize; - } - this.buffer = resizedBuffer; - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.commons; + +import java.util.ArrayList; +import java.util.List; + +/** + * Instance of this class are queues that have a fixed size.
+ * When the queue is full, the elements are shifted and the first element is + * lost. + * + * @param Type of objects stored in this queue + */ +public class FixedSizeQueue { + private T[] buffer; + private int index; + + /** + * Constructor + * + * @param capacity initial capacity + */ + @SuppressWarnings("unchecked") + public FixedSizeQueue(final int capacity) { + this.buffer = (T[]) new Object[capacity]; + this.index = 0; + } + + /** + * Store an element in the buffer + * + * @param element element to store + */ + public void put(final T element) { + if (this.index == this.buffer.length) { + // Full + System.arraycopy(this.buffer, 1, this.buffer, 0, this.buffer.length - 1); + this.buffer[this.index - 1] = element; + } else { + this.buffer[this.index++] = element; + } + } + + /** + * @return all values stored in this queue + */ + public List getValues() { + final List list = new ArrayList(this.index); + for (int i = 0; i < this.index; i++) { + if (this.buffer[i] != null) { + list.add(this.buffer[i]); + } + } + return list; + } + + /** + * @return size of the buffer + */ + public int getSize() { + return this.index; + } + + /** + * @param newSize new size of the buffer. If newSize is lower than the actual + * size, the buffer will contain the last elements that have been + * stored + */ + @SuppressWarnings("unchecked") + public void resizeTo(int newSize) { + if (newSize < 0) { + newSize = 1; + } + if (newSize == this.buffer.length) { + return; + } + final T[] resizedBuffer = (T[]) new Object[newSize]; + if (newSize > this.buffer.length) { + System.arraycopy(this.buffer, 0, resizedBuffer, 0, this.buffer.length); + } else { + final int startPos = Math.max(0, this.index - newSize); + System.arraycopy(this.buffer, startPos, resizedBuffer, 0, newSize); + this.index = newSize; + } + this.buffer = resizedBuffer; + } + +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/HTMLStyledTextParser.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/HTMLStyledTextParser.java index e7802f1f4..cba0b6094 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/HTMLStyledTextParser.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/HTMLStyledTextParser.java @@ -1,488 +1,488 @@ -/******************************************************************************* - * Copyright (c) 2012-2013 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.commons; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StyleRange; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; - -/** - * Instances of this class are used to convert pseudo-HTML content of a styled - * text into style ranges - */ -public class HTMLStyledTextParser { - - private final StyledText styledText; - private StringBuilder output; - private StringBuilder currentTag; - private final List listOfStyles; - private final LinkedList stack; - private int currentPosition; - private final int defaultHeight; - private static final Map HTML_CODES = initHTMLCode(); - - /** - * Constructor - * - * @param styledText styled text to analyze - */ - HTMLStyledTextParser(final StyledText styledText) { - this.styledText = styledText; - listOfStyles = new ArrayList(); - stack = new LinkedList(); - final FontData data = styledText.getFont().getFontData()[0]; - defaultHeight = data.getHeight(); - } - - private static Map initHTMLCode() { - final Map map = new HashMap(); - - map.put("aliceblue", new Integer[] { 240, 248, 255 }); - map.put("antiquewhite", new Integer[] { 250, 235, 215 }); - map.put("aqua", new Integer[] { 0, 255, 255 }); - map.put("aquamarine", new Integer[] { 127, 255, 212 }); - map.put("azure", new Integer[] { 240, 255, 255 }); - map.put("beige", new Integer[] { 245, 245, 220 }); - map.put("bisque", new Integer[] { 255, 228, 196 }); - map.put("black", new Integer[] { 0, 0, 0 }); - map.put("blanchedalmond", new Integer[] { 255, 235, 205 }); - map.put("blue", new Integer[] { 0, 0, 255 }); - map.put("blueviolet", new Integer[] { 138, 43, 226 }); - map.put("brown", new Integer[] { 165, 42, 42 }); - map.put("burlywood", new Integer[] { 222, 184, 135 }); - map.put("cadetblue", new Integer[] { 95, 158, 160 }); - map.put("chartreuse", new Integer[] { 127, 255, 0 }); - map.put("chocolate", new Integer[] { 210, 105, 30 }); - map.put("coral", new Integer[] { 255, 127, 80 }); - map.put("cornflowerblue", new Integer[] { 100, 149, 237 }); - map.put("cornsilk", new Integer[] { 255, 248, 220 }); - map.put("crimson", new Integer[] { 220, 20, 60 }); - map.put("cyan", new Integer[] { 0, 255, 255 }); - map.put("darkblue", new Integer[] { 0, 0, 139 }); - map.put("darkcyan", new Integer[] { 0, 139, 139 }); - map.put("darkgoldenrod", new Integer[] { 184, 134, 11 }); - map.put("darkgray", new Integer[] { 169, 169, 169 }); - map.put("darkgreen", new Integer[] { 0, 100, 0 }); - map.put("darkgrey", new Integer[] { 169, 169, 169 }); - map.put("darkkhaki", new Integer[] { 189, 183, 107 }); - map.put("darkmagenta", new Integer[] { 139, 0, 139 }); - map.put("darkolivegreen", new Integer[] { 85, 107, 47 }); - map.put("darkorange", new Integer[] { 255, 140, 0 }); - map.put("darkorchid", new Integer[] { 153, 50, 204 }); - map.put("darkred", new Integer[] { 139, 0, 0 }); - map.put("darksalmon", new Integer[] { 233, 150, 122 }); - map.put("darkseagreen", new Integer[] { 143, 188, 143 }); - map.put("darkslateblue", new Integer[] { 72, 61, 139 }); - map.put("darkslategray", new Integer[] { 47, 79, 79 }); - map.put("darkslategrey", new Integer[] { 47, 79, 79 }); - map.put("darkturquoise", new Integer[] { 0, 206, 209 }); - map.put("darkviolet", new Integer[] { 148, 0, 211 }); - map.put("deeppink", new Integer[] { 255, 20, 147 }); - map.put("deepskyblue", new Integer[] { 0, 191, 255 }); - map.put("dimgray", new Integer[] { 105, 105, 105 }); - map.put("dimgrey", new Integer[] { 105, 105, 105 }); - map.put("dodgerblue", new Integer[] { 30, 144, 255 }); - map.put("firebrick", new Integer[] { 178, 34, 34 }); - map.put("floralwhite", new Integer[] { 255, 250, 240 }); - map.put("forestgreen", new Integer[] { 34, 139, 34 }); - map.put("fuchsia", new Integer[] { 255, 0, 255 }); - map.put("gainsboro", new Integer[] { 220, 220, 220 }); - map.put("ghostwhite", new Integer[] { 248, 248, 255 }); - map.put("gold", new Integer[] { 255, 215, 0 }); - map.put("goldenrod", new Integer[] { 218, 165, 32 }); - map.put("gray", new Integer[] { 128, 128, 128 }); - map.put("green", new Integer[] { 0, 128, 0 }); - map.put("greenyellow", new Integer[] { 173, 255, 47 }); - map.put("grey", new Integer[] { 128, 128, 128 }); - map.put("honeydew", new Integer[] { 240, 255, 240 }); - map.put("hotpink", new Integer[] { 255, 105, 180 }); - map.put("indianred", new Integer[] { 205, 92, 92 }); - map.put("indigo", new Integer[] { 75, 0, 130 }); - map.put("ivory", new Integer[] { 255, 255, 240 }); - map.put("khaki", new Integer[] { 240, 230, 140 }); - map.put("lavender", new Integer[] { 230, 230, 250 }); - map.put("lavenderblush", new Integer[] { 255, 240, 245 }); - map.put("lawngreen", new Integer[] { 124, 252, 0 }); - map.put("lemonchiffon", new Integer[] { 255, 250, 205 }); - map.put("lightblue", new Integer[] { 173, 216, 230 }); - map.put("lightcoral", new Integer[] { 240, 128, 128 }); - map.put("lightcyan", new Integer[] { 224, 255, 255 }); - map.put("lightgoldenrodyellow", new Integer[] { 250, 250, 210 }); - map.put("lightgray", new Integer[] { 211, 211, 211 }); - map.put("lightgreen", new Integer[] { 144, 238, 144 }); - map.put("lightgrey", new Integer[] { 211, 211, 211 }); - map.put("lightpink", new Integer[] { 255, 182, 193 }); - map.put("lightsalmon", new Integer[] { 255, 160, 122 }); - map.put("lightseagreen", new Integer[] { 32, 178, 170 }); - map.put("lightskyblue", new Integer[] { 135, 206, 250 }); - map.put("lightslategray", new Integer[] { 119, 136, 153 }); - map.put("lightslategrey", new Integer[] { 119, 136, 153 }); - map.put("lightsteelblue", new Integer[] { 176, 196, 222 }); - map.put("lightyellow", new Integer[] { 255, 255, 224 }); - map.put("lime", new Integer[] { 0, 255, 0 }); - map.put("limegreen", new Integer[] { 50, 205, 50 }); - map.put("linen", new Integer[] { 250, 240, 230 }); - map.put("magenta", new Integer[] { 255, 0, 255 }); - map.put("maroon", new Integer[] { 128, 0, 0 }); - map.put("mediumaquamarine", new Integer[] { 102, 205, 170 }); - map.put("mediumblue", new Integer[] { 0, 0, 205 }); - map.put("mediumorchid", new Integer[] { 186, 85, 211 }); - map.put("mediumpurple", new Integer[] { 147, 112, 219 }); - map.put("mediumseagreen", new Integer[] { 60, 179, 113 }); - map.put("mediumslateblue", new Integer[] { 123, 104, 238 }); - map.put("mediumspringgreen", new Integer[] { 0, 250, 154 }); - map.put("mediumturquoise", new Integer[] { 72, 209, 204 }); - map.put("mediumvioletred", new Integer[] { 199, 21, 133 }); - map.put("midnightblue", new Integer[] { 25, 25, 112 }); - map.put("mintcream", new Integer[] { 245, 255, 250 }); - map.put("mistyrose", new Integer[] { 255, 228, 225 }); - map.put("moccasin", new Integer[] { 255, 228, 181 }); - map.put("navajowhite", new Integer[] { 255, 222, 173 }); - map.put("navy", new Integer[] { 0, 0, 128 }); - map.put("oldlace", new Integer[] { 253, 245, 230 }); - map.put("olive", new Integer[] { 128, 128, 0 }); - map.put("olivedrab", new Integer[] { 107, 142, 35 }); - map.put("orange", new Integer[] { 255, 165, 0 }); - map.put("orangered", new Integer[] { 255, 69, 0 }); - map.put("orchid", new Integer[] { 218, 112, 214 }); - map.put("palegoldenrod", new Integer[] { 238, 232, 170 }); - map.put("palegreen", new Integer[] { 152, 251, 152 }); - map.put("paleturquoise", new Integer[] { 175, 238, 238 }); - map.put("palevioletred", new Integer[] { 219, 112, 147 }); - map.put("papayawhip", new Integer[] { 255, 239, 213 }); - map.put("peachpuff", new Integer[] { 255, 218, 185 }); - map.put("peru", new Integer[] { 205, 133, 63 }); - map.put("pink", new Integer[] { 255, 192, 203 }); - map.put("plum", new Integer[] { 221, 160, 221 }); - map.put("powderblue", new Integer[] { 176, 224, 230 }); - map.put("purple", new Integer[] { 128, 0, 128 }); - map.put("red", new Integer[] { 255, 0, 0 }); - map.put("rosybrown", new Integer[] { 188, 143, 143 }); - map.put("royalblue", new Integer[] { 65, 105, 225 }); - map.put("saddlebrown", new Integer[] { 139, 69, 19 }); - map.put("salmon", new Integer[] { 250, 128, 114 }); - map.put("sandybrown", new Integer[] { 244, 164, 96 }); - map.put("seagreen", new Integer[] { 46, 139, 87 }); - map.put("seashell", new Integer[] { 255, 245, 238 }); - map.put("sienna", new Integer[] { 160, 82, 45 }); - map.put("silver", new Integer[] { 192, 192, 192 }); - map.put("skyblue", new Integer[] { 135, 206, 235 }); - map.put("slateblue", new Integer[] { 106, 90, 205 }); - map.put("slategray", new Integer[] { 112, 128, 144 }); - map.put("slategrey", new Integer[] { 112, 128, 144 }); - map.put("snow", new Integer[] { 255, 250, 250 }); - map.put("springgreen", new Integer[] { 0, 255, 127 }); - map.put("steelblue", new Integer[] { 70, 130, 180 }); - map.put("tan", new Integer[] { 210, 180, 140 }); - map.put("teal", new Integer[] { 0, 128, 128 }); - map.put("thistle", new Integer[] { 216, 191, 216 }); - map.put("tomato", new Integer[] { 255, 99, 71 }); - map.put("turquoise", new Integer[] { 64, 224, 208 }); - map.put("violet", new Integer[] { 238, 130, 238 }); - map.put("wheat", new Integer[] { 245, 222, 179 }); - map.put("white", new Integer[] { 255, 255, 255 }); - map.put("whitesmoke", new Integer[] { 245, 245, 245 }); - map.put("yellow", new Integer[] { 255, 255, 0 }); - map.put("yellowgreen", new Integer[] { 154, 205, 50 }); - - return map; - } - - /** - * Parse the content, build the list of style ranges and apply them to the - * styled text widget - * - * @throws IOException - */ - public void parse() throws IOException { - if (styledText == null || "".equals(styledText.getText().trim())) { - return; - } - - initBeforeParsing(); - - final String text = styledText.getText().trim(); - final int max = text.length(); - boolean inTag = false; - - for (int i = 0; i < max; i++) { - final char currentChar = text.charAt(i); - if (currentChar == '<') { - inTag = true; - continue; - } else if (currentChar == '>') { - inTag = false; - handleTag(); - currentTag.delete(0, currentTag.length()); - } else { - if (inTag) { - currentTag.append(currentChar); - } else { - currentPosition++; - output.append(currentChar); - } - } - } - styledText.setText(output.toString()); - styledText.setStyleRanges(removeDoublons()); - } - - private StyleRange[] removeDoublons() { - final Iterator mainIt = listOfStyles.iterator(); - while (mainIt.hasNext()) { - final StyleRange current = mainIt.next(); - final Iterator it = listOfStyles.iterator(); - while (it.hasNext()) { - final StyleRange other = it.next(); - if (current == other) { - continue; - } - if (current.start == other.start && current.length == other.length) { - current.fontStyle = current.fontStyle | other.fontStyle; - if (current.font == null) { - current.font = other.font; - } - if (current.foreground == null) { - current.foreground = other.foreground; - } - if (current.background == null) { - current.background = other.background; - } - it.remove(); - } - } - } - - return listOfStyles.toArray(new StyleRange[listOfStyles.size()]); - } - - private void initBeforeParsing() { - output = new StringBuilder(); - currentTag = new StringBuilder(); - listOfStyles.clear(); - stack.clear(); - currentPosition = 0; - } - - private void handleTag() { - final String tag = currentTag.toString().toLowerCase(); - if ("br".equals(tag) || "br/".equals(tag)) { - output.append("\n"); - currentPosition++; - return; - } - - if ("b".equals(tag)) { - processBeginBold(); - return; - } - if ("i".equals(tag)) { - processBeginItalic(); - return; - } - if ("u".equals(tag)) { - processBeginUnderline(); - return; - } - if (tag.startsWith("size=")) { - processBeginSize(); - return; - } - if (tag.startsWith("color=")) { - processBeginColor(); - return; - } - if (tag.startsWith("backgroundcolor=")) { - processBeginBackgroundColor(); - return; - } - - final String[] acceptedClosingTags = new String[] { "/b", "/i", "/u", "/size", "/color", "/backgroundcolor" }; - for (final String closingTag : acceptedClosingTags) { - if (closingTag.equals(tag)) { - processEndTag(closingTag); - return; - } - } - - final String text = "<" + tag + ">"; - output.append(text); - currentPosition += text.length(); - - } - - private void processBeginBold() { - final StyleRange currentStyleRange = new StyleRange(); - currentStyleRange.start = currentPosition; - currentStyleRange.length = 0; - currentStyleRange.fontStyle = SWT.BOLD; - currentStyleRange.data = ""; - stack.push(currentStyleRange); - } - - private void processEndTag(final String expectedTag) { - final StyleRange currentStyleRange = stack.pop(); - final String wholeExpectedTag = "<" + expectedTag + ">"; - if (!wholeExpectedTag.equals(currentStyleRange.data)) { - final StringBuilder sb = new StringBuilder(); - sb.append("Error at position #").append(currentPosition).// - append(" - closing ").// - append(wholeExpectedTag).// - append(" tag found but "). // - append(currentStyleRange.data).// - append(" tag expected !"); - throw new RuntimeException(sb.toString()); - } - currentStyleRange.length = currentPosition - currentStyleRange.start; - listOfStyles.add(currentStyleRange); - - } - - private void processBeginItalic() { - final StyleRange currentStyleRange = new StyleRange(); - currentStyleRange.start = currentPosition; - currentStyleRange.length = 0; - currentStyleRange.fontStyle = SWT.ITALIC; - currentStyleRange.data = ""; - stack.push(currentStyleRange); - } - - private void processBeginUnderline() { - final StyleRange currentStyleRange = new StyleRange(); - currentStyleRange.start = currentPosition; - currentStyleRange.length = 0; - currentStyleRange.fontStyle = SWT.NONE; - currentStyleRange.underline = true; - currentStyleRange.data = ""; - stack.push(currentStyleRange); - } - - private void processBeginSize() { - final StyleRange currentStyleRange = new StyleRange(); - currentStyleRange.start = currentPosition; - currentStyleRange.length = 0; - currentStyleRange.fontStyle = SWT.NONE; - currentStyleRange.font = computeFont(); - currentStyleRange.data = ""; - stack.push(currentStyleRange); - } - - private Font computeFont() { - final String fontSize = currentTag.toString().toLowerCase().replace("size=", ""); - if (fontSize.length() == 0) { - throw new RuntimeException("Argument size is empty !"); - } - int newSize = defaultHeight; - if (fontSize.startsWith("+")) { - final int delta = Integer.valueOf(fontSize.substring(1)); - newSize += delta; - } else if (fontSize.startsWith("-")) { - final int delta = Integer.valueOf(fontSize.substring(1)); - newSize -= delta; - } - - final FontData fd = styledText.getFont().getFontData()[0]; - final Font newFont = new Font(styledText.getDisplay(), fd.getName(), newSize, SWT.NONE); - styledText.addListener(SWT.Dispose, new Listener() { - @Override - public void handleEvent(final Event event) { - newFont.dispose(); - } - }); - return newFont; - } - - private void processBeginColor() { - final StyleRange currentStyleRange = new StyleRange(); - currentStyleRange.start = currentPosition; - currentStyleRange.length = 0; - currentStyleRange.fontStyle = SWT.NONE; - currentStyleRange.foreground = computeColor(); - currentStyleRange.data = ""; - stack.push(currentStyleRange); - } - - private Color computeColor() { - final String fontColor = currentTag.toString().toLowerCase().replace("color=", "").replace("background", ""); - if (fontColor.length() == 0) { - throw new RuntimeException("Argument color is empty !"); - } - - int red, green, blue; - if (fontColor.startsWith("#")) { - final String hexa = fontColor.substring(1); - if (hexa.length() != 6) { - throw new RuntimeException("Argument [" + hexa + "] is not valid !"); - } - try { - red = Integer.parseInt(hexa.substring(0, 2).toLowerCase(), 16); - green = Integer.parseInt(hexa.substring(2, 4).toLowerCase(), 16); - blue = Integer.parseInt(hexa.substring(4, 6).toLowerCase(), 16); - } catch (final NumberFormatException nfe) { - throw new RuntimeException("Argument [" + hexa + "] is not valid !"); - } - } else if (fontColor.indexOf(',') > -1) { - final String[] args = fontColor.split(","); - if (args.length != 3) { - throw new RuntimeException("Argument [" + fontColor + "] is not valid !"); - } - try { - red = Integer.parseInt(args[0]); - green = Integer.parseInt(args[1]); - blue = Integer.parseInt(args[2]); - } catch (final NumberFormatException nfe) { - throw new RuntimeException("Argument [" + fontColor + "] is not valid !"); - } - } else { - final Integer[] rgb = HTML_CODES.get(fontColor.toLowerCase()); - if (rgb == null) { - red = 0; - green = 0; - blue = 0; - } else { - red = rgb[0]; - green = rgb[1]; - blue = rgb[2]; - } - } - final Color color = new Color(styledText.getDisplay(), red, green, blue); - styledText.addListener(SWT.Dispose, e -> { - color.dispose(); - }); - return color; - } - - private void processBeginBackgroundColor() { - final StyleRange currentStyleRange = new StyleRange(); - currentStyleRange.start = currentPosition; - currentStyleRange.length = 0; - currentStyleRange.fontStyle = SWT.NONE; - currentStyleRange.background = computeColor(); - currentStyleRange.data = ""; - stack.push(currentStyleRange); - } - +/******************************************************************************* + * Copyright (c) 2012-2013 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.commons; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; + +/** + * Instances of this class are used to convert pseudo-HTML content of a styled + * text into style ranges + */ +public class HTMLStyledTextParser { + + private final StyledText styledText; + private StringBuilder output; + private StringBuilder currentTag; + private final List listOfStyles; + private final LinkedList stack; + private int currentPosition; + private final int defaultHeight; + private static final Map HTML_CODES = initHTMLCode(); + + /** + * Constructor + * + * @param styledText styled text to analyze + */ + HTMLStyledTextParser(final StyledText styledText) { + this.styledText = styledText; + listOfStyles = new ArrayList(); + stack = new LinkedList(); + final FontData data = styledText.getFont().getFontData()[0]; + defaultHeight = data.getHeight(); + } + + private static Map initHTMLCode() { + final Map map = new HashMap(); + + map.put("aliceblue", new Integer[] { 240, 248, 255 }); + map.put("antiquewhite", new Integer[] { 250, 235, 215 }); + map.put("aqua", new Integer[] { 0, 255, 255 }); + map.put("aquamarine", new Integer[] { 127, 255, 212 }); + map.put("azure", new Integer[] { 240, 255, 255 }); + map.put("beige", new Integer[] { 245, 245, 220 }); + map.put("bisque", new Integer[] { 255, 228, 196 }); + map.put("black", new Integer[] { 0, 0, 0 }); + map.put("blanchedalmond", new Integer[] { 255, 235, 205 }); + map.put("blue", new Integer[] { 0, 0, 255 }); + map.put("blueviolet", new Integer[] { 138, 43, 226 }); + map.put("brown", new Integer[] { 165, 42, 42 }); + map.put("burlywood", new Integer[] { 222, 184, 135 }); + map.put("cadetblue", new Integer[] { 95, 158, 160 }); + map.put("chartreuse", new Integer[] { 127, 255, 0 }); + map.put("chocolate", new Integer[] { 210, 105, 30 }); + map.put("coral", new Integer[] { 255, 127, 80 }); + map.put("cornflowerblue", new Integer[] { 100, 149, 237 }); + map.put("cornsilk", new Integer[] { 255, 248, 220 }); + map.put("crimson", new Integer[] { 220, 20, 60 }); + map.put("cyan", new Integer[] { 0, 255, 255 }); + map.put("darkblue", new Integer[] { 0, 0, 139 }); + map.put("darkcyan", new Integer[] { 0, 139, 139 }); + map.put("darkgoldenrod", new Integer[] { 184, 134, 11 }); + map.put("darkgray", new Integer[] { 169, 169, 169 }); + map.put("darkgreen", new Integer[] { 0, 100, 0 }); + map.put("darkgrey", new Integer[] { 169, 169, 169 }); + map.put("darkkhaki", new Integer[] { 189, 183, 107 }); + map.put("darkmagenta", new Integer[] { 139, 0, 139 }); + map.put("darkolivegreen", new Integer[] { 85, 107, 47 }); + map.put("darkorange", new Integer[] { 255, 140, 0 }); + map.put("darkorchid", new Integer[] { 153, 50, 204 }); + map.put("darkred", new Integer[] { 139, 0, 0 }); + map.put("darksalmon", new Integer[] { 233, 150, 122 }); + map.put("darkseagreen", new Integer[] { 143, 188, 143 }); + map.put("darkslateblue", new Integer[] { 72, 61, 139 }); + map.put("darkslategray", new Integer[] { 47, 79, 79 }); + map.put("darkslategrey", new Integer[] { 47, 79, 79 }); + map.put("darkturquoise", new Integer[] { 0, 206, 209 }); + map.put("darkviolet", new Integer[] { 148, 0, 211 }); + map.put("deeppink", new Integer[] { 255, 20, 147 }); + map.put("deepskyblue", new Integer[] { 0, 191, 255 }); + map.put("dimgray", new Integer[] { 105, 105, 105 }); + map.put("dimgrey", new Integer[] { 105, 105, 105 }); + map.put("dodgerblue", new Integer[] { 30, 144, 255 }); + map.put("firebrick", new Integer[] { 178, 34, 34 }); + map.put("floralwhite", new Integer[] { 255, 250, 240 }); + map.put("forestgreen", new Integer[] { 34, 139, 34 }); + map.put("fuchsia", new Integer[] { 255, 0, 255 }); + map.put("gainsboro", new Integer[] { 220, 220, 220 }); + map.put("ghostwhite", new Integer[] { 248, 248, 255 }); + map.put("gold", new Integer[] { 255, 215, 0 }); + map.put("goldenrod", new Integer[] { 218, 165, 32 }); + map.put("gray", new Integer[] { 128, 128, 128 }); + map.put("green", new Integer[] { 0, 128, 0 }); + map.put("greenyellow", new Integer[] { 173, 255, 47 }); + map.put("grey", new Integer[] { 128, 128, 128 }); + map.put("honeydew", new Integer[] { 240, 255, 240 }); + map.put("hotpink", new Integer[] { 255, 105, 180 }); + map.put("indianred", new Integer[] { 205, 92, 92 }); + map.put("indigo", new Integer[] { 75, 0, 130 }); + map.put("ivory", new Integer[] { 255, 255, 240 }); + map.put("khaki", new Integer[] { 240, 230, 140 }); + map.put("lavender", new Integer[] { 230, 230, 250 }); + map.put("lavenderblush", new Integer[] { 255, 240, 245 }); + map.put("lawngreen", new Integer[] { 124, 252, 0 }); + map.put("lemonchiffon", new Integer[] { 255, 250, 205 }); + map.put("lightblue", new Integer[] { 173, 216, 230 }); + map.put("lightcoral", new Integer[] { 240, 128, 128 }); + map.put("lightcyan", new Integer[] { 224, 255, 255 }); + map.put("lightgoldenrodyellow", new Integer[] { 250, 250, 210 }); + map.put("lightgray", new Integer[] { 211, 211, 211 }); + map.put("lightgreen", new Integer[] { 144, 238, 144 }); + map.put("lightgrey", new Integer[] { 211, 211, 211 }); + map.put("lightpink", new Integer[] { 255, 182, 193 }); + map.put("lightsalmon", new Integer[] { 255, 160, 122 }); + map.put("lightseagreen", new Integer[] { 32, 178, 170 }); + map.put("lightskyblue", new Integer[] { 135, 206, 250 }); + map.put("lightslategray", new Integer[] { 119, 136, 153 }); + map.put("lightslategrey", new Integer[] { 119, 136, 153 }); + map.put("lightsteelblue", new Integer[] { 176, 196, 222 }); + map.put("lightyellow", new Integer[] { 255, 255, 224 }); + map.put("lime", new Integer[] { 0, 255, 0 }); + map.put("limegreen", new Integer[] { 50, 205, 50 }); + map.put("linen", new Integer[] { 250, 240, 230 }); + map.put("magenta", new Integer[] { 255, 0, 255 }); + map.put("maroon", new Integer[] { 128, 0, 0 }); + map.put("mediumaquamarine", new Integer[] { 102, 205, 170 }); + map.put("mediumblue", new Integer[] { 0, 0, 205 }); + map.put("mediumorchid", new Integer[] { 186, 85, 211 }); + map.put("mediumpurple", new Integer[] { 147, 112, 219 }); + map.put("mediumseagreen", new Integer[] { 60, 179, 113 }); + map.put("mediumslateblue", new Integer[] { 123, 104, 238 }); + map.put("mediumspringgreen", new Integer[] { 0, 250, 154 }); + map.put("mediumturquoise", new Integer[] { 72, 209, 204 }); + map.put("mediumvioletred", new Integer[] { 199, 21, 133 }); + map.put("midnightblue", new Integer[] { 25, 25, 112 }); + map.put("mintcream", new Integer[] { 245, 255, 250 }); + map.put("mistyrose", new Integer[] { 255, 228, 225 }); + map.put("moccasin", new Integer[] { 255, 228, 181 }); + map.put("navajowhite", new Integer[] { 255, 222, 173 }); + map.put("navy", new Integer[] { 0, 0, 128 }); + map.put("oldlace", new Integer[] { 253, 245, 230 }); + map.put("olive", new Integer[] { 128, 128, 0 }); + map.put("olivedrab", new Integer[] { 107, 142, 35 }); + map.put("orange", new Integer[] { 255, 165, 0 }); + map.put("orangered", new Integer[] { 255, 69, 0 }); + map.put("orchid", new Integer[] { 218, 112, 214 }); + map.put("palegoldenrod", new Integer[] { 238, 232, 170 }); + map.put("palegreen", new Integer[] { 152, 251, 152 }); + map.put("paleturquoise", new Integer[] { 175, 238, 238 }); + map.put("palevioletred", new Integer[] { 219, 112, 147 }); + map.put("papayawhip", new Integer[] { 255, 239, 213 }); + map.put("peachpuff", new Integer[] { 255, 218, 185 }); + map.put("peru", new Integer[] { 205, 133, 63 }); + map.put("pink", new Integer[] { 255, 192, 203 }); + map.put("plum", new Integer[] { 221, 160, 221 }); + map.put("powderblue", new Integer[] { 176, 224, 230 }); + map.put("purple", new Integer[] { 128, 0, 128 }); + map.put("red", new Integer[] { 255, 0, 0 }); + map.put("rosybrown", new Integer[] { 188, 143, 143 }); + map.put("royalblue", new Integer[] { 65, 105, 225 }); + map.put("saddlebrown", new Integer[] { 139, 69, 19 }); + map.put("salmon", new Integer[] { 250, 128, 114 }); + map.put("sandybrown", new Integer[] { 244, 164, 96 }); + map.put("seagreen", new Integer[] { 46, 139, 87 }); + map.put("seashell", new Integer[] { 255, 245, 238 }); + map.put("sienna", new Integer[] { 160, 82, 45 }); + map.put("silver", new Integer[] { 192, 192, 192 }); + map.put("skyblue", new Integer[] { 135, 206, 235 }); + map.put("slateblue", new Integer[] { 106, 90, 205 }); + map.put("slategray", new Integer[] { 112, 128, 144 }); + map.put("slategrey", new Integer[] { 112, 128, 144 }); + map.put("snow", new Integer[] { 255, 250, 250 }); + map.put("springgreen", new Integer[] { 0, 255, 127 }); + map.put("steelblue", new Integer[] { 70, 130, 180 }); + map.put("tan", new Integer[] { 210, 180, 140 }); + map.put("teal", new Integer[] { 0, 128, 128 }); + map.put("thistle", new Integer[] { 216, 191, 216 }); + map.put("tomato", new Integer[] { 255, 99, 71 }); + map.put("turquoise", new Integer[] { 64, 224, 208 }); + map.put("violet", new Integer[] { 238, 130, 238 }); + map.put("wheat", new Integer[] { 245, 222, 179 }); + map.put("white", new Integer[] { 255, 255, 255 }); + map.put("whitesmoke", new Integer[] { 245, 245, 245 }); + map.put("yellow", new Integer[] { 255, 255, 0 }); + map.put("yellowgreen", new Integer[] { 154, 205, 50 }); + + return map; + } + + /** + * Parse the content, build the list of style ranges and apply them to the + * styled text widget + * + * @throws IOException + */ + public void parse() throws IOException { + if (styledText == null || "".equals(styledText.getText().trim())) { + return; + } + + initBeforeParsing(); + + final String text = styledText.getText().trim(); + final int max = text.length(); + boolean inTag = false; + + for (int i = 0; i < max; i++) { + final char currentChar = text.charAt(i); + if (currentChar == '<') { + inTag = true; + continue; + } else if (currentChar == '>') { + inTag = false; + handleTag(); + currentTag.delete(0, currentTag.length()); + } else { + if (inTag) { + currentTag.append(currentChar); + } else { + currentPosition++; + output.append(currentChar); + } + } + } + styledText.setText(output.toString()); + styledText.setStyleRanges(removeDoublons()); + } + + private StyleRange[] removeDoublons() { + final Iterator mainIt = listOfStyles.iterator(); + while (mainIt.hasNext()) { + final StyleRange current = mainIt.next(); + final Iterator it = listOfStyles.iterator(); + while (it.hasNext()) { + final StyleRange other = it.next(); + if (current == other) { + continue; + } + if (current.start == other.start && current.length == other.length) { + current.fontStyle = current.fontStyle | other.fontStyle; + if (current.font == null) { + current.font = other.font; + } + if (current.foreground == null) { + current.foreground = other.foreground; + } + if (current.background == null) { + current.background = other.background; + } + it.remove(); + } + } + } + + return listOfStyles.toArray(new StyleRange[listOfStyles.size()]); + } + + private void initBeforeParsing() { + output = new StringBuilder(); + currentTag = new StringBuilder(); + listOfStyles.clear(); + stack.clear(); + currentPosition = 0; + } + + private void handleTag() { + final String tag = currentTag.toString().toLowerCase(); + if ("br".equals(tag) || "br/".equals(tag)) { + output.append("\n"); + currentPosition++; + return; + } + + if ("b".equals(tag)) { + processBeginBold(); + return; + } + if ("i".equals(tag)) { + processBeginItalic(); + return; + } + if ("u".equals(tag)) { + processBeginUnderline(); + return; + } + if (tag.startsWith("size=")) { + processBeginSize(); + return; + } + if (tag.startsWith("color=")) { + processBeginColor(); + return; + } + if (tag.startsWith("backgroundcolor=")) { + processBeginBackgroundColor(); + return; + } + + final String[] acceptedClosingTags = new String[] { "/b", "/i", "/u", "/size", "/color", "/backgroundcolor" }; + for (final String closingTag : acceptedClosingTags) { + if (closingTag.equals(tag)) { + processEndTag(closingTag); + return; + } + } + + final String text = "<" + tag + ">"; + output.append(text); + currentPosition += text.length(); + + } + + private void processBeginBold() { + final StyleRange currentStyleRange = new StyleRange(); + currentStyleRange.start = currentPosition; + currentStyleRange.length = 0; + currentStyleRange.fontStyle = SWT.BOLD; + currentStyleRange.data = ""; + stack.push(currentStyleRange); + } + + private void processEndTag(final String expectedTag) { + final StyleRange currentStyleRange = stack.pop(); + final String wholeExpectedTag = "<" + expectedTag + ">"; + if (!wholeExpectedTag.equals(currentStyleRange.data)) { + final StringBuilder sb = new StringBuilder(); + sb.append("Error at position #").append(currentPosition).// + append(" - closing ").// + append(wholeExpectedTag).// + append(" tag found but "). // + append(currentStyleRange.data).// + append(" tag expected !"); + throw new RuntimeException(sb.toString()); + } + currentStyleRange.length = currentPosition - currentStyleRange.start; + listOfStyles.add(currentStyleRange); + + } + + private void processBeginItalic() { + final StyleRange currentStyleRange = new StyleRange(); + currentStyleRange.start = currentPosition; + currentStyleRange.length = 0; + currentStyleRange.fontStyle = SWT.ITALIC; + currentStyleRange.data = ""; + stack.push(currentStyleRange); + } + + private void processBeginUnderline() { + final StyleRange currentStyleRange = new StyleRange(); + currentStyleRange.start = currentPosition; + currentStyleRange.length = 0; + currentStyleRange.fontStyle = SWT.NONE; + currentStyleRange.underline = true; + currentStyleRange.data = ""; + stack.push(currentStyleRange); + } + + private void processBeginSize() { + final StyleRange currentStyleRange = new StyleRange(); + currentStyleRange.start = currentPosition; + currentStyleRange.length = 0; + currentStyleRange.fontStyle = SWT.NONE; + currentStyleRange.font = computeFont(); + currentStyleRange.data = ""; + stack.push(currentStyleRange); + } + + private Font computeFont() { + final String fontSize = currentTag.toString().toLowerCase().replace("size=", ""); + if (fontSize.length() == 0) { + throw new RuntimeException("Argument size is empty !"); + } + int newSize = defaultHeight; + if (fontSize.startsWith("+")) { + final int delta = Integer.valueOf(fontSize.substring(1)); + newSize += delta; + } else if (fontSize.startsWith("-")) { + final int delta = Integer.valueOf(fontSize.substring(1)); + newSize -= delta; + } + + final FontData fd = styledText.getFont().getFontData()[0]; + final Font newFont = new Font(styledText.getDisplay(), fd.getName(), newSize, SWT.NONE); + styledText.addListener(SWT.Dispose, new Listener() { + @Override + public void handleEvent(final Event event) { + newFont.dispose(); + } + }); + return newFont; + } + + private void processBeginColor() { + final StyleRange currentStyleRange = new StyleRange(); + currentStyleRange.start = currentPosition; + currentStyleRange.length = 0; + currentStyleRange.fontStyle = SWT.NONE; + currentStyleRange.foreground = computeColor(); + currentStyleRange.data = ""; + stack.push(currentStyleRange); + } + + private Color computeColor() { + final String fontColor = currentTag.toString().toLowerCase().replace("color=", "").replace("background", ""); + if (fontColor.length() == 0) { + throw new RuntimeException("Argument color is empty !"); + } + + int red, green, blue; + if (fontColor.startsWith("#")) { + final String hexa = fontColor.substring(1); + if (hexa.length() != 6) { + throw new RuntimeException("Argument [" + hexa + "] is not valid !"); + } + try { + red = Integer.parseInt(hexa.substring(0, 2).toLowerCase(), 16); + green = Integer.parseInt(hexa.substring(2, 4).toLowerCase(), 16); + blue = Integer.parseInt(hexa.substring(4, 6).toLowerCase(), 16); + } catch (final NumberFormatException nfe) { + throw new RuntimeException("Argument [" + hexa + "] is not valid !"); + } + } else if (fontColor.indexOf(',') > -1) { + final String[] args = fontColor.split(","); + if (args.length != 3) { + throw new RuntimeException("Argument [" + fontColor + "] is not valid !"); + } + try { + red = Integer.parseInt(args[0]); + green = Integer.parseInt(args[1]); + blue = Integer.parseInt(args[2]); + } catch (final NumberFormatException nfe) { + throw new RuntimeException("Argument [" + fontColor + "] is not valid !"); + } + } else { + final Integer[] rgb = HTML_CODES.get(fontColor.toLowerCase()); + if (rgb == null) { + red = 0; + green = 0; + blue = 0; + } else { + red = rgb[0]; + green = rgb[1]; + blue = rgb[2]; + } + } + final Color color = new Color(styledText.getDisplay(), red, green, blue); + styledText.addListener(SWT.Dispose, e -> { + color.dispose(); + }); + return color; + } + + private void processBeginBackgroundColor() { + final StyleRange currentStyleRange = new StyleRange(); + currentStyleRange.start = currentPosition; + currentStyleRange.length = 0; + currentStyleRange.fontStyle = SWT.NONE; + currentStyleRange.background = computeColor(); + currentStyleRange.data = ""; + stack.push(currentStyleRange); + } + } \ No newline at end of file diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/OpalItem.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/OpalItem.java index 3c0c06044..ac0a30a4f 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/OpalItem.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/OpalItem.java @@ -1,162 +1,162 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.commons; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; - -/** - * Instances of this object are items manipulated by the widgets of the Opal Project. These items are highly customizable, you can set : - *
    - *
  • Background and foreground colors, - *
  • Font - *
  • Image - *
  • Text - *
  • Height - *
- * You can also store data using the setData methods. - * - */ -public abstract class OpalItem { - - private final Map data = new HashMap(); - private Object datum; - private Color background; - private Font font; - private Color foreground; - private Image image; - private String text; - private int height = -1; - - /** - * @return the background color of the item - */ - public Color getBackground() { - return this.background; - } - - /** - * @return the the data stored in this item - */ - public Object getData() { - return this.datum; - } - - /** - * @param key a key - * @return the the data stored in this item associated to this key - */ - public Object getData(final String key) { - return this.data.get(key); - } - - /** - * @return the font of the item - */ - public Font getFont() { - return this.font; - } - - /** - * @return the foreground color of the item - */ - public Color getForeground() { - return this.foreground; - } - - /** - * @return the height of the item - */ - public int getHeight() { - return this.height; - } - - /** - * @return the image stored in this item - */ - public Image getImage() { - return this.image; - } - - /** - * @return the text stored in this item - */ - public String getText() { - return this.text; - } - - /** - * @param background set the background color of this item - */ - public void setBackground(final Color background) { - this.background = background; - } - - /** - * @param font set the font of this item - */ - public void setFont(final Font font) { - this.font = font; - } - - /** - * @param foreground set the foreground color of this item - */ - public void setForeground(final Color foreground) { - this.foreground = foreground; - } - - /** - * @param height set the height of this item - */ - public void setHeight(final int height) { - this.height = height; - } - - /** - * @param image set the image of this item - */ - public void setImage(final Image image) { - this.image = image; - } - - /** - * @param text set the text of this item - */ - public void setText(final String text) { - this.text = text; - } - - /** - * @param data set the data stored in this item - */ - public void setData(final Object data) { - this.datum = data; - } - - /** - * Store a data associated to a given key in this item - * - * @param key key - * @param value value associated to this key - */ - public void setData(final String key, final Object value) { - this.data.put(key, value); - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.commons; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; + +/** + * Instances of this object are items manipulated by the widgets of the Opal Project. These items are highly customizable, you can set : + *
    + *
  • Background and foreground colors, + *
  • Font + *
  • Image + *
  • Text + *
  • Height + *
+ * You can also store data using the setData methods. + * + */ +public abstract class OpalItem { + + private final Map data = new HashMap(); + private Object datum; + private Color background; + private Font font; + private Color foreground; + private Image image; + private String text; + private int height = -1; + + /** + * @return the background color of the item + */ + public Color getBackground() { + return this.background; + } + + /** + * @return the the data stored in this item + */ + public Object getData() { + return this.datum; + } + + /** + * @param key a key + * @return the the data stored in this item associated to this key + */ + public Object getData(final String key) { + return this.data.get(key); + } + + /** + * @return the font of the item + */ + public Font getFont() { + return this.font; + } + + /** + * @return the foreground color of the item + */ + public Color getForeground() { + return this.foreground; + } + + /** + * @return the height of the item + */ + public int getHeight() { + return this.height; + } + + /** + * @return the image stored in this item + */ + public Image getImage() { + return this.image; + } + + /** + * @return the text stored in this item + */ + public String getText() { + return this.text; + } + + /** + * @param background set the background color of this item + */ + public void setBackground(final Color background) { + this.background = background; + } + + /** + * @param font set the font of this item + */ + public void setFont(final Font font) { + this.font = font; + } + + /** + * @param foreground set the foreground color of this item + */ + public void setForeground(final Color foreground) { + this.foreground = foreground; + } + + /** + * @param height set the height of this item + */ + public void setHeight(final int height) { + this.height = height; + } + + /** + * @param image set the image of this item + */ + public void setImage(final Image image) { + this.image = image; + } + + /** + * @param text set the text of this item + */ + public void setText(final String text) { + this.text = text; + } + + /** + * @param data set the data stored in this item + */ + public void setData(final Object data) { + this.datum = data; + } + + /** + * Store a data associated to a given key in this item + * + * @param key key + * @param value value associated to this key + */ + public void setData(final String key, final Object value) { + this.data.put(key, value); + } + +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ReadOnlyStyledText.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ReadOnlyStyledText.java index 6b591e79e..752233b69 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ReadOnlyStyledText.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ReadOnlyStyledText.java @@ -1,69 +1,69 @@ -/******************************************************************************* - * Copyright (c) 2012 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.commons; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.widgets.Composite; - -/** - * Instances of this class are StyledText that are read-only, that means that we - * use it only as a renderer - * - * @see StyledText - */ -public class ReadOnlyStyledText extends StyledText { - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must - * be built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT - * style constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a widget which will be the parent of the new instance - * (cannot be null) - * @param style the style of widget to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - * @see SWT#FULL_SELECTION - * @see SWT#MULTI - * @see SWT#SINGLE - * @see #getStyle - * @see StyledText - */ - public ReadOnlyStyledText(final Composite parent, final int style) { - super(parent, style | SWT.WRAP | SWT.READ_ONLY); - addListener(SWT.MouseEnter, e-> setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW))); - setCaret(null); - addListener(SWT.Selection, e -> { - setSelection(0, 0); - }); - } -} +/******************************************************************************* + * Copyright (c) 2012 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.commons; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.widgets.Composite; + +/** + * Instances of this class are StyledText that are read-only, that means that we + * use it only as a renderer + * + * @see StyledText + */ +public class ReadOnlyStyledText extends StyledText { + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance + * (cannot be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see SWT#FULL_SELECTION + * @see SWT#MULTI + * @see SWT#SINGLE + * @see #getStyle + * @see StyledText + */ + public ReadOnlyStyledText(final Composite parent, final int style) { + super(parent, style | SWT.WRAP | SWT.READ_ONLY); + addListener(SWT.MouseEnter, e-> setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW))); + setCaret(null); + addListener(SWT.Selection, e -> { + setSelection(0, 0); + }); + } +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ReflectionUtils.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ReflectionUtils.java index b4b0a080f..61d92de35 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ReflectionUtils.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ReflectionUtils.java @@ -1,62 +1,62 @@ -/******************************************************************************* - * Copyright (c) 2019 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.commons; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class ReflectionUtils { - /** - * Call a method using introspection (so ones can call a private or protected method) - * @param object object on which the method will be called - * @param methodName method name - * @param args arguments of this method (can be null) - * @return the value returned by this method (if this method returns a value) - */ - public static Object callMethod(final Object object, final String methodName, final Object... args) { - if (object == null) { - return null; - } - final Class[] array = new Class[args == null ? 0 : args.length]; - int index = 0; - if (args != null) { - for (final Object o : args) { - array[index++] = o == null ? Object.class : o.getClass(); - } - } - - return callMethodWithClassType(object, methodName, array, args); - } - - private static Object callMethodWithClassType(final Object object, final String methodName, final Class[] array, final Object... args) { - Class currentClass = object.getClass(); - Method method = null; - while (currentClass != null) { - try { - method = currentClass.getDeclaredMethod(methodName, array); - break; - } catch (final NoSuchMethodException nsme) { - currentClass = currentClass.getSuperclass(); - } - } - - try { - method.setAccessible(true); - return method.invoke(object, args); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - e.printStackTrace(); - return null; - } - } -} +/******************************************************************************* + * Copyright (c) 2019 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.commons; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class ReflectionUtils { + /** + * Call a method using introspection (so ones can call a private or protected method) + * @param object object on which the method will be called + * @param methodName method name + * @param args arguments of this method (can be null) + * @return the value returned by this method (if this method returns a value) + */ + public static Object callMethod(final Object object, final String methodName, final Object... args) { + if (object == null) { + return null; + } + final Class[] array = new Class[args == null ? 0 : args.length]; + int index = 0; + if (args != null) { + for (final Object o : args) { + array[index++] = o == null ? Object.class : o.getClass(); + } + } + + return callMethodWithClassType(object, methodName, array, args); + } + + private static Object callMethodWithClassType(final Object object, final String methodName, final Class[] array, final Object... args) { + Class currentClass = object.getClass(); + Method method = null; + while (currentClass != null) { + try { + method = currentClass.getDeclaredMethod(methodName, array); + break; + } catch (final NoSuchMethodException nsme) { + currentClass = currentClass.getSuperclass(); + } + } + + try { + method.setAccessible(true); + return method.invoke(object, args); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ResourceManager.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ResourceManager.java index 45c836e1e..549e8d843 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ResourceManager.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/ResourceManager.java @@ -1,90 +1,90 @@ -package org.eclipse.nebula.widgets.opal.commons; - -import java.util.ResourceBundle; - -public class ResourceManager { - private static final ResourceBundle RSC = ResourceBundle - .getBundle(ResourceManager.class.getPackage().getName() + "/resources/opal"); - - public static final String OK = "Ok"; - public static final String CANCEL = "Cancel"; - public static final String CLOSE = "Close"; - public static final String YES = "Yes"; - public static final String NO = "No"; - - public static final String MEGABYTES = "megabytes"; - public static final String PERFORM_GC = "performGC"; - - public static final String LOGIN = "login"; - public static final String NAME = "name"; - public static final String PASSWORD = "password"; - public static final String REMEMBER_PASSWORD = "rememberPassword"; - public static final String LOGIN_FAILED = "loginFailed"; - - public static final String INPUT = "Input"; - public static final String APPLICATION_ERROR = "ApplicationError"; - public static final String INFORMATION = "Information"; - public static final String WARNING = "Warning"; - public static final String CHOICE = "Choice"; - public static final String EXCEPTION = "Exception"; - public static final String SELECT = "Select"; - public static final String FEWER_DETAILS = "FewerDetails"; - public static final String MORE_DETAILS = "MoreDetails"; - - public static final String TIP_OF_THE_DAY = "tipOfTheDay"; - public static final String DID_YOU_KNOW = "didYouKnow"; - public static final String SHOW_TIP_AT_STARTUP = "showTipAtStartup"; - public static final String PREVIOUS_TIP = "previousTip"; - public static final String NEXT_TIP = "nextTip"; - - public static final String CHOOSE = "choose"; - public static final String PREFERENCES = "preferences"; - public static final String VALID_URL = "validURL"; - public static final String CHOOSE_DIRECTORY = "chooseDirectory"; - public static final String ITALIC = "italic"; - public static final String BOLD = "bold"; - - public static final String CATEGORY_SHORT_DESCRIPTION = "category.shortDescription"; - public static final String DESCRIPTION_SHORT_DESCRIPTION = "description.shortDescription"; - public static final String SORT_SHORT_DESCRIPTION = "sort.shortDescription"; - public static final String PROPERTY = "property"; - public static final String VALUE = "value"; - public static final String EDIT_PROPERTY = "editProperty"; - public static final String WIDTH = "width"; - public static final String HEIGHT = "height"; - public static final String TOP = "top"; - public static final String BOTTOM = "bottom"; - public static final String LEFT = "left"; - public static final String RIGHT = "right"; - public static final String ERASE_PROPERTY = "eraseProperty"; - - public static final String PHYSICAL_MEMORY = "physicalMemory"; - public static final String HEAP_MEMORY = "heapMemory"; - public static final String THREADS = "threads"; - public static final String CPU_USAGE = "cpuUsage"; - public static final String PEAK = "peak"; - public static final String MB = "mb"; - - public static final String CALCULATOR_DIVIDE_BY_ZERO = "calculator.dividebyzero"; - public static final String CALCULATOR_INVALID_VALUE = "calculator.invalid"; - - public static final String MULTICHOICE_MESSAGE = "multichoice.message"; - public static final String MULTICHOICE_MESSAGE_PLURAL = "multichoice.message.plural"; - - public static final String APPLY = "apply"; - - public static final String SELECT_ALL = "selectAll"; - public static final String DESELECT_ALL = "deselectAll"; - - /** - * Get a translated label - * - * @param key - * key to get - * @return the translated value of the key - */ - public static String getLabel(final String key) { - return RSC.getString(key); - } - -} +package org.eclipse.nebula.widgets.opal.commons; + +import java.util.ResourceBundle; + +public class ResourceManager { + private static final ResourceBundle RSC = ResourceBundle + .getBundle(ResourceManager.class.getPackage().getName() + "/resources/opal"); + + public static final String OK = "Ok"; + public static final String CANCEL = "Cancel"; + public static final String CLOSE = "Close"; + public static final String YES = "Yes"; + public static final String NO = "No"; + + public static final String MEGABYTES = "megabytes"; + public static final String PERFORM_GC = "performGC"; + + public static final String LOGIN = "login"; + public static final String NAME = "name"; + public static final String PASSWORD = "password"; + public static final String REMEMBER_PASSWORD = "rememberPassword"; + public static final String LOGIN_FAILED = "loginFailed"; + + public static final String INPUT = "Input"; + public static final String APPLICATION_ERROR = "ApplicationError"; + public static final String INFORMATION = "Information"; + public static final String WARNING = "Warning"; + public static final String CHOICE = "Choice"; + public static final String EXCEPTION = "Exception"; + public static final String SELECT = "Select"; + public static final String FEWER_DETAILS = "FewerDetails"; + public static final String MORE_DETAILS = "MoreDetails"; + + public static final String TIP_OF_THE_DAY = "tipOfTheDay"; + public static final String DID_YOU_KNOW = "didYouKnow"; + public static final String SHOW_TIP_AT_STARTUP = "showTipAtStartup"; + public static final String PREVIOUS_TIP = "previousTip"; + public static final String NEXT_TIP = "nextTip"; + + public static final String CHOOSE = "choose"; + public static final String PREFERENCES = "preferences"; + public static final String VALID_URL = "validURL"; + public static final String CHOOSE_DIRECTORY = "chooseDirectory"; + public static final String ITALIC = "italic"; + public static final String BOLD = "bold"; + + public static final String CATEGORY_SHORT_DESCRIPTION = "category.shortDescription"; + public static final String DESCRIPTION_SHORT_DESCRIPTION = "description.shortDescription"; + public static final String SORT_SHORT_DESCRIPTION = "sort.shortDescription"; + public static final String PROPERTY = "property"; + public static final String VALUE = "value"; + public static final String EDIT_PROPERTY = "editProperty"; + public static final String WIDTH = "width"; + public static final String HEIGHT = "height"; + public static final String TOP = "top"; + public static final String BOTTOM = "bottom"; + public static final String LEFT = "left"; + public static final String RIGHT = "right"; + public static final String ERASE_PROPERTY = "eraseProperty"; + + public static final String PHYSICAL_MEMORY = "physicalMemory"; + public static final String HEAP_MEMORY = "heapMemory"; + public static final String THREADS = "threads"; + public static final String CPU_USAGE = "cpuUsage"; + public static final String PEAK = "peak"; + public static final String MB = "mb"; + + public static final String CALCULATOR_DIVIDE_BY_ZERO = "calculator.dividebyzero"; + public static final String CALCULATOR_INVALID_VALUE = "calculator.invalid"; + + public static final String MULTICHOICE_MESSAGE = "multichoice.message"; + public static final String MULTICHOICE_MESSAGE_PLURAL = "multichoice.message.plural"; + + public static final String APPLY = "apply"; + + public static final String SELECT_ALL = "selectAll"; + public static final String DESELECT_ALL = "deselectAll"; + + /** + * Get a translated label + * + * @param key + * key to get + * @return the translated value of the key + */ + public static String getLabel(final String key) { + return RSC.getString(key); + } + +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/SelectionListenerUtil.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/SelectionListenerUtil.java index 661fb9549..7c265f40d 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/SelectionListenerUtil.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/SelectionListenerUtil.java @@ -1,104 +1,104 @@ -/******************************************************************************* - * Copyright (c) 2021 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.commons; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.TypedListener; - -public class SelectionListenerUtil { - /** - * Add a SelectionListener to a given Control - * - * @param control control on which the selection listener is added - * @param listener listener to add - */ - public static void addSelectionListener(final Control control, final SelectionListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - TypedListener typedListener = new TypedListener(listener); - control.addListener(SWT.Selection, typedListener); - } - - /** - * Remove a SelectionListener of a given Control - * - * @param control control on which the selection listener is removed - * @param listener listener to remove - */ - public static void removeSelectionListener(final Control control, final SelectionListener listener) { - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - final Listener[] listeners = control.getListeners(SWT.Selection); - for (Listener l : listeners) { - if (l instanceof TypedListener) { - TypedListener typedListener = (TypedListener) l; - if (typedListener.getEventListener() == listener) { - ReflectionUtils.callMethod(control, "removeListener", SWT.Selection, ((TypedListener) l).getEventListener()); - return; - } - } - } - } - - /** - * Fire the selection listeners of a given control - * - * @param control the control that fires the event - * @param sourceEvent mouse event - * @return true if the selection could be changed, false otherwise - */ - public static boolean fireSelectionListeners(final Control control, final Event sourceEvent) { - return fireSelectionListenersEvent(control, sourceEvent, SWT.Selection); - } - - /** - * Fire the default selection listeners of a given control - * - * @param control the control that fires the event - * @param sourceEvent mouse event - * @return true if the selection could be changed, false otherwise - */ - public static boolean fireDefaultSelectionListeners(final Control control, final Event sourceEvent) { - return fireSelectionListenersEvent(control, sourceEvent, SWT.DefaultSelection); - } - - private static boolean fireSelectionListenersEvent(final Control control, final Event sourceEvent, int type) { - Listener[] listeners = control.getListeners(SWT.Selection); - for(final Listener listener : listeners) { - final Event event = new Event(); - - event.button = sourceEvent==null?1:sourceEvent.button; - event.display = control.getDisplay(); - event.item = null; - event.widget = control; - event.data = sourceEvent == null ? null : sourceEvent.data; - event.time = sourceEvent == null ? 0 : sourceEvent.time; - event.x = sourceEvent == null ? 0 : sourceEvent.x; - event.y = sourceEvent == null ? 0 : sourceEvent.y; - event.type = type; - - listener.handleEvent(event); - if (!event.doit) { - return false; - } - } - return true; - } -} +/******************************************************************************* + * Copyright (c) 2021 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.commons; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.TypedListener; + +public class SelectionListenerUtil { + /** + * Add a SelectionListener to a given Control + * + * @param control control on which the selection listener is added + * @param listener listener to add + */ + public static void addSelectionListener(final Control control, final SelectionListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + TypedListener typedListener = new TypedListener(listener); + control.addListener(SWT.Selection, typedListener); + } + + /** + * Remove a SelectionListener of a given Control + * + * @param control control on which the selection listener is removed + * @param listener listener to remove + */ + public static void removeSelectionListener(final Control control, final SelectionListener listener) { + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + final Listener[] listeners = control.getListeners(SWT.Selection); + for (Listener l : listeners) { + if (l instanceof TypedListener) { + TypedListener typedListener = (TypedListener) l; + if (typedListener.getEventListener() == listener) { + ReflectionUtils.callMethod(control, "removeListener", SWT.Selection, ((TypedListener) l).getEventListener()); + return; + } + } + } + } + + /** + * Fire the selection listeners of a given control + * + * @param control the control that fires the event + * @param sourceEvent mouse event + * @return true if the selection could be changed, false otherwise + */ + public static boolean fireSelectionListeners(final Control control, final Event sourceEvent) { + return fireSelectionListenersEvent(control, sourceEvent, SWT.Selection); + } + + /** + * Fire the default selection listeners of a given control + * + * @param control the control that fires the event + * @param sourceEvent mouse event + * @return true if the selection could be changed, false otherwise + */ + public static boolean fireDefaultSelectionListeners(final Control control, final Event sourceEvent) { + return fireSelectionListenersEvent(control, sourceEvent, SWT.DefaultSelection); + } + + private static boolean fireSelectionListenersEvent(final Control control, final Event sourceEvent, int type) { + Listener[] listeners = control.getListeners(SWT.Selection); + for(final Listener listener : listeners) { + final Event event = new Event(); + + event.button = sourceEvent==null?1:sourceEvent.button; + event.display = control.getDisplay(); + event.item = null; + event.widget = control; + event.data = sourceEvent == null ? null : sourceEvent.data; + event.time = sourceEvent == null ? 0 : sourceEvent.time; + event.x = sourceEvent == null ? 0 : sourceEvent.x; + event.y = sourceEvent == null ? 0 : sourceEvent.y; + event.type = type; + + listener.handleEvent(event); + if (!event.doit) { + return false; + } + } + return true; + } +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/SimpleSelectionAdapter.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/SimpleSelectionAdapter.java index 6ebda824b..ecb01d6eb 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/SimpleSelectionAdapter.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/SimpleSelectionAdapter.java @@ -1,50 +1,50 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.opal.commons; - -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; - -/** - * This class is an adapter for the SelectionListener. Both behaviours (DefaultSelected and Selected) are doing the same thing - */ -public abstract class SimpleSelectionAdapter implements SelectionListener { - - /** - * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetDefaultSelected(final SelectionEvent e) { - this.handle(e); - - } - - /** - * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetSelected(final SelectionEvent e) { - this.handle(e); - - } - - /** - * Sent when selection occurs in the control. - * - * @param e - an event containing information about the selection - */ - public abstract void handle(SelectionEvent e); - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.opal.commons; + +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; + +/** + * This class is an adapter for the SelectionListener. Both behaviours (DefaultSelected and Selected) are doing the same thing + */ +public abstract class SimpleSelectionAdapter implements SelectionListener { + + /** + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetDefaultSelected(final SelectionEvent e) { + this.handle(e); + + } + + /** + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + this.handle(e); + + } + + /** + * Sent when selection occurs in the control. + * + * @param e - an event containing information about the selection + */ + public abstract void handle(SelectionEvent e); + +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/StringUtil.java b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/StringUtil.java index c72ddfc4f..5bd50179f 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/StringUtil.java +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/StringUtil.java @@ -1,89 +1,89 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.commons; - -import java.io.PrintWriter; -import java.io.StringWriter; - -/** - * This class provides useful String manipulation methods - * - */ -public class StringUtil { - - /** - * Returns a "safe" string representation. If source is null, return an - * empty string - * - * @param source source string - * @return the string representation of the source (without space) if the - * source is not null, or an empty string otherwise - */ - public static String safeToString(final Object source) { - return source == null ? "" : source.toString().trim(); - } - - /** - * Check if a string is empty or null - * - * @param source source string - * @return true is the string is empty or null, - * false otherwise - */ - public static boolean isEmpty(final String source) { - return source == null || source.trim().isEmpty(); - } - - /** - * Converts exception stack trace as string - * - * @param exception exception to convert - * @return a string that contains the exception - */ - public static final String stackStraceAsString(final Throwable exception) { - final StringWriter stringWriter = new StringWriter(); - exception.printStackTrace(new PrintWriter(stringWriter)); - return stringWriter.toString(); - } - - /** - * Insert a string in a middle of another string - * - * @param source source string - * @param newEntry string to insert into source - * @param position position to insert source - * @return the new string - */ - public static String insertString(final String source, final String newEntry, final int position) { - final StringBuilder sb = new StringBuilder(); - sb.append(source.substring(0, position)).append(newEntry).append(source.substring(position)); - return sb.toString(); - } - - /** - * Remove a character in a String - * - * @param source source string - * @param position position of the character to remove - * @return the string without the character - */ - public static String removeCharAt(final String source, final int position) { - final StringBuilder sb = new StringBuilder(); - if (position == source.length()) { - return source; - } - sb.append(source.substring(0, position)).append(source.substring(position + 1)); - return sb.toString(); - } -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.commons; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * This class provides useful String manipulation methods + * + */ +public class StringUtil { + + /** + * Returns a "safe" string representation. If source is null, return an + * empty string + * + * @param source source string + * @return the string representation of the source (without space) if the + * source is not null, or an empty string otherwise + */ + public static String safeToString(final Object source) { + return source == null ? "" : source.toString().trim(); + } + + /** + * Check if a string is empty or null + * + * @param source source string + * @return true is the string is empty or null, + * false otherwise + */ + public static boolean isEmpty(final String source) { + return source == null || source.trim().isEmpty(); + } + + /** + * Converts exception stack trace as string + * + * @param exception exception to convert + * @return a string that contains the exception + */ + public static final String stackStraceAsString(final Throwable exception) { + final StringWriter stringWriter = new StringWriter(); + exception.printStackTrace(new PrintWriter(stringWriter)); + return stringWriter.toString(); + } + + /** + * Insert a string in a middle of another string + * + * @param source source string + * @param newEntry string to insert into source + * @param position position to insert source + * @return the new string + */ + public static String insertString(final String source, final String newEntry, final int position) { + final StringBuilder sb = new StringBuilder(); + sb.append(source.substring(0, position)).append(newEntry).append(source.substring(position)); + return sb.toString(); + } + + /** + * Remove a character in a String + * + * @param source source string + * @param position position of the character to remove + * @return the string without the character + */ + public static String removeCharAt(final String source, final int position) { + final StringBuilder sb = new StringBuilder(); + if (position == source.length()) { + return source; + } + sb.append(source.substring(0, position)).append(source.substring(position + 1)); + return sb.toString(); + } +} diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal.properties index e6440d5e1..16d1994ac 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal.properties @@ -1,61 +1,61 @@ -Ok=OK -Cancel=Cancel -Close=Close -Yes=Yes -No=No -MoreDetails=More Details -FewerDetails=Fewer Details -Details=Details -Information=Information -Error=Error -Question=Question -Warning=Warning -Exception=Exception -Choice=Choice -Select=Select -Input=Input -ApplicationError=Application Error -megabytes=Mb -performGC=Perform GC -login=Login -name=Name -password=Password -rememberPassword=Remember password -loginFailed=Login failed -tipOfTheDay=Tip of the day -didYouKnow=Did you know... -showTipAtStartup=Show Tip at startup -previousTip=< Previous Tip -nextTip=Next Tip > -choose=Choose -preferences=Preferences -validURL=Please enter a valid URL -chooseDirectory=Please choose a directory -bold=bold -italic=italic -category.shortDescription = Toggle between Category view and Flat list view -description.shortDescription = Show/Hide the Description pane -sort.shortDescription = Sort Properties and Categories by Name -property=Property -value=Value -editProperty=Edit property -width=Width -height=Height -top=Top -bottom=Bottom -left=Left -right=Right -eraseProperty=Erase the value of the property -physicalMemory=Physical Memory -heapMemory=Heap Memory -threads=Threads -cpuUsage=CPU Usage -peak=Peak -mb=MB -calculator.dividebyzero=Cannot divide by zero ! -calculator.invalid=Invalid input for function ! -multichoice.message=The entry %s is invalid, please check it! -multichoice.message.plural=The entries %s are invalid, please check it! -apply=Apply -selectAll=Select All +Ok=OK +Cancel=Cancel +Close=Close +Yes=Yes +No=No +MoreDetails=More Details +FewerDetails=Fewer Details +Details=Details +Information=Information +Error=Error +Question=Question +Warning=Warning +Exception=Exception +Choice=Choice +Select=Select +Input=Input +ApplicationError=Application Error +megabytes=Mb +performGC=Perform GC +login=Login +name=Name +password=Password +rememberPassword=Remember password +loginFailed=Login failed +tipOfTheDay=Tip of the day +didYouKnow=Did you know... +showTipAtStartup=Show Tip at startup +previousTip=< Previous Tip +nextTip=Next Tip > +choose=Choose +preferences=Preferences +validURL=Please enter a valid URL +chooseDirectory=Please choose a directory +bold=bold +italic=italic +category.shortDescription = Toggle between Category view and Flat list view +description.shortDescription = Show/Hide the Description pane +sort.shortDescription = Sort Properties and Categories by Name +property=Property +value=Value +editProperty=Edit property +width=Width +height=Height +top=Top +bottom=Bottom +left=Left +right=Right +eraseProperty=Erase the value of the property +physicalMemory=Physical Memory +heapMemory=Heap Memory +threads=Threads +cpuUsage=CPU Usage +peak=Peak +mb=MB +calculator.dividebyzero=Cannot divide by zero ! +calculator.invalid=Invalid input for function ! +multichoice.message=The entry %s is invalid, please check it! +multichoice.message.plural=The entries %s are invalid, please check it! +apply=Apply +selectAll=Select All deselectAll=Deselect All \ No newline at end of file diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_de_DE.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_de_DE.properties index b91422be1..718fb91ca 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_de_DE.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_de_DE.properties @@ -1,61 +1,61 @@ -OK=OK -Cancel=Abbrechen -Close=Schließen -Yes=Ja -No=Nein -MoreDetails=Weitere Details -FewerDetails=Weniger Details -Details=Details -Information=Information -Error=Fehler -Question=Frage -Warning=Warnung -Exception=Ausnahme -Choice=Auswahl -Select=Auswählen -Input=Eingabe -ApplicationError=Application Error -megabytes=Mb -performGC=Perform GC -login=Login -name=Name -password=Passwort -rememberPassword=Passwort merken -loginFailed=Login failed -tipOfTheDay=Tip of the day -didYouKnow=Did you know... -showTipAtStartup=Show Tip at startup -previousTip=< Previous Tip -nextTip=Next Tip > -choose=Choose -preferences=Preferences -validURL=Please enter a valid URL -chooseDirectory=Please choose a directory -bold=bold -italic=italic -category.shortDescription = Toggle between Category view and Flat list view -description.shortDescription = Show/Hide the Description pane -sort.shortDescription = Sort Properties and Categories by Name -property=Property -value=Value -editProperty=Edit property -width=Width -height=Height -top=Top -bottom=Bottom -left=Left -right=Right -eraseProperty=Erase the value of the property -physicalMemory=Physical Memory -heapMemory=Heap Memory -threads=Threads -cpuUsage=CPU Usage -peak=Peak -mb=MB -calculator.dividebyzero=Cannot divide by zero ! -calculator.invalid=Invalid input for function ! -multichoice.message=The entry %s is invalid, please check it! -multichoice.message.plural=The entries %s are invalid, please check it! -apply=Anwenden -selectAll=Wählen Sie Alle +OK=OK +Cancel=Abbrechen +Close=Schließen +Yes=Ja +No=Nein +MoreDetails=Weitere Details +FewerDetails=Weniger Details +Details=Details +Information=Information +Error=Fehler +Question=Frage +Warning=Warnung +Exception=Ausnahme +Choice=Auswahl +Select=Auswählen +Input=Eingabe +ApplicationError=Application Error +megabytes=Mb +performGC=Perform GC +login=Login +name=Name +password=Passwort +rememberPassword=Passwort merken +loginFailed=Login failed +tipOfTheDay=Tip of the day +didYouKnow=Did you know... +showTipAtStartup=Show Tip at startup +previousTip=< Previous Tip +nextTip=Next Tip > +choose=Choose +preferences=Preferences +validURL=Please enter a valid URL +chooseDirectory=Please choose a directory +bold=bold +italic=italic +category.shortDescription = Toggle between Category view and Flat list view +description.shortDescription = Show/Hide the Description pane +sort.shortDescription = Sort Properties and Categories by Name +property=Property +value=Value +editProperty=Edit property +width=Width +height=Height +top=Top +bottom=Bottom +left=Left +right=Right +eraseProperty=Erase the value of the property +physicalMemory=Physical Memory +heapMemory=Heap Memory +threads=Threads +cpuUsage=CPU Usage +peak=Peak +mb=MB +calculator.dividebyzero=Cannot divide by zero ! +calculator.invalid=Invalid input for function ! +multichoice.message=The entry %s is invalid, please check it! +multichoice.message.plural=The entries %s are invalid, please check it! +apply=Anwenden +selectAll=Wählen Sie Alle deselectAll=Alle abwählen \ No newline at end of file diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_es_ES.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_es_ES.properties index 31df85544..5f41a47a4 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_es_ES.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_es_ES.properties @@ -1,61 +1,61 @@ -Ok=OK -Cancel=Cancelar -Close=Cerrar -Yes=Sí -No=No -MoreDetails=Más detalles -FewerDetails=Pocos detalles -Details=Detalles -Information=Información -Error=Error -Question=Pregunta -Warning=Advertencia -Exception=Excepción -Choice=Elección -Select=Seleccione -Input=Entrada -ApplicationError=Error de la aplicación -megabytes=Mb -performGC=Ejecutar GC -login=Conexión -name=Nombre -password=Contraseña -rememberPassword=Recordar contraseña -loginFailed=Fallo en la conexión -tipOfTheDay=Consejo diario -didYouKnow=Sabias que...? -showTipAtStartup=Mostrar consejos al inicio -previousTip= -choose=Elegir -preferences=Preferencias -validURL=Por favor, introduzca una URL válida -chooseDirectory=Por favor, escoge un directorio -bold=negrita -italic=cursiva -category.shortDescription = Toggle between Category view and Flat list view -description.shortDescription = Show/Hide the Description pane -sort.shortDescription = Sort Properties and Categories by Name -property=Property -value=Value -editProperty=Edit property -width=Width -height=Height -top=Top -bottom=Bottom -left=Left -right=Right -eraseProperty=Erase the value of the property -physicalMemory=Physical Memory -heapMemory=Heap Memory -threads=Threads -cpuUsage=CPU Usage -peak=Peak -mb=MB -calculator.dividebyzero=Cannot divide by zero ! -calculator.invalid=Invalid input for function ! -multichoice.message=The entry %s is invalid, please check it! -multichoice.message.plural=The entries %s are invalid, please check it! -apply=Aplicar -selectAll=Seleccionar todo +Ok=OK +Cancel=Cancelar +Close=Cerrar +Yes=Sí +No=No +MoreDetails=Más detalles +FewerDetails=Pocos detalles +Details=Detalles +Information=Información +Error=Error +Question=Pregunta +Warning=Advertencia +Exception=Excepción +Choice=Elección +Select=Seleccione +Input=Entrada +ApplicationError=Error de la aplicación +megabytes=Mb +performGC=Ejecutar GC +login=Conexión +name=Nombre +password=Contraseña +rememberPassword=Recordar contraseña +loginFailed=Fallo en la conexión +tipOfTheDay=Consejo diario +didYouKnow=Sabias que...? +showTipAtStartup=Mostrar consejos al inicio +previousTip= +choose=Elegir +preferences=Preferencias +validURL=Por favor, introduzca una URL válida +chooseDirectory=Por favor, escoge un directorio +bold=negrita +italic=cursiva +category.shortDescription = Toggle between Category view and Flat list view +description.shortDescription = Show/Hide the Description pane +sort.shortDescription = Sort Properties and Categories by Name +property=Property +value=Value +editProperty=Edit property +width=Width +height=Height +top=Top +bottom=Bottom +left=Left +right=Right +eraseProperty=Erase the value of the property +physicalMemory=Physical Memory +heapMemory=Heap Memory +threads=Threads +cpuUsage=CPU Usage +peak=Peak +mb=MB +calculator.dividebyzero=Cannot divide by zero ! +calculator.invalid=Invalid input for function ! +multichoice.message=The entry %s is invalid, please check it! +multichoice.message.plural=The entries %s are invalid, please check it! +apply=Aplicar +selectAll=Seleccionar todo deselectAll=Deseleccionar todo \ No newline at end of file diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_fr_FR.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_fr_FR.properties index 9cf31151b..cf9f92341 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_fr_FR.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_fr_FR.properties @@ -1,61 +1,61 @@ -OK=OK -Cancel=Annuler -Close=Fermer -Yes=Oui -No=Non -MoreDetails=Plus de d\u00e9tails -FewerDetails=Moins de d\u00e9tails -Details=D\u00e9tails -Information=Information -Error=Erreur -Question=Question -Warning=Avertissement -Exception=Exception -Choice=Choix -Select=S\u00e9lection -Input=Entr\u00e9e -ApplicationError=Erreur applicative -megabytes=Mo -performGC=Lancer le ramasse-miettes (GC) -login=Identification -name=Nom -password=Mot de passe -rememberPassword=Se souvenir de mon mot de passe -loginFailed=Echec de l'authentification -tipOfTheDay=Astuce du jour -didYouKnow=Le savez-vous ? -showTipAtStartup=Afficher les astuces au d\u00e9marrage -previousTip=< Astuce pr\u00e9c\u00e9dente -nextTip=Astuce suivante > -choose=Choisir -preferences=Pr\u00e9f\u00e9rences -validURL=Merci de saisir une URL valide s'il vous plait -chooseDirectory=Veuillez choisir un r\u00e9pertoire -bold=gras -italic=italique -category.shortDescription = Alterner entre vue par Cat\u00e9gorie et liste -description.shortDescription = Afficher/Cacher le panneau de Description -sort.shortDescription = Trier les Propri\u00e9t\u00e9s et Cat\u00e9gories par Nom -property=Propri\u00e9t\u00e9 -value=Valeur -editProperty=Edition de la valeur de la propri\u00e9t\u00e9 -width=Largeur -height=Hauteur -top=Haut -bottom=Bas -left=Gauche -right=Droite -eraseProperty=Efface la valeur de cette propri\u00e9t\u00e9 -physicalMemory=M\u00e9moire physique -heapMemory=M\u00e9moire Heap -threads=Threads -cpuUsage=Utilisation CPU -peak=Max -mb=Mo -calculator.dividebyzero=Division par z\u00e9ro impossible ! -calculator.invalid=Entr\u00e9e invalide pour cette fonction ! -multichoice.message=L'entr\u00e9e %s n'est pas valide, merci de la v\u00e9rifier ! -multichoice.message.plural=Les entr\u00e9es %s ne sont pas valides, merci de les v\u00e9rifier! -apply=Appliquer -selectAll=Tout s\u00e9lectionner +OK=OK +Cancel=Annuler +Close=Fermer +Yes=Oui +No=Non +MoreDetails=Plus de d\u00e9tails +FewerDetails=Moins de d\u00e9tails +Details=D\u00e9tails +Information=Information +Error=Erreur +Question=Question +Warning=Avertissement +Exception=Exception +Choice=Choix +Select=S\u00e9lection +Input=Entr\u00e9e +ApplicationError=Erreur applicative +megabytes=Mo +performGC=Lancer le ramasse-miettes (GC) +login=Identification +name=Nom +password=Mot de passe +rememberPassword=Se souvenir de mon mot de passe +loginFailed=Echec de l'authentification +tipOfTheDay=Astuce du jour +didYouKnow=Le savez-vous ? +showTipAtStartup=Afficher les astuces au d\u00e9marrage +previousTip=< Astuce pr\u00e9c\u00e9dente +nextTip=Astuce suivante > +choose=Choisir +preferences=Pr\u00e9f\u00e9rences +validURL=Merci de saisir une URL valide s'il vous plait +chooseDirectory=Veuillez choisir un r\u00e9pertoire +bold=gras +italic=italique +category.shortDescription = Alterner entre vue par Cat\u00e9gorie et liste +description.shortDescription = Afficher/Cacher le panneau de Description +sort.shortDescription = Trier les Propri\u00e9t\u00e9s et Cat\u00e9gories par Nom +property=Propri\u00e9t\u00e9 +value=Valeur +editProperty=Edition de la valeur de la propri\u00e9t\u00e9 +width=Largeur +height=Hauteur +top=Haut +bottom=Bas +left=Gauche +right=Droite +eraseProperty=Efface la valeur de cette propri\u00e9t\u00e9 +physicalMemory=M\u00e9moire physique +heapMemory=M\u00e9moire Heap +threads=Threads +cpuUsage=Utilisation CPU +peak=Max +mb=Mo +calculator.dividebyzero=Division par z\u00e9ro impossible ! +calculator.invalid=Entr\u00e9e invalide pour cette fonction ! +multichoice.message=L'entr\u00e9e %s n'est pas valide, merci de la v\u00e9rifier ! +multichoice.message.plural=Les entr\u00e9es %s ne sont pas valides, merci de les v\u00e9rifier! +apply=Appliquer +selectAll=Tout s\u00e9lectionner deselectAll=Tout d\u00e9selectionner \ No newline at end of file diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_it_IT.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_it_IT.properties index 1171340f6..438918c0b 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_it_IT.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_it_IT.properties @@ -1,61 +1,61 @@ -OK=OK -Cancel=Annulla -Close=Chiudi -Yes=Si -No=No -MoreDetails=Pi\u00F9 Dettagli -FewerDetails=Meno Dettagli -Details=Dettagli -Information=Informazione -Error=Errore -Question=Domanda -Warning=Avvertenza -Exception=Eccezione -Choice=Scelta -Select=Seleziona -Input=Input -ApplicationError=Errore di applicazione -megabytes=Mb -performGC=Perform GC -login=Accesso -name=Nome -password=Password -rememberPassword=Remember password -loginFailed=Login failed -tipOfTheDay=Tip of the day -didYouKnow=Did you know... -showTipAtStartup=Show Tip at startup -previousTip=< Previous Tip -nextTip=Next Tip > -choose=Choose -preferences=Preferences -validURL=Please enter a valid URL -chooseDirectory=Please choose a directory -bold=bold -italic=italic -category.shortDescription = Toggle between Category view and Flat list view -description.shortDescription = Show/Hide the Description pane -sort.shortDescription = Sort Properties and Categories by Name -property=Property -value=Value -editProperty=Edit property -width=Width -height=Height -top=Top -bottom=Bottom -left=Left -right=Right -eraseProperty=Erase the value of the property -physicalMemory=Physical Memory -heapMemory=Heap Memory -threads=Threads -cpuUsage=CPU Usage -peak=Peak -mb=MB -calculator.dividebyzero=Cannot divide by zero ! -calculator.invalid=Invalid input for function ! -multichoice.message=The entry %s is invalid, please check it! -multichoice.message.plural=The entries %s are invalid, please check it! -apply=Applicare -selectAll=Seleziona tutto +OK=OK +Cancel=Annulla +Close=Chiudi +Yes=Si +No=No +MoreDetails=Pi\u00F9 Dettagli +FewerDetails=Meno Dettagli +Details=Dettagli +Information=Informazione +Error=Errore +Question=Domanda +Warning=Avvertenza +Exception=Eccezione +Choice=Scelta +Select=Seleziona +Input=Input +ApplicationError=Errore di applicazione +megabytes=Mb +performGC=Perform GC +login=Accesso +name=Nome +password=Password +rememberPassword=Remember password +loginFailed=Login failed +tipOfTheDay=Tip of the day +didYouKnow=Did you know... +showTipAtStartup=Show Tip at startup +previousTip=< Previous Tip +nextTip=Next Tip > +choose=Choose +preferences=Preferences +validURL=Please enter a valid URL +chooseDirectory=Please choose a directory +bold=bold +italic=italic +category.shortDescription = Toggle between Category view and Flat list view +description.shortDescription = Show/Hide the Description pane +sort.shortDescription = Sort Properties and Categories by Name +property=Property +value=Value +editProperty=Edit property +width=Width +height=Height +top=Top +bottom=Bottom +left=Left +right=Right +eraseProperty=Erase the value of the property +physicalMemory=Physical Memory +heapMemory=Heap Memory +threads=Threads +cpuUsage=CPU Usage +peak=Peak +mb=MB +calculator.dividebyzero=Cannot divide by zero ! +calculator.invalid=Invalid input for function ! +multichoice.message=The entry %s is invalid, please check it! +multichoice.message.plural=The entries %s are invalid, please check it! +apply=Applicare +selectAll=Seleziona tutto deselectAll=Deselezionare tutto \ No newline at end of file diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_nl_NL.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_nl_NL.properties index b77d089ae..a16e7fa31 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_nl_NL.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_nl_NL.properties @@ -1,61 +1,61 @@ -Ok=OK -Cancel=Annuleren -Close=Sluiten -Yes=Ja -No=Nee -MoreDetails=Meer info -FewerDetails=Minder info -Details=Info -Information=Informatie -Error=Fout -Question=Vraag -Warning=Waarschuwing -Exception=Exception -Choice=Kies -Select=Kies -Input=Invoer -ApplicationError=Fout in toepassing -megabytes=Mb -performGC=Voer GC uit -login=Login -name=Naam -password=Wachtwoord -rememberPassword=Wachtwoord onthouden -loginFailed=Inloggen mislukt -tipOfTheDay=Tip van de dag -didYouKnow=Wisu u dat... -showTipAtStartup=Tips weergeven bij opstarten -previousTip=< Vorige Tip -nextTip=Volgende Tip > -choose=Kies -preferences=Voorkeuren -validURL=Geef een geldige URL op -chooseDirectory=Kies een map -bold=vet -italic=cursief -category.shortDescription = Wissel tussen weergave per category en lijst weergave -description.shortDescription = Toon/Verberg omschrijving -sort.shortDescription = Sorteer eigenschappen en categorie\u00ebn op naam -property=Eigenschap -value=Waarde -editProperty=Bewerk eigenschap -width=Breedte -height=Hoogte -top=Bovenkant -bottom=Onderkant -left=Links -right=Rechts -eraseProperty=Wis de waarde van de eigenschap -physicalMemory=Physical Memory -heapMemory=Heap Memory -threads=Threads -cpuUsage=CPU Usage -peak=Peak -mb=MB -calculator.dividebyzero=Cannot divide by zero ! -calculator.invalid=Invalid input for function ! -multichoice.message=The entry %s is invalid, please check it! -multichoice.message.plural=The entries %s are invalid, please check it! -apply=Van toepassing zijn -selectAll=Selecteer alles +Ok=OK +Cancel=Annuleren +Close=Sluiten +Yes=Ja +No=Nee +MoreDetails=Meer info +FewerDetails=Minder info +Details=Info +Information=Informatie +Error=Fout +Question=Vraag +Warning=Waarschuwing +Exception=Exception +Choice=Kies +Select=Kies +Input=Invoer +ApplicationError=Fout in toepassing +megabytes=Mb +performGC=Voer GC uit +login=Login +name=Naam +password=Wachtwoord +rememberPassword=Wachtwoord onthouden +loginFailed=Inloggen mislukt +tipOfTheDay=Tip van de dag +didYouKnow=Wisu u dat... +showTipAtStartup=Tips weergeven bij opstarten +previousTip=< Vorige Tip +nextTip=Volgende Tip > +choose=Kies +preferences=Voorkeuren +validURL=Geef een geldige URL op +chooseDirectory=Kies een map +bold=vet +italic=cursief +category.shortDescription = Wissel tussen weergave per category en lijst weergave +description.shortDescription = Toon/Verberg omschrijving +sort.shortDescription = Sorteer eigenschappen en categorie\u00ebn op naam +property=Eigenschap +value=Waarde +editProperty=Bewerk eigenschap +width=Breedte +height=Hoogte +top=Bovenkant +bottom=Onderkant +left=Links +right=Rechts +eraseProperty=Wis de waarde van de eigenschap +physicalMemory=Physical Memory +heapMemory=Heap Memory +threads=Threads +cpuUsage=CPU Usage +peak=Peak +mb=MB +calculator.dividebyzero=Cannot divide by zero ! +calculator.invalid=Invalid input for function ! +multichoice.message=The entry %s is invalid, please check it! +multichoice.message.plural=The entries %s are invalid, please check it! +apply=Van toepassing zijn +selectAll=Selecteer alles deselectAll=Deselecteer alles \ No newline at end of file diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_pl_PL.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_pl_PL.properties index 834a9c31b..d02cc7ee9 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_pl_PL.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_pl_PL.properties @@ -1,61 +1,61 @@ -Ok=OK -Cancel=Anuluj -Close=Zamknij -Yes=Tak -No=Nie -MoreDetails=WiÄ™cej szczegółów -FewerDetails=Mniej szczegółów -Details=Szczegóły -Information=Informacja -Error=BÅ‚Ä…d -Question=Pytanie -Warning=Ostrzeżenie -Exception=WyjÄ…tek -Choice=Wybór -Select=Wybór -Input=Wprowadzanie -ApplicationError=BÅ‚Ä…d aplikacji -megabytes=Mb -performGC=Wykonaj GC -login=Login -name=Nazwa -password=HasÅ‚o -rememberPassword=ZapamiÄ™taj hasÅ‚o -loginFailed=Logowanie nie powiodÅ‚o siÄ™ -tipOfTheDay=Porada dnia -didYouKnow=Czy wiesz, że... -showTipAtStartup=WyÅ›wietl PoradÄ™ dnia przy starcie -previousTip=< Poprzednia Porada -nextTip=NastÄ™pna Porada > -choose=Wybierz -preferences=Preferencje -validURL=Wpisz poprawny adres URL -chooseDirectory=ProszÄ™ wybrać katalog -bold=pogrubienie -italic=kursywa -category.shortDescription = PrzeÅ‚Ä…cz pomiÄ™dzy widokiem kategorii a widokiem pÅ‚askiej listy -description.shortDescription = Pokaż/Ukryj panel Opisu -sort.shortDescription = Sortuj WÅ‚aÅ›ciwoÅ›ci i Kategorie po Nazwie -property=WÅ‚aÅ›ciwość -value=Wartość -editProperty=Edytuj wÅ‚aÅ›ciwość -width=Szerokość -height=Wysokość -top=Góra -bottom=Dół -left=Lewo -right=Prawo -eraseProperty=Wymaż wartość wÅ‚aÅ›ciwoÅ›ci -physicalMemory=Pamięć Fizyczna -heapMemory=Sterta PamiÄ™ci -threads=WÄ…tki -cpuUsage=Wykorzystanie CPU -peak=Pik -mb=MB -calculator.dividebyzero=Nie można dzielić przez zero ! -calculator.invalid=NieprawidÅ‚owe parametry funkcji ! -multichoice.message=The entry %s is invalid, please check it! -multichoice.message.plural=The entries %s are invalid, please check it! -apply=Zastosować -selectAll=Zaznacz wszystko +Ok=OK +Cancel=Anuluj +Close=Zamknij +Yes=Tak +No=Nie +MoreDetails=WiÄ™cej szczegółów +FewerDetails=Mniej szczegółów +Details=Szczegóły +Information=Informacja +Error=BÅ‚Ä…d +Question=Pytanie +Warning=Ostrzeżenie +Exception=WyjÄ…tek +Choice=Wybór +Select=Wybór +Input=Wprowadzanie +ApplicationError=BÅ‚Ä…d aplikacji +megabytes=Mb +performGC=Wykonaj GC +login=Login +name=Nazwa +password=HasÅ‚o +rememberPassword=ZapamiÄ™taj hasÅ‚o +loginFailed=Logowanie nie powiodÅ‚o siÄ™ +tipOfTheDay=Porada dnia +didYouKnow=Czy wiesz, że... +showTipAtStartup=WyÅ›wietl PoradÄ™ dnia przy starcie +previousTip=< Poprzednia Porada +nextTip=NastÄ™pna Porada > +choose=Wybierz +preferences=Preferencje +validURL=Wpisz poprawny adres URL +chooseDirectory=ProszÄ™ wybrać katalog +bold=pogrubienie +italic=kursywa +category.shortDescription = PrzeÅ‚Ä…cz pomiÄ™dzy widokiem kategorii a widokiem pÅ‚askiej listy +description.shortDescription = Pokaż/Ukryj panel Opisu +sort.shortDescription = Sortuj WÅ‚aÅ›ciwoÅ›ci i Kategorie po Nazwie +property=WÅ‚aÅ›ciwość +value=Wartość +editProperty=Edytuj wÅ‚aÅ›ciwość +width=Szerokość +height=Wysokość +top=Góra +bottom=Dół +left=Lewo +right=Prawo +eraseProperty=Wymaż wartość wÅ‚aÅ›ciwoÅ›ci +physicalMemory=Pamięć Fizyczna +heapMemory=Sterta PamiÄ™ci +threads=WÄ…tki +cpuUsage=Wykorzystanie CPU +peak=Pik +mb=MB +calculator.dividebyzero=Nie można dzielić przez zero ! +calculator.invalid=NieprawidÅ‚owe parametry funkcji ! +multichoice.message=The entry %s is invalid, please check it! +multichoice.message.plural=The entries %s are invalid, please check it! +apply=Zastosować +selectAll=Zaznacz wszystko deselectAll=Odznacz wszystkie \ No newline at end of file diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_pt_BR.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_pt_BR.properties index 93e120931..39b27a6d1 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_pt_BR.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_pt_BR.properties @@ -1,61 +1,61 @@ -Ok=OK -Cancel=Cancelar -Close=Fechar -Yes=Sim -No=Não -MoreDetails=Mais detalhes -FewerDetails=Menos detalhes -Details=Detalhes -Information=Informação -Error=Erro -Question=Questão -Warning=Aviso -Exception=Exceção -Choice=Escolher -Select=Selecionar -Input=Entrar -ApplicationError=Erro da aplicação -megabytes=Mb -performGC=Perform GC -login=Login -name=Name -password=Password -rememberPassword=Remember password -loginFailed=Login failed -tipOfTheDay=Tip of the day -didYouKnow=Did you know... -showTipAtStartup=Show Tip at startup -previousTip=< Previous Tip -nextTip=Next Tip > -choose=Choose -preferences=Preferences -validURL=Please enter a valid URL -chooseDirectory=Please choose a directory -bold=bold -italic=italic -category.shortDescription = Toggle between Category view and Flat list view -description.shortDescription = Show/Hide the Description pane -sort.shortDescription = Sort Properties and Categories by Name -property=Property -value=Value -editProperty=Edit property -width=Width -height=Height -top=Top -bottom=Bottom -left=Left -right=Right -eraseProperty=Erase the value of the property -physicalMemory=Physical Memory -heapMemory=Heap Memory -threads=Threads -cpuUsage=CPU Usage -peak=Peak -mb=MB -calculator.dividebyzero=Cannot divide by zero ! -calculator.invalid=Invalid input for function ! -multichoice.message=The entry %s is invalid, please check it! -multichoice.message.plural=The entries %s are invalid, please check it! -apply=Aplique -selectAll=Selecionar tudo +Ok=OK +Cancel=Cancelar +Close=Fechar +Yes=Sim +No=Não +MoreDetails=Mais detalhes +FewerDetails=Menos detalhes +Details=Detalhes +Information=Informação +Error=Erro +Question=Questão +Warning=Aviso +Exception=Exceção +Choice=Escolher +Select=Selecionar +Input=Entrar +ApplicationError=Erro da aplicação +megabytes=Mb +performGC=Perform GC +login=Login +name=Name +password=Password +rememberPassword=Remember password +loginFailed=Login failed +tipOfTheDay=Tip of the day +didYouKnow=Did you know... +showTipAtStartup=Show Tip at startup +previousTip=< Previous Tip +nextTip=Next Tip > +choose=Choose +preferences=Preferences +validURL=Please enter a valid URL +chooseDirectory=Please choose a directory +bold=bold +italic=italic +category.shortDescription = Toggle between Category view and Flat list view +description.shortDescription = Show/Hide the Description pane +sort.shortDescription = Sort Properties and Categories by Name +property=Property +value=Value +editProperty=Edit property +width=Width +height=Height +top=Top +bottom=Bottom +left=Left +right=Right +eraseProperty=Erase the value of the property +physicalMemory=Physical Memory +heapMemory=Heap Memory +threads=Threads +cpuUsage=CPU Usage +peak=Peak +mb=MB +calculator.dividebyzero=Cannot divide by zero ! +calculator.invalid=Invalid input for function ! +multichoice.message=The entry %s is invalid, please check it! +multichoice.message.plural=The entries %s are invalid, please check it! +apply=Aplique +selectAll=Selecionar tudo deselectAll=Desmarcar todos \ No newline at end of file diff --git a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_zh_CN.properties b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_zh_CN.properties index afa8e9f56..9985d8509 100644 --- a/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_zh_CN.properties +++ b/widgets/opal/commons/org.eclipse.nebula.widgets.opal.commons/src/org/eclipse/nebula/widgets/opal/commons/resources/opal_zh_CN.properties @@ -1,61 +1,61 @@ -Ok=\u786e\u5b9a -Cancel=\u653e\u5f03 -Close=\u5173\u95ed -Yes=\u662f -No=\u5426 -MoreDetails=\u8be6\u7ec6\u4fe1\u606f -FewerDetails=\u7b80\u660e\u4fe1\u606f -Details=\u4fe1\u606f -Information=\u4fe1\u606f -Error=\u9519\u8bef -Question=\u95ee\u9898 -Warning=\u8b66\u544a -Exception=\u5f02\u5e38 -Choice=\u9009\u9879 -Select=\u9009\u62e9 -Input=\u8f93\u5165 -ApplicationError=Application Error -megabytes=Mb -performGC=Perform GC -login=Login -name=Name -password=Password -rememberPassword=Remember password -loginFailed=Login failed -tipOfTheDay=Tip of the day -didYouKnow=Did you know... -showTipAtStartup=Show Tip at startup -previousTip=< Previous Tip -nextTip=Next Tip > -choose=Choose -preferences=Preferences -validURL=Please enter a valid URL -chooseDirectory=Please choose a directory -bold=bold -italic=italic -category.shortDescription = Toggle between Category view and Flat list view -description.shortDescription = Show/Hide the Description pane -sort.shortDescription = Sort Properties and Categories by Name -property=Property -value=Value -editProperty=Edit property -width=Width -height=Height -top=Top -bottom=Bottom -left=Left -right=Right -eraseProperty=Erase the value of the property -physicalMemory=Physical Memory -heapMemory=Heap Memory -threads=Threads -cpuUsage=CPU Usage -peak=Peak -mb=MB -calculator.dividebyzero=Cannot divide by zero ! -calculator.invalid=Invalid input for function ! -multichoice.message=The entry %s is invalid, please check it! -multichoice.message.plural=The entries %s are invalid, please check it! -apply=\u5E94\u7528 -selectAll=\u5168\u9009 +Ok=\u786e\u5b9a +Cancel=\u653e\u5f03 +Close=\u5173\u95ed +Yes=\u662f +No=\u5426 +MoreDetails=\u8be6\u7ec6\u4fe1\u606f +FewerDetails=\u7b80\u660e\u4fe1\u606f +Details=\u4fe1\u606f +Information=\u4fe1\u606f +Error=\u9519\u8bef +Question=\u95ee\u9898 +Warning=\u8b66\u544a +Exception=\u5f02\u5e38 +Choice=\u9009\u9879 +Select=\u9009\u62e9 +Input=\u8f93\u5165 +ApplicationError=Application Error +megabytes=Mb +performGC=Perform GC +login=Login +name=Name +password=Password +rememberPassword=Remember password +loginFailed=Login failed +tipOfTheDay=Tip of the day +didYouKnow=Did you know... +showTipAtStartup=Show Tip at startup +previousTip=< Previous Tip +nextTip=Next Tip > +choose=Choose +preferences=Preferences +validURL=Please enter a valid URL +chooseDirectory=Please choose a directory +bold=bold +italic=italic +category.shortDescription = Toggle between Category view and Flat list view +description.shortDescription = Show/Hide the Description pane +sort.shortDescription = Sort Properties and Categories by Name +property=Property +value=Value +editProperty=Edit property +width=Width +height=Height +top=Top +bottom=Bottom +left=Left +right=Right +eraseProperty=Erase the value of the property +physicalMemory=Physical Memory +heapMemory=Heap Memory +threads=Threads +cpuUsage=CPU Usage +peak=Peak +mb=MB +calculator.dividebyzero=Cannot divide by zero ! +calculator.invalid=Invalid input for function ! +multichoice.message=The entry %s is invalid, please check it! +multichoice.message.plural=The entries %s are invalid, please check it! +apply=\u5E94\u7528 +selectAll=\u5168\u9009 deselectAll=\u53D6\u6D88\u5168\u9009 \ No newline at end of file diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/.project b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/.project index fad1fc314..99e5c285b 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/.project +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.dialog.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.dialog.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/build.properties b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/build.properties +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/feature.properties b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/feature.properties +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.classpath b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.classpath +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.project b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.project index c1ab62195..71716da9c 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.project +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.dialog.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.dialog.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/META-INF/MANIFEST.MF b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/META-INF/MANIFEST.MF index 077b06234..d7c8b22e7 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Dialog Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.dialog.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.dialog;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.dialog.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Dialog Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.dialog.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.dialog;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.dialog.snippets diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/build.properties b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/build.properties +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/src/org/eclipse/nebula/widgets/opal/dialog/snippets/OpalDialogSnippet.java b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/src/org/eclipse/nebula/widgets/opal/dialog/snippets/OpalDialogSnippet.java index 3aabe2630..37238152b 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/src/org/eclipse/nebula/widgets/opal/dialog/snippets/OpalDialogSnippet.java +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog.snippets/src/org/eclipse/nebula/widgets/opal/dialog/snippets/OpalDialogSnippet.java @@ -1,391 +1,391 @@ -/******************************************************************************* - * Copyright (c) 2011-2019 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - * Eugene Ryzhikov - Author of the Oxbow Project (http://code.google.com/p/oxbow/) - Inspiration - * Stefan Nöbauer - Bug 550437, Bug 550659 - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.dialog.snippets; - -import java.math.BigDecimal; -import java.util.Arrays; - -import org.eclipse.nebula.widgets.opal.commons.ResourceManager; -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.commons.StringUtil; -import org.eclipse.nebula.widgets.opal.dialog.ChoiceItem; -import org.eclipse.nebula.widgets.opal.dialog.Dialog; -import org.eclipse.nebula.widgets.opal.dialog.Dialog.OpalDialogType; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * This snippet demonstrates the OpalDialog component - * - */ -public class OpalDialogSnippet { - public static void main(final String[] args) { - final Display display = new Display(); - - final Shell shell = new Shell(display); - shell.setText("Dialog Sample"); - shell.setLayout(new GridLayout(3, true)); - - final Button button1 = new Button(shell, SWT.PUSH); - button1.setText("Hello world !"); - button1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button1.addSelectionListener(new SelectionAdapter() { - - /** - * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetSelected(final SelectionEvent e) { - displayHelloWorld(); - } - }); - - final Button button2 = new Button(shell, SWT.PUSH); - button2.setText("Crash and burn"); - button2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button2.addListener(SWT.Selection, e -> { - displayCrashAndBurn(); - }); - - final Button button3 = new Button(shell, SWT.PUSH); - button3.setText("You won !"); - button3.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button3.addListener(SWT.Selection, e -> { - displayYouWon(); - }); - - final Button button4 = new Button(shell, SWT.PUSH); - button4.setText("Confirm exit"); - button4.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button4.addListener(SWT.Selection, e -> { - displayConfirmExit(); - }); - - final Button button5 = new Button(shell, SWT.PUSH); - button5.setText("Radio choice"); - button5.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button5.addListener(SWT.Selection, e -> { - displayRadioChoice(); - }); - - final Button button6 = new Button(shell, SWT.PUSH); - button6.setText("Exception viewer"); - button6.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button6.addListener(SWT.Selection, e -> { - displayException(); - }); - - final Button button7 = new Button(shell, SWT.PUSH); - button7.setText("Input box"); - button7.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button7.addListener(SWT.Selection, e -> { - displayInput(); - }); - - final Button button8 = new Button(shell, SWT.PUSH); - button8.setText("Choice..."); - button8.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button8.addListener(SWT.Selection, e -> { - displayChoice(); - }); - - final Button button9 = new Button(shell, SWT.PUSH); - button9.setText("Delayed quit"); - button9.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button9.addListener(SWT.Selection, e -> { - displayDelayedQuit(); - }); - - final Button button10 = new Button(shell, SWT.PUSH); - button10.setText("Progress bar"); - button10.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button10.addListener(SWT.Selection, e -> { - displayProgressBar(); - }); - - final Button button11 = new Button(shell, SWT.PUSH); - button11.setText("Complex Example 1"); - button11.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button11.addListener(SWT.Selection, e -> { - displaySecurityWarning(); - }); - - final Button button12 = new Button(shell, SWT.PUSH); - button12.setText("Complex Example 2"); - button12.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button12.addListener(SWT.Selection, e -> { - displayComplex(); - }); - - final Button button13 = new Button(shell, SWT.PUSH); - button13.setText("Large Text Example"); - button13.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button13.addListener(SWT.Selection, e -> { - displayLargeText(); - }); - - final Button button14 = new Button(shell, SWT.PUSH); - button14.setText("Issue 29"); - button14.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button14.addListener(SWT.Selection, e -> { - testIssue29(shell); - }); - - final Button button15 = new Button(shell, SWT.PUSH); - button15.setText("Issue 45"); - button15.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button15.addListener(SWT.Selection, e -> { - testIssue45(); - }); - - final Button button16 = new Button(shell, SWT.PUSH); - button16.setText("Bug 533776"); - button16.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button16.addListener(SWT.Selection, e -> { - testBug533776(); - }); - final Button button17 = new Button(shell, SWT.PUSH); - button17.setText("Complex exception"); - button17.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button17.addListener(SWT.Selection, e -> { - displayComplex1(); - }); - - // Open the shell - shell.pack(); - SWTGraphicUtil.centerShell(shell); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - - } - - private static void displayHelloWorld() { - final Dialog dialog = new Dialog(); - dialog.getMessageArea().setText("Hello world"); - dialog.setButtonType(OpalDialogType.OK); - dialog.show(); - - } - - private static void displayCrashAndBurn() { - Dialog.error("CRASH AND BURN !", - "The application has performed an illegal action. This action has been logged and reported. This text may also a bit longer as expected"); - } - - private static void displayYouWon() { - Dialog.inform("You've won!", "The game is over with the 15:3 score"); - - } - - private static void displayConfirmExit() { - final boolean confirm = Dialog.isConfirmed("Are you sure you want to quit?", "Please do not quit yet!"); - System.out.println("Choice is..." + confirm); - } - - private static void displayRadioChoice() { - final int choice = Dialog.radioChoice("You've got selection to make", "Go ahead", 1, "Yes", "No", "May be"); - System.out.println("Choice is..." + choice); - } - - private static void displayException() { - try { - new BigDecimal("seven"); - } catch (final Throwable ex) { - Dialog dialog = Dialog.buildExceptionDialog(ex); - Image mail = new Image(Display.getCurrent(), OpalDialogSnippet.class.getResourceAsStream("mail.png")); - Image mailHot = new Image(Display.getCurrent(), OpalDialogSnippet.class.getResourceAsStream("mail_hover.png")); - Image[] images = Arrays.asList(mail, mailHot).toArray(new Image[0]); - dialog.getFooterArea().addFooterAction(()-> "Send Mail", d -> System.out.println(StringUtil.stackStraceAsString(d.getMessageArea().getException())), images); - dialog.show(); - } - } - - private static void displayChoice() { - final int choice = Dialog.choice("What do you want to do with your game in\nprogress?", "", 1, - new ChoiceItem("Exit and save my game", - "Save your game in progress, then exit. " + "This will\noverwrite any previously saved games."), - new ChoiceItem("Exit and don't save", - "Exit without saving your game. " + "This is counted\nas a loss in your statistics."), - new ChoiceItem("Don't exit", "Return to your game progress")); - System.out.println("Choice is..." + choice); - } - - private static void displayDelayedQuit() { - final boolean choice = Dialog.isConfirmed("Are you sure you want to quit?", "Please do not quit yet!", 10); - System.out.println("Choice is..." + choice); - } - - private static void displaySecurityWarning() { - final Dialog dialog = new Dialog(); - dialog.setTitle("Security Warning"); - dialog.setMinimumWidth(400); - dialog.getMessageArea().setTitle("The publisher cannot be verified.\nDo you want to run this software?") // - .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_WARNING)) // - .setText("Name: C:\\Program Files\\eclipse\\eclipse.exe
" + // - "Publisher: Unknown Publisher
" + // - "Type: Application
"); - - dialog.getFooterArea().addCheckBox("Always ask before opening this file", false).setButtonLabels("Run", - "Cancel"); - dialog.show(); - - System.out.println( - "The choice is " + dialog.getSelectedButton() + ", the checkbox value is " + dialog.getCheckboxValue()); - } - - private static void displayProgressBar() { - final Dialog dialog = new Dialog(); - dialog.setTitle("Copying..."); - dialog.setMinimumWidth(400); - dialog.getMessageArea().setTitle("Copying files") // - .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION)) // - .setText("Location : from 'Others' to 'Others'
" + // - "File Name : photo.jpg") - .// - addProgressBar(0, 100, 0); - - final int[] counter = new int[1]; - counter[0] = 10; - - Display.getCurrent().timerExec(500, new Runnable() { - @Override - public void run() { - dialog.getMessageArea().setProgressBarValue(counter[0]); - dialog.getMessageArea().setText("Location : from 'Others' to 'Others'
" + // - "File Name : photo" + counter[0] + ".jpg"); - counter[0] += 10; - if (counter[0] < 120) { - Display.getCurrent().timerExec(500, this); - } else { - dialog.close(); - } - } - }); - - dialog.show(); - } - - private static void displayInput() { - final String input = Dialog.ask("Enter you name", - "or any other text if you prefer Somthing longer may stress the layout", "Laurent CARON"); - System.out.println("Choice is..." + input); - } - - private static void displayComplex() { - final Dialog dialog = new Dialog(); - dialog.setTitle("Application Error"); - dialog.getMessageArea().setTitle("CRASH AND BURN !").// - setText("The application has performed an illegal action. This action has been logged and reported.").// - setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR)); - dialog.setButtonType(OpalDialogType.OK); - dialog.getFooterArea().setExpanded(false).addCheckBox("Don't show me this error next time", true) - .setDetailText("More explanations to come..."); - dialog.getFooterArea().setFooterText("Your application crashed because a developer forgot to write a unit test") - .setIcon(new Image(null, OpalDialogSnippet.class.getResourceAsStream("warning.png"))); - dialog.show(); - } - - private static void displayComplex1() { - try { - new BigDecimal("seven"); - } catch (final Throwable ex) { - final Dialog dialog = new Dialog(); - - dialog.setTitle(ResourceManager.getLabel(ResourceManager.EXCEPTION)); - - final String msg = ex.getMessage(); - final String className = ex.getClass().getName(); - final boolean noMessage = msg == null || msg.trim().length() == 0; - - dialog.getMessageArea().setTitle(noMessage ? className : msg).// - setText(noMessage ? "" : className).// - setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR)).// - setException(ex).addCheckBox("Don't show this again", false); - - dialog.getFooterArea().setExpanded(true); - - dialog.setButtonType(OpalDialogType.CLOSE); - - dialog.show(); - } - } - - private static void displayLargeText() { - final StringBuilder stringBuilder = new StringBuilder(); - for (int t = 0; t < 20; t++) { - stringBuilder.append("A very long text (10) " + t + ""); - stringBuilder.append("A very long text (+12) " + t + ""); - stringBuilder.append("A very long text (-4) " + t + ""); - stringBuilder.append("A very long text " + t + ""); - stringBuilder.append("A very long text " + t + ""); - stringBuilder.append("A very long text " + t + ""); - stringBuilder.append("A very long text " + t + ""); - stringBuilder.append("A very long text " + t + ""); - stringBuilder.append("A very long text " + t + ""); - stringBuilder.append("A very long text " + t + "
"); - stringBuilder.append("..." + "
"); - } - - final Dialog dialog = new Dialog(true); - dialog.getMessageArea().setVerticalScrollbar(true); - dialog.getMessageArea().setHeight(200); - dialog.getMessageArea().setText(stringBuilder.toString()); - dialog.setButtonType(OpalDialogType.OK); - dialog.show(); - } - - private static void testIssue29(Shell parent) { - final Dialog d = new Dialog(parent); - d.setCenterPolicy(Dialog.CenterOption.CENTER_ON_DIALOG); - d.setTitle("foo title"); - - d.getMessageArea().setTitle("aaaa").setText("bbbb"); - - d.getFooterArea().setButtonLabels(Arrays.asList("Don't Save please", "Cancel")); - d.show(); - } - - private static void testIssue45() { - - final Dialog dialog = new Dialog(true); - dialog.getMessageArea().setVerticalScrollbar(true); - dialog.getMessageArea().setHeight(200); - dialog.getMessageArea().setText("Illegal format :"); - dialog.setButtonType(OpalDialogType.OK); - dialog.show(); - } - - private static void testBug533776() { - final Dialog dialog = new Dialog(true); - dialog.getMessageArea().setVerticalScrollbar(true); - dialog.getMessageArea().setHeight(200); - dialog.getMessageArea().setText("test"); - dialog.setButtonType(OpalDialogType.OK); - dialog.show(); - } - -} +/******************************************************************************* + * Copyright (c) 2011-2019 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + * Eugene Ryzhikov - Author of the Oxbow Project (http://code.google.com/p/oxbow/) - Inspiration + * Stefan Nöbauer - Bug 550437, Bug 550659 + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.dialog.snippets; + +import java.math.BigDecimal; +import java.util.Arrays; + +import org.eclipse.nebula.widgets.opal.commons.ResourceManager; +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.commons.StringUtil; +import org.eclipse.nebula.widgets.opal.dialog.ChoiceItem; +import org.eclipse.nebula.widgets.opal.dialog.Dialog; +import org.eclipse.nebula.widgets.opal.dialog.Dialog.OpalDialogType; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * This snippet demonstrates the OpalDialog component + * + */ +public class OpalDialogSnippet { + public static void main(final String[] args) { + final Display display = new Display(); + + final Shell shell = new Shell(display); + shell.setText("Dialog Sample"); + shell.setLayout(new GridLayout(3, true)); + + final Button button1 = new Button(shell, SWT.PUSH); + button1.setText("Hello world !"); + button1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button1.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + displayHelloWorld(); + } + }); + + final Button button2 = new Button(shell, SWT.PUSH); + button2.setText("Crash and burn"); + button2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button2.addListener(SWT.Selection, e -> { + displayCrashAndBurn(); + }); + + final Button button3 = new Button(shell, SWT.PUSH); + button3.setText("You won !"); + button3.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button3.addListener(SWT.Selection, e -> { + displayYouWon(); + }); + + final Button button4 = new Button(shell, SWT.PUSH); + button4.setText("Confirm exit"); + button4.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button4.addListener(SWT.Selection, e -> { + displayConfirmExit(); + }); + + final Button button5 = new Button(shell, SWT.PUSH); + button5.setText("Radio choice"); + button5.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button5.addListener(SWT.Selection, e -> { + displayRadioChoice(); + }); + + final Button button6 = new Button(shell, SWT.PUSH); + button6.setText("Exception viewer"); + button6.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button6.addListener(SWT.Selection, e -> { + displayException(); + }); + + final Button button7 = new Button(shell, SWT.PUSH); + button7.setText("Input box"); + button7.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button7.addListener(SWT.Selection, e -> { + displayInput(); + }); + + final Button button8 = new Button(shell, SWT.PUSH); + button8.setText("Choice..."); + button8.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button8.addListener(SWT.Selection, e -> { + displayChoice(); + }); + + final Button button9 = new Button(shell, SWT.PUSH); + button9.setText("Delayed quit"); + button9.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button9.addListener(SWT.Selection, e -> { + displayDelayedQuit(); + }); + + final Button button10 = new Button(shell, SWT.PUSH); + button10.setText("Progress bar"); + button10.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button10.addListener(SWT.Selection, e -> { + displayProgressBar(); + }); + + final Button button11 = new Button(shell, SWT.PUSH); + button11.setText("Complex Example 1"); + button11.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button11.addListener(SWT.Selection, e -> { + displaySecurityWarning(); + }); + + final Button button12 = new Button(shell, SWT.PUSH); + button12.setText("Complex Example 2"); + button12.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button12.addListener(SWT.Selection, e -> { + displayComplex(); + }); + + final Button button13 = new Button(shell, SWT.PUSH); + button13.setText("Large Text Example"); + button13.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button13.addListener(SWT.Selection, e -> { + displayLargeText(); + }); + + final Button button14 = new Button(shell, SWT.PUSH); + button14.setText("Issue 29"); + button14.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button14.addListener(SWT.Selection, e -> { + testIssue29(shell); + }); + + final Button button15 = new Button(shell, SWT.PUSH); + button15.setText("Issue 45"); + button15.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button15.addListener(SWT.Selection, e -> { + testIssue45(); + }); + + final Button button16 = new Button(shell, SWT.PUSH); + button16.setText("Bug 533776"); + button16.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button16.addListener(SWT.Selection, e -> { + testBug533776(); + }); + final Button button17 = new Button(shell, SWT.PUSH); + button17.setText("Complex exception"); + button17.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button17.addListener(SWT.Selection, e -> { + displayComplex1(); + }); + + // Open the shell + shell.pack(); + SWTGraphicUtil.centerShell(shell); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + + } + + private static void displayHelloWorld() { + final Dialog dialog = new Dialog(); + dialog.getMessageArea().setText("Hello world"); + dialog.setButtonType(OpalDialogType.OK); + dialog.show(); + + } + + private static void displayCrashAndBurn() { + Dialog.error("CRASH AND BURN !", + "The application has performed an illegal action. This action has been logged and reported. This text may also a bit longer as expected"); + } + + private static void displayYouWon() { + Dialog.inform("You've won!", "The game is over with the 15:3 score"); + + } + + private static void displayConfirmExit() { + final boolean confirm = Dialog.isConfirmed("Are you sure you want to quit?", "Please do not quit yet!"); + System.out.println("Choice is..." + confirm); + } + + private static void displayRadioChoice() { + final int choice = Dialog.radioChoice("You've got selection to make", "Go ahead", 1, "Yes", "No", "May be"); + System.out.println("Choice is..." + choice); + } + + private static void displayException() { + try { + new BigDecimal("seven"); + } catch (final Throwable ex) { + Dialog dialog = Dialog.buildExceptionDialog(ex); + Image mail = new Image(Display.getCurrent(), OpalDialogSnippet.class.getResourceAsStream("mail.png")); + Image mailHot = new Image(Display.getCurrent(), OpalDialogSnippet.class.getResourceAsStream("mail_hover.png")); + Image[] images = Arrays.asList(mail, mailHot).toArray(new Image[0]); + dialog.getFooterArea().addFooterAction(()-> "Send Mail", d -> System.out.println(StringUtil.stackStraceAsString(d.getMessageArea().getException())), images); + dialog.show(); + } + } + + private static void displayChoice() { + final int choice = Dialog.choice("What do you want to do with your game in\nprogress?", "", 1, + new ChoiceItem("Exit and save my game", + "Save your game in progress, then exit. " + "This will\noverwrite any previously saved games."), + new ChoiceItem("Exit and don't save", + "Exit without saving your game. " + "This is counted\nas a loss in your statistics."), + new ChoiceItem("Don't exit", "Return to your game progress")); + System.out.println("Choice is..." + choice); + } + + private static void displayDelayedQuit() { + final boolean choice = Dialog.isConfirmed("Are you sure you want to quit?", "Please do not quit yet!", 10); + System.out.println("Choice is..." + choice); + } + + private static void displaySecurityWarning() { + final Dialog dialog = new Dialog(); + dialog.setTitle("Security Warning"); + dialog.setMinimumWidth(400); + dialog.getMessageArea().setTitle("The publisher cannot be verified.\nDo you want to run this software?") // + .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_WARNING)) // + .setText("Name: C:\\Program Files\\eclipse\\eclipse.exe
" + // + "Publisher: Unknown Publisher
" + // + "Type: Application
"); + + dialog.getFooterArea().addCheckBox("Always ask before opening this file", false).setButtonLabels("Run", + "Cancel"); + dialog.show(); + + System.out.println( + "The choice is " + dialog.getSelectedButton() + ", the checkbox value is " + dialog.getCheckboxValue()); + } + + private static void displayProgressBar() { + final Dialog dialog = new Dialog(); + dialog.setTitle("Copying..."); + dialog.setMinimumWidth(400); + dialog.getMessageArea().setTitle("Copying files") // + .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION)) // + .setText("Location : from 'Others' to 'Others'
" + // + "File Name : photo.jpg") + .// + addProgressBar(0, 100, 0); + + final int[] counter = new int[1]; + counter[0] = 10; + + Display.getCurrent().timerExec(500, new Runnable() { + @Override + public void run() { + dialog.getMessageArea().setProgressBarValue(counter[0]); + dialog.getMessageArea().setText("Location : from 'Others' to 'Others'
" + // + "File Name : photo" + counter[0] + ".jpg"); + counter[0] += 10; + if (counter[0] < 120) { + Display.getCurrent().timerExec(500, this); + } else { + dialog.close(); + } + } + }); + + dialog.show(); + } + + private static void displayInput() { + final String input = Dialog.ask("Enter you name", + "or any other text if you prefer Somthing longer may stress the layout", "Laurent CARON"); + System.out.println("Choice is..." + input); + } + + private static void displayComplex() { + final Dialog dialog = new Dialog(); + dialog.setTitle("Application Error"); + dialog.getMessageArea().setTitle("CRASH AND BURN !").// + setText("The application has performed an illegal action. This action has been logged and reported.").// + setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR)); + dialog.setButtonType(OpalDialogType.OK); + dialog.getFooterArea().setExpanded(false).addCheckBox("Don't show me this error next time", true) + .setDetailText("More explanations to come..."); + dialog.getFooterArea().setFooterText("Your application crashed because a developer forgot to write a unit test") + .setIcon(new Image(null, OpalDialogSnippet.class.getResourceAsStream("warning.png"))); + dialog.show(); + } + + private static void displayComplex1() { + try { + new BigDecimal("seven"); + } catch (final Throwable ex) { + final Dialog dialog = new Dialog(); + + dialog.setTitle(ResourceManager.getLabel(ResourceManager.EXCEPTION)); + + final String msg = ex.getMessage(); + final String className = ex.getClass().getName(); + final boolean noMessage = msg == null || msg.trim().length() == 0; + + dialog.getMessageArea().setTitle(noMessage ? className : msg).// + setText(noMessage ? "" : className).// + setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR)).// + setException(ex).addCheckBox("Don't show this again", false); + + dialog.getFooterArea().setExpanded(true); + + dialog.setButtonType(OpalDialogType.CLOSE); + + dialog.show(); + } + } + + private static void displayLargeText() { + final StringBuilder stringBuilder = new StringBuilder(); + for (int t = 0; t < 20; t++) { + stringBuilder.append("A very long text (10) " + t + ""); + stringBuilder.append("A very long text (+12) " + t + ""); + stringBuilder.append("A very long text (-4) " + t + ""); + stringBuilder.append("A very long text " + t + ""); + stringBuilder.append("A very long text " + t + ""); + stringBuilder.append("A very long text " + t + ""); + stringBuilder.append("A very long text " + t + ""); + stringBuilder.append("A very long text " + t + ""); + stringBuilder.append("A very long text " + t + ""); + stringBuilder.append("A very long text " + t + "
"); + stringBuilder.append("..." + "
"); + } + + final Dialog dialog = new Dialog(true); + dialog.getMessageArea().setVerticalScrollbar(true); + dialog.getMessageArea().setHeight(200); + dialog.getMessageArea().setText(stringBuilder.toString()); + dialog.setButtonType(OpalDialogType.OK); + dialog.show(); + } + + private static void testIssue29(Shell parent) { + final Dialog d = new Dialog(parent); + d.setCenterPolicy(Dialog.CenterOption.CENTER_ON_DIALOG); + d.setTitle("foo title"); + + d.getMessageArea().setTitle("aaaa").setText("bbbb"); + + d.getFooterArea().setButtonLabels(Arrays.asList("Don't Save please", "Cancel")); + d.show(); + } + + private static void testIssue45() { + + final Dialog dialog = new Dialog(true); + dialog.getMessageArea().setVerticalScrollbar(true); + dialog.getMessageArea().setHeight(200); + dialog.getMessageArea().setText("Illegal format :"); + dialog.setButtonType(OpalDialogType.OK); + dialog.show(); + } + + private static void testBug533776() { + final Dialog dialog = new Dialog(true); + dialog.getMessageArea().setVerticalScrollbar(true); + dialog.getMessageArea().setHeight(200); + dialog.getMessageArea().setText("test"); + dialog.setButtonType(OpalDialogType.OK); + dialog.show(); + } + +} diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.classpath b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.classpath +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.project b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.project index 29244f48b..54a5f5285 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.project +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.dialog - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.dialog + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/META-INF/MANIFEST.MF b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/META-INF/MANIFEST.MF index 897d50e79..576161e46 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/META-INF/MANIFEST.MF +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Dialog -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.dialog -Bundle-Version: 1.0.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-Vendor: Eclipse Nebula -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.dialog -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.dialog +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Dialog +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.dialog +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: Eclipse Nebula +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.dialog +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.dialog diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/build.properties b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/build.properties +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/ChoiceItem.java b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/ChoiceItem.java index e7623655e..2efeb04d9 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/ChoiceItem.java +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/ChoiceItem.java @@ -1,58 +1,58 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.dialog; - -/** - * Instances of this class are choice items used by the choice widget - */ -public class ChoiceItem { - - private final String instruction; - private final String text; - - /** - * Constructor - * - * @param instruction instruction of the choice - * @param text text displayed under the instruction - */ - public ChoiceItem(final String instruction, final String text) { - this.instruction = instruction; - this.text = text; - } - - /** - * Constructor - * - * @param instruction instruction - */ - public ChoiceItem(final String instruction) { - this(instruction, null); - } - - /** - * @return the instruction - */ - public String getInstruction() { - return this.instruction; - } - - /** - * @return the text - */ - public String getText() { - return this.text; - }; - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.dialog; + +/** + * Instances of this class are choice items used by the choice widget + */ +public class ChoiceItem { + + private final String instruction; + private final String text; + + /** + * Constructor + * + * @param instruction instruction of the choice + * @param text text displayed under the instruction + */ + public ChoiceItem(final String instruction, final String text) { + this.instruction = instruction; + this.text = text; + } + + /** + * Constructor + * + * @param instruction instruction + */ + public ChoiceItem(final String instruction) { + this(instruction, null); + } + + /** + * @return the instruction + */ + public String getInstruction() { + return this.instruction; + } + + /** + * @return the text + */ + public String getText() { + return this.text; + }; + +} diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/ChoiceWidget.java b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/ChoiceWidget.java index ee4a696d1..de4911a94 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/ChoiceWidget.java +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/ChoiceWidget.java @@ -1,281 +1,281 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.dialog; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Widget; - -/** - * Instance of this class are composite that represents a choice like in Windows - * Vista and Seven. It is composed of a green arrow, instruction and text - */ -public class ChoiceWidget extends Composite { - private Image oldImage; - - private ChoiceItem choiceItem; - - private Label image; - private Label instruction; - private Label text; - - private final List selectionListeners; - - private boolean selection; - private boolean insideComposite; - private boolean insideImage; - private boolean insideText; - private boolean insideInstruction; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a widget which will be the parent of the new instance (cannot - * be null) - * @param style the style of widget to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - * @see Composite#Composite(Composite, int) - * @see SWT#NO_BACKGROUND - * @see SWT#NO_FOCUS - * @see SWT#NO_MERGE_PAINTS - * @see SWT#NO_REDRAW_RESIZE - * @see SWT#NO_RADIO_GROUP - * @see SWT#EMBEDDED - * @see SWT#DOUBLE_BUFFERED - * @see Widget#getStyle - */ - public ChoiceWidget(final Composite parent, final int style) { - super(parent, style); - - setBackgroundMode(SWT.INHERIT_DEFAULT); - setLayout(new GridLayout(2, false)); - - buildGreenArrow(); - buildInstruction(); - buildText(); - addMouseListeners(); - - selectionListeners = new ArrayList(); - addListener(SWT.Resize, event -> { - drawComposite(); - }); - - } - - /** - * Build the green arrow - */ - private void buildGreenArrow() { - final Image greenArrow = SWTGraphicUtil.createImageFromFile("images/arrowGreenRight.png"); - image = new Label(this, SWT.NONE); - image.setImage(greenArrow); - image.setLayoutData(new GridData(GridData.CENTER, GridData.BEGINNING, false, false, 1, 2)); - SWTGraphicUtil.addDisposer(this, greenArrow); - } - - /** - * Build the instruction - */ - private void buildInstruction() { - final Color color = new Color(Display.getCurrent(), 35, 107, 178); - SWTGraphicUtil.addDisposer(this, color); - - instruction = new Label(this, SWT.NONE); - instruction.setForeground(color); - instruction.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); - } - - /** - * Build the panel - */ - private void buildText() { - text = new Label(this, SWT.NONE); - text.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); - text.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, true)); - } - - /** - * Add mouse listeners - */ - private void addMouseListeners() { - final Listener mouseEnterListener = event -> { - - if (event.widget.equals(ChoiceWidget.this)) { - insideComposite = true; - } - - if (event.widget.equals(image)) { - insideImage = true; - } - if (event.widget.equals(text)) { - insideText = true; - } - if (event.widget.equals(instruction)) { - insideInstruction = true; - } - - drawComposite(); - }; - - final Listener mouseExitListener = event -> { - if (event.widget.equals(ChoiceWidget.this)) { - insideComposite = false; - } - - if (event.widget.equals(image)) { - insideImage = false; - } - if (event.widget.equals(text)) { - insideText = false; - } - if (event.widget.equals(instruction)) { - insideInstruction = false; - } - drawComposite(); - }; - - final Listener mouseClickListener = event -> { - for (final SelectionListener selectionListener : selectionListeners) { - selectionListener.widgetSelected(null); - } - }; - - addListener(SWT.MouseEnter, mouseEnterListener); - image.addListener(SWT.MouseEnter, mouseEnterListener); - text.addListener(SWT.MouseEnter, mouseEnterListener); - instruction.addListener(SWT.MouseEnter, mouseEnterListener); - - addListener(SWT.MouseExit, mouseExitListener); - image.addListener(SWT.MouseExit, mouseExitListener); - text.addListener(SWT.MouseExit, mouseExitListener); - instruction.addListener(SWT.MouseExit, mouseExitListener); - - addListener(SWT.MouseUp, mouseClickListener); - image.addListener(SWT.MouseUp, mouseClickListener); - text.addListener(SWT.MouseUp, mouseClickListener); - instruction.addListener(SWT.MouseUp, mouseClickListener); - } - - /** - * Draw the composite - */ - private void drawComposite() { - - final Rectangle rect = getClientArea(); - final Image newImage = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height)); - - final GC gc = new GC(newImage); - - final boolean inside = insideComposite || insideImage || insideInstruction || insideText; - - if (!inside && !selection) { - gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - gc.drawRectangle(rect.x, rect.y, rect.width, rect.height); - } else { - // The mouse is over OR the item is selected - final Color gradientColor = inside ? new Color(getDisplay(), 220, 231, 243) : new Color(getDisplay(), 241, 241, 241); - final Color borderColor = inside ? new Color(getDisplay(), 35, 107, 178) : new Color(getDisplay(), 192, 192, 192); - - gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - gc.setBackground(gradientColor); - gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true); - - gc.setForeground(borderColor); - gc.drawRoundRectangle(rect.x, rect.y, rect.width - 1, rect.height - 1, 2, 2); - - gradientColor.dispose(); - borderColor.dispose(); - } - gc.dispose(); - - setBackgroundImage(newImage); - if (oldImage != null) { - oldImage.dispose(); - } - oldImage = newImage; - } - - /** - * @return the current choice item - */ - public ChoiceItem getChoiceItem() { - return choiceItem; - } - - /** - * @param choiceItem the choiceItem to set - */ - public void setChoiceItem(final ChoiceItem choiceItem) { - this.choiceItem = choiceItem; - instruction.setText(choiceItem.getInstruction()); - text.setText(choiceItem.getText()); - } - - /** - * Add a selection listener to this widget - * - * @param listener listener to add - */ - public void addSelectionListener(final SelectionListener listener) { - selectionListeners.add(listener); - } - - /** - * Remove a selection listener - * - * @param listener listener to remove - */ - public void removeSelectionListener(final SelectionListener listener) { - selectionListeners.remove(listener); - } - - public void setSelection(final boolean selection) { - this.selection = selection; - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.dialog; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Widget; + +/** + * Instance of this class are composite that represents a choice like in Windows + * Vista and Seven. It is composed of a green arrow, instruction and text + */ +public class ChoiceWidget extends Composite { + private Image oldImage; + + private ChoiceItem choiceItem; + + private Label image; + private Label instruction; + private Label text; + + private final List selectionListeners; + + private boolean selection; + private boolean insideComposite; + private boolean insideImage; + private boolean insideText; + private boolean insideInstruction; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance (cannot + * be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see Composite#Composite(Composite, int) + * @see SWT#NO_BACKGROUND + * @see SWT#NO_FOCUS + * @see SWT#NO_MERGE_PAINTS + * @see SWT#NO_REDRAW_RESIZE + * @see SWT#NO_RADIO_GROUP + * @see SWT#EMBEDDED + * @see SWT#DOUBLE_BUFFERED + * @see Widget#getStyle + */ + public ChoiceWidget(final Composite parent, final int style) { + super(parent, style); + + setBackgroundMode(SWT.INHERIT_DEFAULT); + setLayout(new GridLayout(2, false)); + + buildGreenArrow(); + buildInstruction(); + buildText(); + addMouseListeners(); + + selectionListeners = new ArrayList(); + addListener(SWT.Resize, event -> { + drawComposite(); + }); + + } + + /** + * Build the green arrow + */ + private void buildGreenArrow() { + final Image greenArrow = SWTGraphicUtil.createImageFromFile("images/arrowGreenRight.png"); + image = new Label(this, SWT.NONE); + image.setImage(greenArrow); + image.setLayoutData(new GridData(GridData.CENTER, GridData.BEGINNING, false, false, 1, 2)); + SWTGraphicUtil.addDisposer(this, greenArrow); + } + + /** + * Build the instruction + */ + private void buildInstruction() { + final Color color = new Color(Display.getCurrent(), 35, 107, 178); + SWTGraphicUtil.addDisposer(this, color); + + instruction = new Label(this, SWT.NONE); + instruction.setForeground(color); + instruction.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); + } + + /** + * Build the panel + */ + private void buildText() { + text = new Label(this, SWT.NONE); + text.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK)); + text.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, true)); + } + + /** + * Add mouse listeners + */ + private void addMouseListeners() { + final Listener mouseEnterListener = event -> { + + if (event.widget.equals(ChoiceWidget.this)) { + insideComposite = true; + } + + if (event.widget.equals(image)) { + insideImage = true; + } + if (event.widget.equals(text)) { + insideText = true; + } + if (event.widget.equals(instruction)) { + insideInstruction = true; + } + + drawComposite(); + }; + + final Listener mouseExitListener = event -> { + if (event.widget.equals(ChoiceWidget.this)) { + insideComposite = false; + } + + if (event.widget.equals(image)) { + insideImage = false; + } + if (event.widget.equals(text)) { + insideText = false; + } + if (event.widget.equals(instruction)) { + insideInstruction = false; + } + drawComposite(); + }; + + final Listener mouseClickListener = event -> { + for (final SelectionListener selectionListener : selectionListeners) { + selectionListener.widgetSelected(null); + } + }; + + addListener(SWT.MouseEnter, mouseEnterListener); + image.addListener(SWT.MouseEnter, mouseEnterListener); + text.addListener(SWT.MouseEnter, mouseEnterListener); + instruction.addListener(SWT.MouseEnter, mouseEnterListener); + + addListener(SWT.MouseExit, mouseExitListener); + image.addListener(SWT.MouseExit, mouseExitListener); + text.addListener(SWT.MouseExit, mouseExitListener); + instruction.addListener(SWT.MouseExit, mouseExitListener); + + addListener(SWT.MouseUp, mouseClickListener); + image.addListener(SWT.MouseUp, mouseClickListener); + text.addListener(SWT.MouseUp, mouseClickListener); + instruction.addListener(SWT.MouseUp, mouseClickListener); + } + + /** + * Draw the composite + */ + private void drawComposite() { + + final Rectangle rect = getClientArea(); + final Image newImage = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height)); + + final GC gc = new GC(newImage); + + final boolean inside = insideComposite || insideImage || insideInstruction || insideText; + + if (!inside && !selection) { + gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + gc.drawRectangle(rect.x, rect.y, rect.width, rect.height); + } else { + // The mouse is over OR the item is selected + final Color gradientColor = inside ? new Color(getDisplay(), 220, 231, 243) : new Color(getDisplay(), 241, 241, 241); + final Color borderColor = inside ? new Color(getDisplay(), 35, 107, 178) : new Color(getDisplay(), 192, 192, 192); + + gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + gc.setBackground(gradientColor); + gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true); + + gc.setForeground(borderColor); + gc.drawRoundRectangle(rect.x, rect.y, rect.width - 1, rect.height - 1, 2, 2); + + gradientColor.dispose(); + borderColor.dispose(); + } + gc.dispose(); + + setBackgroundImage(newImage); + if (oldImage != null) { + oldImage.dispose(); + } + oldImage = newImage; + } + + /** + * @return the current choice item + */ + public ChoiceItem getChoiceItem() { + return choiceItem; + } + + /** + * @param choiceItem the choiceItem to set + */ + public void setChoiceItem(final ChoiceItem choiceItem) { + this.choiceItem = choiceItem; + instruction.setText(choiceItem.getInstruction()); + text.setText(choiceItem.getText()); + } + + /** + * Add a selection listener to this widget + * + * @param listener listener to add + */ + public void addSelectionListener(final SelectionListener listener) { + selectionListeners.add(listener); + } + + /** + * Remove a selection listener + * + * @param listener listener to remove + */ + public void removeSelectionListener(final SelectionListener listener) { + selectionListeners.remove(listener); + } + + public void setSelection(final boolean selection) { + this.selection = selection; + } + +} diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/Dialog.java b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/Dialog.java index 43fad7cbb..fde4b0ce2 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/Dialog.java +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/Dialog.java @@ -1,665 +1,665 @@ -/******************************************************************************* - * Copyright (c) 2011-2019 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - * Stefan Nöbauer - Bug 550437, Bug 550659 - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.dialog; - -import org.eclipse.nebula.widgets.opal.commons.ResourceManager; -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Instances of this class are dialog box This component was inspired by the - * Oxbow Project (http://code.google.com/p/oxbow/) by Eugene Ryzhikov - */ -public class Dialog { - - /** - * Types of opal dialog - */ - public enum OpalDialogType { - CLOSE, YES_NO, OK, OK_CANCEL, SELECT_CANCEL, NO_BUTTON, OTHER, NONE - } - - public enum CenterOption { - CENTER_ON_SCREEN, CENTER_ON_DIALOG - } - - private CenterOption centerPolicy = CenterOption.CENTER_ON_SCREEN; - - private String title; - OpalDialogType buttonType; - private final MessageArea messageArea; - private final FooterArea footerArea; - final Shell shell; - - private int minimumWidth = 400; - private int minimumHeight = 150; - - private Point lastSize; - - /** - * Constructor - */ - public Dialog() { - this(null); - } - - /** - * Constructor - * - * @param resizable if true, the window is resizable - */ - public Dialog(final boolean resizable) { - this(null, resizable); - } - - /** - * Constructor - * - * @param parent parent shell - */ - public Dialog(final Shell parent) { - this(parent, true); - } - - /** - * Constructor - * - * @param parent parent shell - * @param resizable if true, the window is resizable - */ - public Dialog(final Shell parent, final boolean resizable) { - if (parent == null) { - shell = new Shell(Display.getCurrent(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | (resizable ? SWT.RESIZE : SWT.NONE)); - } else { - shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | (resizable ? SWT.RESIZE : SWT.NONE)); - if (parent.getImage() != null) { - shell.setImage(parent.getImage()); - } - } - messageArea = new MessageArea(this); - footerArea = new FooterArea(this); - } - - /** - * Show the dialog box - * - * @return the index of the selected button - */ - public int show() { - final GridLayout gd = new GridLayout(1, true); - gd.horizontalSpacing = 0; - gd.verticalSpacing = 0; - gd.marginHeight = gd.marginWidth = 0; - shell.setLayout(gd); - - messageArea.render(); - footerArea.render(); - if (title != null) { - shell.setText(title); - } - pack(); - center(); - - shell.setMinimumSize(shell.computeSize(minimumWidth, SWT.DEFAULT)); - shell.open(); - - final Display display = shell.getDisplay(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - return footerArea.getSelectedButton(); - } - - private void center() { - final Point preferredSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT); - - if (preferredSize.x < minimumWidth) { - preferredSize.x = minimumWidth; - } - - if (preferredSize.y < minimumHeight) { - preferredSize.y = minimumHeight; - } - - final int centerX; - final int centerY; - - if (centerPolicy == CenterOption.CENTER_ON_SCREEN || shell.getParent() == null) { - Shell activeShell = shell.getDisplay().getActiveShell(); - if (activeShell == null) { - activeShell = shell; - } - final Rectangle monitorBounds = SWTGraphicUtil.getBoundsOfMonitorOnWhichShellIsDisplayed(activeShell); - centerX = monitorBounds.x + (monitorBounds.width - preferredSize.x) / 2; - centerY = monitorBounds.y + (monitorBounds.height - preferredSize.y) / 2; - } else { - final Shell parent = (Shell) shell.getParent(); - centerX = parent.getLocation().x + (parent.getSize().x - preferredSize.x) / 2; - centerY = parent.getLocation().y + (parent.getSize().y - preferredSize.y) / 2; - } - - shell.setBounds(centerX, centerY, preferredSize.x, preferredSize.y); - } - - /** - * Close the dialog box - */ - public void close() { - shell.dispose(); - } - - /** - * Compute the size of the shell - */ - void pack() { - - final Point preferredSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT); - Rectangle bounds = shell.getBounds(); - - preferredSize.x = Math.max(preferredSize.x, minimumWidth); - preferredSize.y = Math.max(preferredSize.y, minimumHeight); - - - if(lastSize != null) { - preferredSize.x = Math.max(preferredSize.x, lastSize.x); - preferredSize.y = Math.max(preferredSize.y, lastSize.y); - } - - shell.setBounds(bounds.x, bounds.y, preferredSize.x, preferredSize.y); - lastSize = null; - } - - - // ------------------------------------------- Convenient methods - - /** - * Create a dialog box that asks a question - * - * @param title title of the dialog box - * @param text text of the question - * @param defaultValue default value of the input - * @return the value typed by the user - */ - public static String ask(final String title, final String text, final String defaultValue) { - return ask(null, title, text, defaultValue); - } - - /** - * Create a dialog box that asks a question - * - * @shell parent shell - * @param title title of the dialog box - * @param text text of the question - * @param defaultValue default value of the input - * @return the value typed by the user - */ - public static String ask(final Shell shell, final String title, final String text, final String defaultValue) { - Dialog dialog = buildAskDialog(shell, title, text, defaultValue); - if (dialog.show() == 0) { - return dialog.getMessageArea().getTextBoxValue(); - } else { - return null; - } - } - - /** - * Build a dialog box that asks a question - * - * @shell parent shell - * @param title title of the dialog box - * @param text text of the question - * @param defaultValue default value of the input - * @return dialog - */ - public static Dialog buildAskDialog(final Shell shell, final String title, final String text, - final String defaultValue) { - final Dialog dialog = new Dialog(shell); - dialog.setTitle(ResourceManager.getLabel(ResourceManager.INPUT)); - dialog.getMessageArea().setTitle(title).setText(text) - .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_QUESTION)).addTextBox(defaultValue); - dialog.setButtonType(OpalDialogType.OK_CANCEL); - return dialog; - } - - /** - * Create a dialog box that displays an error message - * - * @param title title of the dialog box - * @param errorMessage Error message - */ - public static void error(final String title, final String errorMessage) { - error(null, title, errorMessage); - } - - /** - * Create a dialog box that displays an error message - * - * @param shell parent shell - * @param title title of the dialog box - * @param errorMessage Error message - */ - public static void error(final Shell shell, final String title, final String errorMessage) { - buildErrorDialog(shell, title, errorMessage).show(); - } - - /** - * Build a dialog box that displays an error message - * - * @param shell parent shell - * @param title title of the dialog box - * @param errorMessage Error message - * @return dialog - */ - public static Dialog buildErrorDialog(final Shell shell, final String title, final String errorMessage) { - final Dialog dialog = new Dialog(shell); - dialog.setTitle(ResourceManager.getLabel(ResourceManager.APPLICATION_ERROR)); - dialog.getMessageArea().setTitle(title).// - setText(errorMessage).// - setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR)); - dialog.setButtonType(OpalDialogType.OK); - return dialog; - } - - /** - * Create a dialog box that inform the user - * - * @param title title of the dialog box - * @param text text to display - */ - public static void inform(final String title, final String text) { - inform(null, title, text); - } - - /** - * Create a dialog box that inform the user - * - * @param shell parent shell - * @param title title of the dialog box - * @param text text to display - */ - public static void inform(final Shell shell, final String title, final String text) { - buildInformDialog(shell, title, text).show(); - } - - /** - * Build a dialog box that inform the user - * - * @param shell parent shell - * @param title title of the dialog box - * @param text text to display - * @return dialog - */ - public static Dialog buildInformDialog(final Shell shell, final String title, final String text) { - final Dialog dialog = new Dialog(shell); - dialog.setTitle(ResourceManager.getLabel(ResourceManager.INFORMATION)); - dialog.getMessageArea().setTitle(title).// - setText(text).setIcon(Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION)); - dialog.setButtonType(OpalDialogType.CLOSE); - return dialog; - } - - /** - * Create a dialog box that asks the user a confirmation - * - * @param title title of the dialog box - * @param text text to display - * @return true if the user confirmed, false otherwise - */ - public static boolean isConfirmed(final String title, final String text) { - return isConfirmed(null, title, text, -1); - } - - /** - * Create a dialog box that asks the user a confirmation - * - * @param shell parent shell - * @param title title of the dialog box - * @param text text to display - * @return true if the user confirmed, false otherwise - */ - public static boolean isConfirmed(final Shell shell, final String title, final String text) { - return isConfirmed(shell, title, text, -1); - } - - /** - * Create a dialog box that asks the user a confirmation. The button "yes" is - * not enabled before timer seconds - * - * @param title title of the dialog box - * @param text text to display - * @param timer number of seconds before enabling the yes button - * @return true if the user confirmed, false otherwise - */ - public static boolean isConfirmed(final String title, final String text, final int timer) { - return isConfirmed(null, title, text, timer); - } - - /** - * Create a dialog box that asks the user a confirmation. The button "yes" is - * not enabled before timer seconds - * - * @param shell parent shell - * @param title title of the dialog box - * @param text text to display - * @param timer number of seconds before enabling the yes button - * @return true if the user confirmed, false otherwise - */ - public static boolean isConfirmed(final Shell shell, final String title, final String text, final int timer) { - return buildConfirmDialog(shell, title, text, timer).show() == 0; - } - - /** - * Build a dialog box that asks the user a confirmation. The button "yes" is - * not enabled before timer seconds - * - * @param shell parent shell - * @param title title of the dialog box - * @param text text to display - * @param timer number of seconds before enabling the yes button - * @return dialog - */ - public static Dialog buildConfirmDialog(final Shell shell, final String title, final String text, final int timer) { - final Dialog dialog = new Dialog(shell); - dialog.setTitle(ResourceManager.getLabel(ResourceManager.WARNING)); - dialog.getMessageArea().setTitle(title).setText(text) - .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_WARNING)); - - dialog.getFooterArea().setTimer(timer).setTimerIndexButton(0); - dialog.setButtonType(OpalDialogType.YES_NO); - return dialog; - } - - /** - * Create a dialog box with a radio choice - * - * @param title title of the dialog box - * @param text text to display - * @param defaultSelection index of the default selection - * @param values values to display - * @return the index of the selection - */ - public static int radioChoice(final String title, final String text, final int defaultSelection, final String... values) { - return radioChoice(null, title, text, defaultSelection, values); - } - - /** - * Create a dialog box with a radio choice - * - * @param shell parent shell - * @param title title of the dialog box - * @param text text to display - * @param defaultSelection index of the default selection - * @param values values to display - * @return the index of the selection - */ - public static int radioChoice(final Shell shell, final String title, final String text, final int defaultSelection, - final String... values) { - final Dialog dialog = buildRadioChoiceDialog(shell, title, text, defaultSelection, values); - if (dialog.show() == 0) { - return dialog.getMessageArea().getRadioChoice(); - } else { - return -1; - } - } - - /** - * Build a dialog box with a radio choice - * - * @param shell parent shell - * @param title title of the dialog box - * @param text text to display - * @param defaultSelection index of the default selection - * @param values values to display - * @return dialog - */ - public static Dialog buildRadioChoiceDialog(final Shell shell, final String title, final String text, - final int defaultSelection, final String... values) { - final Dialog dialog = new Dialog(shell); - dialog.setTitle(ResourceManager.getLabel(ResourceManager.CHOICE)); - dialog.getMessageArea().setTitle(title).setText(text) - .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_QUESTION)) - .addRadioButtons(defaultSelection, values); - dialog.setButtonType(OpalDialogType.SELECT_CANCEL); - return dialog; - } - - /** - * Display a dialog box with an exception - * - * @param exception exception to display - */ - public static void showException(final Throwable exception) { - buildExceptionDialog(exception).show(); - } - - /** - * Build a dialog box with an exception - * - * @param exception exception to display - * @return dialog - */ - public static Dialog buildExceptionDialog(final Throwable exception) { - final Dialog dialog = new Dialog(); - - dialog.setTitle(ResourceManager.getLabel(ResourceManager.EXCEPTION)); - - final String msg = exception.getMessage(); - final String className = exception.getClass().getName(); - final boolean noMessage = msg == null || msg.trim().length() == 0; - - dialog.getMessageArea().setTitle(noMessage ? className : msg).// - setText(noMessage ? "" : className).// - setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR)).// - setException(exception); - - dialog.getFooterArea().setExpanded(true); - - dialog.setButtonType(OpalDialogType.CLOSE); - return dialog; - } - - /** - * Create a dialog box with a choice - * - * @param title title of the dialog box - * @param text text to display - * @param defaultSelection index of the default selection - * @param items items to display - * @return the index of the selected value - */ - public static int choice(final String title, final String text, final int defaultSelection, - final ChoiceItem... items) { - return choice(null, title, text, defaultSelection, items); - } - - /** - * Create a dialog box with a choice - * - * @param shell parent shell - * @param title title of the dialog box - * @param text text to display - * @param defaultSelection index of the default selection - * @param items items to display - * @return the index of the selected value - */ - public static int choice(final Shell shell, final String title, final String text, final int defaultSelection, final ChoiceItem... items) { - final Dialog dialog = buildChoiceDialog(shell, title, text, defaultSelection, items); - dialog.show(); - return dialog.getMessageArea().getChoice(); - } - - /** - * Build a dialog box with a choice - * - * @param shell parent shell - * @param title title of the dialog box - * @param text text to display - * @param defaultSelection index of the default selection - * @param items items to display - * @return dialog - */ - public static Dialog buildChoiceDialog(final Shell shell, final String title, final String text, - final int defaultSelection, final ChoiceItem... items) { - final Dialog dialog = new Dialog(shell); - dialog.setTitle(ResourceManager.getLabel(ResourceManager.CHOICE)); - dialog.getMessageArea().setTitle(title).setText(text) - .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_QUESTION)).addChoice(defaultSelection, items); - dialog.setButtonType(OpalDialogType.NONE); - return dialog; - } - - // ------------------------------------------- Getters & Setters - - /** - * @return the title - */ - public String getTitle() { - return title; - } - - /** - * @param title the title to set - */ - public void setTitle(final String title) { - this.title = title; - } - - /** - * @return the buttonType - */ - public OpalDialogType getButtonType() { - return buttonType; - } - - /** - * @param buttonType the buttonType to set - */ - public void setButtonType(final OpalDialogType buttonType) { - this.buttonType = buttonType; - - switch (buttonType) { - case CLOSE: - footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.CLOSE)).setDefaultButtonIndex(0); - break; - case NO_BUTTON: - break; - case OK: - footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.OK)).setDefaultButtonIndex(0); - break; - case OK_CANCEL: - footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.OK), ResourceManager.getLabel(ResourceManager.CANCEL)).setDefaultButtonIndex(-1); - break; - case SELECT_CANCEL: - footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.SELECT), ResourceManager.getLabel(ResourceManager.CANCEL)).setDefaultButtonIndex(-1); - break; - case YES_NO: - footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.YES), ResourceManager.getLabel(ResourceManager.NO)).setDefaultButtonIndex(0); - break; - default: - break; - } - - } - - /** - * @return the messageArea - */ - public MessageArea getMessageArea() { - return messageArea; - } - - /** - * @return the footerArea - */ - public FooterArea getFooterArea() { - return footerArea; - } - - /** - * @return the shell - */ - public Shell getShell() { - return shell; - } - - /** - * @return the index of the selected button - */ - public int getSelectedButton() { - return getFooterArea().getSelectedButton(); - } - - /** - * @return the selection state of the checkbox - */ - public boolean getCheckboxValue() { - return footerArea.getCheckBoxValue(); - } - - /** - * @return the minimum width of the dialog box - */ - public int getMinimumWidth() { - return minimumWidth; - } - - /** - * @param minimumWidth the minimum width of the dialog box to set - */ - public void setMinimumWidth(final int minimumWidth) { - this.minimumWidth = minimumWidth; - } - - /** - * @return the minimum height of the dialog box - */ - public int getMinimumHeight() { - return minimumHeight; - } - - /** - * @param minimumHeight the minimum height of the dialog box to set - */ - public void setMinimumHeight(final int minimumHeight) { - this.minimumHeight = minimumHeight; - } - - /** - * @return the center policy (Dialog centered on screen or centered in the - * center of the parent window) - */ - public CenterOption getCenterPolicy() { - return centerPolicy; - } - - /** - * @param centerPolicy center policy - */ - public void setCenterPolicy(final CenterOption centerPolicy) { - this.centerPolicy = centerPolicy; - } - - void setLastSize(Point lastSize) { - this.lastSize = lastSize; - } - -} +/******************************************************************************* + * Copyright (c) 2011-2019 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + * Stefan Nöbauer - Bug 550437, Bug 550659 + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.dialog; + +import org.eclipse.nebula.widgets.opal.commons.ResourceManager; +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Instances of this class are dialog box This component was inspired by the + * Oxbow Project (http://code.google.com/p/oxbow/) by Eugene Ryzhikov + */ +public class Dialog { + + /** + * Types of opal dialog + */ + public enum OpalDialogType { + CLOSE, YES_NO, OK, OK_CANCEL, SELECT_CANCEL, NO_BUTTON, OTHER, NONE + } + + public enum CenterOption { + CENTER_ON_SCREEN, CENTER_ON_DIALOG + } + + private CenterOption centerPolicy = CenterOption.CENTER_ON_SCREEN; + + private String title; + OpalDialogType buttonType; + private final MessageArea messageArea; + private final FooterArea footerArea; + final Shell shell; + + private int minimumWidth = 400; + private int minimumHeight = 150; + + private Point lastSize; + + /** + * Constructor + */ + public Dialog() { + this(null); + } + + /** + * Constructor + * + * @param resizable if true, the window is resizable + */ + public Dialog(final boolean resizable) { + this(null, resizable); + } + + /** + * Constructor + * + * @param parent parent shell + */ + public Dialog(final Shell parent) { + this(parent, true); + } + + /** + * Constructor + * + * @param parent parent shell + * @param resizable if true, the window is resizable + */ + public Dialog(final Shell parent, final boolean resizable) { + if (parent == null) { + shell = new Shell(Display.getCurrent(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | (resizable ? SWT.RESIZE : SWT.NONE)); + } else { + shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | (resizable ? SWT.RESIZE : SWT.NONE)); + if (parent.getImage() != null) { + shell.setImage(parent.getImage()); + } + } + messageArea = new MessageArea(this); + footerArea = new FooterArea(this); + } + + /** + * Show the dialog box + * + * @return the index of the selected button + */ + public int show() { + final GridLayout gd = new GridLayout(1, true); + gd.horizontalSpacing = 0; + gd.verticalSpacing = 0; + gd.marginHeight = gd.marginWidth = 0; + shell.setLayout(gd); + + messageArea.render(); + footerArea.render(); + if (title != null) { + shell.setText(title); + } + pack(); + center(); + + shell.setMinimumSize(shell.computeSize(minimumWidth, SWT.DEFAULT)); + shell.open(); + + final Display display = shell.getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + return footerArea.getSelectedButton(); + } + + private void center() { + final Point preferredSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + + if (preferredSize.x < minimumWidth) { + preferredSize.x = minimumWidth; + } + + if (preferredSize.y < minimumHeight) { + preferredSize.y = minimumHeight; + } + + final int centerX; + final int centerY; + + if (centerPolicy == CenterOption.CENTER_ON_SCREEN || shell.getParent() == null) { + Shell activeShell = shell.getDisplay().getActiveShell(); + if (activeShell == null) { + activeShell = shell; + } + final Rectangle monitorBounds = SWTGraphicUtil.getBoundsOfMonitorOnWhichShellIsDisplayed(activeShell); + centerX = monitorBounds.x + (monitorBounds.width - preferredSize.x) / 2; + centerY = monitorBounds.y + (monitorBounds.height - preferredSize.y) / 2; + } else { + final Shell parent = (Shell) shell.getParent(); + centerX = parent.getLocation().x + (parent.getSize().x - preferredSize.x) / 2; + centerY = parent.getLocation().y + (parent.getSize().y - preferredSize.y) / 2; + } + + shell.setBounds(centerX, centerY, preferredSize.x, preferredSize.y); + } + + /** + * Close the dialog box + */ + public void close() { + shell.dispose(); + } + + /** + * Compute the size of the shell + */ + void pack() { + + final Point preferredSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + Rectangle bounds = shell.getBounds(); + + preferredSize.x = Math.max(preferredSize.x, minimumWidth); + preferredSize.y = Math.max(preferredSize.y, minimumHeight); + + + if(lastSize != null) { + preferredSize.x = Math.max(preferredSize.x, lastSize.x); + preferredSize.y = Math.max(preferredSize.y, lastSize.y); + } + + shell.setBounds(bounds.x, bounds.y, preferredSize.x, preferredSize.y); + lastSize = null; + } + + + // ------------------------------------------- Convenient methods + + /** + * Create a dialog box that asks a question + * + * @param title title of the dialog box + * @param text text of the question + * @param defaultValue default value of the input + * @return the value typed by the user + */ + public static String ask(final String title, final String text, final String defaultValue) { + return ask(null, title, text, defaultValue); + } + + /** + * Create a dialog box that asks a question + * + * @shell parent shell + * @param title title of the dialog box + * @param text text of the question + * @param defaultValue default value of the input + * @return the value typed by the user + */ + public static String ask(final Shell shell, final String title, final String text, final String defaultValue) { + Dialog dialog = buildAskDialog(shell, title, text, defaultValue); + if (dialog.show() == 0) { + return dialog.getMessageArea().getTextBoxValue(); + } else { + return null; + } + } + + /** + * Build a dialog box that asks a question + * + * @shell parent shell + * @param title title of the dialog box + * @param text text of the question + * @param defaultValue default value of the input + * @return dialog + */ + public static Dialog buildAskDialog(final Shell shell, final String title, final String text, + final String defaultValue) { + final Dialog dialog = new Dialog(shell); + dialog.setTitle(ResourceManager.getLabel(ResourceManager.INPUT)); + dialog.getMessageArea().setTitle(title).setText(text) + .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_QUESTION)).addTextBox(defaultValue); + dialog.setButtonType(OpalDialogType.OK_CANCEL); + return dialog; + } + + /** + * Create a dialog box that displays an error message + * + * @param title title of the dialog box + * @param errorMessage Error message + */ + public static void error(final String title, final String errorMessage) { + error(null, title, errorMessage); + } + + /** + * Create a dialog box that displays an error message + * + * @param shell parent shell + * @param title title of the dialog box + * @param errorMessage Error message + */ + public static void error(final Shell shell, final String title, final String errorMessage) { + buildErrorDialog(shell, title, errorMessage).show(); + } + + /** + * Build a dialog box that displays an error message + * + * @param shell parent shell + * @param title title of the dialog box + * @param errorMessage Error message + * @return dialog + */ + public static Dialog buildErrorDialog(final Shell shell, final String title, final String errorMessage) { + final Dialog dialog = new Dialog(shell); + dialog.setTitle(ResourceManager.getLabel(ResourceManager.APPLICATION_ERROR)); + dialog.getMessageArea().setTitle(title).// + setText(errorMessage).// + setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR)); + dialog.setButtonType(OpalDialogType.OK); + return dialog; + } + + /** + * Create a dialog box that inform the user + * + * @param title title of the dialog box + * @param text text to display + */ + public static void inform(final String title, final String text) { + inform(null, title, text); + } + + /** + * Create a dialog box that inform the user + * + * @param shell parent shell + * @param title title of the dialog box + * @param text text to display + */ + public static void inform(final Shell shell, final String title, final String text) { + buildInformDialog(shell, title, text).show(); + } + + /** + * Build a dialog box that inform the user + * + * @param shell parent shell + * @param title title of the dialog box + * @param text text to display + * @return dialog + */ + public static Dialog buildInformDialog(final Shell shell, final String title, final String text) { + final Dialog dialog = new Dialog(shell); + dialog.setTitle(ResourceManager.getLabel(ResourceManager.INFORMATION)); + dialog.getMessageArea().setTitle(title).// + setText(text).setIcon(Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION)); + dialog.setButtonType(OpalDialogType.CLOSE); + return dialog; + } + + /** + * Create a dialog box that asks the user a confirmation + * + * @param title title of the dialog box + * @param text text to display + * @return true if the user confirmed, false otherwise + */ + public static boolean isConfirmed(final String title, final String text) { + return isConfirmed(null, title, text, -1); + } + + /** + * Create a dialog box that asks the user a confirmation + * + * @param shell parent shell + * @param title title of the dialog box + * @param text text to display + * @return true if the user confirmed, false otherwise + */ + public static boolean isConfirmed(final Shell shell, final String title, final String text) { + return isConfirmed(shell, title, text, -1); + } + + /** + * Create a dialog box that asks the user a confirmation. The button "yes" is + * not enabled before timer seconds + * + * @param title title of the dialog box + * @param text text to display + * @param timer number of seconds before enabling the yes button + * @return true if the user confirmed, false otherwise + */ + public static boolean isConfirmed(final String title, final String text, final int timer) { + return isConfirmed(null, title, text, timer); + } + + /** + * Create a dialog box that asks the user a confirmation. The button "yes" is + * not enabled before timer seconds + * + * @param shell parent shell + * @param title title of the dialog box + * @param text text to display + * @param timer number of seconds before enabling the yes button + * @return true if the user confirmed, false otherwise + */ + public static boolean isConfirmed(final Shell shell, final String title, final String text, final int timer) { + return buildConfirmDialog(shell, title, text, timer).show() == 0; + } + + /** + * Build a dialog box that asks the user a confirmation. The button "yes" is + * not enabled before timer seconds + * + * @param shell parent shell + * @param title title of the dialog box + * @param text text to display + * @param timer number of seconds before enabling the yes button + * @return dialog + */ + public static Dialog buildConfirmDialog(final Shell shell, final String title, final String text, final int timer) { + final Dialog dialog = new Dialog(shell); + dialog.setTitle(ResourceManager.getLabel(ResourceManager.WARNING)); + dialog.getMessageArea().setTitle(title).setText(text) + .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_WARNING)); + + dialog.getFooterArea().setTimer(timer).setTimerIndexButton(0); + dialog.setButtonType(OpalDialogType.YES_NO); + return dialog; + } + + /** + * Create a dialog box with a radio choice + * + * @param title title of the dialog box + * @param text text to display + * @param defaultSelection index of the default selection + * @param values values to display + * @return the index of the selection + */ + public static int radioChoice(final String title, final String text, final int defaultSelection, final String... values) { + return radioChoice(null, title, text, defaultSelection, values); + } + + /** + * Create a dialog box with a radio choice + * + * @param shell parent shell + * @param title title of the dialog box + * @param text text to display + * @param defaultSelection index of the default selection + * @param values values to display + * @return the index of the selection + */ + public static int radioChoice(final Shell shell, final String title, final String text, final int defaultSelection, + final String... values) { + final Dialog dialog = buildRadioChoiceDialog(shell, title, text, defaultSelection, values); + if (dialog.show() == 0) { + return dialog.getMessageArea().getRadioChoice(); + } else { + return -1; + } + } + + /** + * Build a dialog box with a radio choice + * + * @param shell parent shell + * @param title title of the dialog box + * @param text text to display + * @param defaultSelection index of the default selection + * @param values values to display + * @return dialog + */ + public static Dialog buildRadioChoiceDialog(final Shell shell, final String title, final String text, + final int defaultSelection, final String... values) { + final Dialog dialog = new Dialog(shell); + dialog.setTitle(ResourceManager.getLabel(ResourceManager.CHOICE)); + dialog.getMessageArea().setTitle(title).setText(text) + .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_QUESTION)) + .addRadioButtons(defaultSelection, values); + dialog.setButtonType(OpalDialogType.SELECT_CANCEL); + return dialog; + } + + /** + * Display a dialog box with an exception + * + * @param exception exception to display + */ + public static void showException(final Throwable exception) { + buildExceptionDialog(exception).show(); + } + + /** + * Build a dialog box with an exception + * + * @param exception exception to display + * @return dialog + */ + public static Dialog buildExceptionDialog(final Throwable exception) { + final Dialog dialog = new Dialog(); + + dialog.setTitle(ResourceManager.getLabel(ResourceManager.EXCEPTION)); + + final String msg = exception.getMessage(); + final String className = exception.getClass().getName(); + final boolean noMessage = msg == null || msg.trim().length() == 0; + + dialog.getMessageArea().setTitle(noMessage ? className : msg).// + setText(noMessage ? "" : className).// + setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR)).// + setException(exception); + + dialog.getFooterArea().setExpanded(true); + + dialog.setButtonType(OpalDialogType.CLOSE); + return dialog; + } + + /** + * Create a dialog box with a choice + * + * @param title title of the dialog box + * @param text text to display + * @param defaultSelection index of the default selection + * @param items items to display + * @return the index of the selected value + */ + public static int choice(final String title, final String text, final int defaultSelection, + final ChoiceItem... items) { + return choice(null, title, text, defaultSelection, items); + } + + /** + * Create a dialog box with a choice + * + * @param shell parent shell + * @param title title of the dialog box + * @param text text to display + * @param defaultSelection index of the default selection + * @param items items to display + * @return the index of the selected value + */ + public static int choice(final Shell shell, final String title, final String text, final int defaultSelection, final ChoiceItem... items) { + final Dialog dialog = buildChoiceDialog(shell, title, text, defaultSelection, items); + dialog.show(); + return dialog.getMessageArea().getChoice(); + } + + /** + * Build a dialog box with a choice + * + * @param shell parent shell + * @param title title of the dialog box + * @param text text to display + * @param defaultSelection index of the default selection + * @param items items to display + * @return dialog + */ + public static Dialog buildChoiceDialog(final Shell shell, final String title, final String text, + final int defaultSelection, final ChoiceItem... items) { + final Dialog dialog = new Dialog(shell); + dialog.setTitle(ResourceManager.getLabel(ResourceManager.CHOICE)); + dialog.getMessageArea().setTitle(title).setText(text) + .setIcon(Display.getCurrent().getSystemImage(SWT.ICON_QUESTION)).addChoice(defaultSelection, items); + dialog.setButtonType(OpalDialogType.NONE); + return dialog; + } + + // ------------------------------------------- Getters & Setters + + /** + * @return the title + */ + public String getTitle() { + return title; + } + + /** + * @param title the title to set + */ + public void setTitle(final String title) { + this.title = title; + } + + /** + * @return the buttonType + */ + public OpalDialogType getButtonType() { + return buttonType; + } + + /** + * @param buttonType the buttonType to set + */ + public void setButtonType(final OpalDialogType buttonType) { + this.buttonType = buttonType; + + switch (buttonType) { + case CLOSE: + footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.CLOSE)).setDefaultButtonIndex(0); + break; + case NO_BUTTON: + break; + case OK: + footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.OK)).setDefaultButtonIndex(0); + break; + case OK_CANCEL: + footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.OK), ResourceManager.getLabel(ResourceManager.CANCEL)).setDefaultButtonIndex(-1); + break; + case SELECT_CANCEL: + footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.SELECT), ResourceManager.getLabel(ResourceManager.CANCEL)).setDefaultButtonIndex(-1); + break; + case YES_NO: + footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.YES), ResourceManager.getLabel(ResourceManager.NO)).setDefaultButtonIndex(0); + break; + default: + break; + } + + } + + /** + * @return the messageArea + */ + public MessageArea getMessageArea() { + return messageArea; + } + + /** + * @return the footerArea + */ + public FooterArea getFooterArea() { + return footerArea; + } + + /** + * @return the shell + */ + public Shell getShell() { + return shell; + } + + /** + * @return the index of the selected button + */ + public int getSelectedButton() { + return getFooterArea().getSelectedButton(); + } + + /** + * @return the selection state of the checkbox + */ + public boolean getCheckboxValue() { + return footerArea.getCheckBoxValue(); + } + + /** + * @return the minimum width of the dialog box + */ + public int getMinimumWidth() { + return minimumWidth; + } + + /** + * @param minimumWidth the minimum width of the dialog box to set + */ + public void setMinimumWidth(final int minimumWidth) { + this.minimumWidth = minimumWidth; + } + + /** + * @return the minimum height of the dialog box + */ + public int getMinimumHeight() { + return minimumHeight; + } + + /** + * @param minimumHeight the minimum height of the dialog box to set + */ + public void setMinimumHeight(final int minimumHeight) { + this.minimumHeight = minimumHeight; + } + + /** + * @return the center policy (Dialog centered on screen or centered in the + * center of the parent window) + */ + public CenterOption getCenterPolicy() { + return centerPolicy; + } + + /** + * @param centerPolicy center policy + */ + public void setCenterPolicy(final CenterOption centerPolicy) { + this.centerPolicy = centerPolicy; + } + + void setLastSize(Point lastSize) { + this.lastSize = lastSize; + } + +} diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/DialogArea.java b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/DialogArea.java index 276558f76..e2d4604ff 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/DialogArea.java +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/DialogArea.java @@ -1,143 +1,143 @@ -/******************************************************************************* - * Copyright (c) 2011-2019 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - * Stefan Nöbauer - Bug 550437 - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.dialog; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; - -/** - * This abstract class if the mother of MessageArea and FooterArea classes - */ -abstract class DialogArea { - private static final String MORE_DETAILS_IMAGE = "moreDetails.png"; - private static final String FEWER_DETAILS_IMAGE = "fewerDetails.png"; - private static final String WINDOWS_DEFAULT_FONT = "Segoe UI"; - private static final String MAC_OS_DEFAULT_FONT = "Lucida Grande"; - protected final Dialog parent; - private boolean initialised; - - /** - * Constructor - * - * @param parent parent dialog - */ - public DialogArea(final Dialog parent) { - this.parent = parent; - } - - /** - * Render the content of an area - */ - abstract void render(); - - /** - * @return the initialised field - */ - boolean isInitialised() { - return initialised; - } - - /** - * @param initialised the initialised value to set - */ - void setInitialised(final boolean initialised) { - this.initialised = initialised; - } - - /** - * @return the normal font used by the dialog box - */ - protected Font getNormalFont() { - if (SWTGraphicUtil.isMacOS()) { - return getFont(MAC_OS_DEFAULT_FONT, 11, SWT.NONE); - } else { - return getFont(WINDOWS_DEFAULT_FONT, 9, SWT.NONE); - } - } - - /** - * @return the bigger font used by the dialog box - */ - protected Font getBiggerFont() { - if (SWTGraphicUtil.isMacOS()) { - return getFont(MAC_OS_DEFAULT_FONT, 13, SWT.NONE); - } else { - return getFont(WINDOWS_DEFAULT_FONT, 11, SWT.NONE); - } - } - - /** - * Build a font - * - * @param name name of the font - * @param size size of the font - * @param style style of the font - * @return the font - */ - private Font getFont(final String name, final int size, final int style) { - final Font font = new Font(Display.getCurrent(), name, size, style); - parent.shell.addDisposeListener(e -> { - SWTGraphicUtil.safeDispose(font); - }); - return font; - } - - /** - * @return the title's color (blue) - */ - protected Color getTitleColor() { - final Color color = new Color(Display.getCurrent(), 35, 107, 178); - SWTGraphicUtil.addDisposer(parent.shell, color); - return color; - } - - /** - * @return the grey color - */ - protected Color getGreyColor() { - final Color color = new Color(Display.getCurrent(), 240, 240, 240); - SWTGraphicUtil.addDisposer(parent.shell, color); - return color; - } - - /** - * @return the image "fewer details" - */ - protected Image getFewerDetailsImage() { - return loadImage("images/" + FEWER_DETAILS_IMAGE); - } - - /** - * @return the image "more details" - */ - protected Image getMoreDetailsImage() { - return loadImage("images/" + MORE_DETAILS_IMAGE); - } - - /** - * Loads an image - * - * @param fileName file name of the image - * @return the image - */ - private Image loadImage(final String fileName) { - final Image image = SWTGraphicUtil.createImageFromFile(fileName); - SWTGraphicUtil.addDisposer(parent.shell, image); - return image; - } -} +/******************************************************************************* + * Copyright (c) 2011-2019 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + * Stefan Nöbauer - Bug 550437 + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.dialog; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +/** + * This abstract class if the mother of MessageArea and FooterArea classes + */ +abstract class DialogArea { + private static final String MORE_DETAILS_IMAGE = "moreDetails.png"; + private static final String FEWER_DETAILS_IMAGE = "fewerDetails.png"; + private static final String WINDOWS_DEFAULT_FONT = "Segoe UI"; + private static final String MAC_OS_DEFAULT_FONT = "Lucida Grande"; + protected final Dialog parent; + private boolean initialised; + + /** + * Constructor + * + * @param parent parent dialog + */ + public DialogArea(final Dialog parent) { + this.parent = parent; + } + + /** + * Render the content of an area + */ + abstract void render(); + + /** + * @return the initialised field + */ + boolean isInitialised() { + return initialised; + } + + /** + * @param initialised the initialised value to set + */ + void setInitialised(final boolean initialised) { + this.initialised = initialised; + } + + /** + * @return the normal font used by the dialog box + */ + protected Font getNormalFont() { + if (SWTGraphicUtil.isMacOS()) { + return getFont(MAC_OS_DEFAULT_FONT, 11, SWT.NONE); + } else { + return getFont(WINDOWS_DEFAULT_FONT, 9, SWT.NONE); + } + } + + /** + * @return the bigger font used by the dialog box + */ + protected Font getBiggerFont() { + if (SWTGraphicUtil.isMacOS()) { + return getFont(MAC_OS_DEFAULT_FONT, 13, SWT.NONE); + } else { + return getFont(WINDOWS_DEFAULT_FONT, 11, SWT.NONE); + } + } + + /** + * Build a font + * + * @param name name of the font + * @param size size of the font + * @param style style of the font + * @return the font + */ + private Font getFont(final String name, final int size, final int style) { + final Font font = new Font(Display.getCurrent(), name, size, style); + parent.shell.addDisposeListener(e -> { + SWTGraphicUtil.safeDispose(font); + }); + return font; + } + + /** + * @return the title's color (blue) + */ + protected Color getTitleColor() { + final Color color = new Color(Display.getCurrent(), 35, 107, 178); + SWTGraphicUtil.addDisposer(parent.shell, color); + return color; + } + + /** + * @return the grey color + */ + protected Color getGreyColor() { + final Color color = new Color(Display.getCurrent(), 240, 240, 240); + SWTGraphicUtil.addDisposer(parent.shell, color); + return color; + } + + /** + * @return the image "fewer details" + */ + protected Image getFewerDetailsImage() { + return loadImage("images/" + FEWER_DETAILS_IMAGE); + } + + /** + * @return the image "more details" + */ + protected Image getMoreDetailsImage() { + return loadImage("images/" + MORE_DETAILS_IMAGE); + } + + /** + * Loads an image + * + * @param fileName file name of the image + * @return the image + */ + private Image loadImage(final String fileName) { + final Image image = SWTGraphicUtil.createImageFromFile(fileName); + SWTGraphicUtil.addDisposer(parent.shell, image); + return image; + } +} diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/FooterArea.java b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/FooterArea.java index ba9ee47cb..440078d00 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/FooterArea.java +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/FooterArea.java @@ -1,610 +1,610 @@ -/******************************************************************************* - * Copyright (c) 2011-2019 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - * Stefan Nöbauer - Bug 550659 - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.dialog; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Supplier; - -import org.eclipse.nebula.widgets.opal.commons.ResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; - -/** - * Instances of this class are message areas - */ -public class FooterArea extends DialogArea { - private static final int BUTTON_WIDTH = 70; - private Image icon; - private String footerText; - - private List buttonLabels; - private int defaultButtonIndex; - - private int timer; - private int timerIndexButton; - - int selectedButtonIndex; - - private String collapsedLabelText; - private String expandedLabelText; - private boolean expanded; - private String detailText; - private boolean details; - private Button disabledButton; - - private String checkBoxLabel; - private boolean checkBoxValue; - - private Text expandedPanel; - private Composite composite; - private ToolBar toolbar; - - private List footerActions = new ArrayList<>(); - - /** - * Constructor - * - * @param parent dialog that is composed of this footer area - */ - public FooterArea(final Dialog parent) { - super(parent); - selectedButtonIndex = -1; - expandedLabelText = ResourceManager.getLabel(ResourceManager.FEWER_DETAILS); - collapsedLabelText = ResourceManager.getLabel(ResourceManager.MORE_DETAILS); - timer = -1; - timerIndexButton = -1; - } - - /** - * Add a check box - * - * @param label label to display - * @param selection default value of the check box - * @return this footer area - */ - public FooterArea addCheckBox(final String label, final boolean selection) { - checkBoxLabel = label; - checkBoxValue = selection; - setInitialised(true); - return this; - } - - /** - * @see org.eclipse.nebula.widgets.opal.dialog.DialogArea#render() - */ - @Override - void render() { - if (!isInitialised()) { - return; - } - - createSeparator(); - - composite = new Composite(parent.shell, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - composite.setBackground(getGreyColor()); - - int numberOfColumns = buttonLabels == null ? 0 : buttonLabels.size(); - if (details || !footerActions.isEmpty()) { - numberOfColumns += 1; - } - - final GridLayout gridLayout = new GridLayout(numberOfColumns, false); - gridLayout.marginHeight = gridLayout.marginWidth = 10; - composite.setLayout(gridLayout); - - if (details || !footerActions.isEmpty()) { - gridLayout.marginHeight = 5; - toolbar = new ToolBar(composite, SWT.NONE); - } - - if(details) { - createDetails(numberOfColumns); - } - - if(!footerActions.isEmpty()) { - createFooterActions(); - } - - if (buttonLabels != null) { - createButtons(); - } - - if (details && parent.getMessageArea().getException() == null && expanded) { - createExpandedPanel(numberOfColumns); - } - - if (checkBoxLabel != null) { - createCheckBox(numberOfColumns); - } - - if (footerText != null) { - createFooter(); - } - - } - - /** - * Create the buttons - */ - private void createButtons() { - Button defaultButton = null; - for (int i = 0; i < buttonLabels.size(); i++) { - final Button button = new Button(composite, SWT.PUSH); - button.setText(buttonLabels.get(i)); - - final GridData gd = new GridData(GridData.END, GridData.CENTER, i == 0, false); - final int defaultWidth = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; - gd.minimumWidth = Math.max(BUTTON_WIDTH, defaultWidth); - gd.widthHint = Math.max(BUTTON_WIDTH, defaultWidth); - button.setLayoutData(gd); - - if (i == defaultButtonIndex) { - defaultButton = button; - } - - final Integer integer = Integer.valueOf(i); - button.addListener(SWT.Selection, e -> { - FooterArea.this.parent.shell.dispose(); - selectedButtonIndex = integer.intValue(); - }); - - if (i == timerIndexButton && timer != -1) { - disabledButton = button; - button.setData(button.getText()); - button.setText(button.getText() + " (" + timer + ")"); - button.setEnabled(false); - final int newWidth = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; - gd.minimumWidth = Math.max(BUTTON_WIDTH, newWidth); - gd.widthHint = Math.max(BUTTON_WIDTH, newWidth); - button.getParent().layout(new Control[] { button }); - } - - } - - if (timerIndexButton != -1 && timer != -1) { - Display.getCurrent().timerExec(1000, new Runnable() { - - @Override - public void run() { - timer--; - if (disabledButton.isDisposed()) { - return; - } - - if (timer == 0) { - disabledButton.setText((String) disabledButton.getData()); - disabledButton.setEnabled(true); - } else { - disabledButton.setText(disabledButton.getData() + " (" + timer + ")"); - final GridData gd = (GridData) disabledButton.getLayoutData(); - final int defaultWidth = disabledButton.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; - gd.minimumWidth = Math.max(BUTTON_WIDTH, defaultWidth); - gd.widthHint = Math.max(BUTTON_WIDTH, defaultWidth); - disabledButton.getParent().layout(new Control[] { disabledButton }); - Display.getCurrent().timerExec(1000, this); - } - - } - }); - } - - parent.shell.setDefaultButton(defaultButton); - } - - /** - * Create the details section - * - * @param numberOfColumns - */ - private void createDetails(final int numberOfColumns) { - final ToolItem detailsItem = new ToolItem(toolbar, SWT.NONE); - detailsItem.setImage(isExpanded() ? getFewerDetailsImage() : getMoreDetailsImage()); - detailsItem.setText(isExpanded() ? expandedLabelText : collapsedLabelText); - - final int numberOfColumnsParam = numberOfColumns; - - final Listener listener = event -> { - if (FooterArea.this.parent.getMessageArea().getException() != null) { - if (detailsItem.getText().equals(expandedLabelText)) { - detailsItem.setText(collapsedLabelText); - detailsItem.setImage(FooterArea.this.getMoreDetailsImage()); - - FooterArea.this.parent.getMessageArea().hideException(); - } else { - detailsItem.setText(expandedLabelText); - detailsItem.setImage(FooterArea.this.getFewerDetailsImage()); - - FooterArea.this.parent.getMessageArea().showException(); - } - - } else { - if (detailsItem.getText().equals(expandedLabelText)) { - detailsItem.setText(collapsedLabelText); - detailsItem.setImage(FooterArea.this.getMoreDetailsImage()); - - expandedPanel.dispose(); - FooterArea.this.parent.pack(); - } else { - detailsItem.setText(expandedLabelText); - detailsItem.setImage(FooterArea.this.getFewerDetailsImage()); - - FooterArea.this.createExpandedPanel(numberOfColumnsParam); - FooterArea.this.parent.pack(); - } - } - }; - - detailsItem.addListener(SWT.Selection, listener); - } - - private void createFooterActions() { - for (FooterAction action : footerActions) { - final ToolItem item = new ToolItem(toolbar, SWT.NONE); - item.setText(action.getLabel()); - item.addListener(SWT.Selection, e -> action.getAction().accept(parent)); - - if (action.getActive().isPresent()) { - item.setImage(action.getActive().get()); - } - if (action.getInactive().isPresent()) { - item.setDisabledImage(action.getInactive().get()); - } - if (action.getHot().isPresent()) { - item.setHotImage(action.getHot().get()); - } - - } - } - - /** - * Create a check box - * - * @param numberOfColumns - */ - private void createCheckBox(final int numberOfColumns) { - final Button button = new Button(composite, SWT.CHECK); - button.setText(checkBoxLabel); - button.setSelection(checkBoxValue); - button.setBackground(getGreyColor()); - button.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, false, numberOfColumns, 1)); - button.addListener(SWT.Selection, e -> { - checkBoxValue = button.getSelection(); - }); - } - - /** - * Create footer section - */ - private void createFooter() { - createSeparator(); - - final Composite informationComposite = new Composite(parent.shell, SWT.NONE); - informationComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - informationComposite.setBackground(getGreyColor()); - - informationComposite.setLayout(new GridLayout(icon == null ? 1 : 2, false)); - - if (icon != null) { - final Label labelIcon = new Label(informationComposite, SWT.NONE); - labelIcon.setBackground(getGreyColor()); - labelIcon.setImage(icon); - labelIcon.setLayoutData(new GridData(GridData.CENTER, GridData.CENTER, false, false)); - } - final Label labelText = new Label(informationComposite, SWT.NONE); - labelText.setBackground(getGreyColor()); - labelText.setText(footerText); - labelText.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); - } - - /** - * Create the expanded panel - * - * @param numberOfColumns - */ - private void createExpandedPanel(final int numberOfColumns) { - expandedPanel = new Text(composite, SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); - expandedPanel.setText(detailText); - expandedPanel.setBackground(getGreyColor()); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false, numberOfColumns, 1); - gd.minimumHeight = gd.heightHint = 150; - expandedPanel.setLayoutData(gd); - } - - /** - * Create a separator - */ - private void createSeparator() { - final Composite c = new Composite(parent.shell, SWT.NONE); - c.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - c.setBackground(getGreyColor()); - - final GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginHeight = gridLayout.marginWidth = 0; - c.setLayout(gridLayout); - - final Label separator = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL); - separator.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - } - - // ------------------------------------------- Getters & Setters - - /** - * @return the icon - */ - public Image getIcon() { - return icon; - } - - /** - * @param icon the icon to set - * @return this footer area - */ - public FooterArea setIcon(final Image icon) { - this.icon = icon; - setInitialised(true); - return this; - } - - /** - * @return the text - */ - public String getFooterText() { - return footerText; - } - - /** - * @param text the text to set - * @return this footer area - */ - public FooterArea setFooterText(final String text) { - footerText = text; - setInitialised(true); - return this; - } - - /** - * @return the button labels - */ - public List getButtonLabels() { - return buttonLabels; - } - - /** - * @param buttonLabels the button labels to set - * @return this footer area - */ - public FooterArea setButtonLabels(final List buttonLabels) { - this.buttonLabels = buttonLabels; - setInitialised(true); - return this; - } - - /** - * @param buttonLabels the button labels to set - * @return this footer area - */ - public FooterArea setButtonLabels(final String... buttonLabels) { - this.buttonLabels = Arrays.asList(buttonLabels); - setInitialised(true); - return this; - } - - /** - * - * @param action Runnable to be called when pressed. - * @param label label of the footer action - * @param images Images Array [active, highlight, inactive] - * @return - */ - public FooterArea addFooterAction(Supplier label, Consumer action, Image... images) { - footerActions.add(new FooterAction(label, action, images)); - return this; - } - - /** - * @return the default button index - */ - public int getDefaultButtonIndex() { - return defaultButtonIndex; - } - - /** - * @param defaultButtonIndex the default button index to set - * @return this footer area - */ - public FooterArea setDefaultButtonIndex(final int defaultButtonIndex) { - this.defaultButtonIndex = defaultButtonIndex; - setInitialised(true); - return this; - } - - /** - * @return the timer value - */ - public int getTimer() { - return timer; - } - - /** - * @param timer the timer value to set - * @return this footer area - */ - public FooterArea setTimer(final int timer) { - this.timer = timer; - setInitialised(true); - return this; - } - - /** - * @return the timer index button - */ - public int getTimerIndexButton() { - return timerIndexButton; - } - - /** - * @param timerIndexButton the timer index button to set - * @return this footer area - */ - public FooterArea setTimerIndexButton(final int timerIndexButton) { - this.timerIndexButton = timerIndexButton; - setInitialised(true); - return this; - } - - /** - * @return the selected button - */ - int getSelectedButton() { - return selectedButtonIndex; - } - - /** - * @return the collapsed label text - */ - public String getCollapsedLabelText() { - return collapsedLabelText; - } - - /** - * @param collapsedLabelText the collapsed label text to set - * @return this footer area - */ - public FooterArea setCollapsedLabelText(final String collapsedLabelText) { - details = true; - this.collapsedLabelText = collapsedLabelText; - setInitialised(true); - return this; - } - - /** - * @return the expanded label text - */ - public String getExpandedLabelText() { - return expandedLabelText; - } - - /** - * @param expandedLabelText the expanded label text to set - * @return this footer area - */ - public FooterArea setExpandedLabelText(final String expandedLabelText) { - details = true; - this.expandedLabelText = expandedLabelText; - setInitialised(true); - return this; - } - - /** - * @return the expanded flag - */ - public boolean isExpanded() { - return expanded; - } - - /** - * @param expanded the expanded flag to set - * @return this footer area - */ - public FooterArea setExpanded(final boolean expanded) { - details = true; - this.expanded = expanded; - setInitialised(true); - return this; - } - - /** - * @return the detail text - */ - public String getDetailText() { - return detailText; - } - - /** - * @param detailText the detail text to set - * @return this footer area - */ - public FooterArea setDetailText(final String detailText) { - details = true; - this.detailText = detailText; - setInitialised(true); - return this; - } - - /** - * @return the check box vqlue - */ - public boolean getCheckBoxValue() { - return checkBoxValue; - } - - private class FooterAction { - private Consumer action; - private Image active; - private Image inactive; - private Image hot; - private Supplier label; - - public FooterAction(Supplier label, Consumer action, Image... images) { - this.label = label; - this.action = action; - if (images.length > 0) { - active = images[0]; - } - if (images.length > 1) { - hot = images[1]; - } - if (images.length > 2) { - inactive = images[2]; - } - } - - public Consumer getAction() { - return action; - } - - public Optional getActive() { - return Optional.ofNullable(active); - } - - public Optional getInactive() { - return Optional.ofNullable(inactive); - } - - public Optional getHot() { - return Optional.ofNullable(hot); - } - - public String getLabel() { - return label.get(); - } - - } -} +/******************************************************************************* + * Copyright (c) 2011-2019 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + * Stefan Nöbauer - Bug 550659 + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.dialog; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import org.eclipse.nebula.widgets.opal.commons.ResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +/** + * Instances of this class are message areas + */ +public class FooterArea extends DialogArea { + private static final int BUTTON_WIDTH = 70; + private Image icon; + private String footerText; + + private List buttonLabels; + private int defaultButtonIndex; + + private int timer; + private int timerIndexButton; + + int selectedButtonIndex; + + private String collapsedLabelText; + private String expandedLabelText; + private boolean expanded; + private String detailText; + private boolean details; + private Button disabledButton; + + private String checkBoxLabel; + private boolean checkBoxValue; + + private Text expandedPanel; + private Composite composite; + private ToolBar toolbar; + + private List footerActions = new ArrayList<>(); + + /** + * Constructor + * + * @param parent dialog that is composed of this footer area + */ + public FooterArea(final Dialog parent) { + super(parent); + selectedButtonIndex = -1; + expandedLabelText = ResourceManager.getLabel(ResourceManager.FEWER_DETAILS); + collapsedLabelText = ResourceManager.getLabel(ResourceManager.MORE_DETAILS); + timer = -1; + timerIndexButton = -1; + } + + /** + * Add a check box + * + * @param label label to display + * @param selection default value of the check box + * @return this footer area + */ + public FooterArea addCheckBox(final String label, final boolean selection) { + checkBoxLabel = label; + checkBoxValue = selection; + setInitialised(true); + return this; + } + + /** + * @see org.eclipse.nebula.widgets.opal.dialog.DialogArea#render() + */ + @Override + void render() { + if (!isInitialised()) { + return; + } + + createSeparator(); + + composite = new Composite(parent.shell, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + composite.setBackground(getGreyColor()); + + int numberOfColumns = buttonLabels == null ? 0 : buttonLabels.size(); + if (details || !footerActions.isEmpty()) { + numberOfColumns += 1; + } + + final GridLayout gridLayout = new GridLayout(numberOfColumns, false); + gridLayout.marginHeight = gridLayout.marginWidth = 10; + composite.setLayout(gridLayout); + + if (details || !footerActions.isEmpty()) { + gridLayout.marginHeight = 5; + toolbar = new ToolBar(composite, SWT.NONE); + } + + if(details) { + createDetails(numberOfColumns); + } + + if(!footerActions.isEmpty()) { + createFooterActions(); + } + + if (buttonLabels != null) { + createButtons(); + } + + if (details && parent.getMessageArea().getException() == null && expanded) { + createExpandedPanel(numberOfColumns); + } + + if (checkBoxLabel != null) { + createCheckBox(numberOfColumns); + } + + if (footerText != null) { + createFooter(); + } + + } + + /** + * Create the buttons + */ + private void createButtons() { + Button defaultButton = null; + for (int i = 0; i < buttonLabels.size(); i++) { + final Button button = new Button(composite, SWT.PUSH); + button.setText(buttonLabels.get(i)); + + final GridData gd = new GridData(GridData.END, GridData.CENTER, i == 0, false); + final int defaultWidth = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; + gd.minimumWidth = Math.max(BUTTON_WIDTH, defaultWidth); + gd.widthHint = Math.max(BUTTON_WIDTH, defaultWidth); + button.setLayoutData(gd); + + if (i == defaultButtonIndex) { + defaultButton = button; + } + + final Integer integer = Integer.valueOf(i); + button.addListener(SWT.Selection, e -> { + FooterArea.this.parent.shell.dispose(); + selectedButtonIndex = integer.intValue(); + }); + + if (i == timerIndexButton && timer != -1) { + disabledButton = button; + button.setData(button.getText()); + button.setText(button.getText() + " (" + timer + ")"); + button.setEnabled(false); + final int newWidth = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; + gd.minimumWidth = Math.max(BUTTON_WIDTH, newWidth); + gd.widthHint = Math.max(BUTTON_WIDTH, newWidth); + button.getParent().layout(new Control[] { button }); + } + + } + + if (timerIndexButton != -1 && timer != -1) { + Display.getCurrent().timerExec(1000, new Runnable() { + + @Override + public void run() { + timer--; + if (disabledButton.isDisposed()) { + return; + } + + if (timer == 0) { + disabledButton.setText((String) disabledButton.getData()); + disabledButton.setEnabled(true); + } else { + disabledButton.setText(disabledButton.getData() + " (" + timer + ")"); + final GridData gd = (GridData) disabledButton.getLayoutData(); + final int defaultWidth = disabledButton.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; + gd.minimumWidth = Math.max(BUTTON_WIDTH, defaultWidth); + gd.widthHint = Math.max(BUTTON_WIDTH, defaultWidth); + disabledButton.getParent().layout(new Control[] { disabledButton }); + Display.getCurrent().timerExec(1000, this); + } + + } + }); + } + + parent.shell.setDefaultButton(defaultButton); + } + + /** + * Create the details section + * + * @param numberOfColumns + */ + private void createDetails(final int numberOfColumns) { + final ToolItem detailsItem = new ToolItem(toolbar, SWT.NONE); + detailsItem.setImage(isExpanded() ? getFewerDetailsImage() : getMoreDetailsImage()); + detailsItem.setText(isExpanded() ? expandedLabelText : collapsedLabelText); + + final int numberOfColumnsParam = numberOfColumns; + + final Listener listener = event -> { + if (FooterArea.this.parent.getMessageArea().getException() != null) { + if (detailsItem.getText().equals(expandedLabelText)) { + detailsItem.setText(collapsedLabelText); + detailsItem.setImage(FooterArea.this.getMoreDetailsImage()); + + FooterArea.this.parent.getMessageArea().hideException(); + } else { + detailsItem.setText(expandedLabelText); + detailsItem.setImage(FooterArea.this.getFewerDetailsImage()); + + FooterArea.this.parent.getMessageArea().showException(); + } + + } else { + if (detailsItem.getText().equals(expandedLabelText)) { + detailsItem.setText(collapsedLabelText); + detailsItem.setImage(FooterArea.this.getMoreDetailsImage()); + + expandedPanel.dispose(); + FooterArea.this.parent.pack(); + } else { + detailsItem.setText(expandedLabelText); + detailsItem.setImage(FooterArea.this.getFewerDetailsImage()); + + FooterArea.this.createExpandedPanel(numberOfColumnsParam); + FooterArea.this.parent.pack(); + } + } + }; + + detailsItem.addListener(SWT.Selection, listener); + } + + private void createFooterActions() { + for (FooterAction action : footerActions) { + final ToolItem item = new ToolItem(toolbar, SWT.NONE); + item.setText(action.getLabel()); + item.addListener(SWT.Selection, e -> action.getAction().accept(parent)); + + if (action.getActive().isPresent()) { + item.setImage(action.getActive().get()); + } + if (action.getInactive().isPresent()) { + item.setDisabledImage(action.getInactive().get()); + } + if (action.getHot().isPresent()) { + item.setHotImage(action.getHot().get()); + } + + } + } + + /** + * Create a check box + * + * @param numberOfColumns + */ + private void createCheckBox(final int numberOfColumns) { + final Button button = new Button(composite, SWT.CHECK); + button.setText(checkBoxLabel); + button.setSelection(checkBoxValue); + button.setBackground(getGreyColor()); + button.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, false, numberOfColumns, 1)); + button.addListener(SWT.Selection, e -> { + checkBoxValue = button.getSelection(); + }); + } + + /** + * Create footer section + */ + private void createFooter() { + createSeparator(); + + final Composite informationComposite = new Composite(parent.shell, SWT.NONE); + informationComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + informationComposite.setBackground(getGreyColor()); + + informationComposite.setLayout(new GridLayout(icon == null ? 1 : 2, false)); + + if (icon != null) { + final Label labelIcon = new Label(informationComposite, SWT.NONE); + labelIcon.setBackground(getGreyColor()); + labelIcon.setImage(icon); + labelIcon.setLayoutData(new GridData(GridData.CENTER, GridData.CENTER, false, false)); + } + final Label labelText = new Label(informationComposite, SWT.NONE); + labelText.setBackground(getGreyColor()); + labelText.setText(footerText); + labelText.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); + } + + /** + * Create the expanded panel + * + * @param numberOfColumns + */ + private void createExpandedPanel(final int numberOfColumns) { + expandedPanel = new Text(composite, SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); + expandedPanel.setText(detailText); + expandedPanel.setBackground(getGreyColor()); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false, numberOfColumns, 1); + gd.minimumHeight = gd.heightHint = 150; + expandedPanel.setLayoutData(gd); + } + + /** + * Create a separator + */ + private void createSeparator() { + final Composite c = new Composite(parent.shell, SWT.NONE); + c.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + c.setBackground(getGreyColor()); + + final GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginHeight = gridLayout.marginWidth = 0; + c.setLayout(gridLayout); + + final Label separator = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL); + separator.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + } + + // ------------------------------------------- Getters & Setters + + /** + * @return the icon + */ + public Image getIcon() { + return icon; + } + + /** + * @param icon the icon to set + * @return this footer area + */ + public FooterArea setIcon(final Image icon) { + this.icon = icon; + setInitialised(true); + return this; + } + + /** + * @return the text + */ + public String getFooterText() { + return footerText; + } + + /** + * @param text the text to set + * @return this footer area + */ + public FooterArea setFooterText(final String text) { + footerText = text; + setInitialised(true); + return this; + } + + /** + * @return the button labels + */ + public List getButtonLabels() { + return buttonLabels; + } + + /** + * @param buttonLabels the button labels to set + * @return this footer area + */ + public FooterArea setButtonLabels(final List buttonLabels) { + this.buttonLabels = buttonLabels; + setInitialised(true); + return this; + } + + /** + * @param buttonLabels the button labels to set + * @return this footer area + */ + public FooterArea setButtonLabels(final String... buttonLabels) { + this.buttonLabels = Arrays.asList(buttonLabels); + setInitialised(true); + return this; + } + + /** + * + * @param action Runnable to be called when pressed. + * @param label label of the footer action + * @param images Images Array [active, highlight, inactive] + * @return + */ + public FooterArea addFooterAction(Supplier label, Consumer action, Image... images) { + footerActions.add(new FooterAction(label, action, images)); + return this; + } + + /** + * @return the default button index + */ + public int getDefaultButtonIndex() { + return defaultButtonIndex; + } + + /** + * @param defaultButtonIndex the default button index to set + * @return this footer area + */ + public FooterArea setDefaultButtonIndex(final int defaultButtonIndex) { + this.defaultButtonIndex = defaultButtonIndex; + setInitialised(true); + return this; + } + + /** + * @return the timer value + */ + public int getTimer() { + return timer; + } + + /** + * @param timer the timer value to set + * @return this footer area + */ + public FooterArea setTimer(final int timer) { + this.timer = timer; + setInitialised(true); + return this; + } + + /** + * @return the timer index button + */ + public int getTimerIndexButton() { + return timerIndexButton; + } + + /** + * @param timerIndexButton the timer index button to set + * @return this footer area + */ + public FooterArea setTimerIndexButton(final int timerIndexButton) { + this.timerIndexButton = timerIndexButton; + setInitialised(true); + return this; + } + + /** + * @return the selected button + */ + int getSelectedButton() { + return selectedButtonIndex; + } + + /** + * @return the collapsed label text + */ + public String getCollapsedLabelText() { + return collapsedLabelText; + } + + /** + * @param collapsedLabelText the collapsed label text to set + * @return this footer area + */ + public FooterArea setCollapsedLabelText(final String collapsedLabelText) { + details = true; + this.collapsedLabelText = collapsedLabelText; + setInitialised(true); + return this; + } + + /** + * @return the expanded label text + */ + public String getExpandedLabelText() { + return expandedLabelText; + } + + /** + * @param expandedLabelText the expanded label text to set + * @return this footer area + */ + public FooterArea setExpandedLabelText(final String expandedLabelText) { + details = true; + this.expandedLabelText = expandedLabelText; + setInitialised(true); + return this; + } + + /** + * @return the expanded flag + */ + public boolean isExpanded() { + return expanded; + } + + /** + * @param expanded the expanded flag to set + * @return this footer area + */ + public FooterArea setExpanded(final boolean expanded) { + details = true; + this.expanded = expanded; + setInitialised(true); + return this; + } + + /** + * @return the detail text + */ + public String getDetailText() { + return detailText; + } + + /** + * @param detailText the detail text to set + * @return this footer area + */ + public FooterArea setDetailText(final String detailText) { + details = true; + this.detailText = detailText; + setInitialised(true); + return this; + } + + /** + * @return the check box vqlue + */ + public boolean getCheckBoxValue() { + return checkBoxValue; + } + + private class FooterAction { + private Consumer action; + private Image active; + private Image inactive; + private Image hot; + private Supplier label; + + public FooterAction(Supplier label, Consumer action, Image... images) { + this.label = label; + this.action = action; + if (images.length > 0) { + active = images[0]; + } + if (images.length > 1) { + hot = images[1]; + } + if (images.length > 2) { + inactive = images[2]; + } + } + + public Consumer getAction() { + return action; + } + + public Optional getActive() { + return Optional.ofNullable(active); + } + + public Optional getInactive() { + return Optional.ofNullable(inactive); + } + + public Optional getHot() { + return Optional.ofNullable(hot); + } + + public String getLabel() { + return label.get(); + } + + } +} diff --git a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/MessageArea.java b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/MessageArea.java index 9c2df06f8..ed142acf7 100644 --- a/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/MessageArea.java +++ b/widgets/opal/dialog/org.eclipse.nebula.widgets.opal.dialog/src/org/eclipse/nebula/widgets/opal/dialog/MessageArea.java @@ -1,658 +1,658 @@ -/******************************************************************************* - * Copyright (c) 2011-2019 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation - * Stefan Nöbauer - Bug 550437 - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.dialog; - -import org.eclipse.nebula.widgets.opal.commons.ReadOnlyStyledText; -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.commons.StringUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ProgressBar; -import org.eclipse.swt.widgets.Text; - -/** - * Instances of this class are message areas - */ -public class MessageArea extends DialogArea { - private static final int INDENT_NO_ICON = 8; - private static final int DEFAULT_MARGIN = 10; - - // Main composite - private Composite composite; - - // Informations for a simple dialog box - private String title; - private Image icon; - private String text; - - // Informations for a radio choice dialog box - private int radioChoice; - private int radioDefaultSelection; - private String[] radioValues; - - // Informations for a exception viewer dialog box - private Throwable exception; - private Text textException; - - // Informations for an input dialog box - private String textBoxValue; - - // Informations for a choice dialog box - private int choice; - private int choiceDefaultSelection; - private ChoiceItem[] choiceValues; - - // Informations for a progress bar displayed in a dialog box - private ProgressBar progressBar; - private int progressBarMinimumValue; - private int progressBarMaximumValue; - private int progressBarValue; - - private boolean verticalScrollbar = false; - private int height = -1; - - private StyledText label; - - private String checkBoxLabel; - private boolean checkBoxValue; - private Composite bottomComponent; - - /** - * Constructor - * - * @param parent dialog that is composed of this message area - */ - public MessageArea(final Dialog parent) { - super(parent); - radioChoice = -1; - choice = -1; - progressBarValue = -1; - } - - /** - * Add a choice - * - * @param defaultSelection default selection - * @param items a list of the choice item - * @return the current message area - */ - public MessageArea addChoice(final int defaultSelection, final ChoiceItem... items) { - setInitialised(true); - choiceDefaultSelection = defaultSelection; - choiceValues = items; - return this; - } - - /** - * Add a choice composed of radio buttons - * - * @param defaultSelection default selection - * @param values values - * @return the current message area - */ - public MessageArea addRadioButtons(final int defaultSelection, final String... values) { - setInitialised(true); - radioDefaultSelection = defaultSelection; - radioValues = values; - return this; - } - - /** - * Add a text box for input - * - * @param value defaut value of the textbox - * @return the current message area - */ - public MessageArea addTextBox(final String value) { - setInitialised(true); - textBoxValue = value; - return this; - } - - /** - * Add a progress bar - * - * @param mininum minimum value - * @param maximum maximum value - * @param value default value - * @return the current message area - */ - public MessageArea addProgressBar(final int mininum, final int maximum, final int value) { - setInitialised(true); - progressBarMinimumValue = mininum; - progressBarMaximumValue = maximum; - progressBarValue = value; - return this; - } - - /** - * Add a check box - * - * @param label label to display - * @param selection default value of the check box - * @return this message area - */ - public MessageArea addCheckBox(final String label, final boolean selection) { - checkBoxLabel = label; - checkBoxValue = selection; - setInitialised(true); - return this; - } - /** - * @see org.eclipse.nebula.widgets.opal.dialog.DialogArea#render() - */ - @Override - public void render() { - if (!isInitialised()) { - return; - } - - composite = new Composite(parent.shell, SWT.NONE); - composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - composite.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - composite.setBackgroundMode(SWT.INHERIT_DEFAULT); - - final boolean hasIcon = icon != null; - final boolean hasTitle = !StringUtil.isEmpty(title); - final boolean hasText = !StringUtil.isEmpty(text); - final boolean hasRadio = radioValues != null; - final boolean hasException = exception != null; - final boolean hasTextbox = textBoxValue != null; - final boolean hasChoice = choiceValues != null; - final boolean hasProgressBar = progressBarValue != -1; - final boolean hasCheckbox = !StringUtil.isEmpty(checkBoxLabel); - - final int numberOfColumns = hasIcon ? 2 : 1; - int numberOfRows = hasTitle && hasText ? 2 : 1; - - if (hasRadio) { - numberOfRows += radioValues.length; - } - - if (hasChoice) { - numberOfRows += choiceValues.length; - } - - if (hasException || hasTextbox) { - numberOfRows++; - } - - if (hasProgressBar) { - numberOfRows++; - } - - final GridLayout gridLayout = new GridLayout(numberOfColumns, false); - gridLayout.marginHeight = gridLayout.marginWidth = 0; - gridLayout.marginRight = DEFAULT_MARGIN; - gridLayout.marginLeft = DEFAULT_MARGIN; - gridLayout.marginTop = DEFAULT_MARGIN; - gridLayout.marginBottom = DEFAULT_MARGIN; - composite.setLayout(gridLayout); - - if (hasIcon) { - createIcon(numberOfRows); - } - - if (hasTitle) { - createTitle(hasIcon); - } - - if (hasText) { - createText(hasIcon, hasTitle); - } - - if (hasRadio) { - createRadioButtons(); - } - - if (hasException) { - createTextException(); - } - - if (hasTextbox) { - createTextBox(); - } - - if (hasChoice) { - createChoice(); - } - - if (hasProgressBar) { - createProgressBar(); - } - - - bottomComponent = new Composite(parent.shell, SWT.NONE); - bottomComponent.setLayoutData(new GridData(GridData.FILL, SWT.BOTTOM, true, false)); - bottomComponent.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - bottomComponent.setBackgroundMode(SWT.INHERIT_DEFAULT); - - final GridLayout bottomGridLayout = new GridLayout(1, false); - bottomGridLayout.marginHeight = gridLayout.marginWidth = 0; - bottomGridLayout.marginRight = DEFAULT_MARGIN; - bottomGridLayout.marginLeft = DEFAULT_MARGIN; - bottomGridLayout.marginTop = DEFAULT_MARGIN; - bottomGridLayout.marginBottom = DEFAULT_MARGIN; - bottomComponent.setLayout(gridLayout); - - if (hasCheckbox) { - createCheckBox(); - } - - } - - /** - * Create the icon - * - * @param numberOfRows number of rows displayed - */ - private void createIcon(final int numberOfRows) { - final Label label = new Label(composite, SWT.NONE); - label.setImage(icon); - label.setLayoutData(new GridData(GridData.CENTER, GridData.BEGINNING, false, false, 1, numberOfRows)); - } - - /** - * Create the title - * - * @param hasIcon if true an icon is displayed - */ - private void createTitle(final boolean hasIcon) { - final Label label = new Label(composite, SWT.NONE); - label.setText(title); - label.setFont(getBiggerFont()); - label.setForeground(getTitleColor()); - final GridData gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false, 1, 1); - - if (hasIcon) { - gd.horizontalIndent = INDENT_NO_ICON; - } else { - gd.horizontalIndent = DEFAULT_MARGIN; - gd.verticalIndent = DEFAULT_MARGIN; - } - - label.setLayoutData(gd); - } - - /** - * Create the text - * - * @param hasIcon if true an icon is displayed - * @param hasTitle if true a title is displayed - */ - private void createText(final boolean hasIcon, final boolean hasTitle) { - label = new ReadOnlyStyledText(composite, SWT.NONE | (verticalScrollbar ? SWT.V_SCROLL : SWT.NONE)); - label.setText(text); - - SWTGraphicUtil.applyHTMLFormating(label); - label.setEditable(false); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1); - if (height != -1) { - gd.heightHint = height; - } - - if (hasIcon) { - gd.horizontalIndent = INDENT_NO_ICON; - } else { - gd.horizontalIndent = DEFAULT_MARGIN * 2; - if (hasTitle) { - gd.verticalIndent = INDENT_NO_ICON; - } else { - gd.verticalIndent = DEFAULT_MARGIN * 2; - } - } - - label.setLayoutData(gd); - } - - /** - * Create radio buttons - */ - private void createRadioButtons() { - for (int i = 0; i < radioValues.length; i++) { - final Button button = new Button(composite, SWT.RADIO); - button.setText(radioValues[i]); - - final Integer index = Integer.valueOf(i); - button.addListener(SWT.Selection, e -> { - if (button.getSelection()) { - radioChoice = index.intValue(); - } - }); - - button.setSelection(i == radioDefaultSelection); - final GridData gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false, 1, 1); - gd.horizontalIndent = DEFAULT_MARGIN; - button.setLayoutData(gd); - } - } - - /** - * Create the text that displays an exception - */ - private void createTextException() { - textException = new Text(composite, SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); - textException.setText(StringUtil.stackStraceAsString(exception)); - textException.setBackground(composite.getBackground()); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1); - textException.setLayoutData(gd); - } - - /** - * Create a text box - */ - private void createTextBox() { - final Text textbox = new Text(composite, SWT.BORDER | SWT.WRAP); - textbox.setText(textBoxValue); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1); - textbox.setLayoutData(gd); - textbox.addListener(SWT.Modify, e -> { - textBoxValue = textbox.getText(); - }); - - textbox.addListener(SWT.KeyUp, e -> { - if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { - MessageArea.this.parent.shell.dispose(); - MessageArea.this.parent.getFooterArea().selectedButtonIndex = 0; - } - }); - - textbox.getShell().addListener(SWT.Activate, new Listener() { - - @Override - public void handleEvent(final Event arg0) { - textbox.forceFocus(); - textbox.setSelection(textbox.getText().length()); - textbox.getShell().removeListener(SWT.Activate, this); - } - }); - - } - - /** - * Create a choice selection - */ - private void createChoice() { - for (int i = 0; i < choiceValues.length; i++) { - final ChoiceWidget choice = new ChoiceWidget(composite, SWT.RADIO); - choice.setChoiceItem(choiceValues[i]); - - final Integer index = Integer.valueOf(i); - choice.addSelectionListener(new SelectionAdapter() { - - /** - * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetSelected(final SelectionEvent e) { - MessageArea.this.choice = index.intValue(); - MessageArea.this.parent.shell.dispose(); - } - - }); - - choice.setSelection(i == choiceDefaultSelection); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false, 1, 1); - choice.setLayoutData(gd); - } - } - - /** - * Create a progress bar - */ - private void createProgressBar() { - progressBar = new ProgressBar(composite, SWT.SMOOTH | SWT.HORIZONTAL); - progressBar.setMinimum(progressBarMinimumValue); - progressBar.setMaximum(progressBarMaximumValue); - progressBar.setSelection(progressBarValue); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1); - progressBar.setLayoutData(gd); - } - - /** - * Create a check box - * - * @param numberOfColumns - */ - private void createCheckBox() { - final Button button = new Button(bottomComponent, SWT.CHECK); - button.setText(checkBoxLabel); - button.setSelection(checkBoxValue); - button.setLayoutData(new GridData(SWT.BEGINNING, SWT.BOTTOM, true, true, 1, 1)); - button.addListener(SWT.Selection, e -> { - checkBoxValue = button.getSelection(); - }); - } - - /** - * Hide the exception panel - */ - void hideException() { - Point size = parent.shell.getSize(); - - textException.setVisible(false); - ((GridData)textException.getLayoutData()).exclude = true; - - parent.shell.setMinimumSize(new Point(0,0)); - parent.shell.layout(); - parent.pack(); - parent.shell.setMinimumSize(parent.shell.getSize()); - parent.setLastSize(size); - } - - /** - * Show the exception panel - */ - void showException() { - if(textException == null) { - createTextException(); - } else { - textException.setVisible(true); - ((GridData)textException.getLayoutData()).exclude = false; - parent.shell.layout(); - } - parent.pack(); - } - - // ------------------------------------------- Getters & Setters - - /** - * @return the title - */ - public String getTitle() { - return title; - } - - /** - * @param title the title to set - * @return the current message area - */ - public MessageArea setTitle(final String title) { - this.title = title; - setInitialised(true); - return this; - } - - /** - * @return the icon - */ - public Image getIcon() { - return icon; - } - - /** - * @param icon the icon to set - */ - public MessageArea setIcon(final Image icon) { - this.icon = icon; - setInitialised(true); - return this; - } - - /** - * @return the text - */ - public String getText() { - return text; - } - - /** - * @param text the text to set - */ - public MessageArea setText(final String text) { - this.text = text; - setInitialised(true); - if (progressBar != null && label != null && !label.isDisposed()) { - label.setText(text); - SWTGraphicUtil.applyHTMLFormating(label); - } - return this; - } - - /** - * @return the radio choice - */ - public int getRadioChoice() { - return radioChoice; - } - - /** - * @return the exception - */ - public Throwable getException() { - return exception; - } - - /** - * @param exception the exception to set - * @return - */ - public MessageArea setException(final Throwable exception) { - this.exception = exception; - setInitialised(true); - return this; - } - - /** - * @return the choice - */ - public int getChoice() { - return choice; - } - - /** - * @return the value stored in the text box - */ - public String getTextBoxValue() { - return textBoxValue; - } - - /** - * @return the progress bar minimum value - */ - public int getProgressBarMinimumValue() { - return progressBarMinimumValue; - } - - /** - * @param progressBarMinimumValue the progress bar minimum value to set - */ - public void setProgressBarMinimumValue(final int progressBarMinimumValue) { - this.progressBarMinimumValue = progressBarMinimumValue; - if (progressBar != null && !progressBar.isDisposed()) { - progressBar.setMinimum(progressBarMinimumValue); - } - } - - /** - * @return the progress bar maximum value - */ - public int getProgressBarMaximumValue() { - return progressBarMaximumValue; - } - - /** - * @param progressBarMaximumValue the progress bar minimum value to set - */ - public void setProgressBarMaximumValue(final int progressBarMaximumValue) { - this.progressBarMaximumValue = progressBarMaximumValue; - if (progressBar != null && !progressBar.isDisposed()) { - progressBar.setMaximum(progressBarMaximumValue); - } - } - - /** - * @return the progress bar value - */ - public int getProgressBarValue() { - return progressBarValue; - } - - /** - * @param progressBarValue the progress bar value to set - */ - public void setProgressBarValue(final int progressBarValue) { - this.progressBarValue = progressBarValue; - if (progressBar != null && !progressBar.isDisposed()) { - progressBar.setSelection(progressBarValue); - } - } - - /** - * @return the verticalScrollbar - */ - public boolean isVerticalScrollbar() { - return verticalScrollbar; - } - - /** - * @param verticalScrollbar the verticalScrollbar to set - */ - public void setVerticalScrollbar(final boolean verticalScrollbar) { - this.verticalScrollbar = verticalScrollbar; - } - - /** - * @return the height - */ - public int getHeight() { - return height; - } - - /** - * @param height the height to set - */ - public void setHeight(final int height) { - this.height = height; - } - - /** - * @return the check box vqlue - */ - public boolean getCheckBoxValue() { - return checkBoxValue; - } - -} +/******************************************************************************* + * Copyright (c) 2011-2019 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation + * Stefan Nöbauer - Bug 550437 + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.dialog; + +import org.eclipse.nebula.widgets.opal.commons.ReadOnlyStyledText; +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.commons.StringUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ProgressBar; +import org.eclipse.swt.widgets.Text; + +/** + * Instances of this class are message areas + */ +public class MessageArea extends DialogArea { + private static final int INDENT_NO_ICON = 8; + private static final int DEFAULT_MARGIN = 10; + + // Main composite + private Composite composite; + + // Informations for a simple dialog box + private String title; + private Image icon; + private String text; + + // Informations for a radio choice dialog box + private int radioChoice; + private int radioDefaultSelection; + private String[] radioValues; + + // Informations for a exception viewer dialog box + private Throwable exception; + private Text textException; + + // Informations for an input dialog box + private String textBoxValue; + + // Informations for a choice dialog box + private int choice; + private int choiceDefaultSelection; + private ChoiceItem[] choiceValues; + + // Informations for a progress bar displayed in a dialog box + private ProgressBar progressBar; + private int progressBarMinimumValue; + private int progressBarMaximumValue; + private int progressBarValue; + + private boolean verticalScrollbar = false; + private int height = -1; + + private StyledText label; + + private String checkBoxLabel; + private boolean checkBoxValue; + private Composite bottomComponent; + + /** + * Constructor + * + * @param parent dialog that is composed of this message area + */ + public MessageArea(final Dialog parent) { + super(parent); + radioChoice = -1; + choice = -1; + progressBarValue = -1; + } + + /** + * Add a choice + * + * @param defaultSelection default selection + * @param items a list of the choice item + * @return the current message area + */ + public MessageArea addChoice(final int defaultSelection, final ChoiceItem... items) { + setInitialised(true); + choiceDefaultSelection = defaultSelection; + choiceValues = items; + return this; + } + + /** + * Add a choice composed of radio buttons + * + * @param defaultSelection default selection + * @param values values + * @return the current message area + */ + public MessageArea addRadioButtons(final int defaultSelection, final String... values) { + setInitialised(true); + radioDefaultSelection = defaultSelection; + radioValues = values; + return this; + } + + /** + * Add a text box for input + * + * @param value defaut value of the textbox + * @return the current message area + */ + public MessageArea addTextBox(final String value) { + setInitialised(true); + textBoxValue = value; + return this; + } + + /** + * Add a progress bar + * + * @param mininum minimum value + * @param maximum maximum value + * @param value default value + * @return the current message area + */ + public MessageArea addProgressBar(final int mininum, final int maximum, final int value) { + setInitialised(true); + progressBarMinimumValue = mininum; + progressBarMaximumValue = maximum; + progressBarValue = value; + return this; + } + + /** + * Add a check box + * + * @param label label to display + * @param selection default value of the check box + * @return this message area + */ + public MessageArea addCheckBox(final String label, final boolean selection) { + checkBoxLabel = label; + checkBoxValue = selection; + setInitialised(true); + return this; + } + /** + * @see org.eclipse.nebula.widgets.opal.dialog.DialogArea#render() + */ + @Override + public void render() { + if (!isInitialised()) { + return; + } + + composite = new Composite(parent.shell, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + composite.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + composite.setBackgroundMode(SWT.INHERIT_DEFAULT); + + final boolean hasIcon = icon != null; + final boolean hasTitle = !StringUtil.isEmpty(title); + final boolean hasText = !StringUtil.isEmpty(text); + final boolean hasRadio = radioValues != null; + final boolean hasException = exception != null; + final boolean hasTextbox = textBoxValue != null; + final boolean hasChoice = choiceValues != null; + final boolean hasProgressBar = progressBarValue != -1; + final boolean hasCheckbox = !StringUtil.isEmpty(checkBoxLabel); + + final int numberOfColumns = hasIcon ? 2 : 1; + int numberOfRows = hasTitle && hasText ? 2 : 1; + + if (hasRadio) { + numberOfRows += radioValues.length; + } + + if (hasChoice) { + numberOfRows += choiceValues.length; + } + + if (hasException || hasTextbox) { + numberOfRows++; + } + + if (hasProgressBar) { + numberOfRows++; + } + + final GridLayout gridLayout = new GridLayout(numberOfColumns, false); + gridLayout.marginHeight = gridLayout.marginWidth = 0; + gridLayout.marginRight = DEFAULT_MARGIN; + gridLayout.marginLeft = DEFAULT_MARGIN; + gridLayout.marginTop = DEFAULT_MARGIN; + gridLayout.marginBottom = DEFAULT_MARGIN; + composite.setLayout(gridLayout); + + if (hasIcon) { + createIcon(numberOfRows); + } + + if (hasTitle) { + createTitle(hasIcon); + } + + if (hasText) { + createText(hasIcon, hasTitle); + } + + if (hasRadio) { + createRadioButtons(); + } + + if (hasException) { + createTextException(); + } + + if (hasTextbox) { + createTextBox(); + } + + if (hasChoice) { + createChoice(); + } + + if (hasProgressBar) { + createProgressBar(); + } + + + bottomComponent = new Composite(parent.shell, SWT.NONE); + bottomComponent.setLayoutData(new GridData(GridData.FILL, SWT.BOTTOM, true, false)); + bottomComponent.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + bottomComponent.setBackgroundMode(SWT.INHERIT_DEFAULT); + + final GridLayout bottomGridLayout = new GridLayout(1, false); + bottomGridLayout.marginHeight = gridLayout.marginWidth = 0; + bottomGridLayout.marginRight = DEFAULT_MARGIN; + bottomGridLayout.marginLeft = DEFAULT_MARGIN; + bottomGridLayout.marginTop = DEFAULT_MARGIN; + bottomGridLayout.marginBottom = DEFAULT_MARGIN; + bottomComponent.setLayout(gridLayout); + + if (hasCheckbox) { + createCheckBox(); + } + + } + + /** + * Create the icon + * + * @param numberOfRows number of rows displayed + */ + private void createIcon(final int numberOfRows) { + final Label label = new Label(composite, SWT.NONE); + label.setImage(icon); + label.setLayoutData(new GridData(GridData.CENTER, GridData.BEGINNING, false, false, 1, numberOfRows)); + } + + /** + * Create the title + * + * @param hasIcon if true an icon is displayed + */ + private void createTitle(final boolean hasIcon) { + final Label label = new Label(composite, SWT.NONE); + label.setText(title); + label.setFont(getBiggerFont()); + label.setForeground(getTitleColor()); + final GridData gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false, 1, 1); + + if (hasIcon) { + gd.horizontalIndent = INDENT_NO_ICON; + } else { + gd.horizontalIndent = DEFAULT_MARGIN; + gd.verticalIndent = DEFAULT_MARGIN; + } + + label.setLayoutData(gd); + } + + /** + * Create the text + * + * @param hasIcon if true an icon is displayed + * @param hasTitle if true a title is displayed + */ + private void createText(final boolean hasIcon, final boolean hasTitle) { + label = new ReadOnlyStyledText(composite, SWT.NONE | (verticalScrollbar ? SWT.V_SCROLL : SWT.NONE)); + label.setText(text); + + SWTGraphicUtil.applyHTMLFormating(label); + label.setEditable(false); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1); + if (height != -1) { + gd.heightHint = height; + } + + if (hasIcon) { + gd.horizontalIndent = INDENT_NO_ICON; + } else { + gd.horizontalIndent = DEFAULT_MARGIN * 2; + if (hasTitle) { + gd.verticalIndent = INDENT_NO_ICON; + } else { + gd.verticalIndent = DEFAULT_MARGIN * 2; + } + } + + label.setLayoutData(gd); + } + + /** + * Create radio buttons + */ + private void createRadioButtons() { + for (int i = 0; i < radioValues.length; i++) { + final Button button = new Button(composite, SWT.RADIO); + button.setText(radioValues[i]); + + final Integer index = Integer.valueOf(i); + button.addListener(SWT.Selection, e -> { + if (button.getSelection()) { + radioChoice = index.intValue(); + } + }); + + button.setSelection(i == radioDefaultSelection); + final GridData gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false, 1, 1); + gd.horizontalIndent = DEFAULT_MARGIN; + button.setLayoutData(gd); + } + } + + /** + * Create the text that displays an exception + */ + private void createTextException() { + textException = new Text(composite, SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); + textException.setText(StringUtil.stackStraceAsString(exception)); + textException.setBackground(composite.getBackground()); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1); + textException.setLayoutData(gd); + } + + /** + * Create a text box + */ + private void createTextBox() { + final Text textbox = new Text(composite, SWT.BORDER | SWT.WRAP); + textbox.setText(textBoxValue); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1); + textbox.setLayoutData(gd); + textbox.addListener(SWT.Modify, e -> { + textBoxValue = textbox.getText(); + }); + + textbox.addListener(SWT.KeyUp, e -> { + if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + MessageArea.this.parent.shell.dispose(); + MessageArea.this.parent.getFooterArea().selectedButtonIndex = 0; + } + }); + + textbox.getShell().addListener(SWT.Activate, new Listener() { + + @Override + public void handleEvent(final Event arg0) { + textbox.forceFocus(); + textbox.setSelection(textbox.getText().length()); + textbox.getShell().removeListener(SWT.Activate, this); + } + }); + + } + + /** + * Create a choice selection + */ + private void createChoice() { + for (int i = 0; i < choiceValues.length; i++) { + final ChoiceWidget choice = new ChoiceWidget(composite, SWT.RADIO); + choice.setChoiceItem(choiceValues[i]); + + final Integer index = Integer.valueOf(i); + choice.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + MessageArea.this.choice = index.intValue(); + MessageArea.this.parent.shell.dispose(); + } + + }); + + choice.setSelection(i == choiceDefaultSelection); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false, 1, 1); + choice.setLayoutData(gd); + } + } + + /** + * Create a progress bar + */ + private void createProgressBar() { + progressBar = new ProgressBar(composite, SWT.SMOOTH | SWT.HORIZONTAL); + progressBar.setMinimum(progressBarMinimumValue); + progressBar.setMaximum(progressBarMaximumValue); + progressBar.setSelection(progressBarValue); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1); + progressBar.setLayoutData(gd); + } + + /** + * Create a check box + * + * @param numberOfColumns + */ + private void createCheckBox() { + final Button button = new Button(bottomComponent, SWT.CHECK); + button.setText(checkBoxLabel); + button.setSelection(checkBoxValue); + button.setLayoutData(new GridData(SWT.BEGINNING, SWT.BOTTOM, true, true, 1, 1)); + button.addListener(SWT.Selection, e -> { + checkBoxValue = button.getSelection(); + }); + } + + /** + * Hide the exception panel + */ + void hideException() { + Point size = parent.shell.getSize(); + + textException.setVisible(false); + ((GridData)textException.getLayoutData()).exclude = true; + + parent.shell.setMinimumSize(new Point(0,0)); + parent.shell.layout(); + parent.pack(); + parent.shell.setMinimumSize(parent.shell.getSize()); + parent.setLastSize(size); + } + + /** + * Show the exception panel + */ + void showException() { + if(textException == null) { + createTextException(); + } else { + textException.setVisible(true); + ((GridData)textException.getLayoutData()).exclude = false; + parent.shell.layout(); + } + parent.pack(); + } + + // ------------------------------------------- Getters & Setters + + /** + * @return the title + */ + public String getTitle() { + return title; + } + + /** + * @param title the title to set + * @return the current message area + */ + public MessageArea setTitle(final String title) { + this.title = title; + setInitialised(true); + return this; + } + + /** + * @return the icon + */ + public Image getIcon() { + return icon; + } + + /** + * @param icon the icon to set + */ + public MessageArea setIcon(final Image icon) { + this.icon = icon; + setInitialised(true); + return this; + } + + /** + * @return the text + */ + public String getText() { + return text; + } + + /** + * @param text the text to set + */ + public MessageArea setText(final String text) { + this.text = text; + setInitialised(true); + if (progressBar != null && label != null && !label.isDisposed()) { + label.setText(text); + SWTGraphicUtil.applyHTMLFormating(label); + } + return this; + } + + /** + * @return the radio choice + */ + public int getRadioChoice() { + return radioChoice; + } + + /** + * @return the exception + */ + public Throwable getException() { + return exception; + } + + /** + * @param exception the exception to set + * @return + */ + public MessageArea setException(final Throwable exception) { + this.exception = exception; + setInitialised(true); + return this; + } + + /** + * @return the choice + */ + public int getChoice() { + return choice; + } + + /** + * @return the value stored in the text box + */ + public String getTextBoxValue() { + return textBoxValue; + } + + /** + * @return the progress bar minimum value + */ + public int getProgressBarMinimumValue() { + return progressBarMinimumValue; + } + + /** + * @param progressBarMinimumValue the progress bar minimum value to set + */ + public void setProgressBarMinimumValue(final int progressBarMinimumValue) { + this.progressBarMinimumValue = progressBarMinimumValue; + if (progressBar != null && !progressBar.isDisposed()) { + progressBar.setMinimum(progressBarMinimumValue); + } + } + + /** + * @return the progress bar maximum value + */ + public int getProgressBarMaximumValue() { + return progressBarMaximumValue; + } + + /** + * @param progressBarMaximumValue the progress bar minimum value to set + */ + public void setProgressBarMaximumValue(final int progressBarMaximumValue) { + this.progressBarMaximumValue = progressBarMaximumValue; + if (progressBar != null && !progressBar.isDisposed()) { + progressBar.setMaximum(progressBarMaximumValue); + } + } + + /** + * @return the progress bar value + */ + public int getProgressBarValue() { + return progressBarValue; + } + + /** + * @param progressBarValue the progress bar value to set + */ + public void setProgressBarValue(final int progressBarValue) { + this.progressBarValue = progressBarValue; + if (progressBar != null && !progressBar.isDisposed()) { + progressBar.setSelection(progressBarValue); + } + } + + /** + * @return the verticalScrollbar + */ + public boolean isVerticalScrollbar() { + return verticalScrollbar; + } + + /** + * @param verticalScrollbar the verticalScrollbar to set + */ + public void setVerticalScrollbar(final boolean verticalScrollbar) { + this.verticalScrollbar = verticalScrollbar; + } + + /** + * @return the height + */ + public int getHeight() { + return height; + } + + /** + * @param height the height to set + */ + public void setHeight(final int height) { + this.height = height; + } + + /** + * @return the check box vqlue + */ + public boolean getCheckBoxValue() { + return checkBoxValue; + } + +} diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/.project b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/.project index bbf48417f..69194316f 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/.project +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.duallist.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.duallist.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/build.properties b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/build.properties +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/feature.properties b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/feature.properties +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.classpath b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.classpath +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.project b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.project index 2146e0245..2ada0fa1d 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.project +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.duallist.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.duallist.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/META-INF/MANIFEST.MF b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/META-INF/MANIFEST.MF index 4e058b979..25fdef3d0 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Dual List Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.duallist.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.duallist;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.duallist.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Dual List Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.duallist.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.duallist;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.duallist.snippets diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/build.properties b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/build.properties +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/src/org/eclipse/nebula/widgets/opal/duallist/snippets/DualListSnippet.java b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/src/org/eclipse/nebula/widgets/opal/duallist/snippets/DualListSnippet.java index c7a9fe8a2..c3951ce93 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/src/org/eclipse/nebula/widgets/opal/duallist/snippets/DualListSnippet.java +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/src/org/eclipse/nebula/widgets/opal/duallist/snippets/DualListSnippet.java @@ -1,133 +1,133 @@ -/******************************************************************************* - * Copyright (c) 2011-2021 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.duallist.snippets; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.duallist.DLItem; -import org.eclipse.nebula.widgets.opal.duallist.DLItem.LAST_ACTION; -import org.eclipse.nebula.widgets.opal.duallist.DualList; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple snipper for the DualList Widget - * - */ -public class DualListSnippet { - - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setText("Dual List Snippet"); - shell.setSize(600, 600); - shell.setLayout(new GridLayout(1, false)); - - final DualList dl = new DualList(shell, SWT.NONE); - dl.setItems(createItems(shell)); - - dl.addSelectionChangeListener(e -> { - System.out.println("Selection Change Listener called"); - for (final DLItem item : e.getItems()) { - final StringBuilder sb = new StringBuilder(); - if (item.getLastAction() == LAST_ACTION.SELECTION) { - sb.append("[SELECTION] "); - } else { - sb.append("[DE-SELECTION] "); - } - sb.append(item.getText()); - System.out.println(sb.toString()); - } - }); - - dl.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - - } - - private static List createItems(final Shell shell) { - final List list = new ArrayList<>(); - - String defaultFontName = null; - int defaultHeight = -1; - for (final FontData fontData : shell.getFont().getFontData()) { - if (defaultFontName == null) { - defaultFontName = fontData.getName(); - } - if (defaultHeight == -1) { - defaultHeight = fontData.getHeight(); - } - } - - final Font font = new Font(shell.getDisplay(), defaultFontName, defaultHeight, SWT.BOLD); - - list.add(new DLItem("Austria", createImage(shell, "austria"))); - list.add(new DLItem("Belgium", createImage(shell, "belgium"))); - list.add(new DLItem("Bulgaria", createImage(shell, "bulgaria"))); - list.add(new DLItem("Cyprus", createImage(shell, "cyprus"))); - list.add(new DLItem("Czech Republic", createImage(shell, "czech"))); - list.add(new DLItem("Denmark", createImage(shell, "denmark"))); - list.add(new DLItem("Estonia", createImage(shell, "estonia"))); - list.add(new DLItem("Finland", createImage(shell, "finland"))); - list.add(new DLItem("France", createImage(shell, "france"), font)); - list.add(new DLItem("Germany", createImage(shell, "germany"))); - list.add(new DLItem("Greece", createImage(shell, "greece"))); - list.add(new DLItem("Hungary", createImage(shell, "hungary"))); - list.add(new DLItem("Ireland", createImage(shell, "ireland"))); - list.add(new DLItem("Italy", createImage(shell, "italy"))); - list.add(new DLItem("Latvia", createImage(shell, "latvia"))); - list.add(new DLItem("Lithuania", createImage(shell, "lithuania"))); - list.add(new DLItem("Luxembourg", createImage(shell, "luxembourg"))); - list.add(new DLItem("Malta", createImage(shell, "malta"))); - list.add(new DLItem("Netherlands", createImage(shell, "netherlands"))); - list.add(new DLItem("Poland", createImage(shell, "poland"), shell.getDisplay().getSystemColor(SWT.COLOR_WHITE), shell.getDisplay().getSystemColor(SWT.COLOR_RED))); - list.add(new DLItem("Portugal", createImage(shell, "portugal"))); - list.add(new DLItem("Romania", createImage(shell, "romania"))); - list.add(new DLItem("Slovakia", createImage(shell, "slovakia"))); - list.add(new DLItem("Slovenia", createImage(shell, "slovenia"))); - list.add(new DLItem("Spain", createImage(shell, "spain"))); - list.add(new DLItem("Sweden", createImage(shell, "sweden"))); - list.add(new DLItem("United Kingdom", createImage(shell, "unitedkingdom"))); - - shell.addDisposeListener(e -> { - font.dispose(); - }); - - return list; - } - - private static Image createImage(final Shell shell, final String fileName) { - final Image image = new Image(shell.getDisplay(), DualListSnippet.class.// - getResourceAsStream("flags/" + fileName + ".png")); - shell.addDisposeListener(e -> { - image.dispose(); - }); - return image; - } -} +/******************************************************************************* + * Copyright (c) 2011-2021 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.duallist.snippets; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.duallist.DLItem; +import org.eclipse.nebula.widgets.opal.duallist.DLItem.LAST_ACTION; +import org.eclipse.nebula.widgets.opal.duallist.DualList; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple snipper for the DualList Widget + * + */ +public class DualListSnippet { + + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setText("Dual List Snippet"); + shell.setSize(600, 600); + shell.setLayout(new GridLayout(1, false)); + + final DualList dl = new DualList(shell, SWT.NONE); + dl.setItems(createItems(shell)); + + dl.addSelectionChangeListener(e -> { + System.out.println("Selection Change Listener called"); + for (final DLItem item : e.getItems()) { + final StringBuilder sb = new StringBuilder(); + if (item.getLastAction() == LAST_ACTION.SELECTION) { + sb.append("[SELECTION] "); + } else { + sb.append("[DE-SELECTION] "); + } + sb.append(item.getText()); + System.out.println(sb.toString()); + } + }); + + dl.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + + } + + private static List createItems(final Shell shell) { + final List list = new ArrayList<>(); + + String defaultFontName = null; + int defaultHeight = -1; + for (final FontData fontData : shell.getFont().getFontData()) { + if (defaultFontName == null) { + defaultFontName = fontData.getName(); + } + if (defaultHeight == -1) { + defaultHeight = fontData.getHeight(); + } + } + + final Font font = new Font(shell.getDisplay(), defaultFontName, defaultHeight, SWT.BOLD); + + list.add(new DLItem("Austria", createImage(shell, "austria"))); + list.add(new DLItem("Belgium", createImage(shell, "belgium"))); + list.add(new DLItem("Bulgaria", createImage(shell, "bulgaria"))); + list.add(new DLItem("Cyprus", createImage(shell, "cyprus"))); + list.add(new DLItem("Czech Republic", createImage(shell, "czech"))); + list.add(new DLItem("Denmark", createImage(shell, "denmark"))); + list.add(new DLItem("Estonia", createImage(shell, "estonia"))); + list.add(new DLItem("Finland", createImage(shell, "finland"))); + list.add(new DLItem("France", createImage(shell, "france"), font)); + list.add(new DLItem("Germany", createImage(shell, "germany"))); + list.add(new DLItem("Greece", createImage(shell, "greece"))); + list.add(new DLItem("Hungary", createImage(shell, "hungary"))); + list.add(new DLItem("Ireland", createImage(shell, "ireland"))); + list.add(new DLItem("Italy", createImage(shell, "italy"))); + list.add(new DLItem("Latvia", createImage(shell, "latvia"))); + list.add(new DLItem("Lithuania", createImage(shell, "lithuania"))); + list.add(new DLItem("Luxembourg", createImage(shell, "luxembourg"))); + list.add(new DLItem("Malta", createImage(shell, "malta"))); + list.add(new DLItem("Netherlands", createImage(shell, "netherlands"))); + list.add(new DLItem("Poland", createImage(shell, "poland"), shell.getDisplay().getSystemColor(SWT.COLOR_WHITE), shell.getDisplay().getSystemColor(SWT.COLOR_RED))); + list.add(new DLItem("Portugal", createImage(shell, "portugal"))); + list.add(new DLItem("Romania", createImage(shell, "romania"))); + list.add(new DLItem("Slovakia", createImage(shell, "slovakia"))); + list.add(new DLItem("Slovenia", createImage(shell, "slovenia"))); + list.add(new DLItem("Spain", createImage(shell, "spain"))); + list.add(new DLItem("Sweden", createImage(shell, "sweden"))); + list.add(new DLItem("United Kingdom", createImage(shell, "unitedkingdom"))); + + shell.addDisposeListener(e -> { + font.dispose(); + }); + + return list; + } + + private static Image createImage(final Shell shell, final String fileName) { + final Image image = new Image(shell.getDisplay(), DualListSnippet.class.// + getResourceAsStream("flags/" + fileName + ".png")); + shell.addDisposeListener(e -> { + image.dispose(); + }); + return image; + } +} diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/src/org/eclipse/nebula/widgets/opal/duallist/snippets/DualListTextSnippet.java b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/src/org/eclipse/nebula/widgets/opal/duallist/snippets/DualListTextSnippet.java index fc036114b..afec91923 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/src/org/eclipse/nebula/widgets/opal/duallist/snippets/DualListTextSnippet.java +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist.snippets/src/org/eclipse/nebula/widgets/opal/duallist/snippets/DualListTextSnippet.java @@ -1,178 +1,178 @@ -/******************************************************************************* - * Copyright (c) 2011-2021 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.duallist.snippets; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.duallist.DLConfiguration; -import org.eclipse.nebula.widgets.opal.duallist.DLItem; -import org.eclipse.nebula.widgets.opal.duallist.DualList; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple snipper for the DualList Widget - * - */ -public class DualListTextSnippet { - private static final String DOUBLE_DOWN_IMAGE = "double_down.png"; - private static final String DOUBLE_UP_IMAGE = "double_up.png"; - private static final String DOUBLE_LEFT_IMAGE = "double_left.png"; - private static final String DOUBLE_RIGHT_IMAGE = "double_right.png"; - private static final String ARROW_DOWN_IMAGE = "arrow_down.png"; - private static final String ARROW_LEFT_IMAGE = "arrow_left.png"; - private static final String ARROW_UP_IMAGE = "arrow_up.png"; - private static final String ARROW_RIGHT_IMAGE = "arrow_right.png"; - private static DualList dl; - - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setText("Dual List Snippet"); - shell.setSize(600, 600); - shell.setLayout(new GridLayout(1, false)); - - dl = new DualList(shell, SWT.NONE); - dl.setItems(createItems(shell)); - dl.addListener(SWT.Selection, e -> { - System.out.println("Selection Listener called"); - }); - - dl.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - - GridData gdButtons = new GridData(GridData.END, GridData.FILL, true, false); - gdButtons.widthHint = 150; - - Button changeConfiguration = new Button(shell, SWT.PUSH); - changeConfiguration.setText("Change Configuration"); - changeConfiguration.setLayoutData(gdButtons); - changeConfiguration.addListener(SWT.Selection, e -> dl.setConfiguration(createConfiguration())); - - Button hideButtons = new Button(shell, SWT.PUSH); - hideButtons.setText("Hide buttons"); - hideButtons.setLayoutData(gdButtons); - hideButtons.addListener(SWT.Selection, e -> { - DLConfiguration config = new DLConfiguration(); - config.setDoubleDownVisible(false).setDoubleUpVisible(false).// - setDoubleRightVisible(false).setDoubleLeftVisible(false).// - setDownVisible(false).setUpVisible(false); - dl.setConfiguration(config); - }); - - Button resetConfiguration = new Button(shell, SWT.PUSH); - resetConfiguration.setText("Reset Configuration"); - resetConfiguration.setLayoutData(gdButtons); - resetConfiguration.addListener(SWT.Selection, e -> dl.setConfiguration(null)); - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - - } - - private static List createItems(final Shell shell) { - final List list = new ArrayList(); - - String defaultFontName = null; - int defaultHeight = -1; - for (final FontData fontData : shell.getFont().getFontData()) { - if (defaultFontName == null) { - defaultFontName = fontData.getName(); - } - if (defaultHeight == -1) { - defaultHeight = fontData.getHeight(); - } - } - - final Font font = new Font(shell.getDisplay(), defaultFontName, defaultHeight, SWT.BOLD); - - list.add(new DLItem("Austria")); - list.add(new DLItem("Belgium")); - list.add(new DLItem("Bulgaria")); - list.add(new DLItem("Cyprus")); - list.add(new DLItem("Czech Republic")); - list.add(new DLItem("Denmark")); - list.add(new DLItem("Estonia")); - list.add(new DLItem("Finland")); - list.add(new DLItem("France").setSelected(true)); - list.add(new DLItem("Germany")); - list.add(new DLItem("Greece")); - list.add(new DLItem("Hungary").setSelected(true)); - list.add(new DLItem("Ireland")); - list.add(new DLItem("Italy")); - list.add(new DLItem("Latvia")); - list.add(new DLItem("Lithuania").setSelected(true)); - list.add(new DLItem("Luxembourg")); - list.add(new DLItem("Malta")); - list.add(new DLItem("Netherlands")); - list.add(new DLItem("Poland").setSelected(true)); - list.add(new DLItem("Portugal")); - list.add(new DLItem("Romania")); - list.add(new DLItem("Slovakia")); - list.add(new DLItem("Slovenia")); - list.add(new DLItem("Spain")); - list.add(new DLItem("Sweden")); - list.add(new DLItem("United Kingdom")); - - shell.addDisposeListener(e -> { - font.dispose(); - }); - - return list; - } - - private static DLConfiguration createConfiguration() { - DLConfiguration config = new DLConfiguration(); - Display display = Display.getCurrent(); - // Change colors for both panels - config.setItemsBackgroundColor(display.getSystemColor(SWT.COLOR_BLACK)).// - setItemsForegroundColor(display.getSystemColor(SWT.COLOR_WHITE)).// - setItemsOddLinesColor(display.getSystemColor(SWT.COLOR_GRAY)); - config.setSelectionBackgroundColor(display.getSystemColor(SWT.COLOR_DARK_GREEN)).// - setSelectionForegroundColor(display.getSystemColor(SWT.COLOR_YELLOW)).// - setSelectionOddLinesColor(display.getSystemColor(SWT.COLOR_RED)); - - // Change text alignment - config.setItemsTextAlignment(SWT.RIGHT).setSelectionTextAlignment(SWT.CENTER); - - // Change buttons - config.setDownImage(createImage(ARROW_DOWN_IMAGE)).setUpImage(createImage(ARROW_UP_IMAGE)).// - setRightImage(createImage(ARROW_RIGHT_IMAGE)).setLeftImage(createImage(ARROW_LEFT_IMAGE)).// - setDoubleDownImage(createImage(DOUBLE_DOWN_IMAGE)).setDoubleUpImage(createImage(DOUBLE_UP_IMAGE)).// - setDoubleLeftImage(createImage(DOUBLE_LEFT_IMAGE)).setDoubleRightImage(createImage(DOUBLE_RIGHT_IMAGE)); - - return config; - } - - private static Image createImage(String fileName) { - Image image = new Image(Display.getCurrent(), // - DualListTextSnippet.class.getResourceAsStream("arrows/" + fileName)); - SWTGraphicUtil.addDisposer(dl, image); - return image; - } -} +/******************************************************************************* + * Copyright (c) 2011-2021 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.duallist.snippets; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.duallist.DLConfiguration; +import org.eclipse.nebula.widgets.opal.duallist.DLItem; +import org.eclipse.nebula.widgets.opal.duallist.DualList; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple snipper for the DualList Widget + * + */ +public class DualListTextSnippet { + private static final String DOUBLE_DOWN_IMAGE = "double_down.png"; + private static final String DOUBLE_UP_IMAGE = "double_up.png"; + private static final String DOUBLE_LEFT_IMAGE = "double_left.png"; + private static final String DOUBLE_RIGHT_IMAGE = "double_right.png"; + private static final String ARROW_DOWN_IMAGE = "arrow_down.png"; + private static final String ARROW_LEFT_IMAGE = "arrow_left.png"; + private static final String ARROW_UP_IMAGE = "arrow_up.png"; + private static final String ARROW_RIGHT_IMAGE = "arrow_right.png"; + private static DualList dl; + + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setText("Dual List Snippet"); + shell.setSize(600, 600); + shell.setLayout(new GridLayout(1, false)); + + dl = new DualList(shell, SWT.NONE); + dl.setItems(createItems(shell)); + dl.addListener(SWT.Selection, e -> { + System.out.println("Selection Listener called"); + }); + + dl.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + + GridData gdButtons = new GridData(GridData.END, GridData.FILL, true, false); + gdButtons.widthHint = 150; + + Button changeConfiguration = new Button(shell, SWT.PUSH); + changeConfiguration.setText("Change Configuration"); + changeConfiguration.setLayoutData(gdButtons); + changeConfiguration.addListener(SWT.Selection, e -> dl.setConfiguration(createConfiguration())); + + Button hideButtons = new Button(shell, SWT.PUSH); + hideButtons.setText("Hide buttons"); + hideButtons.setLayoutData(gdButtons); + hideButtons.addListener(SWT.Selection, e -> { + DLConfiguration config = new DLConfiguration(); + config.setDoubleDownVisible(false).setDoubleUpVisible(false).// + setDoubleRightVisible(false).setDoubleLeftVisible(false).// + setDownVisible(false).setUpVisible(false); + dl.setConfiguration(config); + }); + + Button resetConfiguration = new Button(shell, SWT.PUSH); + resetConfiguration.setText("Reset Configuration"); + resetConfiguration.setLayoutData(gdButtons); + resetConfiguration.addListener(SWT.Selection, e -> dl.setConfiguration(null)); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + + } + + private static List createItems(final Shell shell) { + final List list = new ArrayList(); + + String defaultFontName = null; + int defaultHeight = -1; + for (final FontData fontData : shell.getFont().getFontData()) { + if (defaultFontName == null) { + defaultFontName = fontData.getName(); + } + if (defaultHeight == -1) { + defaultHeight = fontData.getHeight(); + } + } + + final Font font = new Font(shell.getDisplay(), defaultFontName, defaultHeight, SWT.BOLD); + + list.add(new DLItem("Austria")); + list.add(new DLItem("Belgium")); + list.add(new DLItem("Bulgaria")); + list.add(new DLItem("Cyprus")); + list.add(new DLItem("Czech Republic")); + list.add(new DLItem("Denmark")); + list.add(new DLItem("Estonia")); + list.add(new DLItem("Finland")); + list.add(new DLItem("France").setSelected(true)); + list.add(new DLItem("Germany")); + list.add(new DLItem("Greece")); + list.add(new DLItem("Hungary").setSelected(true)); + list.add(new DLItem("Ireland")); + list.add(new DLItem("Italy")); + list.add(new DLItem("Latvia")); + list.add(new DLItem("Lithuania").setSelected(true)); + list.add(new DLItem("Luxembourg")); + list.add(new DLItem("Malta")); + list.add(new DLItem("Netherlands")); + list.add(new DLItem("Poland").setSelected(true)); + list.add(new DLItem("Portugal")); + list.add(new DLItem("Romania")); + list.add(new DLItem("Slovakia")); + list.add(new DLItem("Slovenia")); + list.add(new DLItem("Spain")); + list.add(new DLItem("Sweden")); + list.add(new DLItem("United Kingdom")); + + shell.addDisposeListener(e -> { + font.dispose(); + }); + + return list; + } + + private static DLConfiguration createConfiguration() { + DLConfiguration config = new DLConfiguration(); + Display display = Display.getCurrent(); + // Change colors for both panels + config.setItemsBackgroundColor(display.getSystemColor(SWT.COLOR_BLACK)).// + setItemsForegroundColor(display.getSystemColor(SWT.COLOR_WHITE)).// + setItemsOddLinesColor(display.getSystemColor(SWT.COLOR_GRAY)); + config.setSelectionBackgroundColor(display.getSystemColor(SWT.COLOR_DARK_GREEN)).// + setSelectionForegroundColor(display.getSystemColor(SWT.COLOR_YELLOW)).// + setSelectionOddLinesColor(display.getSystemColor(SWT.COLOR_RED)); + + // Change text alignment + config.setItemsTextAlignment(SWT.RIGHT).setSelectionTextAlignment(SWT.CENTER); + + // Change buttons + config.setDownImage(createImage(ARROW_DOWN_IMAGE)).setUpImage(createImage(ARROW_UP_IMAGE)).// + setRightImage(createImage(ARROW_RIGHT_IMAGE)).setLeftImage(createImage(ARROW_LEFT_IMAGE)).// + setDoubleDownImage(createImage(DOUBLE_DOWN_IMAGE)).setDoubleUpImage(createImage(DOUBLE_UP_IMAGE)).// + setDoubleLeftImage(createImage(DOUBLE_LEFT_IMAGE)).setDoubleRightImage(createImage(DOUBLE_RIGHT_IMAGE)); + + return config; + } + + private static Image createImage(String fileName) { + Image image = new Image(Display.getCurrent(), // + DualListTextSnippet.class.getResourceAsStream("arrows/" + fileName)); + SWTGraphicUtil.addDisposer(dl, image); + return image; + } +} diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.classpath b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.classpath +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.project b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.project index c0d3d5bbf..652e839e4 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.project +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.duallist - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.duallist + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/META-INF/MANIFEST.MF b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/META-INF/MANIFEST.MF index 42ec98905..289301e55 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/META-INF/MANIFEST.MF +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Dual List -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.duallist -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.duallist -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.duallist +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Dual List +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.duallist +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.duallist +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.duallist diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/build.properties b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/build.properties +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DLConfiguration.java b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DLConfiguration.java index a5b4f03d0..f675f1449 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DLConfiguration.java +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DLConfiguration.java @@ -1,391 +1,391 @@ -/******************************************************************************* - * Copyright (c) 2021 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.duallist; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Image; - -/** - * Configuration class for the DualList widget - */ -public class DLConfiguration { - private Color itemsBackgroundColor, itemsOddLinesColor, itemsForegroundColor, selectionBackgroundColor, selectionOddLinesColor, selectionForegroundColor; - private int itemsTextAlignment = SWT.LEFT, selectionTextAlignment = SWT.LEFT; - private Image doubleDownImage, doubleUpImage, doubleLeftImage, doubleRightImage, // - downImage, leftImage, upImage, rightImage; - - private boolean doubleRightVisible = true; - private boolean doubleLeftVisible = true; - private boolean doubleUpVisible = true; - private boolean upVisible = true; - private boolean doubleDownVisible = true; - private boolean downVisible = true; - - /** - * @return the background color of the items panel - */ - public Color getItemsBackgroundColor() { - return itemsBackgroundColor; - } - - /** - * @param color the background color of the items panel to set - */ - public DLConfiguration setItemsBackgroundColor(Color color) { - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.itemsBackgroundColor = color; - return this; - } - - /** - * @return the background color of the odd lines for the unselected items list - */ - public Color getItemsOddLinesColor() { - return itemsOddLinesColor; - } - - /** - * @param color the background color of the odd lines for the unselected items list to set - */ - public DLConfiguration setItemsOddLinesColor(Color color) { - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.itemsOddLinesColor = color; - return this; - } - - /** - * @return the background color of the selected items panel - */ - public Color getSelectionBackgroundColor() { - return selectionBackgroundColor; - } - - /** - * @param color the background color of the items panel to set - */ - public DLConfiguration setSelectionBackgroundColor(Color color) { - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.selectionBackgroundColor = color; - return this; - } - - /** - * @return the background color of the odd lines for the selected items list - */ - public Color getSelectionOddLinesColor() { - return selectionOddLinesColor; - } - - /** - * @param color the background color of the odd lines for the selected items list to set - */ - public DLConfiguration setSelectionOddLinesColor(Color color) { - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.selectionOddLinesColor = color; - return this; - } - - /** - * @return the text alignment (SWT.RIGHT, SWT.CENTER, SWT.LEFT) for the unselected items - */ - public int getItemsTextAlignment() { - return itemsTextAlignment; - } - - /** - * @param alignment the text alignment (SWT.RIGHT, SWT.CENTER, SWT.LEFT) for the unselected items to set - */ - public DLConfiguration setItemsTextAlignment(int alignment) { - if (alignment != SWT.NONE && alignment != SWT.LEFT && alignment != SWT.RIGHT && alignment != SWT.CENTER) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.itemsTextAlignment = alignment; - return this; - } - - /** - * @return the text alignment (SWT.RIGHT, SWT.CENTER, SWT.LEFT) for the selected items - */ - public int getSelectionTextAlignment() { - return selectionTextAlignment; - } - - /** - * @param alignment the text alignment (SWT.RIGHT, SWT.CENTER, SWT.LEFT) for the unselected items to set - */ - public DLConfiguration setSelectionTextAlignment(int alignment) { - if (alignment != SWT.NONE && alignment != SWT.LEFT && alignment != SWT.RIGHT && alignment != SWT.CENTER) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.selectionTextAlignment = alignment; - return this; - } - - /** - * @return the image for the "double down" button - */ - public Image getDoubleDownImage() { - return doubleDownImage; - } - - /** - * @param image the image for the "double down" button to set - */ - public DLConfiguration setDoubleDownImage(Image image) { - this.doubleDownImage = image; - return this; - } - - /** - * @return the image for the "double up" button - */ - public Image getDoubleUpImage() { - return doubleUpImage; - } - - /** - * @param image the image for the "double up" button to set - */ - public DLConfiguration setDoubleUpImage(Image image) { - this.doubleUpImage = image; - return this; - } - - /** - * @return the image for the "double left" button - */ - public Image getDoubleLeftImage() { - return doubleLeftImage; - } - - /** - * @param image the image for the "double left" button to set - */ - public DLConfiguration setDoubleLeftImage(Image image) { - this.doubleLeftImage = image; - return this; - } - - /** - * @return the image for the "double right" button - */ - public Image getDoubleRightImage() { - return doubleRightImage; - } - - /** - * @param image the image for the "double right" button to set - */ - public DLConfiguration setDoubleRightImage(Image image) { - this.doubleRightImage = image; - return this; - } - - /** - * @return the image for the "down" button - */ - public Image getDownImage() { - return downImage; - } - - /** - * @param image the image for the "down" button to set - */ - public DLConfiguration setDownImage(Image image) { - this.downImage = image; - return this; - } - - /** - * @return the image for the "left" button - */ - public Image getLeftImage() { - return leftImage; - } - - /** - * @param image the image for the "left" button to set - */ - public DLConfiguration setLeftImage(Image image) { - this.leftImage = image; - return this; - } - - /** - * @return the image for the "up" button - */ - public Image getUpImage() { - return upImage; - } - - /** - * @param image the image for the "up" button to set - */ - public DLConfiguration setUpImage(Image image) { - this.upImage = image; - return this; - } - - /** - * @return the image for the "right" button - */ - public Image getRightImage() { - return rightImage; - } - - /** - * @param image the image for the "right" button to set - */ - public DLConfiguration setRightImage(Image image) { - this.rightImage = image; - return this; - } - - /** - * @return true if the "double right" button is visible, false otherwise - */ - public boolean isDoubleRightVisible() { - return doubleRightVisible; - } - - /** - * @param visible the visibility of the "double right" button - */ - public DLConfiguration setDoubleRightVisible(boolean visible) { - this.doubleRightVisible = visible; - return this; - } - - /** - * @return true if the "double left" button is visible, false otherwise - */ - public boolean isDoubleLeftVisible() { - return doubleLeftVisible; - } - - /** - * @param visible the visibility of the "double left" button - */ - public DLConfiguration setDoubleLeftVisible(boolean visible) { - this.doubleLeftVisible = visible; - return this; - } - - /** - * @return true if the "double up" button is visible, false otherwise - */ - public boolean isDoubleUpVisible() { - return doubleUpVisible; - } - - /** - * @param visible the visibility of the "double up" button - */ - public DLConfiguration setDoubleUpVisible(boolean visible) { - this.doubleUpVisible = visible; - return this; - } - - /** - * @return true if the "up" button is visible, false otherwise - */ - public boolean isUpVisible() { - return upVisible; - } - - /** - * @param visible the visibility of the "up" button - */ - public DLConfiguration setUpVisible(boolean visible) { - this.upVisible = visible; - return this; - } - - /** - * @return true if the "double down" button is visible, false otherwise - */ - public boolean isDoubleDownVisible() { - return doubleDownVisible; - } - - /** - * @param visible the visibility of the "double down" button - */ - public DLConfiguration setDoubleDownVisible(boolean visible) { - this.doubleDownVisible = visible; - return this; - } - - /** - * @return true if the "down" button is visible, false otherwise - */ - public boolean isDownVisible() { - return downVisible; - } - - /** - * @param visible the visibility of the "down" button - */ - public DLConfiguration setDownVisible(boolean visible) { - this.downVisible = visible; - return this; - } - - /** - * @return the foreground color of the items panel - */ - public Color getItemsForegroundColor() { - return itemsForegroundColor; - } - - /** - * @param color the foreground color of the items panel to set - * @return - */ - public DLConfiguration setItemsForegroundColor(Color color) { - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.itemsForegroundColor = color; - return this; - } - - /** - * @return the foreground color of the items panel - */ - public Color getSelectionForegroundColor() { - return selectionForegroundColor; - } - - /** - * @param color the foreground color of the selection panel to set - * @return - */ - public DLConfiguration setSelectionForegroundColor(Color color) { - if (color != null && color.isDisposed()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.selectionForegroundColor = color; - return this; - } - -} +/******************************************************************************* + * Copyright (c) 2021 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.duallist; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; + +/** + * Configuration class for the DualList widget + */ +public class DLConfiguration { + private Color itemsBackgroundColor, itemsOddLinesColor, itemsForegroundColor, selectionBackgroundColor, selectionOddLinesColor, selectionForegroundColor; + private int itemsTextAlignment = SWT.LEFT, selectionTextAlignment = SWT.LEFT; + private Image doubleDownImage, doubleUpImage, doubleLeftImage, doubleRightImage, // + downImage, leftImage, upImage, rightImage; + + private boolean doubleRightVisible = true; + private boolean doubleLeftVisible = true; + private boolean doubleUpVisible = true; + private boolean upVisible = true; + private boolean doubleDownVisible = true; + private boolean downVisible = true; + + /** + * @return the background color of the items panel + */ + public Color getItemsBackgroundColor() { + return itemsBackgroundColor; + } + + /** + * @param color the background color of the items panel to set + */ + public DLConfiguration setItemsBackgroundColor(Color color) { + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.itemsBackgroundColor = color; + return this; + } + + /** + * @return the background color of the odd lines for the unselected items list + */ + public Color getItemsOddLinesColor() { + return itemsOddLinesColor; + } + + /** + * @param color the background color of the odd lines for the unselected items list to set + */ + public DLConfiguration setItemsOddLinesColor(Color color) { + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.itemsOddLinesColor = color; + return this; + } + + /** + * @return the background color of the selected items panel + */ + public Color getSelectionBackgroundColor() { + return selectionBackgroundColor; + } + + /** + * @param color the background color of the items panel to set + */ + public DLConfiguration setSelectionBackgroundColor(Color color) { + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.selectionBackgroundColor = color; + return this; + } + + /** + * @return the background color of the odd lines for the selected items list + */ + public Color getSelectionOddLinesColor() { + return selectionOddLinesColor; + } + + /** + * @param color the background color of the odd lines for the selected items list to set + */ + public DLConfiguration setSelectionOddLinesColor(Color color) { + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.selectionOddLinesColor = color; + return this; + } + + /** + * @return the text alignment (SWT.RIGHT, SWT.CENTER, SWT.LEFT) for the unselected items + */ + public int getItemsTextAlignment() { + return itemsTextAlignment; + } + + /** + * @param alignment the text alignment (SWT.RIGHT, SWT.CENTER, SWT.LEFT) for the unselected items to set + */ + public DLConfiguration setItemsTextAlignment(int alignment) { + if (alignment != SWT.NONE && alignment != SWT.LEFT && alignment != SWT.RIGHT && alignment != SWT.CENTER) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.itemsTextAlignment = alignment; + return this; + } + + /** + * @return the text alignment (SWT.RIGHT, SWT.CENTER, SWT.LEFT) for the selected items + */ + public int getSelectionTextAlignment() { + return selectionTextAlignment; + } + + /** + * @param alignment the text alignment (SWT.RIGHT, SWT.CENTER, SWT.LEFT) for the unselected items to set + */ + public DLConfiguration setSelectionTextAlignment(int alignment) { + if (alignment != SWT.NONE && alignment != SWT.LEFT && alignment != SWT.RIGHT && alignment != SWT.CENTER) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.selectionTextAlignment = alignment; + return this; + } + + /** + * @return the image for the "double down" button + */ + public Image getDoubleDownImage() { + return doubleDownImage; + } + + /** + * @param image the image for the "double down" button to set + */ + public DLConfiguration setDoubleDownImage(Image image) { + this.doubleDownImage = image; + return this; + } + + /** + * @return the image for the "double up" button + */ + public Image getDoubleUpImage() { + return doubleUpImage; + } + + /** + * @param image the image for the "double up" button to set + */ + public DLConfiguration setDoubleUpImage(Image image) { + this.doubleUpImage = image; + return this; + } + + /** + * @return the image for the "double left" button + */ + public Image getDoubleLeftImage() { + return doubleLeftImage; + } + + /** + * @param image the image for the "double left" button to set + */ + public DLConfiguration setDoubleLeftImage(Image image) { + this.doubleLeftImage = image; + return this; + } + + /** + * @return the image for the "double right" button + */ + public Image getDoubleRightImage() { + return doubleRightImage; + } + + /** + * @param image the image for the "double right" button to set + */ + public DLConfiguration setDoubleRightImage(Image image) { + this.doubleRightImage = image; + return this; + } + + /** + * @return the image for the "down" button + */ + public Image getDownImage() { + return downImage; + } + + /** + * @param image the image for the "down" button to set + */ + public DLConfiguration setDownImage(Image image) { + this.downImage = image; + return this; + } + + /** + * @return the image for the "left" button + */ + public Image getLeftImage() { + return leftImage; + } + + /** + * @param image the image for the "left" button to set + */ + public DLConfiguration setLeftImage(Image image) { + this.leftImage = image; + return this; + } + + /** + * @return the image for the "up" button + */ + public Image getUpImage() { + return upImage; + } + + /** + * @param image the image for the "up" button to set + */ + public DLConfiguration setUpImage(Image image) { + this.upImage = image; + return this; + } + + /** + * @return the image for the "right" button + */ + public Image getRightImage() { + return rightImage; + } + + /** + * @param image the image for the "right" button to set + */ + public DLConfiguration setRightImage(Image image) { + this.rightImage = image; + return this; + } + + /** + * @return true if the "double right" button is visible, false otherwise + */ + public boolean isDoubleRightVisible() { + return doubleRightVisible; + } + + /** + * @param visible the visibility of the "double right" button + */ + public DLConfiguration setDoubleRightVisible(boolean visible) { + this.doubleRightVisible = visible; + return this; + } + + /** + * @return true if the "double left" button is visible, false otherwise + */ + public boolean isDoubleLeftVisible() { + return doubleLeftVisible; + } + + /** + * @param visible the visibility of the "double left" button + */ + public DLConfiguration setDoubleLeftVisible(boolean visible) { + this.doubleLeftVisible = visible; + return this; + } + + /** + * @return true if the "double up" button is visible, false otherwise + */ + public boolean isDoubleUpVisible() { + return doubleUpVisible; + } + + /** + * @param visible the visibility of the "double up" button + */ + public DLConfiguration setDoubleUpVisible(boolean visible) { + this.doubleUpVisible = visible; + return this; + } + + /** + * @return true if the "up" button is visible, false otherwise + */ + public boolean isUpVisible() { + return upVisible; + } + + /** + * @param visible the visibility of the "up" button + */ + public DLConfiguration setUpVisible(boolean visible) { + this.upVisible = visible; + return this; + } + + /** + * @return true if the "double down" button is visible, false otherwise + */ + public boolean isDoubleDownVisible() { + return doubleDownVisible; + } + + /** + * @param visible the visibility of the "double down" button + */ + public DLConfiguration setDoubleDownVisible(boolean visible) { + this.doubleDownVisible = visible; + return this; + } + + /** + * @return true if the "down" button is visible, false otherwise + */ + public boolean isDownVisible() { + return downVisible; + } + + /** + * @param visible the visibility of the "down" button + */ + public DLConfiguration setDownVisible(boolean visible) { + this.downVisible = visible; + return this; + } + + /** + * @return the foreground color of the items panel + */ + public Color getItemsForegroundColor() { + return itemsForegroundColor; + } + + /** + * @param color the foreground color of the items panel to set + * @return + */ + public DLConfiguration setItemsForegroundColor(Color color) { + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.itemsForegroundColor = color; + return this; + } + + /** + * @return the foreground color of the items panel + */ + public Color getSelectionForegroundColor() { + return selectionForegroundColor; + } + + /** + * @param color the foreground color of the selection panel to set + * @return + */ + public DLConfiguration setSelectionForegroundColor(Color color) { + if (color != null && color.isDisposed()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.selectionForegroundColor = color; + return this; + } + +} diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DLItem.java b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DLItem.java index 1945d0fea..7a6737ae1 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DLItem.java +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DLItem.java @@ -1,138 +1,138 @@ -/******************************************************************************* - * Copyright (c) 2011-2021 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.duallist; - -import org.eclipse.nebula.widgets.opal.commons.OpalItem; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; - -/** - * Instances of this class represents items manipulated by this DualList widget - */ -public class DLItem extends OpalItem { - - public enum LAST_ACTION { - NONE, SELECTION, DESELECTION - }; - - private LAST_ACTION lastAction; - - /** - * Constructor - * - * @param text the text displayed in the DualList widget for this item - */ - public DLItem(final String text) { - this(text, null); - } - - /** - * Constructor - * - * @param text the text displayed in the DualList widget for this item - * @param image the image displayed in the DualList widget for this item - */ - public DLItem(final String text, final Image image) { - this(text, image, (Font) null, (Color) null); - } - - /** - * Constructor - * - * @param text the text displayed in the DualList widget for this item - * @param image the image displayed in the DualList widget for this item - * @param font the font displayed in the DualList widget for this item - * @param foregroundColor the foreground color displayed in the DualList widget - * for this item - */ - public DLItem(final String text, final Image image, final Font font, final Color foregroundColor) { - setText(text); - setImage(image); - setFont(font); - setForeground(foregroundColor); - lastAction = LAST_ACTION.NONE; - } - - /** - * Constructor - * - * @param text the text displayed in the DualList widget for this item - * @param image the image displayed in the DualList widget for this item - * @param foregroundColor the foreground color displayed in the DualList widget - * for this item - * @param backgroundColor the background color displayed in the DualList widget - * for this item - */ - public DLItem(final String text, final Image image, final Color foregroundColor, final Color backgroundColor) { - setText(text); - setImage(image); - setForeground(foregroundColor); - setBackground(backgroundColor); - lastAction = LAST_ACTION.NONE; - } - - /** - * Constructor - * - * @param text the text displayed in the DualList widget for this item - * @param image the image displayed in the DualList widget for this item - * @param font the font displayed in the DualList widget for this item - */ - public DLItem(final String text, final Image image, final Font font) { - this(text, image, font, null); - } - - /** - * @see org.eclipse.nebula.widgets.opal.commons.OpalItem#getHeight() - */ - @Override - public int getHeight() { - throw new UnsupportedOperationException("DLItem does not support this method"); - } - - /** - * @see org.eclipse.nebula.widgets.opal.commons.OpalItem#setHeight(int) - */ - @Override - public void setHeight(final int height) { - throw new UnsupportedOperationException("DLItem does not support this method"); - } - - /** - * @return the last action (NONE, SELECTION, DESELECTION) - */ - public LAST_ACTION getLastAction() { - return lastAction; - } - - /** - * @param lastAction the last action performed on this DLItem - * @return - */ - public DLItem setLastAction(final LAST_ACTION lastAction) { - this.lastAction = lastAction; - return this; - } - - /** - * Change the selection state of this item - * - * @param selection - * @return - */ - public DLItem setSelected(boolean selection) { - this.lastAction = selection ? LAST_ACTION.SELECTION : LAST_ACTION.DESELECTION; - return this; - } -} +/******************************************************************************* + * Copyright (c) 2011-2021 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.duallist; + +import org.eclipse.nebula.widgets.opal.commons.OpalItem; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; + +/** + * Instances of this class represents items manipulated by this DualList widget + */ +public class DLItem extends OpalItem { + + public enum LAST_ACTION { + NONE, SELECTION, DESELECTION + }; + + private LAST_ACTION lastAction; + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + */ + public DLItem(final String text) { + this(text, null); + } + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + * @param image the image displayed in the DualList widget for this item + */ + public DLItem(final String text, final Image image) { + this(text, image, (Font) null, (Color) null); + } + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + * @param image the image displayed in the DualList widget for this item + * @param font the font displayed in the DualList widget for this item + * @param foregroundColor the foreground color displayed in the DualList widget + * for this item + */ + public DLItem(final String text, final Image image, final Font font, final Color foregroundColor) { + setText(text); + setImage(image); + setFont(font); + setForeground(foregroundColor); + lastAction = LAST_ACTION.NONE; + } + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + * @param image the image displayed in the DualList widget for this item + * @param foregroundColor the foreground color displayed in the DualList widget + * for this item + * @param backgroundColor the background color displayed in the DualList widget + * for this item + */ + public DLItem(final String text, final Image image, final Color foregroundColor, final Color backgroundColor) { + setText(text); + setImage(image); + setForeground(foregroundColor); + setBackground(backgroundColor); + lastAction = LAST_ACTION.NONE; + } + + /** + * Constructor + * + * @param text the text displayed in the DualList widget for this item + * @param image the image displayed in the DualList widget for this item + * @param font the font displayed in the DualList widget for this item + */ + public DLItem(final String text, final Image image, final Font font) { + this(text, image, font, null); + } + + /** + * @see org.eclipse.nebula.widgets.opal.commons.OpalItem#getHeight() + */ + @Override + public int getHeight() { + throw new UnsupportedOperationException("DLItem does not support this method"); + } + + /** + * @see org.eclipse.nebula.widgets.opal.commons.OpalItem#setHeight(int) + */ + @Override + public void setHeight(final int height) { + throw new UnsupportedOperationException("DLItem does not support this method"); + } + + /** + * @return the last action (NONE, SELECTION, DESELECTION) + */ + public LAST_ACTION getLastAction() { + return lastAction; + } + + /** + * @param lastAction the last action performed on this DLItem + * @return + */ + public DLItem setLastAction(final LAST_ACTION lastAction) { + this.lastAction = lastAction; + return this; + } + + /** + * Change the selection state of this item + * + * @param selection + * @return + */ + public DLItem setSelected(boolean selection) { + this.lastAction = selection ? LAST_ACTION.SELECTION : LAST_ACTION.DESELECTION; + return this; + } +} diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DualList.java b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DualList.java index f7f735252..e5ad6e93b 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DualList.java +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/DualList.java @@ -1,1867 +1,1867 @@ -/******************************************************************************* - * Copyright (c) 2011-2021 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.duallist; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; -import org.eclipse.nebula.widgets.opal.duallist.DLItem.LAST_ACTION; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -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.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; - -/** - * Instances of this class are controls that allow the user to select multiple - * elements. - *
- *
Styles:
- *
(none)
- *
Events:
- *
Selection
- *
- */ - -public class DualList extends Composite { - - private static final String DOUBLE_DOWN_IMAGE = "double_down.png"; - private static final String DOUBLE_UP_IMAGE = "double_up.png"; - private static final String DOUBLE_LEFT_IMAGE = "double_left.png"; - private static final String DOUBLE_RIGHT_IMAGE = "double_right.png"; - private static final String ARROW_DOWN_IMAGE = "arrow_down.png"; - private static final String ARROW_LEFT_IMAGE = "arrow_left.png"; - private static final String ARROW_UP_IMAGE = "arrow_up.png"; - private static final String ARROW_RIGHT_IMAGE = "arrow_right.png"; - - private final List items; - private final List selection; - - private Table itemsTable; - private Table selectionTable; - - private List selectionChangeListeners; - private DLConfiguration configuration; - private Button buttonSelectAll, buttonMoveFirst, buttonSelect, buttonMoveUp, // - buttonDeselect, buttonMoveDown, buttonDeselectAll, buttonMoveLast; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - */ - public DualList(final Composite parent, final int style) { - super(parent, style); - items = new ArrayList(); - selection = new ArrayList(); - - setLayout(new GridLayout(4, false)); - createItemsTable(); - createButtonSelectAll(); - createSelectionTable(); - createButtonMoveFirst(); - createButtonSelect(); - createButtonMoveUp(); - createButtonDeselect(); - createButtonMoveDown(); - createButtonDeselectAll(); - createButtonMoveLast(); - } - - private void createItemsTable() { - itemsTable = createTable(); - itemsTable.addListener(SWT.MouseDoubleClick, event -> { - selectItem(); - }); - } - - /** - * @return a table that will contain data - */ - private Table createTable() { - final Table table = new Table(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); - table.setLinesVisible(false); - table.setHeaderVisible(false); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 4); - gd.widthHint = 200; - table.setLayoutData(gd); - new TableColumn(table, SWT.CENTER); - new TableColumn(table, SWT.LEFT); - table.setData(-1); - return table; - } - - private void createButtonSelectAll() { - buttonSelectAll = createButton(DOUBLE_RIGHT_IMAGE, true, GridData.END); - buttonSelectAll.addListener(SWT.Selection, e -> { - selectAll(); - }); - } - - private void createSelectionTable() { - selectionTable = createTable(); - selectionTable.addListener(SWT.MouseDoubleClick, event -> { - deselectItem(); - }); - } - - private void createButtonMoveFirst() { - buttonMoveFirst = createButton(DOUBLE_UP_IMAGE, true, GridData.END); - buttonMoveFirst.addListener(SWT.Selection, e -> { - moveSelectionToFirstPosition(); - }); - } - - private void createButtonSelect() { - buttonSelect = createButton(ARROW_RIGHT_IMAGE, false, GridData.CENTER); - buttonSelect.addListener(SWT.Selection, e -> { - selectItem(); - }); - } - - private void createButtonMoveUp() { - buttonMoveUp = createButton(ARROW_UP_IMAGE, false, GridData.CENTER); - buttonMoveUp.addListener(SWT.Selection, e -> { - moveUpItem(); - }); - } - - private void createButtonDeselect() { - buttonDeselect = createButton(ARROW_LEFT_IMAGE, false, GridData.CENTER); - buttonDeselect.addListener(SWT.Selection, e -> { - deselectItem(); - }); - } - - private void createButtonMoveDown() { - buttonMoveDown = createButton(ARROW_DOWN_IMAGE, false, GridData.CENTER); - buttonMoveDown.addListener(SWT.Selection, e -> { - moveDownItem(); - }); - } - - private void createButtonDeselectAll() { - buttonDeselectAll = createButton(DOUBLE_LEFT_IMAGE, false, GridData.BEGINNING); - buttonDeselectAll.addListener(SWT.Selection, e -> { - deselectAll(); - }); - } - - private void createButtonMoveLast() { - buttonMoveLast = createButton(DOUBLE_DOWN_IMAGE, true, GridData.BEGINNING); - buttonMoveLast.addListener(SWT.Selection, e -> { - moveSelectionToLastPosition(); - }); - } - - /** - * Create a button - * - * @param fileName file name of the icon - * @param verticalExpand if true, the button will take all the - * available space vertically - * @param alignment button alignment - * @return a new button - */ - private Button createButton(final String fileName, final boolean verticalExpand, final int alignment) { - final Button button = new Button(this, SWT.PUSH); - final Image image = SWTGraphicUtil.createImageFromFile("images/" + fileName); - button.setImage(image); - button.setLayoutData(new GridData(GridData.CENTER, alignment, false, verticalExpand)); - SWTGraphicUtil.addDisposer(button, image); - return button; - } - - /** - * Adds the argument to the end of the receiver's list. - * - * @param item the new item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see #add(DLItem,int) - */ - public void add(final DLItem item) { - checkWidget(); - if (item == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - items.add(item); - redrawTables(); - } - - /** - * Adds the argument to the receiver's list at the given zero-relative index. - *

- * Note: To add an item at the end of the list, use the result of calling - * getItemCount() as the index or use add(DLItem). - *

- * - * @param item the new item - * @param index the index for the item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and - * the number of elements in the list (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see #add(String) - */ - public void add(final DLItem item, final int index) { - checkWidget(); - if (item == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (index < 0 || index >= items.size()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - items.add(index, item); - redrawTables(); - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the user changes the receiver's selection, by sending it one of the messages - * defined in the SelectionListener interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - SelectionListenerUtil.addSelectionListener(this, listener); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the user changes the receiver's selection. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.removeSelectionListener(this, listener); - } - - /** - * Adds the listener to the collection of listeners who will be notified when - * the user changes the receiver's selection, by sending it one of the messages - * defined in the SelectionChangeListener interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionChangeListener - * @see #removeSelectionChangeListener - * @see SelectionChangeEvent - */ - public void addSelectionChangeListener(final SelectionChangeListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (selectionChangeListeners == null) { - selectionChangeListeners = new ArrayList(); - } - selectionChangeListeners.add(listener); - } - - /** - * Removes the listener from the collection of listeners who will be notified - * when the user changes the receiver's selection. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionChangeListener - * @see #addSelectionChangeListener - */ - public void removeSelectionChangeListener(final SelectionChangeListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (selectionChangeListeners == null) { - return; - } - selectionChangeListeners.remove(listener); - } - - /** - * Deselects the item at the given zero-relative index in the receiver. If the - * item at the index was already deselected, it remains deselected. Indices that - * are out of range are ignored. - * - * @param index the index of the item to deselect - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void deselect(final int index) { - deselect(index, true); - } - - /** - * Deselects the item at the given zero-relative index in the receiver. If the - * item at the index was already deselected, it remains deselected. Indices that - * are out of range are ignored. - * - * @param index the index of the item to deselect - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void deselectDoNotFireEvent(final int index) { - deselect(index, false); - } - - /** - * Deselects the item at the given zero-relative index in the receiver. If the - * item at the index was already deselected, it remains deselected. Indices that - * are out of range are ignored. - * - * @param index the index of the item to deselect - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - private void deselect(final int index, final boolean shouldFireEvents) { - checkWidget(); - if (index < 0 || index >= items.size()) { - return; - } - final DLItem item = selection.remove(index); - if (shouldFireEvents) { - fireSelectionEvent(item); - } - - final List deselectedItems = new ArrayList(); - item.setLastAction(LAST_ACTION.DESELECTION); - deselectedItems.add(item); - if (shouldFireEvents) { - fireSelectionChangeEvent(deselectedItems); - } - redrawTables(); - } - - /** - * Deselects the items at the given zero-relative indices in the receiver. If - * the item at the given zero-relative index in the receiver is selected, it is - * deselected. If the item at the index was not selected, it remains deselected. - * Indices that are out of range and duplicate indices are ignored. - * - * @param indices the array of indices for the items to deselect - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the set of indices is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void deselect(final int[] indices) { - deselect(indices, true); - } - - /** - * Deselects the items at the given zero-relative indices in the receiver. If - * the item at the given zero-relative index in the receiver is selected, it is - * deselected. If the item at the index was not selected, it remains deselected. - * Indices that are out of range and duplicate indices are ignored. - * - * @param indices the array of indices for the items to deselect - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the set of indices is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void deselectDoNotFireEvent(final int[] indices) { - deselect(indices, false); - } - - /** - * Deselects the items at the given zero-relative indices in the receiver. If - * the item at the given zero-relative index in the receiver is selected, it is - * deselected. If the item at the index was not selected, it remains deselected. - * Indices that are out of range and duplicate indices are ignored. - * - * @param indices the array of indices for the items to deselect - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the set of indices is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - private void deselect(final int[] indices, final boolean shouldFireEvents) { - checkWidget(); - if (indices == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - final List toBeRemoved = new ArrayList(); - - for (final int index : indices) { - if (index < 0 || index >= items.size()) { - continue; - } - toBeRemoved.add(selection.get(index)); - } - - for (final DLItem item : toBeRemoved) { - selection.remove(item); - if (shouldFireEvents) { - fireSelectionEvent(item); - } - } - if (shouldFireEvents) { - fireSelectionChangeEvent(toBeRemoved); - } - - toBeRemoved.clear(); - redrawTables(); - } - - /** - * Deselects the items at the given zero-relative indices in the receiver. If - * the item at the given zero-relative index in the receiver is selected, it is - * deselected. If the item at the index was not selected, it remains deselected. - * The range of the indices is inclusive. Indices that are out of range are - * ignored. - * - * @param start the start index of the items to deselect - * @param end the end index of the items to deselect - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if start is greater than end
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void deselect(final int start, final int end) { - deselect(start, end, true); - } - - /** - * Deselects the items at the given zero-relative indices in the receiver. If - * the item at the given zero-relative index in the receiver is selected, it is - * deselected. If the item at the index was not selected, it remains deselected. - * The range of the indices is inclusive. Indices that are out of range are - * ignored. - * - * @param start the start index of the items to deselect - * @param end the end index of the items to deselect - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if start is greater than end
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void deselectDoNotFireEvent(final int start, final int end) { - deselect(start, end, false); - } - - private void deselect(final int start, final int end, final boolean shouldFireEvents) { - checkWidget(); - if (start > end) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - final List toBeRemoved = new ArrayList(); - - for (int index = start; index <= end; index++) { - if (index < 0 || index >= items.size()) { - continue; - } - toBeRemoved.add(selection.get(index)); - } - - for (final DLItem item : toBeRemoved) { - selection.remove(item); - if (shouldFireEvents) { - fireSelectionEvent(item); - } - } - if (shouldFireEvents) { - fireSelectionChangeEvent(toBeRemoved); - } - toBeRemoved.clear(); - redrawTables(); - } - - /** - * Deselects all selected items in the receiver. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void deselectAll() { - deselectAll(true); - } - - /** - * Deselects all selected items in the receiver. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void deselectAllDoNotFireEvent() { - deselectAll(false); - } - - /** - * Deselects all selected items in the receiver. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void deselectAll(final boolean shouldFireEvents) { - checkWidget(); - items.addAll(selection); - - final List deselectedItems = new ArrayList(); - for (final DLItem item : selection) { - item.setLastAction(LAST_ACTION.DESELECTION); - deselectedItems.add(item); - if (shouldFireEvents) { - fireSelectionEvent(item); - } - } - fireSelectionChangeEvent(deselectedItems); - - selection.clear(); - redrawTables(); - } - - /** - * Returns the item at the given, zero-relative index in the receiver. Throws an - * exception if the index is out of range. - * - * @param index the index of the item to return - * @return the item at the given index - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and - * the number of elements in the list minus 1 (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - - public DLItem getItem(final int index) { - checkWidget(); - if (index < 0 || index >= items.size()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - return items.get(index); - } - - /** - * Returns the number of items contained in the receiver. - * - * @return the number of items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getItemCount() { - checkWidget(); - return items.size(); - } - - /** - * Returns a (possibly empty) array of DLItems which are the items - * in the receiver. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * list of items, so modifying the array will not affect the receiver. - *

- * - * @return the items in the receiver's list - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public DLItem[] getItems() { - checkWidget(); - return items.toArray(new DLItem[items.size()]); - } - - /** - * Returns a (possibly empty) list of DLItems which are the items - * in the receiver. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * list of items, so modifying the array will not affect the receiver. - *

- * - * @return the items in the receiver's list - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public List getItemsAsList() { - checkWidget(); - return new ArrayList(items); - } - - /** - * Returns an array of DLItems that are currently selected in the - * receiver. An empty array indicates that no items are selected. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * selection, so modifying the array will not affect the receiver. - *

- * - * @return an array representing the selection - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public DLItem[] getSelection() { - checkWidget(); - return selection.toArray(new DLItem[selection.size()]); - } - - /** - * Returns a list of DLItems that are currently selected in the - * receiver. An empty array indicates that no items are selected. - *

- * Note: This is not the actual structure used by the receiver to maintain its - * selection, so modifying the array will not affect the receiver. - *

- * - * @return an array representing the selection - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public List getSelectionAsList() { - checkWidget(); - return new ArrayList(selection); - } - - /** - * Returns the number of selected items contained in the receiver. - * - * @return the number of selected items - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getSelectionCount() { - checkWidget(); - return selection.size(); - } - - /** - * Removes the item from the receiver at the given zero-relative index. - * - * @param index the index for the item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and - * the number of elements in the list minus 1 (inclusive)
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void remove(final int index) { - checkWidget(); - if (index < 0 || index >= items.size()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - items.remove(index); - redrawTables(); - } - - /** - * Removes the items from the receiver at the given zero-relative indices. - * - * @param indices the array of indices of the items - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and - * the number of elements in the list minus 1 (inclusive)
  • - *
  • ERROR_NULL_ARGUMENT - if the indices array is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void remove(final int[] indices) { - checkWidget(); - for (final int index : indices) { - if (index < 0 || index >= items.size()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - items.remove(index); - } - redrawTables(); - } - - /** - * Removes the items from the receiver which are between the given zero-relative - * start and end indices (inclusive). - * - * @param start the start of the range - * @param end the end of the range - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if either the start or end are not - * between 0 and the number of elements in the list minus 1 - * (inclusive) or if start>end
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void remove(final int start, final int end) { - checkWidget(); - if (start > end) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - for (int index = start; index < end; index++) { - if (index < 0 || index >= items.size()) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - items.remove(index); - } - redrawTables(); - } - - /** - * Searches the receiver's list starting at the first item until an item is - * found that is equal to the argument, and removes that item from the list. - * - * @param item the item to remove - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
  • ERROR_INVALID_ARGUMENT - if the item is not found in the - * list
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void remove(final DLItem item) { - checkWidget(); - if (item == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (!items.contains(item)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - items.remove(item); - redrawTables(); - } - - /** - * Removes all of the items from the receiver. - *

- * - * @exception SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void removeAll() { - checkWidget(); - items.clear(); - redrawTables(); - } - - /** - * Selects the item at the given zero-relative index in the receiver's list. If - * the item at the index was already selected, it remains selected. Indices that - * are out of range are ignored. - * - * @param index the index of the item to select - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void select(final int index) { - select(index, true); - } - - /** - * Selects the item at the given zero-relative index in the receiver's list. If - * the item at the index was already selected, it remains selected. Indices that - * are out of range are ignored. - * - * @param index the index of the item to select - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void selectDoNotFireEvent(final int index) { - select(index, false); - } - - private void select(final int index, final boolean shouldFireEvents) { - checkWidget(); - if (index < 0 || index >= items.size()) { - return; - } - final List selectedItems = new ArrayList(); - final DLItem item = items.remove(index); - item.setLastAction(LAST_ACTION.SELECTION); - selectedItems.add(item); - selection.add(item); - - if (shouldFireEvents) { - fireSelectionEvent(item); - fireSelectionChangeEvent(selectedItems); - } - - redrawTables(); - } - - /** - * Selects the items at the given zero-relative indices in the receiver. The - * current selection is not cleared before the new items are selected. - *

- * If the item at a given index is not selected, it is selected. If the item at - * a given index was already selected, it remains selected. Indices that are out - * of range and duplicate indices are ignored. If the receiver is single-select - * and multiple indices are specified, then all indices are ignored. - * - * @param indices the array of indices for the items to select - * - * @exception IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the array of indices is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void select(final int[] indices) { - select(indices, true); - } - - /** - * Selects the items at the given zero-relative indices in the receiver. The - * current selection is not cleared before the new items are selected. - *

- * If the item at a given index is not selected, it is selected. If the item at - * a given index was already selected, it remains selected. Indices that are out - * of range and duplicate indices are ignored. If the receiver is single-select - * and multiple indices are specified, then all indices are ignored. - * - * @param indices the array of indices for the items to select - * - * @exception IllegalArgumentException - *

    - *
  • ERROR_NULL_ARGUMENT - if the array of indices is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void selectDoNotFireEvent(final int[] indices) { - select(indices, false); - } - - private void select(final int[] indices, final boolean shouldFireEvents) { - checkWidget(); - if (indices == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - final List selectedItems = new ArrayList(); - for (final int index : indices) { - if (index < 0 || index >= items.size()) { - continue; - } - final DLItem item = items.get(index); - item.setLastAction(LAST_ACTION.SELECTION); - selectedItems.add(item); - - selection.add(item); - if (shouldFireEvents) { - fireSelectionEvent(item); - } - } - items.removeAll(selectedItems); - if (shouldFireEvents) { - fireSelectionChangeEvent(selectedItems); - } - redrawTables(); - } - - /** - * Selects the items in the range specified by the given zero-relative indices - * in the receiver. The range of indices is inclusive. The current selection is - * not cleared before the new items are selected. - *

- * If an item in the given range is not selected, it is selected. If an item in - * the given range was already selected, it remains selected. Indices that are - * out of range are ignored and no items will be selected if start is greater - * than end. If the receiver is single-select and there is more than one item in - * the given range, then all indices are ignored. - * - * @param start the start of the range - * @param end the end of the range - * - * @exception SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see List#setSelection(int,int) - */ - public void select(final int start, final int end) { - select(start, end, true); - } - - /** - * Selects the items in the range specified by the given zero-relative indices - * in the receiver. The range of indices is inclusive. The current selection is - * not cleared before the new items are selected. - *

- * If an item in the given range is not selected, it is selected. If an item in - * the given range was already selected, it remains selected. Indices that are - * out of range are ignored and no items will be selected if start is greater - * than end. If the receiver is single-select and there is more than one item in - * the given range, then all indices are ignored. - * - * @param start the start of the range - * @param end the end of the range - * - * @exception SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see List#setSelection(int,int) - */ - public void selectDoNotFireEvent(final int start, final int end) { - select(start, end, false); - } - - private void select(final int start, final int end, final boolean shouldFireEvents) { - checkWidget(); - if (start > end) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - final List selectedItems = new ArrayList(); - for (int index = start; index <= end; index++) { - if (index < 0 || index >= items.size()) { - continue; - } - final DLItem item = items.get(index); - item.setLastAction(LAST_ACTION.SELECTION); - selectedItems.add(item); - selection.add(item); - if (shouldFireEvents) { - fireSelectionEvent(item); - } - } - if (shouldFireEvents) { - fireSelectionChangeEvent(selectedItems); - } - redrawTables(); - } - - /** - * Selects all of the items in the receiver. - *

- * If the receiver is single-select, do nothing. - * - * @exception SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void selectAll() { - selectAll(true); - } - - /** - * Selects all of the items in the receiver. - *

- * If the receiver is single-select, do nothing. - * - * @exception SWTException - *

    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void selectAllDoNotFireEvent() { - selectAll(false); - } - - private void selectAll(final boolean shouldFireEvents) { - checkWidget(); - selection.addAll(items); - if (shouldFireEvents) { - for (final DLItem item : items) { - fireSelectionEvent(item); - } - } - - if (shouldFireEvents) { - final List selectedItems = new ArrayList(); - for (final DLItem item : items) { - item.setLastAction(LAST_ACTION.SELECTION); - selectedItems.add(item); - } - fireSelectionChangeEvent(selectedItems); - } - items.clear(); - redrawTables(); - } - - /** - * @see org.eclipse.swt.widgets.Control#setBounds(int, int, int, int) - */ - @Override - public void setBounds(final int x, final int y, final int width, final int height) { - super.setBounds(x, y, width, height); - layout(true); - final boolean itemsContainImage = itemsContainImage(); - final Point itemsTableDefaultSize = itemsTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); - final Point selectionTableDefaultSize = selectionTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); - - int itemsTableSize = itemsTable.getSize().x; - if (itemsTableDefaultSize.y > itemsTable.getSize().y) { - itemsTableSize -= itemsTable.getVerticalBar().getSize().x + 1; - } - - int selectionTableSize = selectionTable.getSize().x; - if (selectionTableDefaultSize.y > selectionTable.getSize().y) { - selectionTableSize -= selectionTable.getVerticalBar().getSize().x; - } - - if (itemsContainImage) { - itemsTable.getColumn(0).pack(); - itemsTable.getColumn(1).setWidth(itemsTableSize - itemsTable.getColumn(0).getWidth()); - - selectionTable.getColumn(0).pack(); - selectionTable.getColumn(1).setWidth(selectionTableSize - selectionTable.getColumn(0).getWidth()); - - } else { - itemsTable.getColumn(0).setWidth(0); - itemsTable.getColumn(1).setWidth(itemsTableSize); - - selectionTable.getColumn(0).setWidth(0); - selectionTable.getColumn(1).setWidth(selectionTableSize); - } - - } - - /** - * @return true if any item contains an image - */ - private boolean itemsContainImage() { - for (final DLItem item : items) { - if (item.getImage() != null) { - return true; - } - } - - for (final DLItem item : selection) { - if (item.getImage() != null) { - return true; - } - } - - return false; - } - - /** - * Sets the item in the receiver's list at the given zero-relative index to the - * item argument. - * - * @param index the index for the item - * @param item the new item - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_RANGE - if the index is not between 0 and - * the number of elements in the list minus 1 (inclusive)
  • - *
  • ERROR_NULL_ARGUMENT - if the item is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setItem(final int index, final DLItem item) { - checkWidget(); - if (item == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - if (index < 0 || index >= items.size()) { - SWT.error(SWT.ERROR_INVALID_RANGE); - } - items.set(index, item); - redrawTables(); - } - - /** - * Sets the receiver's items to be the given array of items. - * - * @param items the array of items - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the items array is null
  • - *
  • ERROR_INVALID_ARGUMENT - if an item in the items array is - * null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setItems(final DLItem[] items) { - checkWidget(); - if (items == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - final List temp = new ArrayList(); - for (final DLItem item : items) { - if (item == null) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - temp.add(item); - } - this.items.clear(); - this.items.addAll(temp); - redrawTables(); - } - - /** - * Sets the receiver's items to be the given list of items. - * - * @param items the list of items - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the items list is null
  • - *
  • ERROR_INVALID_ARGUMENT - if an item in the items list is - * null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setItems(final List items) { - checkWidget(); - if (items == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - - final List unselectedItems = new ArrayList(); - final List selectedItems = new ArrayList(); - for (final DLItem item : items) { - if (item == null) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - if (item.getLastAction() == LAST_ACTION.SELECTION) { - selectedItems.add(item); - } else { - unselectedItems.add(item); - } - } - this.items.clear(); - this.items.addAll(unselectedItems); - - this.selection.clear(); - this.selection.addAll(selectedItems); - - redrawTables(); - } - - /** - * Redraws all tables that compose this widget - */ - private void redrawTables() { - setRedraw(false); - redrawTable(itemsTable, false); - redrawTable(selectionTable, true); - Rectangle bounds = getBounds(); - this.setBounds(bounds.x, bounds.y, bounds.width, bounds.height); - setRedraw(true); - } - - /** - * Redraw a given table - * - * @param table table to be redrawned - * @param isSelected if true, fill the table with the selection. - * Otherwise, fill the table with the unselected items. - */ - private void redrawTable(final Table table, final boolean isSelected) { - clean(table); - fillData(table, isSelected); - } - - /** - * Cleans the content of a table - * - * @param table table to be emptied - */ - private void clean(final Table table) { - if (table == null) { - return; - } - - for (final TableItem item : table.getItems()) { - item.dispose(); - } - } - - /** - * Fill a table with data - * - * @param table table to be filled - * @param listOfData list of data - */ - private void fillData(final Table table, final boolean isSelected) { - List listOfData = isSelected ? selection : items; - int counter = 0; - for (final DLItem item : listOfData) { - final TableItem tableItem = new TableItem(table, SWT.NONE); - tableItem.setData(item); - - if (item.getBackground() != null) { - tableItem.setBackground(item.getBackground()); - } - - if (item.getForeground() != null) { - tableItem.setForeground(item.getForeground()); - } - - if (item.getImage() != null) { - tableItem.setImage(0, item.getImage()); - } - - if (item.getFont() != null) { - tableItem.setFont(item.getFont()); - } - tableItem.setText(1, item.getText()); - if (configuration != null && item.getBackground() == null && counter % 2 == 0) { - if (isSelected) { - tableItem.setBackground(configuration.getSelectionOddLinesColor()); - } else { - tableItem.setBackground(configuration.getItemsOddLinesColor()); - } - } - counter++; - } - } - - /** - * Move the selected item to the first position - */ - protected void moveSelectionToFirstPosition() { - if (selectionTable.getSelectionCount() == 0) { - return; - } - - int index = 0; - for (final TableItem tableItem : selectionTable.getSelection()) { - final DLItem item = (DLItem) tableItem.getData(); - selection.remove(item); - selection.add(index++, item); - } - - redrawTables(); - selectionTable.select(0, index - 1); - selectionTable.forceFocus(); - } - - /** - * Select a given item - */ - protected void selectItem() { - if (itemsTable.getSelectionCount() == 0) { - return; - } - final List selectedItems = new ArrayList(); - for (final TableItem tableItem : itemsTable.getSelection()) { - final DLItem item = (DLItem) tableItem.getData(); - item.setLastAction(LAST_ACTION.SELECTION); - selectedItems.add(item); - selection.add(item); - items.remove(item); - fireSelectionEvent(item); - } - fireSelectionChangeEvent(selectedItems); - - redrawTables(); - } - - /** - * Move the selected item up - */ - protected void moveUpItem() { - if (selectionTable.getSelectionCount() == 0) { - return; - } - - for (final int index : selectionTable.getSelectionIndices()) { - if (index == 0) { - selectionTable.forceFocus(); - return; - } - } - - final int[] newSelection = new int[selectionTable.getSelectionCount()]; - int newSelectionIndex = 0; - for (final TableItem tableItem : selectionTable.getSelection()) { - final int position = selection.indexOf(tableItem.getData()); - swap(position, position - 1); - newSelection[newSelectionIndex++] = position - 1; - } - - redrawTables(); - selectionTable.select(newSelection); - selectionTable.forceFocus(); - } - - /** - * Deselect a given item - */ - protected void deselectItem() { - if (selectionTable.getSelectionCount() == 0) { - return; - } - final List deselectedItems = new ArrayList(); - for (final TableItem tableItem : selectionTable.getSelection()) { - final DLItem item = (DLItem) tableItem.getData(); - item.setLastAction(LAST_ACTION.DESELECTION); - deselectedItems.add(item); - items.add(item); - selection.remove(item); - fireSelectionEvent(item); - } - fireSelectionChangeEvent(deselectedItems); - redrawTables(); - } - - /** - * Move the selected item down - */ - protected void moveDownItem() { - if (selectionTable.getSelectionCount() == 0) { - return; - } - - for (final int index : selectionTable.getSelectionIndices()) { - if (index == selectionTable.getItemCount() - 1) { - selectionTable.forceFocus(); - return; - } - } - - final int[] newSelection = new int[selectionTable.getSelectionCount()]; - int newSelectionIndex = 0; - for (final TableItem tableItem : selectionTable.getSelection()) { - final int position = selection.indexOf(tableItem.getData()); - swap(position, position + 1); - newSelection[newSelectionIndex++] = position + 1; - } - - redrawTables(); - selectionTable.select(newSelection); - selectionTable.forceFocus(); - } - - /** - * Swap 2 items - * - * @param first position of the first item to swap - * @param second position of the second item to swap - */ - private void swap(final int first, final int second) { - final DLItem temp = selection.get(first); - selection.set(first, selection.get(second)); - selection.set(second, temp); - } - - /** - * Move the selected item to the last position - */ - protected void moveSelectionToLastPosition() { - if (selectionTable.getSelectionCount() == 0) { - return; - } - - final int numberOfSelectedElements = selectionTable.getSelectionCount(); - for (final TableItem tableItem : selectionTable.getSelection()) { - final DLItem item = (DLItem) tableItem.getData(); - selection.remove(item); - selection.add(item); - } - - redrawTables(); - final int numberOfElements = selectionTable.getItemCount(); - selectionTable.select(numberOfElements - numberOfSelectedElements, numberOfElements - 1); - selectionTable.forceFocus(); - } - - /** - * Call all selection listeners - * - * @param item selected item - */ - private void fireSelectionEvent(final DLItem item) { - final Event event = new Event(); - event.button = 1; - event.display = getDisplay(); - event.item = null; - event.widget = this; - event.data = item; - - SelectionListenerUtil.fireSelectionListeners(this, event); - } - - private void fireSelectionChangeEvent(final List items) { - if (selectionChangeListeners == null) { - return; - } - - final Event event = new Event(); - event.button = 1; - event.display = getDisplay(); - event.item = null; - event.widget = this; - final SelectionChangeEvent selectionChangeEvent = new SelectionChangeEvent(event); - selectionChangeEvent.setItems(items); - - for (final SelectionChangeListener listener : selectionChangeListeners) { - listener.widgetSelected(selectionChangeEvent); - } - } - - /** - * Returns the configuration of the receiver. - * - * @return the current configuration of the receiver - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public DLConfiguration getConfiguration() { - checkWidget(); - return configuration; - } - - /** - * Sets the receiver's configuration - * - * @param configuration the new configuration - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setConfiguration(DLConfiguration configuration) { - checkWidget(); - this.configuration = configuration; - applyNewConfiguration(); - } - - private void applyNewConfiguration() { - try { - setRedraw(true); - if (configuration == null) { - resetConfigurationToDefault(); - } else { - modifyPanelsColors(); - modifyTextAlignment(); - modifyButtonImages(); - modifyButtonVisibility(); - } - redrawTables(); - } finally { - setRedraw(true); - } - } - - private void resetConfigurationToDefault() { - itemsTable.setBackground(null); - itemsTable.setForeground(null); - selectionTable.setBackground(null); - selectionTable.setForeground(null); - - recreateTableColumns(itemsTable, SWT.LEFT); - recreateTableColumns(selectionTable, SWT.LEFT); - - resetButton(buttonMoveLast, DOUBLE_DOWN_IMAGE); - resetButton(buttonMoveFirst, DOUBLE_UP_IMAGE); - resetButton(buttonDeselectAll, DOUBLE_LEFT_IMAGE); - resetButton(buttonSelectAll, DOUBLE_RIGHT_IMAGE); - resetButton(buttonMoveDown, ARROW_DOWN_IMAGE); - resetButton(buttonMoveUp, ARROW_UP_IMAGE); - resetButton(buttonDeselect, ARROW_LEFT_IMAGE); - resetButton(buttonSelect, ARROW_RIGHT_IMAGE); - } - - private void resetButton(Button button, String fileName) { - final Image image = SWTGraphicUtil.createImageFromFile("images/" + fileName); - button.setImage(image); - SWTGraphicUtil.addDisposer(button, image); - button.setVisible(true); - } - - private void modifyPanelsColors() { - if (configuration.getItemsBackgroundColor() != null) { - itemsTable.setBackground(configuration.getItemsBackgroundColor()); - } - if (configuration.getItemsForegroundColor() != null) { - itemsTable.setForeground(configuration.getItemsForegroundColor()); - } - if (configuration.getSelectionBackgroundColor() != null) { - selectionTable.setBackground(configuration.getSelectionBackgroundColor()); - } - if (configuration.getSelectionForegroundColor() != null) { - selectionTable.setForeground(configuration.getSelectionForegroundColor()); - } - } - - private void modifyTextAlignment() { - recreateTableColumns(itemsTable, configuration.getItemsTextAlignment()); - recreateTableColumns(selectionTable, configuration.getSelectionTextAlignment()); - } - - private void recreateTableColumns(Table table, int textAlignment) { - for (TableColumn tc : table.getColumns()) { - tc.dispose(); - } - new TableColumn(table, SWT.CENTER); - new TableColumn(table, textAlignment); - } - - private void modifyButtonImages() { - if (configuration.getDoubleDownImage() != null) { - buttonMoveLast.setImage(configuration.getDoubleDownImage()); - } - if (configuration.getDoubleUpImage() != null) { - buttonMoveFirst.setImage(configuration.getDoubleUpImage()); - } - if (configuration.getDoubleLeftImage() != null) { - buttonDeselectAll.setImage(configuration.getDoubleLeftImage()); - } - if (configuration.getDoubleRightImage() != null) { - buttonSelectAll.setImage(configuration.getDoubleRightImage()); - } - if (configuration.getDownImage() != null) { - buttonMoveDown.setImage(configuration.getDownImage()); - } - if (configuration.getUpImage() != null) { - buttonMoveUp.setImage(configuration.getUpImage()); - } - if (configuration.getLeftImage() != null) { - buttonDeselect.setImage(configuration.getLeftImage()); - } - if (configuration.getRightImage() != null) { - buttonSelect.setImage(configuration.getRightImage()); - } - } - - private void modifyButtonVisibility() { - buttonMoveLast.setVisible(configuration.isDoubleDownVisible()); - buttonMoveFirst.setVisible(configuration.isDoubleUpVisible()); - buttonDeselectAll.setVisible(configuration.isDoubleLeftVisible()); - buttonSelectAll.setVisible(configuration.isDoubleRightVisible()); - buttonMoveDown.setVisible(configuration.isDownVisible()); - buttonMoveUp.setVisible(configuration.isUpVisible()); - } - -} +/******************************************************************************* + * Copyright (c) 2011-2021 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.duallist; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; +import org.eclipse.nebula.widgets.opal.duallist.DLItem.LAST_ACTION; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +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.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; + +/** + * Instances of this class are controls that allow the user to select multiple + * elements. + *
+ *
Styles:
+ *
(none)
+ *
Events:
+ *
Selection
+ *
+ */ + +public class DualList extends Composite { + + private static final String DOUBLE_DOWN_IMAGE = "double_down.png"; + private static final String DOUBLE_UP_IMAGE = "double_up.png"; + private static final String DOUBLE_LEFT_IMAGE = "double_left.png"; + private static final String DOUBLE_RIGHT_IMAGE = "double_right.png"; + private static final String ARROW_DOWN_IMAGE = "arrow_down.png"; + private static final String ARROW_LEFT_IMAGE = "arrow_left.png"; + private static final String ARROW_UP_IMAGE = "arrow_up.png"; + private static final String ARROW_RIGHT_IMAGE = "arrow_right.png"; + + private final List items; + private final List selection; + + private Table itemsTable; + private Table selectionTable; + + private List selectionChangeListeners; + private DLConfiguration configuration; + private Button buttonSelectAll, buttonMoveFirst, buttonSelect, buttonMoveUp, // + buttonDeselect, buttonMoveDown, buttonDeselectAll, buttonMoveLast; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + public DualList(final Composite parent, final int style) { + super(parent, style); + items = new ArrayList(); + selection = new ArrayList(); + + setLayout(new GridLayout(4, false)); + createItemsTable(); + createButtonSelectAll(); + createSelectionTable(); + createButtonMoveFirst(); + createButtonSelect(); + createButtonMoveUp(); + createButtonDeselect(); + createButtonMoveDown(); + createButtonDeselectAll(); + createButtonMoveLast(); + } + + private void createItemsTable() { + itemsTable = createTable(); + itemsTable.addListener(SWT.MouseDoubleClick, event -> { + selectItem(); + }); + } + + /** + * @return a table that will contain data + */ + private Table createTable() { + final Table table = new Table(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); + table.setLinesVisible(false); + table.setHeaderVisible(false); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 4); + gd.widthHint = 200; + table.setLayoutData(gd); + new TableColumn(table, SWT.CENTER); + new TableColumn(table, SWT.LEFT); + table.setData(-1); + return table; + } + + private void createButtonSelectAll() { + buttonSelectAll = createButton(DOUBLE_RIGHT_IMAGE, true, GridData.END); + buttonSelectAll.addListener(SWT.Selection, e -> { + selectAll(); + }); + } + + private void createSelectionTable() { + selectionTable = createTable(); + selectionTable.addListener(SWT.MouseDoubleClick, event -> { + deselectItem(); + }); + } + + private void createButtonMoveFirst() { + buttonMoveFirst = createButton(DOUBLE_UP_IMAGE, true, GridData.END); + buttonMoveFirst.addListener(SWT.Selection, e -> { + moveSelectionToFirstPosition(); + }); + } + + private void createButtonSelect() { + buttonSelect = createButton(ARROW_RIGHT_IMAGE, false, GridData.CENTER); + buttonSelect.addListener(SWT.Selection, e -> { + selectItem(); + }); + } + + private void createButtonMoveUp() { + buttonMoveUp = createButton(ARROW_UP_IMAGE, false, GridData.CENTER); + buttonMoveUp.addListener(SWT.Selection, e -> { + moveUpItem(); + }); + } + + private void createButtonDeselect() { + buttonDeselect = createButton(ARROW_LEFT_IMAGE, false, GridData.CENTER); + buttonDeselect.addListener(SWT.Selection, e -> { + deselectItem(); + }); + } + + private void createButtonMoveDown() { + buttonMoveDown = createButton(ARROW_DOWN_IMAGE, false, GridData.CENTER); + buttonMoveDown.addListener(SWT.Selection, e -> { + moveDownItem(); + }); + } + + private void createButtonDeselectAll() { + buttonDeselectAll = createButton(DOUBLE_LEFT_IMAGE, false, GridData.BEGINNING); + buttonDeselectAll.addListener(SWT.Selection, e -> { + deselectAll(); + }); + } + + private void createButtonMoveLast() { + buttonMoveLast = createButton(DOUBLE_DOWN_IMAGE, true, GridData.BEGINNING); + buttonMoveLast.addListener(SWT.Selection, e -> { + moveSelectionToLastPosition(); + }); + } + + /** + * Create a button + * + * @param fileName file name of the icon + * @param verticalExpand if true, the button will take all the + * available space vertically + * @param alignment button alignment + * @return a new button + */ + private Button createButton(final String fileName, final boolean verticalExpand, final int alignment) { + final Button button = new Button(this, SWT.PUSH); + final Image image = SWTGraphicUtil.createImageFromFile("images/" + fileName); + button.setImage(image); + button.setLayoutData(new GridData(GridData.CENTER, alignment, false, verticalExpand)); + SWTGraphicUtil.addDisposer(button, image); + return button; + } + + /** + * Adds the argument to the end of the receiver's list. + * + * @param item the new item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see #add(DLItem,int) + */ + public void add(final DLItem item) { + checkWidget(); + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + items.add(item); + redrawTables(); + } + + /** + * Adds the argument to the receiver's list at the given zero-relative index. + *

+ * Note: To add an item at the end of the list, use the result of calling + * getItemCount() as the index or use add(DLItem). + *

+ * + * @param item the new item + * @param index the index for the item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and + * the number of elements in the list (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see #add(String) + */ + public void add(final DLItem item, final int index) { + checkWidget(); + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (index < 0 || index >= items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + items.add(index, item); + redrawTables(); + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the user changes the receiver's selection, by sending it one of the messages + * defined in the SelectionListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + SelectionListenerUtil.addSelectionListener(this, listener); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the user changes the receiver's selection. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.removeSelectionListener(this, listener); + } + + /** + * Adds the listener to the collection of listeners who will be notified when + * the user changes the receiver's selection, by sending it one of the messages + * defined in the SelectionChangeListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionChangeListener + * @see #removeSelectionChangeListener + * @see SelectionChangeEvent + */ + public void addSelectionChangeListener(final SelectionChangeListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (selectionChangeListeners == null) { + selectionChangeListeners = new ArrayList(); + } + selectionChangeListeners.add(listener); + } + + /** + * Removes the listener from the collection of listeners who will be notified + * when the user changes the receiver's selection. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionChangeListener + * @see #addSelectionChangeListener + */ + public void removeSelectionChangeListener(final SelectionChangeListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (selectionChangeListeners == null) { + return; + } + selectionChangeListeners.remove(listener); + } + + /** + * Deselects the item at the given zero-relative index in the receiver. If the + * item at the index was already deselected, it remains deselected. Indices that + * are out of range are ignored. + * + * @param index the index of the item to deselect + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselect(final int index) { + deselect(index, true); + } + + /** + * Deselects the item at the given zero-relative index in the receiver. If the + * item at the index was already deselected, it remains deselected. Indices that + * are out of range are ignored. + * + * @param index the index of the item to deselect + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselectDoNotFireEvent(final int index) { + deselect(index, false); + } + + /** + * Deselects the item at the given zero-relative index in the receiver. If the + * item at the index was already deselected, it remains deselected. Indices that + * are out of range are ignored. + * + * @param index the index of the item to deselect + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + private void deselect(final int index, final boolean shouldFireEvents) { + checkWidget(); + if (index < 0 || index >= items.size()) { + return; + } + final DLItem item = selection.remove(index); + if (shouldFireEvents) { + fireSelectionEvent(item); + } + + final List deselectedItems = new ArrayList(); + item.setLastAction(LAST_ACTION.DESELECTION); + deselectedItems.add(item); + if (shouldFireEvents) { + fireSelectionChangeEvent(deselectedItems); + } + redrawTables(); + } + + /** + * Deselects the items at the given zero-relative indices in the receiver. If + * the item at the given zero-relative index in the receiver is selected, it is + * deselected. If the item at the index was not selected, it remains deselected. + * Indices that are out of range and duplicate indices are ignored. + * + * @param indices the array of indices for the items to deselect + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the set of indices is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselect(final int[] indices) { + deselect(indices, true); + } + + /** + * Deselects the items at the given zero-relative indices in the receiver. If + * the item at the given zero-relative index in the receiver is selected, it is + * deselected. If the item at the index was not selected, it remains deselected. + * Indices that are out of range and duplicate indices are ignored. + * + * @param indices the array of indices for the items to deselect + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the set of indices is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselectDoNotFireEvent(final int[] indices) { + deselect(indices, false); + } + + /** + * Deselects the items at the given zero-relative indices in the receiver. If + * the item at the given zero-relative index in the receiver is selected, it is + * deselected. If the item at the index was not selected, it remains deselected. + * Indices that are out of range and duplicate indices are ignored. + * + * @param indices the array of indices for the items to deselect + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the set of indices is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + private void deselect(final int[] indices, final boolean shouldFireEvents) { + checkWidget(); + if (indices == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final List toBeRemoved = new ArrayList(); + + for (final int index : indices) { + if (index < 0 || index >= items.size()) { + continue; + } + toBeRemoved.add(selection.get(index)); + } + + for (final DLItem item : toBeRemoved) { + selection.remove(item); + if (shouldFireEvents) { + fireSelectionEvent(item); + } + } + if (shouldFireEvents) { + fireSelectionChangeEvent(toBeRemoved); + } + + toBeRemoved.clear(); + redrawTables(); + } + + /** + * Deselects the items at the given zero-relative indices in the receiver. If + * the item at the given zero-relative index in the receiver is selected, it is + * deselected. If the item at the index was not selected, it remains deselected. + * The range of the indices is inclusive. Indices that are out of range are + * ignored. + * + * @param start the start index of the items to deselect + * @param end the end index of the items to deselect + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if start is greater than end
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselect(final int start, final int end) { + deselect(start, end, true); + } + + /** + * Deselects the items at the given zero-relative indices in the receiver. If + * the item at the given zero-relative index in the receiver is selected, it is + * deselected. If the item at the index was not selected, it remains deselected. + * The range of the indices is inclusive. Indices that are out of range are + * ignored. + * + * @param start the start index of the items to deselect + * @param end the end index of the items to deselect + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if start is greater than end
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselectDoNotFireEvent(final int start, final int end) { + deselect(start, end, false); + } + + private void deselect(final int start, final int end, final boolean shouldFireEvents) { + checkWidget(); + if (start > end) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + final List toBeRemoved = new ArrayList(); + + for (int index = start; index <= end; index++) { + if (index < 0 || index >= items.size()) { + continue; + } + toBeRemoved.add(selection.get(index)); + } + + for (final DLItem item : toBeRemoved) { + selection.remove(item); + if (shouldFireEvents) { + fireSelectionEvent(item); + } + } + if (shouldFireEvents) { + fireSelectionChangeEvent(toBeRemoved); + } + toBeRemoved.clear(); + redrawTables(); + } + + /** + * Deselects all selected items in the receiver. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselectAll() { + deselectAll(true); + } + + /** + * Deselects all selected items in the receiver. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselectAllDoNotFireEvent() { + deselectAll(false); + } + + /** + * Deselects all selected items in the receiver. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void deselectAll(final boolean shouldFireEvents) { + checkWidget(); + items.addAll(selection); + + final List deselectedItems = new ArrayList(); + for (final DLItem item : selection) { + item.setLastAction(LAST_ACTION.DESELECTION); + deselectedItems.add(item); + if (shouldFireEvents) { + fireSelectionEvent(item); + } + } + fireSelectionChangeEvent(deselectedItems); + + selection.clear(); + redrawTables(); + } + + /** + * Returns the item at the given, zero-relative index in the receiver. Throws an + * exception if the index is out of range. + * + * @param index the index of the item to return + * @return the item at the given index + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and + * the number of elements in the list minus 1 (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + + public DLItem getItem(final int index) { + checkWidget(); + if (index < 0 || index >= items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return items.get(index); + } + + /** + * Returns the number of items contained in the receiver. + * + * @return the number of items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getItemCount() { + checkWidget(); + return items.size(); + } + + /** + * Returns a (possibly empty) array of DLItems which are the items + * in the receiver. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the items in the receiver's list + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public DLItem[] getItems() { + checkWidget(); + return items.toArray(new DLItem[items.size()]); + } + + /** + * Returns a (possibly empty) list of DLItems which are the items + * in the receiver. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * list of items, so modifying the array will not affect the receiver. + *

+ * + * @return the items in the receiver's list + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public List getItemsAsList() { + checkWidget(); + return new ArrayList(items); + } + + /** + * Returns an array of DLItems that are currently selected in the + * receiver. An empty array indicates that no items are selected. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * selection, so modifying the array will not affect the receiver. + *

+ * + * @return an array representing the selection + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public DLItem[] getSelection() { + checkWidget(); + return selection.toArray(new DLItem[selection.size()]); + } + + /** + * Returns a list of DLItems that are currently selected in the + * receiver. An empty array indicates that no items are selected. + *

+ * Note: This is not the actual structure used by the receiver to maintain its + * selection, so modifying the array will not affect the receiver. + *

+ * + * @return an array representing the selection + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public List getSelectionAsList() { + checkWidget(); + return new ArrayList(selection); + } + + /** + * Returns the number of selected items contained in the receiver. + * + * @return the number of selected items + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getSelectionCount() { + checkWidget(); + return selection.size(); + } + + /** + * Removes the item from the receiver at the given zero-relative index. + * + * @param index the index for the item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and + * the number of elements in the list minus 1 (inclusive)
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void remove(final int index) { + checkWidget(); + if (index < 0 || index >= items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + items.remove(index); + redrawTables(); + } + + /** + * Removes the items from the receiver at the given zero-relative indices. + * + * @param indices the array of indices of the items + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and + * the number of elements in the list minus 1 (inclusive)
  • + *
  • ERROR_NULL_ARGUMENT - if the indices array is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void remove(final int[] indices) { + checkWidget(); + for (final int index : indices) { + if (index < 0 || index >= items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + items.remove(index); + } + redrawTables(); + } + + /** + * Removes the items from the receiver which are between the given zero-relative + * start and end indices (inclusive). + * + * @param start the start of the range + * @param end the end of the range + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if either the start or end are not + * between 0 and the number of elements in the list minus 1 + * (inclusive) or if start>end
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void remove(final int start, final int end) { + checkWidget(); + if (start > end) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + for (int index = start; index < end; index++) { + if (index < 0 || index >= items.size()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + items.remove(index); + } + redrawTables(); + } + + /** + * Searches the receiver's list starting at the first item until an item is + * found that is equal to the argument, and removes that item from the list. + * + * @param item the item to remove + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
  • ERROR_INVALID_ARGUMENT - if the item is not found in the + * list
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void remove(final DLItem item) { + checkWidget(); + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (!items.contains(item)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + items.remove(item); + redrawTables(); + } + + /** + * Removes all of the items from the receiver. + *

+ * + * @exception SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void removeAll() { + checkWidget(); + items.clear(); + redrawTables(); + } + + /** + * Selects the item at the given zero-relative index in the receiver's list. If + * the item at the index was already selected, it remains selected. Indices that + * are out of range are ignored. + * + * @param index the index of the item to select + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void select(final int index) { + select(index, true); + } + + /** + * Selects the item at the given zero-relative index in the receiver's list. If + * the item at the index was already selected, it remains selected. Indices that + * are out of range are ignored. + * + * @param index the index of the item to select + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void selectDoNotFireEvent(final int index) { + select(index, false); + } + + private void select(final int index, final boolean shouldFireEvents) { + checkWidget(); + if (index < 0 || index >= items.size()) { + return; + } + final List selectedItems = new ArrayList(); + final DLItem item = items.remove(index); + item.setLastAction(LAST_ACTION.SELECTION); + selectedItems.add(item); + selection.add(item); + + if (shouldFireEvents) { + fireSelectionEvent(item); + fireSelectionChangeEvent(selectedItems); + } + + redrawTables(); + } + + /** + * Selects the items at the given zero-relative indices in the receiver. The + * current selection is not cleared before the new items are selected. + *

+ * If the item at a given index is not selected, it is selected. If the item at + * a given index was already selected, it remains selected. Indices that are out + * of range and duplicate indices are ignored. If the receiver is single-select + * and multiple indices are specified, then all indices are ignored. + * + * @param indices the array of indices for the items to select + * + * @exception IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the array of indices is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void select(final int[] indices) { + select(indices, true); + } + + /** + * Selects the items at the given zero-relative indices in the receiver. The + * current selection is not cleared before the new items are selected. + *

+ * If the item at a given index is not selected, it is selected. If the item at + * a given index was already selected, it remains selected. Indices that are out + * of range and duplicate indices are ignored. If the receiver is single-select + * and multiple indices are specified, then all indices are ignored. + * + * @param indices the array of indices for the items to select + * + * @exception IllegalArgumentException + *

    + *
  • ERROR_NULL_ARGUMENT - if the array of indices is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void selectDoNotFireEvent(final int[] indices) { + select(indices, false); + } + + private void select(final int[] indices, final boolean shouldFireEvents) { + checkWidget(); + if (indices == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final List selectedItems = new ArrayList(); + for (final int index : indices) { + if (index < 0 || index >= items.size()) { + continue; + } + final DLItem item = items.get(index); + item.setLastAction(LAST_ACTION.SELECTION); + selectedItems.add(item); + + selection.add(item); + if (shouldFireEvents) { + fireSelectionEvent(item); + } + } + items.removeAll(selectedItems); + if (shouldFireEvents) { + fireSelectionChangeEvent(selectedItems); + } + redrawTables(); + } + + /** + * Selects the items in the range specified by the given zero-relative indices + * in the receiver. The range of indices is inclusive. The current selection is + * not cleared before the new items are selected. + *

+ * If an item in the given range is not selected, it is selected. If an item in + * the given range was already selected, it remains selected. Indices that are + * out of range are ignored and no items will be selected if start is greater + * than end. If the receiver is single-select and there is more than one item in + * the given range, then all indices are ignored. + * + * @param start the start of the range + * @param end the end of the range + * + * @exception SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see List#setSelection(int,int) + */ + public void select(final int start, final int end) { + select(start, end, true); + } + + /** + * Selects the items in the range specified by the given zero-relative indices + * in the receiver. The range of indices is inclusive. The current selection is + * not cleared before the new items are selected. + *

+ * If an item in the given range is not selected, it is selected. If an item in + * the given range was already selected, it remains selected. Indices that are + * out of range are ignored and no items will be selected if start is greater + * than end. If the receiver is single-select and there is more than one item in + * the given range, then all indices are ignored. + * + * @param start the start of the range + * @param end the end of the range + * + * @exception SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see List#setSelection(int,int) + */ + public void selectDoNotFireEvent(final int start, final int end) { + select(start, end, false); + } + + private void select(final int start, final int end, final boolean shouldFireEvents) { + checkWidget(); + if (start > end) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + final List selectedItems = new ArrayList(); + for (int index = start; index <= end; index++) { + if (index < 0 || index >= items.size()) { + continue; + } + final DLItem item = items.get(index); + item.setLastAction(LAST_ACTION.SELECTION); + selectedItems.add(item); + selection.add(item); + if (shouldFireEvents) { + fireSelectionEvent(item); + } + } + if (shouldFireEvents) { + fireSelectionChangeEvent(selectedItems); + } + redrawTables(); + } + + /** + * Selects all of the items in the receiver. + *

+ * If the receiver is single-select, do nothing. + * + * @exception SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void selectAll() { + selectAll(true); + } + + /** + * Selects all of the items in the receiver. + *

+ * If the receiver is single-select, do nothing. + * + * @exception SWTException + *

    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void selectAllDoNotFireEvent() { + selectAll(false); + } + + private void selectAll(final boolean shouldFireEvents) { + checkWidget(); + selection.addAll(items); + if (shouldFireEvents) { + for (final DLItem item : items) { + fireSelectionEvent(item); + } + } + + if (shouldFireEvents) { + final List selectedItems = new ArrayList(); + for (final DLItem item : items) { + item.setLastAction(LAST_ACTION.SELECTION); + selectedItems.add(item); + } + fireSelectionChangeEvent(selectedItems); + } + items.clear(); + redrawTables(); + } + + /** + * @see org.eclipse.swt.widgets.Control#setBounds(int, int, int, int) + */ + @Override + public void setBounds(final int x, final int y, final int width, final int height) { + super.setBounds(x, y, width, height); + layout(true); + final boolean itemsContainImage = itemsContainImage(); + final Point itemsTableDefaultSize = itemsTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); + final Point selectionTableDefaultSize = selectionTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); + + int itemsTableSize = itemsTable.getSize().x; + if (itemsTableDefaultSize.y > itemsTable.getSize().y) { + itemsTableSize -= itemsTable.getVerticalBar().getSize().x + 1; + } + + int selectionTableSize = selectionTable.getSize().x; + if (selectionTableDefaultSize.y > selectionTable.getSize().y) { + selectionTableSize -= selectionTable.getVerticalBar().getSize().x; + } + + if (itemsContainImage) { + itemsTable.getColumn(0).pack(); + itemsTable.getColumn(1).setWidth(itemsTableSize - itemsTable.getColumn(0).getWidth()); + + selectionTable.getColumn(0).pack(); + selectionTable.getColumn(1).setWidth(selectionTableSize - selectionTable.getColumn(0).getWidth()); + + } else { + itemsTable.getColumn(0).setWidth(0); + itemsTable.getColumn(1).setWidth(itemsTableSize); + + selectionTable.getColumn(0).setWidth(0); + selectionTable.getColumn(1).setWidth(selectionTableSize); + } + + } + + /** + * @return true if any item contains an image + */ + private boolean itemsContainImage() { + for (final DLItem item : items) { + if (item.getImage() != null) { + return true; + } + } + + for (final DLItem item : selection) { + if (item.getImage() != null) { + return true; + } + } + + return false; + } + + /** + * Sets the item in the receiver's list at the given zero-relative index to the + * item argument. + * + * @param index the index for the item + * @param item the new item + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_RANGE - if the index is not between 0 and + * the number of elements in the list minus 1 (inclusive)
  • + *
  • ERROR_NULL_ARGUMENT - if the item is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setItem(final int index, final DLItem item) { + checkWidget(); + if (item == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + if (index < 0 || index >= items.size()) { + SWT.error(SWT.ERROR_INVALID_RANGE); + } + items.set(index, item); + redrawTables(); + } + + /** + * Sets the receiver's items to be the given array of items. + * + * @param items the array of items + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the items array is null
  • + *
  • ERROR_INVALID_ARGUMENT - if an item in the items array is + * null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setItems(final DLItem[] items) { + checkWidget(); + if (items == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final List temp = new ArrayList(); + for (final DLItem item : items) { + if (item == null) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + temp.add(item); + } + this.items.clear(); + this.items.addAll(temp); + redrawTables(); + } + + /** + * Sets the receiver's items to be the given list of items. + * + * @param items the list of items + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the items list is null
  • + *
  • ERROR_INVALID_ARGUMENT - if an item in the items list is + * null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setItems(final List items) { + checkWidget(); + if (items == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + + final List unselectedItems = new ArrayList(); + final List selectedItems = new ArrayList(); + for (final DLItem item : items) { + if (item == null) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + if (item.getLastAction() == LAST_ACTION.SELECTION) { + selectedItems.add(item); + } else { + unselectedItems.add(item); + } + } + this.items.clear(); + this.items.addAll(unselectedItems); + + this.selection.clear(); + this.selection.addAll(selectedItems); + + redrawTables(); + } + + /** + * Redraws all tables that compose this widget + */ + private void redrawTables() { + setRedraw(false); + redrawTable(itemsTable, false); + redrawTable(selectionTable, true); + Rectangle bounds = getBounds(); + this.setBounds(bounds.x, bounds.y, bounds.width, bounds.height); + setRedraw(true); + } + + /** + * Redraw a given table + * + * @param table table to be redrawned + * @param isSelected if true, fill the table with the selection. + * Otherwise, fill the table with the unselected items. + */ + private void redrawTable(final Table table, final boolean isSelected) { + clean(table); + fillData(table, isSelected); + } + + /** + * Cleans the content of a table + * + * @param table table to be emptied + */ + private void clean(final Table table) { + if (table == null) { + return; + } + + for (final TableItem item : table.getItems()) { + item.dispose(); + } + } + + /** + * Fill a table with data + * + * @param table table to be filled + * @param listOfData list of data + */ + private void fillData(final Table table, final boolean isSelected) { + List listOfData = isSelected ? selection : items; + int counter = 0; + for (final DLItem item : listOfData) { + final TableItem tableItem = new TableItem(table, SWT.NONE); + tableItem.setData(item); + + if (item.getBackground() != null) { + tableItem.setBackground(item.getBackground()); + } + + if (item.getForeground() != null) { + tableItem.setForeground(item.getForeground()); + } + + if (item.getImage() != null) { + tableItem.setImage(0, item.getImage()); + } + + if (item.getFont() != null) { + tableItem.setFont(item.getFont()); + } + tableItem.setText(1, item.getText()); + if (configuration != null && item.getBackground() == null && counter % 2 == 0) { + if (isSelected) { + tableItem.setBackground(configuration.getSelectionOddLinesColor()); + } else { + tableItem.setBackground(configuration.getItemsOddLinesColor()); + } + } + counter++; + } + } + + /** + * Move the selected item to the first position + */ + protected void moveSelectionToFirstPosition() { + if (selectionTable.getSelectionCount() == 0) { + return; + } + + int index = 0; + for (final TableItem tableItem : selectionTable.getSelection()) { + final DLItem item = (DLItem) tableItem.getData(); + selection.remove(item); + selection.add(index++, item); + } + + redrawTables(); + selectionTable.select(0, index - 1); + selectionTable.forceFocus(); + } + + /** + * Select a given item + */ + protected void selectItem() { + if (itemsTable.getSelectionCount() == 0) { + return; + } + final List selectedItems = new ArrayList(); + for (final TableItem tableItem : itemsTable.getSelection()) { + final DLItem item = (DLItem) tableItem.getData(); + item.setLastAction(LAST_ACTION.SELECTION); + selectedItems.add(item); + selection.add(item); + items.remove(item); + fireSelectionEvent(item); + } + fireSelectionChangeEvent(selectedItems); + + redrawTables(); + } + + /** + * Move the selected item up + */ + protected void moveUpItem() { + if (selectionTable.getSelectionCount() == 0) { + return; + } + + for (final int index : selectionTable.getSelectionIndices()) { + if (index == 0) { + selectionTable.forceFocus(); + return; + } + } + + final int[] newSelection = new int[selectionTable.getSelectionCount()]; + int newSelectionIndex = 0; + for (final TableItem tableItem : selectionTable.getSelection()) { + final int position = selection.indexOf(tableItem.getData()); + swap(position, position - 1); + newSelection[newSelectionIndex++] = position - 1; + } + + redrawTables(); + selectionTable.select(newSelection); + selectionTable.forceFocus(); + } + + /** + * Deselect a given item + */ + protected void deselectItem() { + if (selectionTable.getSelectionCount() == 0) { + return; + } + final List deselectedItems = new ArrayList(); + for (final TableItem tableItem : selectionTable.getSelection()) { + final DLItem item = (DLItem) tableItem.getData(); + item.setLastAction(LAST_ACTION.DESELECTION); + deselectedItems.add(item); + items.add(item); + selection.remove(item); + fireSelectionEvent(item); + } + fireSelectionChangeEvent(deselectedItems); + redrawTables(); + } + + /** + * Move the selected item down + */ + protected void moveDownItem() { + if (selectionTable.getSelectionCount() == 0) { + return; + } + + for (final int index : selectionTable.getSelectionIndices()) { + if (index == selectionTable.getItemCount() - 1) { + selectionTable.forceFocus(); + return; + } + } + + final int[] newSelection = new int[selectionTable.getSelectionCount()]; + int newSelectionIndex = 0; + for (final TableItem tableItem : selectionTable.getSelection()) { + final int position = selection.indexOf(tableItem.getData()); + swap(position, position + 1); + newSelection[newSelectionIndex++] = position + 1; + } + + redrawTables(); + selectionTable.select(newSelection); + selectionTable.forceFocus(); + } + + /** + * Swap 2 items + * + * @param first position of the first item to swap + * @param second position of the second item to swap + */ + private void swap(final int first, final int second) { + final DLItem temp = selection.get(first); + selection.set(first, selection.get(second)); + selection.set(second, temp); + } + + /** + * Move the selected item to the last position + */ + protected void moveSelectionToLastPosition() { + if (selectionTable.getSelectionCount() == 0) { + return; + } + + final int numberOfSelectedElements = selectionTable.getSelectionCount(); + for (final TableItem tableItem : selectionTable.getSelection()) { + final DLItem item = (DLItem) tableItem.getData(); + selection.remove(item); + selection.add(item); + } + + redrawTables(); + final int numberOfElements = selectionTable.getItemCount(); + selectionTable.select(numberOfElements - numberOfSelectedElements, numberOfElements - 1); + selectionTable.forceFocus(); + } + + /** + * Call all selection listeners + * + * @param item selected item + */ + private void fireSelectionEvent(final DLItem item) { + final Event event = new Event(); + event.button = 1; + event.display = getDisplay(); + event.item = null; + event.widget = this; + event.data = item; + + SelectionListenerUtil.fireSelectionListeners(this, event); + } + + private void fireSelectionChangeEvent(final List items) { + if (selectionChangeListeners == null) { + return; + } + + final Event event = new Event(); + event.button = 1; + event.display = getDisplay(); + event.item = null; + event.widget = this; + final SelectionChangeEvent selectionChangeEvent = new SelectionChangeEvent(event); + selectionChangeEvent.setItems(items); + + for (final SelectionChangeListener listener : selectionChangeListeners) { + listener.widgetSelected(selectionChangeEvent); + } + } + + /** + * Returns the configuration of the receiver. + * + * @return the current configuration of the receiver + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public DLConfiguration getConfiguration() { + checkWidget(); + return configuration; + } + + /** + * Sets the receiver's configuration + * + * @param configuration the new configuration + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setConfiguration(DLConfiguration configuration) { + checkWidget(); + this.configuration = configuration; + applyNewConfiguration(); + } + + private void applyNewConfiguration() { + try { + setRedraw(true); + if (configuration == null) { + resetConfigurationToDefault(); + } else { + modifyPanelsColors(); + modifyTextAlignment(); + modifyButtonImages(); + modifyButtonVisibility(); + } + redrawTables(); + } finally { + setRedraw(true); + } + } + + private void resetConfigurationToDefault() { + itemsTable.setBackground(null); + itemsTable.setForeground(null); + selectionTable.setBackground(null); + selectionTable.setForeground(null); + + recreateTableColumns(itemsTable, SWT.LEFT); + recreateTableColumns(selectionTable, SWT.LEFT); + + resetButton(buttonMoveLast, DOUBLE_DOWN_IMAGE); + resetButton(buttonMoveFirst, DOUBLE_UP_IMAGE); + resetButton(buttonDeselectAll, DOUBLE_LEFT_IMAGE); + resetButton(buttonSelectAll, DOUBLE_RIGHT_IMAGE); + resetButton(buttonMoveDown, ARROW_DOWN_IMAGE); + resetButton(buttonMoveUp, ARROW_UP_IMAGE); + resetButton(buttonDeselect, ARROW_LEFT_IMAGE); + resetButton(buttonSelect, ARROW_RIGHT_IMAGE); + } + + private void resetButton(Button button, String fileName) { + final Image image = SWTGraphicUtil.createImageFromFile("images/" + fileName); + button.setImage(image); + SWTGraphicUtil.addDisposer(button, image); + button.setVisible(true); + } + + private void modifyPanelsColors() { + if (configuration.getItemsBackgroundColor() != null) { + itemsTable.setBackground(configuration.getItemsBackgroundColor()); + } + if (configuration.getItemsForegroundColor() != null) { + itemsTable.setForeground(configuration.getItemsForegroundColor()); + } + if (configuration.getSelectionBackgroundColor() != null) { + selectionTable.setBackground(configuration.getSelectionBackgroundColor()); + } + if (configuration.getSelectionForegroundColor() != null) { + selectionTable.setForeground(configuration.getSelectionForegroundColor()); + } + } + + private void modifyTextAlignment() { + recreateTableColumns(itemsTable, configuration.getItemsTextAlignment()); + recreateTableColumns(selectionTable, configuration.getSelectionTextAlignment()); + } + + private void recreateTableColumns(Table table, int textAlignment) { + for (TableColumn tc : table.getColumns()) { + tc.dispose(); + } + new TableColumn(table, SWT.CENTER); + new TableColumn(table, textAlignment); + } + + private void modifyButtonImages() { + if (configuration.getDoubleDownImage() != null) { + buttonMoveLast.setImage(configuration.getDoubleDownImage()); + } + if (configuration.getDoubleUpImage() != null) { + buttonMoveFirst.setImage(configuration.getDoubleUpImage()); + } + if (configuration.getDoubleLeftImage() != null) { + buttonDeselectAll.setImage(configuration.getDoubleLeftImage()); + } + if (configuration.getDoubleRightImage() != null) { + buttonSelectAll.setImage(configuration.getDoubleRightImage()); + } + if (configuration.getDownImage() != null) { + buttonMoveDown.setImage(configuration.getDownImage()); + } + if (configuration.getUpImage() != null) { + buttonMoveUp.setImage(configuration.getUpImage()); + } + if (configuration.getLeftImage() != null) { + buttonDeselect.setImage(configuration.getLeftImage()); + } + if (configuration.getRightImage() != null) { + buttonSelect.setImage(configuration.getRightImage()); + } + } + + private void modifyButtonVisibility() { + buttonMoveLast.setVisible(configuration.isDoubleDownVisible()); + buttonMoveFirst.setVisible(configuration.isDoubleUpVisible()); + buttonDeselectAll.setVisible(configuration.isDoubleLeftVisible()); + buttonSelectAll.setVisible(configuration.isDoubleRightVisible()); + buttonMoveDown.setVisible(configuration.isDownVisible()); + buttonMoveUp.setVisible(configuration.isUpVisible()); + } + +} diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/SelectionChangeEvent.java b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/SelectionChangeEvent.java index 5ab125aef..0fe96d473 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/SelectionChangeEvent.java +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/SelectionChangeEvent.java @@ -1,66 +1,66 @@ -/******************************************************************************* - * Copyright (c) 2014-2021 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.duallist; - -import java.util.List; - -import org.eclipse.swt.events.TypedEvent; -import org.eclipse.swt.widgets.Event; - -/** - * Instances of this class are sent as a result of - * DualList being selected. - * - * @see SelectionChangeListener - */ -public class SelectionChangeEvent extends TypedEvent { - - private static final long serialVersionUID = -7164363995093867940L; - - /** - * The items that were selected. - */ - private List items; - - /** - * A flag indicating whether the operation should be allowed. - * Setting this field to false will cancel the - * operation, depending on the widget. - */ - public boolean doit; - - /** - * Constructs a new instance of this class based on the - * information in the given untyped event. - * - * @param e the untyped event containing the information - */ - public SelectionChangeEvent(final Event e) { - super(e); - } - - /** - * @return the list of items - */ - public List getItems() { - return items; - } - - /** - * @param items the list of items to set - */ - public void setItems(final List items) { - this.items = items; - } -} +/******************************************************************************* + * Copyright (c) 2014-2021 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.duallist; + +import java.util.List; + +import org.eclipse.swt.events.TypedEvent; +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * DualList being selected. + * + * @see SelectionChangeListener + */ +public class SelectionChangeEvent extends TypedEvent { + + private static final long serialVersionUID = -7164363995093867940L; + + /** + * The items that were selected. + */ + private List items; + + /** + * A flag indicating whether the operation should be allowed. + * Setting this field to false will cancel the + * operation, depending on the widget. + */ + public boolean doit; + + /** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ + public SelectionChangeEvent(final Event e) { + super(e); + } + + /** + * @return the list of items + */ + public List getItems() { + return items; + } + + /** + * @param items the list of items to set + */ + public void setItems(final List items) { + this.items = items; + } +} diff --git a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/SelectionChangeListener.java b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/SelectionChangeListener.java index 3a92ce33a..2a9da0c3f 100644 --- a/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/SelectionChangeListener.java +++ b/widgets/opal/duallist/org.eclipse.nebula.widgets.opal.duallist/src/org/eclipse/nebula/widgets/opal/duallist/SelectionChangeListener.java @@ -1,41 +1,41 @@ -/******************************************************************************* - * Copyright (c) 2014-2021 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.duallist; - -import org.eclipse.swt.internal.SWTEventListener; - -/** - * Classes which implement this interface provide methods that deal with the - * events that are generated when selection occurs in a control. - *

- * After creating an instance of a class that implements this interface it can - * be added to a control using the addSelectionChangeListener - * method and removed using the removeSelectionChangeListener - * method. When selection occurs in a control the appropriate method will be - * invoked. - *

- * - * @see SelectionChangeEvent - */ -@SuppressWarnings("restriction") -@FunctionalInterface -public interface SelectionChangeListener extends SWTEventListener { - - /** - * Sent when selection occurs in the control. - * - * @param e an event containing information about the selection - */ - public void widgetSelected(SelectionChangeEvent e); - -} +/******************************************************************************* + * Copyright (c) 2014-2021 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.duallist; + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods that deal with the + * events that are generated when selection occurs in a control. + *

+ * After creating an instance of a class that implements this interface it can + * be added to a control using the addSelectionChangeListener + * method and removed using the removeSelectionChangeListener + * method. When selection occurs in a control the appropriate method will be + * invoked. + *

+ * + * @see SelectionChangeEvent + */ +@SuppressWarnings("restriction") +@FunctionalInterface +public interface SelectionChangeListener extends SWTEventListener { + + /** + * Sent when selection occurs in the control. + * + * @param e an event containing information about the selection + */ + public void widgetSelected(SelectionChangeEvent e); + +} diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/.project b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/.project index 2954fd227..732c9c836 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/.project +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.header.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.header.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/build.properties b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/build.properties +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/feature.properties b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/feature.properties +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.classpath b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.classpath +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.project b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.project index e10a40034..34a71bdeb 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.project +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.header.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.header.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/META-INF/MANIFEST.MF b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/META-INF/MANIFEST.MF index a856c7963..a9dbb79b7 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/META-INF/MANIFEST.MF @@ -1,12 +1,12 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Header Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.header.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -RRequire-Bundle: org.eclipse.nebula.widgets.opal.header;bundle-version="1.0.0" -Export-Package: org.eclipse.nebula.widgets.opal.header.snippets -Require-Bundle: org.eclipse.nebula.widgets.opal.header;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.header.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Header Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.header.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +RRequire-Bundle: org.eclipse.nebula.widgets.opal.header;bundle-version="1.0.0" +Export-Package: org.eclipse.nebula.widgets.opal.header.snippets +Require-Bundle: org.eclipse.nebula.widgets.opal.header;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.header.snippets diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/build.properties b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/build.properties +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.classpath b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.classpath +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.project b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.project index 3f0ed9cca..bdc87c379 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.project +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.header - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.header + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/META-INF/MANIFEST.MF b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/META-INF/MANIFEST.MF index 5fb9f0e52..001481bd9 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/META-INF/MANIFEST.MF +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Header -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.header -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.header -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.header +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Header +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.header +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.header +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.header diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/build.properties b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/build.properties +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/src/org/eclipse/nebula/widgets/opal/header/Header.java b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/src/org/eclipse/nebula/widgets/opal/header/Header.java index 8696833bb..5ea2b6ad4 100644 --- a/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/src/org/eclipse/nebula/widgets/opal/header/Header.java +++ b/widgets/opal/header/org.eclipse.nebula.widgets.opal.header/src/org/eclipse/nebula/widgets/opal/header/Header.java @@ -1,565 +1,565 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron@gmail.com) - initial API and - * implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.header; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Layout; - -/** - * Instances of this class provide a header, which is composed of a text, a - * description and an image. - *

- *

- *
Styles:
- *
BORDER
- *
Events:
- *
(none)
- *
- */ -public class Header extends Composite { - - private Image image; - private String title; - private String description; - private Font titleFont; - private Color titleColor; - - private Image previousGeneratedImage; - private Color gradientEnd; - private Color gradientStart; - private Color separatorColor; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - */ - public Header(final Composite parent, final int style) { - super(parent, style); - - initFontAndColors(); - - setBackgroundMode(SWT.INHERIT_FORCE); - - addListener(SWT.Resize, e -> { - redrawComposite(); - }); - } - - private void initFontAndColors() { - final Font defaultFont; - final FontData[] fontData = getFont().getFontData(); - if (fontData != null && fontData.length > 0) { - final FontData fd = fontData[0]; - fd.setStyle(SWT.BOLD); - fd.setHeight(fd.getHeight() + 2); - defaultFont = new Font(getDisplay(), fd); - } else { - defaultFont = null; - } - titleFont = defaultFont; - SWTGraphicUtil.addDisposer(this, defaultFont); - - final Color defaultTitleColor = new Color(getDisplay(), 0, 88, 150); - titleColor = defaultTitleColor; - SWTGraphicUtil.addDisposer(this, defaultTitleColor); - - final Color defaultGradientEndColor = new Color(getDisplay(), 239, 239, 239); - gradientEnd = defaultGradientEndColor; - SWTGraphicUtil.addDisposer(this, defaultGradientEndColor); - - final Color defaultGradientStartColor = new Color(getDisplay(), 255, 255, 255); - gradientStart = defaultGradientStartColor; - SWTGraphicUtil.addDisposer(this, defaultGradientStartColor); - - final Color defaultSeparatorColor = new Color(getDisplay(), 229, 229, 229); - separatorColor = defaultSeparatorColor; - SWTGraphicUtil.addDisposer(this, defaultSeparatorColor); - } - - /** - * Redraw the composite - */ - private void redrawComposite() { - // Dispose previous content - for (final Control c : getChildren()) { - c.dispose(); - } - - int numberOfColumns = 1; - if (image != null) { - numberOfColumns++; - } - - super.setLayout(new GridLayout(numberOfColumns, false)); - createContent(); - drawBackground(); - } - - /** - * Create the content (title, image, description) - */ - private void createContent() { - if (title != null) { - createTitle(); - } - - if (image != null) { - createImage(); - } - - if (description != null) { - createDescription(); - } - } - - /** - * Create the title - */ - private void createTitle() { - final Label labelTitle = new Label(this, SWT.NONE); - labelTitle.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false)); - labelTitle.setFont(titleFont); - labelTitle.setForeground(titleColor); - labelTitle.setText(title); - } - - /** - * Create the image - */ - private void createImage() { - int numberOfLines = 1; - if (title != null && description != null) { - numberOfLines++; - } - final Label labelImage = new Label(this, SWT.NONE); - labelImage.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, true, 1, numberOfLines)); - labelImage.setImage(image); - } - - /** - * Create the description - */ - private void createDescription() { - final StyledText labelDescription = new StyledText(this, SWT.WRAP | SWT.READ_ONLY); - labelDescription.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - labelDescription.setEnabled(false); - labelDescription.setFont(getFont()); - labelDescription.setForeground(getForeground()); - labelDescription.setText(description); - SWTGraphicUtil.applyHTMLFormating(labelDescription); - } - - /** - * Draw the background (a gradient+a separator) - */ - private void drawBackground() { - final Display display = getDisplay(); - final Rectangle rect = getClientArea(); - final Image newImage = new Image(display, Math.max(1, rect.width), Math.max(1, rect.height)); - - final GC gc = new GC(newImage); - gc.setForeground(gradientStart); - gc.setBackground(gradientEnd); - - gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, false); - - gc.setForeground(separatorColor); - gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height - 1); - - gc.dispose(); - - setBackgroundImage(newImage); - if (previousGeneratedImage != null) { - previousGeneratedImage.dispose(); - } - previousGeneratedImage = newImage; - } - - /** - * @see org.eclipse.swt.widgets.Composite#setLayout(org.eclipse.swt.widgets.Layout) - */ - @Override - public void setLayout(final Layout layout) { - throw new UnsupportedOperationException("Not supported"); - } - - // ------------------------------------ Getters and Setters - - /** - * Returns the receiver's description if it has one, or null if it does not. - * - * @return the receiver's description if it has one, or null if it does not - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public String getDescription() { - checkWidget(); - return description; - } - - /** - * Returns the receiver's gradient end color. - * - * @return the receiver's gradient end color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getGradientEnd() { - checkWidget(); - return gradientEnd; - } - - /** - * Returns the receiver's gradient start color. - * - * @return the receiver's gradient start color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getGradientStart() { - checkWidget(); - return gradientStart; - } - - /** - * Returns the receiver's image if it has one, or null if it does not. - * - * @return the receiver's image if it has one, or null if it does not - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Image getImage() { - checkWidget(); - return image; - } - - /** - * Returns the receiver's separator color. - * - * @return the receiver's separator color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getSeparatorColor() { - checkWidget(); - return separatorColor; - } - - /** - * Returns the receiver's title if it has one, or null if it does not. - * - * @return the receiver's title if it has one, or null if it does not - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public String getTitle() { - checkWidget(); - return title; - } - - /** - * Returns the title's color. - * - * @return the title's color - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Color getTitleColor() { - checkWidget(); - return titleColor; - } - - /** - * Returns the title's font. - * - * @return the title's font. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public Font getTitleFont() { - checkWidget(); - return titleFont; - } - - /** - * Sets the receiver's description to the argument, which may be null indicating - * that no description should be displayed. - * - * @param description the description of the header (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setDescription(final String description) { - checkWidget(); - this.description = description; - } - - /** - * Sets the receiver's gradient end color. - * - * @param gradientEnd the receiver's gradient end color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setGradientEnd(final Color gradientEnd) { - checkWidget(); - this.gradientEnd = gradientEnd; - } - - /** - * Sets the receiver's gradient start color. - * - * @param gradientStart the receiver's gradient start color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setGradientStart(final Color gradientStart) { - checkWidget(); - this.gradientStart = gradientStart; - } - - /** - * Sets the receiver's image to the argument, which may be null indicating that - * no image should be displayed. - * - * @param image the image to display on the receiver (may be null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setImage(final Image image) { - checkWidget(); - this.image = image; - } - - /** - * Sets the receiver's separator color. - * - * @param separatorColor the receiver's separator color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setSeparatorColor(final Color separatorColor) { - this.separatorColor = separatorColor; - } - - /** - * Sets the receiver's title to the argument, which may be null indicating that - * no title should be displayed. - * - * @param title the title - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setTitle(final String title) { - checkWidget(); - this.title = title; - } - - /** - * Sets the receiver's title color. - * - * @param headerColor the receiver's title color - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setTitleColor(final Color headerColor) { - checkWidget(); - titleColor = headerColor; - } - - /** - * Sets the receiver's title font. - * - * @param headerFont the receiver's title font - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the image has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setTitleFont(final Font headerFont) { - checkWidget(); - titleFont = headerFont; - } -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron@gmail.com) - initial API and + * implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.header; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; + +/** + * Instances of this class provide a header, which is composed of a text, a + * description and an image. + *

+ *

+ *
Styles:
+ *
BORDER
+ *
Events:
+ *
(none)
+ *
+ */ +public class Header extends Composite { + + private Image image; + private String title; + private String description; + private Font titleFont; + private Color titleColor; + + private Image previousGeneratedImage; + private Color gradientEnd; + private Color gradientStart; + private Color separatorColor; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + public Header(final Composite parent, final int style) { + super(parent, style); + + initFontAndColors(); + + setBackgroundMode(SWT.INHERIT_FORCE); + + addListener(SWT.Resize, e -> { + redrawComposite(); + }); + } + + private void initFontAndColors() { + final Font defaultFont; + final FontData[] fontData = getFont().getFontData(); + if (fontData != null && fontData.length > 0) { + final FontData fd = fontData[0]; + fd.setStyle(SWT.BOLD); + fd.setHeight(fd.getHeight() + 2); + defaultFont = new Font(getDisplay(), fd); + } else { + defaultFont = null; + } + titleFont = defaultFont; + SWTGraphicUtil.addDisposer(this, defaultFont); + + final Color defaultTitleColor = new Color(getDisplay(), 0, 88, 150); + titleColor = defaultTitleColor; + SWTGraphicUtil.addDisposer(this, defaultTitleColor); + + final Color defaultGradientEndColor = new Color(getDisplay(), 239, 239, 239); + gradientEnd = defaultGradientEndColor; + SWTGraphicUtil.addDisposer(this, defaultGradientEndColor); + + final Color defaultGradientStartColor = new Color(getDisplay(), 255, 255, 255); + gradientStart = defaultGradientStartColor; + SWTGraphicUtil.addDisposer(this, defaultGradientStartColor); + + final Color defaultSeparatorColor = new Color(getDisplay(), 229, 229, 229); + separatorColor = defaultSeparatorColor; + SWTGraphicUtil.addDisposer(this, defaultSeparatorColor); + } + + /** + * Redraw the composite + */ + private void redrawComposite() { + // Dispose previous content + for (final Control c : getChildren()) { + c.dispose(); + } + + int numberOfColumns = 1; + if (image != null) { + numberOfColumns++; + } + + super.setLayout(new GridLayout(numberOfColumns, false)); + createContent(); + drawBackground(); + } + + /** + * Create the content (title, image, description) + */ + private void createContent() { + if (title != null) { + createTitle(); + } + + if (image != null) { + createImage(); + } + + if (description != null) { + createDescription(); + } + } + + /** + * Create the title + */ + private void createTitle() { + final Label labelTitle = new Label(this, SWT.NONE); + labelTitle.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false)); + labelTitle.setFont(titleFont); + labelTitle.setForeground(titleColor); + labelTitle.setText(title); + } + + /** + * Create the image + */ + private void createImage() { + int numberOfLines = 1; + if (title != null && description != null) { + numberOfLines++; + } + final Label labelImage = new Label(this, SWT.NONE); + labelImage.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, true, 1, numberOfLines)); + labelImage.setImage(image); + } + + /** + * Create the description + */ + private void createDescription() { + final StyledText labelDescription = new StyledText(this, SWT.WRAP | SWT.READ_ONLY); + labelDescription.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + labelDescription.setEnabled(false); + labelDescription.setFont(getFont()); + labelDescription.setForeground(getForeground()); + labelDescription.setText(description); + SWTGraphicUtil.applyHTMLFormating(labelDescription); + } + + /** + * Draw the background (a gradient+a separator) + */ + private void drawBackground() { + final Display display = getDisplay(); + final Rectangle rect = getClientArea(); + final Image newImage = new Image(display, Math.max(1, rect.width), Math.max(1, rect.height)); + + final GC gc = new GC(newImage); + gc.setForeground(gradientStart); + gc.setBackground(gradientEnd); + + gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, false); + + gc.setForeground(separatorColor); + gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height - 1); + + gc.dispose(); + + setBackgroundImage(newImage); + if (previousGeneratedImage != null) { + previousGeneratedImage.dispose(); + } + previousGeneratedImage = newImage; + } + + /** + * @see org.eclipse.swt.widgets.Composite#setLayout(org.eclipse.swt.widgets.Layout) + */ + @Override + public void setLayout(final Layout layout) { + throw new UnsupportedOperationException("Not supported"); + } + + // ------------------------------------ Getters and Setters + + /** + * Returns the receiver's description if it has one, or null if it does not. + * + * @return the receiver's description if it has one, or null if it does not + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getDescription() { + checkWidget(); + return description; + } + + /** + * Returns the receiver's gradient end color. + * + * @return the receiver's gradient end color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getGradientEnd() { + checkWidget(); + return gradientEnd; + } + + /** + * Returns the receiver's gradient start color. + * + * @return the receiver's gradient start color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getGradientStart() { + checkWidget(); + return gradientStart; + } + + /** + * Returns the receiver's image if it has one, or null if it does not. + * + * @return the receiver's image if it has one, or null if it does not + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Image getImage() { + checkWidget(); + return image; + } + + /** + * Returns the receiver's separator color. + * + * @return the receiver's separator color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getSeparatorColor() { + checkWidget(); + return separatorColor; + } + + /** + * Returns the receiver's title if it has one, or null if it does not. + * + * @return the receiver's title if it has one, or null if it does not + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public String getTitle() { + checkWidget(); + return title; + } + + /** + * Returns the title's color. + * + * @return the title's color + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Color getTitleColor() { + checkWidget(); + return titleColor; + } + + /** + * Returns the title's font. + * + * @return the title's font. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public Font getTitleFont() { + checkWidget(); + return titleFont; + } + + /** + * Sets the receiver's description to the argument, which may be null indicating + * that no description should be displayed. + * + * @param description the description of the header (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setDescription(final String description) { + checkWidget(); + this.description = description; + } + + /** + * Sets the receiver's gradient end color. + * + * @param gradientEnd the receiver's gradient end color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setGradientEnd(final Color gradientEnd) { + checkWidget(); + this.gradientEnd = gradientEnd; + } + + /** + * Sets the receiver's gradient start color. + * + * @param gradientStart the receiver's gradient start color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setGradientStart(final Color gradientStart) { + checkWidget(); + this.gradientStart = gradientStart; + } + + /** + * Sets the receiver's image to the argument, which may be null indicating that + * no image should be displayed. + * + * @param image the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setImage(final Image image) { + checkWidget(); + this.image = image; + } + + /** + * Sets the receiver's separator color. + * + * @param separatorColor the receiver's separator color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSeparatorColor(final Color separatorColor) { + this.separatorColor = separatorColor; + } + + /** + * Sets the receiver's title to the argument, which may be null indicating that + * no title should be displayed. + * + * @param title the title + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTitle(final String title) { + checkWidget(); + this.title = title; + } + + /** + * Sets the receiver's title color. + * + * @param headerColor the receiver's title color + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTitleColor(final Color headerColor) { + checkWidget(); + titleColor = headerColor; + } + + /** + * Sets the receiver's title font. + * + * @param headerFont the receiver's title font + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the image has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setTitleFont(final Font headerFont) { + checkWidget(); + titleFont = headerFont; + } +} diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/.project b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/.project index a2bc741db..31921dff0 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/.project +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.heapmanager.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.heapmanager.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/build.properties b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/build.properties +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/feature.properties b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/feature.properties +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.classpath b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.classpath +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.project b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.project index d1127ed27..98f45a0f4 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.project +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.heapmanager.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.heapmanager.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/META-INF/MANIFEST.MF b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/META-INF/MANIFEST.MF index c8b301f8e..1821cb683 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Heap Manager Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.heapmanager.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.heapmanager;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.heapmanager.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Heap Manager Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.heapmanager.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.heapmanager;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.heapmanager.snippets diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/build.properties b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/build.properties +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/src/org/eclipse/nebula/widgets/opal/heapmanager/snippets/HeapManagerSnippet.java b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/src/org/eclipse/nebula/widgets/opal/heapmanager/snippets/HeapManagerSnippet.java index 20a4b3b34..14e498882 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/src/org/eclipse/nebula/widgets/opal/heapmanager/snippets/HeapManagerSnippet.java +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager.snippets/src/org/eclipse/nebula/widgets/opal/heapmanager/snippets/HeapManagerSnippet.java @@ -1,59 +1,59 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron@gmail.com) - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.heapmanager.snippets; - -import org.eclipse.nebula.widgets.opal.heapmanager.HeapManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple snippet for the TextAssist Widget - */ -public class HeapManagerSnippet { - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - - new HeapManager(shell, SWT.NONE); - - final int[] counter = new int[1]; - counter[0] = 1; - - display.timerExec(10, new Runnable() { - - @Override - public void run() { - for (int i = 0; i < 10000; i++) { - @SuppressWarnings("unused") - final String[] temp = new String[1000]; - } - counter[0]++; - if (counter[0] < 100) { - display.timerExec(10, this); - } - } - }); - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron@gmail.com) + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.heapmanager.snippets; + +import org.eclipse.nebula.widgets.opal.heapmanager.HeapManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple snippet for the TextAssist Widget + */ +public class HeapManagerSnippet { + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + + new HeapManager(shell, SWT.NONE); + + final int[] counter = new int[1]; + counter[0] = 1; + + display.timerExec(10, new Runnable() { + + @Override + public void run() { + for (int i = 0; i < 10000; i++) { + @SuppressWarnings("unused") + final String[] temp = new String[1000]; + } + counter[0]++; + if (counter[0] < 100) { + display.timerExec(10, this); + } + } + }); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } +} diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.classpath b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.classpath +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.project b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.project index 806217b10..97f114702 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.project +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.heapmanager - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.heapmanager + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/META-INF/MANIFEST.MF b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/META-INF/MANIFEST.MF index 5bca1baf2..31fe40ba1 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/META-INF/MANIFEST.MF +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Heap Manager Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.heapmanager -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.heapmanager -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.heapmanager +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Heap Manager Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.heapmanager +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.heapmanager +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.heapmanager diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/build.properties b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/build.properties +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/src/org/eclipse/nebula/widgets/opal/heapmanager/HeapManager.java b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/src/org/eclipse/nebula/widgets/opal/heapmanager/HeapManager.java index 7b8f2c655..7786716b7 100644 --- a/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/src/org/eclipse/nebula/widgets/opal/heapmanager/HeapManager.java +++ b/widgets/opal/heapmanager/org.eclipse.nebula.widgets.opal.heapmanager/src/org/eclipse/nebula/widgets/opal/heapmanager/HeapManager.java @@ -1,270 +1,270 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial - * implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.heapmanager; - -import org.eclipse.nebula.widgets.opal.commons.ResourceManager; -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.graphics.Color; -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.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Widget; - -/** - * Instances of this class are controls that display the memory used, the whole - * memory, and contains a button to perform a GC - */ -public class HeapManager extends Composite { - private Canvas bar; - private Button button; - private int heapMaxSize; - private int heapSize; - private Color barBorderColor; - private Color barInnerColor; - private Color barTextColor; - private Color barGradientColorTopStart; - private Color barGradientColorTopEnd; - private Color barGradientColorMiddleStart; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a widget which will be the parent of the new instance (cannot - * be null) - * @param style the style of widget to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - * @see Composite#Composite(Composite, int) - * @see Widget#getStyle - */ - public HeapManager(final Composite parent, final int style) { - super(parent, style); - final GridLayout gridLayout = new GridLayout(2, false); - gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0; - setLayout(gridLayout); - - createBar(); - createButton(); - updateContent(); - createDefaultColors(); - } - - /** - * Creates the bar that displays the memory - */ - private void createBar() { - bar = new Canvas(this, SWT.NONE); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false); - gd.minimumWidth = 100; - gd.heightHint = 30; - bar.setLayoutData(gd); - heapMaxSize = (int) (Runtime.getRuntime().maxMemory() / (1024 * 1024)); - bar.addPaintListener(e -> { - drawBar(e); - }); - } - - /** - * Draw the bar - * - * @param e {@link PaintEvent} - */ - private void drawBar(final PaintEvent e) { - final GC gc = e.gc; - final Rectangle clientArea = bar.getClientArea(); - - gc.setForeground(barBorderColor); - gc.setBackground(barInnerColor); - gc.fillRectangle(clientArea); - gc.drawRectangle(clientArea.x, clientArea.y, clientArea.width - 1, clientArea.height - 1); - - final float width = (clientArea.width - 2f) * heapSize / heapMaxSize; - - gc.setForeground(barGradientColorTopStart); - gc.setBackground(barGradientColorTopEnd); - gc.fillGradientRectangle(clientArea.x + 1, clientArea.y + 1, (int) width, clientArea.height / 2, true); - - gc.setForeground(barGradientColorMiddleStart); - gc.setBackground(barBorderColor); - gc.fillGradientRectangle(clientArea.x + 1, clientArea.height / 2, (int) width, clientArea.height / 2, true); - - final String message = heapSize + " " + ResourceManager.getLabel(ResourceManager.MEGABYTES) + "/" + // - heapMaxSize + " " + ResourceManager.getLabel(ResourceManager.MEGABYTES); - final Point size = gc.stringExtent(message); - - gc.setForeground(barTextColor); - gc.setFont(getFont()); - gc.drawText(message, (clientArea.width - size.x) / 2, (clientArea.height - size.y) / 2, true); - - gc.dispose(); - - } - - /** - * Create the button used to perform GC - */ - private void createButton() { - button = new Button(this, SWT.PUSH); - final Image image = SWTGraphicUtil.createImageFromFile("images/trash.png"); - button.setImage(image); - SWTGraphicUtil.addDisposer(button, image); - button.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - button.addListener(SWT.Selection, e -> { - System.gc(); - }); - button.setToolTipText(ResourceManager.getLabel(ResourceManager.PERFORM_GC)); - button.pack(); - } - - /** - * Update the content of the bar - */ - private void updateContent() { - getDisplay().timerExec(500, new Runnable() { - @Override - public void run() { - heapSize = (int) (Runtime.getRuntime().totalMemory() / (1024 * 1024)); - if (!isDisposed()) { - bar.redraw(); - if (!getDisplay().isDisposed()) { - getDisplay().timerExec(500, this); - } - } - } - }); - } - - /** - * Creates the default colors - */ - private void createDefaultColors() { - barTextColor = SWTGraphicUtil.getDefaultColor(this, 57, 98, 149); - barInnerColor = SWTGraphicUtil.getDefaultColor(this, 219, 230, 243); - barBorderColor = SWTGraphicUtil.getDefaultColor(this, 101, 148, 207); - barGradientColorTopStart = SWTGraphicUtil.getDefaultColor(this, 175, 202, 237); - barGradientColorTopEnd = SWTGraphicUtil.getDefaultColor(this, 136, 177, 229); - barGradientColorMiddleStart = SWTGraphicUtil.getDefaultColor(this, 112, 161, 223); - } - - /** - * @return the barBorderColor - */ - public Color getBarBorderColor() { - return barBorderColor; - } - - /** - * @param barBorderColor the barBorderColor to set - */ - public void setBarBorderColor(final Color barBorderColor) { - this.barBorderColor = barBorderColor; - } - - /** - * @return the barInnerColor - */ - public Color getBarInnerColor() { - return barInnerColor; - } - - /** - * @param barInnerColor the barInnerColor to set - */ - public void setBarInnerColor(final Color barInnerColor) { - this.barInnerColor = barInnerColor; - } - - /** - * @return the barTextColor - */ - public Color getBarTextColor() { - return barTextColor; - } - - /** - * @param barTextColor the barTextColor to set - */ - public void setBarTextColor(final Color barTextColor) { - this.barTextColor = barTextColor; - } - - /** - * @return the barGradientColorTopStart - */ - public Color getBarGradientColorTopStart() { - return barGradientColorTopStart; - } - - /** - * @param barGradientColorTopStart the barGradientColorTopStart to set - */ - public void setBarGradientColorTopStart(final Color barGradientColorTopStart) { - this.barGradientColorTopStart = barGradientColorTopStart; - } - - /** - * @return the barGradientColorTopEnd - */ - public Color getBarGradientColorTopEnd() { - return barGradientColorTopEnd; - } - - /** - * @param barGradientColorTopEnd the barGradientColorTopEnd to set - */ - public void setBarGradientColorTopEnd(final Color barGradientColorTopEnd) { - this.barGradientColorTopEnd = barGradientColorTopEnd; - } - - /** - * @return the barGradientColorMiddleStart - */ - public Color getBarGradientColorMiddleStart() { - return barGradientColorMiddleStart; - } - - /** - * @param barGradientColorMiddleStart the barGradientColorMiddleStart to set - */ - public void setBarGradientColorMiddleStart(final Color barGradientColorMiddleStart) { - this.barGradientColorMiddleStart = barGradientColorMiddleStart; - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - Initial + * implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.heapmanager; + +import org.eclipse.nebula.widgets.opal.commons.ResourceManager; +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.Color; +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.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Widget; + +/** + * Instances of this class are controls that display the memory used, the whole + * memory, and contains a button to perform a GC + */ +public class HeapManager extends Composite { + private Canvas bar; + private Button button; + private int heapMaxSize; + private int heapSize; + private Color barBorderColor; + private Color barInnerColor; + private Color barTextColor; + private Color barGradientColorTopStart; + private Color barGradientColorTopEnd; + private Color barGradientColorMiddleStart; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a widget which will be the parent of the new instance (cannot + * be null) + * @param style the style of widget to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + * @see Composite#Composite(Composite, int) + * @see Widget#getStyle + */ + public HeapManager(final Composite parent, final int style) { + super(parent, style); + final GridLayout gridLayout = new GridLayout(2, false); + gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0; + setLayout(gridLayout); + + createBar(); + createButton(); + updateContent(); + createDefaultColors(); + } + + /** + * Creates the bar that displays the memory + */ + private void createBar() { + bar = new Canvas(this, SWT.NONE); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false); + gd.minimumWidth = 100; + gd.heightHint = 30; + bar.setLayoutData(gd); + heapMaxSize = (int) (Runtime.getRuntime().maxMemory() / (1024 * 1024)); + bar.addPaintListener(e -> { + drawBar(e); + }); + } + + /** + * Draw the bar + * + * @param e {@link PaintEvent} + */ + private void drawBar(final PaintEvent e) { + final GC gc = e.gc; + final Rectangle clientArea = bar.getClientArea(); + + gc.setForeground(barBorderColor); + gc.setBackground(barInnerColor); + gc.fillRectangle(clientArea); + gc.drawRectangle(clientArea.x, clientArea.y, clientArea.width - 1, clientArea.height - 1); + + final float width = (clientArea.width - 2f) * heapSize / heapMaxSize; + + gc.setForeground(barGradientColorTopStart); + gc.setBackground(barGradientColorTopEnd); + gc.fillGradientRectangle(clientArea.x + 1, clientArea.y + 1, (int) width, clientArea.height / 2, true); + + gc.setForeground(barGradientColorMiddleStart); + gc.setBackground(barBorderColor); + gc.fillGradientRectangle(clientArea.x + 1, clientArea.height / 2, (int) width, clientArea.height / 2, true); + + final String message = heapSize + " " + ResourceManager.getLabel(ResourceManager.MEGABYTES) + "/" + // + heapMaxSize + " " + ResourceManager.getLabel(ResourceManager.MEGABYTES); + final Point size = gc.stringExtent(message); + + gc.setForeground(barTextColor); + gc.setFont(getFont()); + gc.drawText(message, (clientArea.width - size.x) / 2, (clientArea.height - size.y) / 2, true); + + gc.dispose(); + + } + + /** + * Create the button used to perform GC + */ + private void createButton() { + button = new Button(this, SWT.PUSH); + final Image image = SWTGraphicUtil.createImageFromFile("images/trash.png"); + button.setImage(image); + SWTGraphicUtil.addDisposer(button, image); + button.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + button.addListener(SWT.Selection, e -> { + System.gc(); + }); + button.setToolTipText(ResourceManager.getLabel(ResourceManager.PERFORM_GC)); + button.pack(); + } + + /** + * Update the content of the bar + */ + private void updateContent() { + getDisplay().timerExec(500, new Runnable() { + @Override + public void run() { + heapSize = (int) (Runtime.getRuntime().totalMemory() / (1024 * 1024)); + if (!isDisposed()) { + bar.redraw(); + if (!getDisplay().isDisposed()) { + getDisplay().timerExec(500, this); + } + } + } + }); + } + + /** + * Creates the default colors + */ + private void createDefaultColors() { + barTextColor = SWTGraphicUtil.getDefaultColor(this, 57, 98, 149); + barInnerColor = SWTGraphicUtil.getDefaultColor(this, 219, 230, 243); + barBorderColor = SWTGraphicUtil.getDefaultColor(this, 101, 148, 207); + barGradientColorTopStart = SWTGraphicUtil.getDefaultColor(this, 175, 202, 237); + barGradientColorTopEnd = SWTGraphicUtil.getDefaultColor(this, 136, 177, 229); + barGradientColorMiddleStart = SWTGraphicUtil.getDefaultColor(this, 112, 161, 223); + } + + /** + * @return the barBorderColor + */ + public Color getBarBorderColor() { + return barBorderColor; + } + + /** + * @param barBorderColor the barBorderColor to set + */ + public void setBarBorderColor(final Color barBorderColor) { + this.barBorderColor = barBorderColor; + } + + /** + * @return the barInnerColor + */ + public Color getBarInnerColor() { + return barInnerColor; + } + + /** + * @param barInnerColor the barInnerColor to set + */ + public void setBarInnerColor(final Color barInnerColor) { + this.barInnerColor = barInnerColor; + } + + /** + * @return the barTextColor + */ + public Color getBarTextColor() { + return barTextColor; + } + + /** + * @param barTextColor the barTextColor to set + */ + public void setBarTextColor(final Color barTextColor) { + this.barTextColor = barTextColor; + } + + /** + * @return the barGradientColorTopStart + */ + public Color getBarGradientColorTopStart() { + return barGradientColorTopStart; + } + + /** + * @param barGradientColorTopStart the barGradientColorTopStart to set + */ + public void setBarGradientColorTopStart(final Color barGradientColorTopStart) { + this.barGradientColorTopStart = barGradientColorTopStart; + } + + /** + * @return the barGradientColorTopEnd + */ + public Color getBarGradientColorTopEnd() { + return barGradientColorTopEnd; + } + + /** + * @param barGradientColorTopEnd the barGradientColorTopEnd to set + */ + public void setBarGradientColorTopEnd(final Color barGradientColorTopEnd) { + this.barGradientColorTopEnd = barGradientColorTopEnd; + } + + /** + * @return the barGradientColorMiddleStart + */ + public Color getBarGradientColorMiddleStart() { + return barGradientColorMiddleStart; + } + + /** + * @param barGradientColorMiddleStart the barGradientColorMiddleStart to set + */ + public void setBarGradientColorMiddleStart(final Color barGradientColorMiddleStart) { + this.barGradientColorMiddleStart = barGradientColorMiddleStart; + } + +} diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/.project b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/.project index 4db8028b9..47ee36b08 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/.project +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.horizontalspinner.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.horizontalspinner.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/build.properties b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/build.properties +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/feature.properties b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/feature.properties +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.classpath b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.classpath +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.project b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.project index 5dcdd9713..0fea3ac09 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.project +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.horizontalspinner.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.horizontalspinner.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/META-INF/MANIFEST.MF b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/META-INF/MANIFEST.MF index cbff221f9..bea01d0f3 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Horizontal Spinner Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.horizontalspinner.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.horizontalspinner;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.horizontalspinner.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Horizontal Spinner Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.horizontalspinner.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.horizontalspinner;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.horizontalspinner.snippets diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/build.properties b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/build.properties +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/src/org/eclipse/nebula/widgets/opal/horizontalspinner/snippets/HorizontalSpinnerSnippet.java b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/src/org/eclipse/nebula/widgets/opal/horizontalspinner/snippets/HorizontalSpinnerSnippet.java index 57730feab..600ffdc9b 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/src/org/eclipse/nebula/widgets/opal/horizontalspinner/snippets/HorizontalSpinnerSnippet.java +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner.snippets/src/org/eclipse/nebula/widgets/opal/horizontalspinner/snippets/HorizontalSpinnerSnippet.java @@ -1,205 +1,205 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron@gmail.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.horizontalspinner.snippets; - -import org.eclipse.nebula.widgets.opal.horizontalspinner.HorizontalSpinner; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Spinner; -import org.eclipse.swt.widgets.ToolTip; - -/** - * A simple snipper for the Horizontal Spinner widget - * - */ -public class HorizontalSpinnerSnippet { - - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(4, true)); - - createSpinnerGroup(shell); - createHorizontalSpinnerGroup(shell, "Default look", SWT.NONE); - createHorizontalSpinnerGroup(shell, "Buttons on the left", SWT.LEFT); - createHorizontalSpinnerGroup(shell, "Buttons on the right", SWT.RIGHT); - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - - } - - private static void createSpinnerGroup(final Shell shell) { - final Group group = new Group(shell, SWT.NONE); - group.setLayout(new GridLayout(1, false)); - - final Label lbl1 = new Label(group, SWT.NONE); - lbl1.setText("Simple vertical spinner :"); - final Spinner spinner1 = new Spinner(group, SWT.BORDER); - spinner1.setMinimum(0); - spinner1.setMaximum(1000); - spinner1.setSelection(500); - spinner1.setIncrement(1); - spinner1.setPageIncrement(100); - - final Label lbl2 = new Label(group, SWT.NONE); - lbl2.setText("Floating point values in Spinner :"); - final Spinner spinner2 = new Spinner(group, SWT.NONE); - // allow 3 decimal places - spinner2.setDigits(3); - // set the minimum value to 0.001 - spinner2.setMinimum(1); - // set the maximum value to 20 - spinner2.setMaximum(20000); - // set the increment value to 0.010 - spinner2.setIncrement(10); - // set the seletion to 3.456 - spinner2.setSelection(3456); - spinner2.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - final int selection = spinner2.getSelection(); - final int digits = spinner2.getDigits(); - System.out.println("Selection is " + selection / Math.pow(10, digits)); - } - }); - - final Label lbl3 = new Label(group, SWT.NONE); - lbl3.setText("Validate input in a spinner widget :"); - final Spinner spinner3 = new Spinner(group, SWT.BORDER); - spinner3.setValues(0, -100, 100, 0, 1, 10); - spinner3.setLayoutData(new GridData(200, SWT.DEFAULT)); - final ToolTip toolTip = new ToolTip(shell, SWT.BALLOON | SWT.ICON_WARNING); - spinner3.addModifyListener(e -> { - final String string = spinner3.getText(); - String message = null; - try { - final int value = Integer.parseInt(string); - final int maximum = spinner3.getMaximum(); - final int minimum = spinner3.getMinimum(); - if (value > maximum) { - message = "Current input is greater than the maximum limit (" + maximum + ")"; - } else if (value < minimum) { - message = "Current input is less than the minimum limit (" + minimum + ")"; - } - } catch (final Exception ex) { - message = "Current input is not numeric"; - } - if (message != null) { - spinner3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_RED)); - final Rectangle rect = spinner3.getBounds(); - final GC gc = new GC(spinner3); - final Point pt = gc.textExtent(string); - gc.dispose(); - toolTip.setLocation(shell.getDisplay().map(shell, null, rect.x + pt.x, rect.y + rect.height)); - toolTip.setMessage(message); - toolTip.setVisible(true); - } else { - toolTip.setVisible(false); - spinner3.setForeground(null); - } - }); - - } - - private static void createHorizontalSpinnerGroup(final Shell shell, final String title, final int style) { - final Group group = new Group(shell, SWT.NONE); - group.setLayout(new GridLayout(1, false)); - group.setText(title); - - final Label lbl1 = new Label(group, SWT.NONE); - lbl1.setText("Simple horizontal spinner :"); - final HorizontalSpinner spinner1 = new HorizontalSpinner(group, SWT.BORDER | style); - spinner1.setMinimum(0); - spinner1.setMaximum(1000); - spinner1.setSelection(500); - spinner1.setIncrement(1); - spinner1.setPageIncrement(100); - - final Label lbl2 = new Label(group, SWT.NONE); - lbl2.setText("Floating point values in Spinner :"); - final HorizontalSpinner spinner2 = new HorizontalSpinner(group, style); - // allow 3 decimal places - spinner2.setDigits(3); - // set the minimum value to 0.001 - spinner2.setMinimum(1); - // set the maximum value to 20 - spinner2.setMaximum(20000); - // set the increment value to 0.010 - spinner2.setIncrement(10); - // set the seletion to 3.456 - spinner2.setSelection(3456); - spinner2.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(final SelectionEvent e) { - final int selection = spinner2.getSelection(); - final int digits = spinner2.getDigits(); - System.out.println("Selection is " + selection / Math.pow(10, digits)); - } - }); - - final Label lbl3 = new Label(group, SWT.NONE); - lbl3.setText("Validate input in a spinner widget :"); - final HorizontalSpinner spinner3 = new HorizontalSpinner(group, SWT.BORDER | style); - spinner3.setValues(0, -100, 100, 0, 1, 10); - spinner3.setLayoutData(new GridData(200, SWT.DEFAULT)); - final ToolTip toolTip = new ToolTip(shell, SWT.BALLOON | SWT.ICON_WARNING); - spinner3.addModifyListener(e -> { - final String string = spinner3.getText(); - String message = null; - try { - final int value = Integer.parseInt(string); - final int maximum = spinner3.getMaximum(); - final int minimum = spinner3.getMinimum(); - if (value > maximum) { - message = "Current input is greater than the maximum limit (" + maximum + ")"; - } else if (value < minimum) { - message = "Current input is less than the minimum limit (" + minimum + ")"; - } - } catch (final Exception ex) { - message = "Current input is not numeric"; - } - if (message != null) { - spinner3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_RED)); - final Rectangle rect = spinner3.getBounds(); - final GC gc = new GC(spinner3); - final Point pt = gc.textExtent(string); - gc.dispose(); - toolTip.setLocation(shell.getDisplay().map(group, null, rect.x + pt.x, rect.y + rect.height)); - toolTip.setMessage(message); - toolTip.setVisible(true); - } else { - toolTip.setVisible(false); - spinner3.setForeground(null); - } - }); - } -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron@gmail.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.horizontalspinner.snippets; + +import org.eclipse.nebula.widgets.opal.horizontalspinner.HorizontalSpinner; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Spinner; +import org.eclipse.swt.widgets.ToolTip; + +/** + * A simple snipper for the Horizontal Spinner widget + * + */ +public class HorizontalSpinnerSnippet { + + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(4, true)); + + createSpinnerGroup(shell); + createHorizontalSpinnerGroup(shell, "Default look", SWT.NONE); + createHorizontalSpinnerGroup(shell, "Buttons on the left", SWT.LEFT); + createHorizontalSpinnerGroup(shell, "Buttons on the right", SWT.RIGHT); + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + + } + + private static void createSpinnerGroup(final Shell shell) { + final Group group = new Group(shell, SWT.NONE); + group.setLayout(new GridLayout(1, false)); + + final Label lbl1 = new Label(group, SWT.NONE); + lbl1.setText("Simple vertical spinner :"); + final Spinner spinner1 = new Spinner(group, SWT.BORDER); + spinner1.setMinimum(0); + spinner1.setMaximum(1000); + spinner1.setSelection(500); + spinner1.setIncrement(1); + spinner1.setPageIncrement(100); + + final Label lbl2 = new Label(group, SWT.NONE); + lbl2.setText("Floating point values in Spinner :"); + final Spinner spinner2 = new Spinner(group, SWT.NONE); + // allow 3 decimal places + spinner2.setDigits(3); + // set the minimum value to 0.001 + spinner2.setMinimum(1); + // set the maximum value to 20 + spinner2.setMaximum(20000); + // set the increment value to 0.010 + spinner2.setIncrement(10); + // set the seletion to 3.456 + spinner2.setSelection(3456); + spinner2.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + final int selection = spinner2.getSelection(); + final int digits = spinner2.getDigits(); + System.out.println("Selection is " + selection / Math.pow(10, digits)); + } + }); + + final Label lbl3 = new Label(group, SWT.NONE); + lbl3.setText("Validate input in a spinner widget :"); + final Spinner spinner3 = new Spinner(group, SWT.BORDER); + spinner3.setValues(0, -100, 100, 0, 1, 10); + spinner3.setLayoutData(new GridData(200, SWT.DEFAULT)); + final ToolTip toolTip = new ToolTip(shell, SWT.BALLOON | SWT.ICON_WARNING); + spinner3.addModifyListener(e -> { + final String string = spinner3.getText(); + String message = null; + try { + final int value = Integer.parseInt(string); + final int maximum = spinner3.getMaximum(); + final int minimum = spinner3.getMinimum(); + if (value > maximum) { + message = "Current input is greater than the maximum limit (" + maximum + ")"; + } else if (value < minimum) { + message = "Current input is less than the minimum limit (" + minimum + ")"; + } + } catch (final Exception ex) { + message = "Current input is not numeric"; + } + if (message != null) { + spinner3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_RED)); + final Rectangle rect = spinner3.getBounds(); + final GC gc = new GC(spinner3); + final Point pt = gc.textExtent(string); + gc.dispose(); + toolTip.setLocation(shell.getDisplay().map(shell, null, rect.x + pt.x, rect.y + rect.height)); + toolTip.setMessage(message); + toolTip.setVisible(true); + } else { + toolTip.setVisible(false); + spinner3.setForeground(null); + } + }); + + } + + private static void createHorizontalSpinnerGroup(final Shell shell, final String title, final int style) { + final Group group = new Group(shell, SWT.NONE); + group.setLayout(new GridLayout(1, false)); + group.setText(title); + + final Label lbl1 = new Label(group, SWT.NONE); + lbl1.setText("Simple horizontal spinner :"); + final HorizontalSpinner spinner1 = new HorizontalSpinner(group, SWT.BORDER | style); + spinner1.setMinimum(0); + spinner1.setMaximum(1000); + spinner1.setSelection(500); + spinner1.setIncrement(1); + spinner1.setPageIncrement(100); + + final Label lbl2 = new Label(group, SWT.NONE); + lbl2.setText("Floating point values in Spinner :"); + final HorizontalSpinner spinner2 = new HorizontalSpinner(group, style); + // allow 3 decimal places + spinner2.setDigits(3); + // set the minimum value to 0.001 + spinner2.setMinimum(1); + // set the maximum value to 20 + spinner2.setMaximum(20000); + // set the increment value to 0.010 + spinner2.setIncrement(10); + // set the seletion to 3.456 + spinner2.setSelection(3456); + spinner2.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + final int selection = spinner2.getSelection(); + final int digits = spinner2.getDigits(); + System.out.println("Selection is " + selection / Math.pow(10, digits)); + } + }); + + final Label lbl3 = new Label(group, SWT.NONE); + lbl3.setText("Validate input in a spinner widget :"); + final HorizontalSpinner spinner3 = new HorizontalSpinner(group, SWT.BORDER | style); + spinner3.setValues(0, -100, 100, 0, 1, 10); + spinner3.setLayoutData(new GridData(200, SWT.DEFAULT)); + final ToolTip toolTip = new ToolTip(shell, SWT.BALLOON | SWT.ICON_WARNING); + spinner3.addModifyListener(e -> { + final String string = spinner3.getText(); + String message = null; + try { + final int value = Integer.parseInt(string); + final int maximum = spinner3.getMaximum(); + final int minimum = spinner3.getMinimum(); + if (value > maximum) { + message = "Current input is greater than the maximum limit (" + maximum + ")"; + } else if (value < minimum) { + message = "Current input is less than the minimum limit (" + minimum + ")"; + } + } catch (final Exception ex) { + message = "Current input is not numeric"; + } + if (message != null) { + spinner3.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_RED)); + final Rectangle rect = spinner3.getBounds(); + final GC gc = new GC(spinner3); + final Point pt = gc.textExtent(string); + gc.dispose(); + toolTip.setLocation(shell.getDisplay().map(group, null, rect.x + pt.x, rect.y + rect.height)); + toolTip.setMessage(message); + toolTip.setVisible(true); + } else { + toolTip.setVisible(false); + spinner3.setForeground(null); + } + }); + } +} diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.classpath b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.classpath +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.project b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.project index 08b622e00..4ba11a995 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.project +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.horizontalspinner - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.horizontalspinner + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/META-INF/MANIFEST.MF b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/META-INF/MANIFEST.MF index 3a2d9d221..da922a1cb 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/META-INF/MANIFEST.MF +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Horizontal Spinner Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.horizontalspinner -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.horizontalspinner -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.horizontalspinner +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Horizontal Spinner Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.horizontalspinner +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.horizontalspinner +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.horizontalspinner diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/build.properties b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/build.properties +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/src/org/eclipse/nebula/widgets/opal/horizontalspinner/HorizontalSpinner.java b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/src/org/eclipse/nebula/widgets/opal/horizontalspinner/HorizontalSpinner.java index ec8aec15b..e69f01d4f 100644 --- a/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/src/org/eclipse/nebula/widgets/opal/horizontalspinner/HorizontalSpinner.java +++ b/widgets/opal/horizontalspinner/org.eclipse.nebula.widgets.opal.horizontalspinner/src/org/eclipse/nebula/widgets/opal/horizontalspinner/HorizontalSpinner.java @@ -1,1149 +1,1149 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.horizontalspinner; - -import java.text.DecimalFormatSymbols; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; -import org.eclipse.nebula.widgets.opal.commons.StringUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Text; - -/** - * Instances of this class are selectable user interface objects that allow the - * user to enter and modify numeric values. - *

- *

- *
Styles:
- *
READ_ONLY, FLAT
- *
Events:
- *
Selection, Modify
- *
- *

- */ -public class HorizontalSpinner extends Composite { - - private enum ALIGNMENT { - LEFT, RIGHT, BOTH - }; - - private final List modifyListeners = new ArrayList(); - - private Button leftButton; - private Button rightButton; - private Text text; - private int digits = 0; - private int increment = 1; - private int maximum = 0; - private int minimum = 255; - private int pageIncrement = 10; - private int storedValue = 0; - private ALIGNMENT alignment = ALIGNMENT.BOTH; - - private final char decimalFormatSeparator; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must - * be built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT - * style constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an - * allowed subclass
  • - *
- * - * @see SWT#READ_ONLY - * @see SWT#FLAT - */ - public HorizontalSpinner(final Composite parent, final int style) { - super(parent, style); - - if ((style & SWT.LEFT) == SWT.LEFT) { - alignment = ALIGNMENT.LEFT; - } - - if ((style & SWT.RIGHT) == SWT.RIGHT) { - alignment = ALIGNMENT.RIGHT; - } - - final GridLayout gd = new GridLayout(3, false); - gd.horizontalSpacing = gd.verticalSpacing = 0; - gd.marginWidth = gd.marginHeight = 0; - setLayout(gd); - - createContent(style); - addTextListeners(); - addButtonsListener(); - addModifyListeners(); - - decimalFormatSeparator = new DecimalFormatSymbols().getDecimalSeparator(); - } - - /** - * Create the content of the widget - * - * @param style style of the widget - */ - private void createContent(final int style) { - final boolean readOnly = (style & SWT.READ_ONLY) == SWT.READ_ONLY; - final boolean flat = (style & SWT.FLAT) == SWT.FLAT; - final int buttonStyle = SWT.ARROW | (flat ? SWT.FLAT : SWT.NONE); - - if (alignment == ALIGNMENT.BOTH) { - createMinusButton(buttonStyle); - createText(readOnly); - createPlusButton(buttonStyle); - } else if (alignment == ALIGNMENT.LEFT) { - createMinusButton(buttonStyle); - createPlusButton(buttonStyle); - createText(readOnly); - } else { - createText(readOnly); - createMinusButton(buttonStyle); - createPlusButton(buttonStyle); - } - } - - /** - * Create minus button - * - * @param buttonStyle button style - */ - private void createMinusButton(final int buttonStyle) { - leftButton = new Button(this, buttonStyle | SWT.LEFT); - leftButton.setFont(getFont()); - leftButton.setBackground(getBackground()); - leftButton.setCursor(getCursor()); - leftButton.setEnabled(getEnabled()); - leftButton.setFont(getFont()); - leftButton.setForeground(getForeground()); - leftButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - } - - /** - * Create the text zone - * - * @param readOnly if true, the text is read only - */ - private void createText(final boolean readOnly) { - text = new Text(this, readOnly ? SWT.READ_ONLY : SWT.NONE); - final GridData gd = new GridData(GridData.FILL, GridData.CENTER, true, false); - gd.minimumWidth = 40; - text.setLayoutData(gd); - } - - /** - * Create plus button - * - * @param buttonStyle button style - */ - private void createPlusButton(final int buttonStyle) { - rightButton = new Button(this, buttonStyle | SWT.RIGHT); - rightButton.setFont(getFont()); - rightButton.setBackground(getBackground()); - rightButton.setCursor(getCursor()); - rightButton.setEnabled(getEnabled()); - rightButton.setFont(getFont()); - rightButton.setForeground(getForeground()); - rightButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - } - - /** - * Add the text listeners - */ - private void addTextListeners() { - text.addListener(SWT.Verify, e -> { - if (e.character != 0 && !(Character.isDigit(e.character) || e.character == '-') && e.keyCode != SWT.BS && e.keyCode != SWT.DEL) { - e.doit = false; - return; - } - e.doit = verifyEntryAndStoreValue(e.text, e.keyCode); - }); - - text.addListener(SWT.KeyUp, e -> { - if (e.keyCode == SWT.ARROW_UP) { - increaseValue(increment); - } - if (e.keyCode == SWT.ARROW_DOWN) { - decreaseValue(increment); - } - if (e.keyCode == SWT.PAGE_UP) { - increaseValue(pageIncrement); - } - if (e.keyCode == SWT.PAGE_DOWN) { - decreaseValue(pageIncrement); - } - - }); - - text.addListener(SWT.FocusOut, e -> { - if (text.getText().trim().equals("")) { - setSelection(storedValue); - } - }); - } - - /** - * Verify the entry and store the value in the field storedValue - * - * @param entry entry to check - * @param keyCode code of the typed key - * @return true if the entry if correct, false - * otherwise - */ - private boolean verifyEntryAndStoreValue(final String entry, final int keyCode) { - final String work; - if (keyCode == SWT.DEL) { - work = StringUtil.removeCharAt(text.getText(), text.getCaretPosition()); - } else if (keyCode == SWT.BS && text.getCaretPosition() == 0) { - work = StringUtil.removeCharAt(text.getText(), text.getCaretPosition() - 1); - } else if (keyCode == 0) { - work = entry; - } else { - work = StringUtil.insertString(text.getText(), entry, text.getCaretPosition()); - } - - try { - final double d = Double.parseDouble(work.replace(decimalFormatSeparator, '.')); - storedValue = (int) (d * Math.pow(10, getDigits())); - } catch (final NumberFormatException nfe) { - return false; - } - - SelectionListenerUtil.fireSelectionListeners(this,null); - - return true; - } - - /** - * Add the listener to the buttons - */ - private void addButtonsListener() { - leftButton.addListener(SWT.Selection, e -> { - decreaseValue(increment); - }); - - rightButton.addListener(SWT.Selection, e -> { - increaseValue(increment); - }); - - } - - /** - * Increase the value stored in this snippet - * - * @param value value to increase - */ - private void increaseValue(final int value) { - setSelection(getSelection() + value); - - } - - /** - * Decrease the value stored in this snippet - * - * @param value value to decrease - */ - private void decreaseValue(final int value) { - setSelection(getSelection() - value); - } - - /** - * Add the modify listeners - */ - private void addModifyListeners() { - text.addModifyListener(e -> { - for (final ModifyListener m : modifyListeners) { - m.modifyText(e); - } - }); - - } - - /** - * Adds the listener to the collection of listeners who will be notified - * when the receiver's text is modified, by sending it one of the messages - * defined in the ModifyListener interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #removeModifyListener - * @see org.eclipse.swt.widgets.Spinner#addModifyListener(org.eclipse.swt.events.ModifyListener) - */ - - public void addModifyListener(final ModifyListener listener) { - checkWidget(); - modifyListeners.add(listener); - } - - /** - * Adds the listener to the collection of listeners who will be notified - * when the control is selected by the user, by sending it one of the - * messages defined in the SelectionListener interface. - *

- * widgetSelected is not called for texts. - * widgetDefaultSelected is typically called when ENTER is - * pressed in a single-line text. - *

- * - * @param listener the listener which should be notified when the control is - * selected by the user - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.addSelectionListener(this, listener); - } - - /** - * Copies the selected text. - *

- * The current selection is copied to the clipboard. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void copy() { - checkWidget(); - text.copy(); - } - - /** - * Cuts the selected text. - *

- * The current selection is first copied to the clipboard and then deleted - * from the widget. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void cut() { - checkWidget(); - text.cut(); - } - - /** - * Returns the number of decimal places used by the receiver. - * - * @return the digits - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getDigits() { - checkWidget(); - return digits; - } - - /** - * Returns the amount that the receiver's value will be modified by when the - * up/down arrows are pressed. - * - * @return the increment - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getIncrement() { - checkWidget(); - return increment; - } - - /** - * Returns the maximum value which the receiver will allow. - * - * @return the maximum - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getMaximum() { - checkWidget(); - return maximum; - } - - /** - * Returns the minimum value which the receiver will allow. - * - * @return the minimum - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getMinimum() { - checkWidget(); - return minimum; - } - - /** - * Returns the amount that the receiver's position will be modified by when - * the page up/down keys are pressed. - * - * @return the page increment - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getPageIncrement() { - checkWidget(); - return pageIncrement; - } - - /** - * Returns the selection, which is the receiver's position. - * - * @return the selection - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getSelection() { - checkWidget(); - return storedValue; - } - - /** - * Returns a string containing a copy of the contents of the receiver's text - * field, or an empty string if there are no contents. - * - * @return the receiver's text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - */ - public String getText() { - checkWidget(); - return text.getText(); - } - - /** - * Returns the maximum number of characters that the receiver's text field - * is capable of holding. If this has not been changed by - * setTextLimit(), it will be the constant - * Spinner.LIMIT. - * - * @return the text limit - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see #LIMIT - */ - public int getTextLimit() { - checkWidget(); - return text.getTextLimit(); - } - - /** - * Pastes text from clipboard. - *

- * The selected text is deleted from the widget and new text inserted from - * the clipboard. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void paste() { - checkWidget(); - text.paste(); - } - - /** - * Removes the listener from the collection of listeners who will be - * notified when the receiver's text is modified. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #addModifyListener - */ - public void removeModifyListener(final ModifyListener listener) { - checkWidget(); - modifyListeners.remove(listener); - } - - /** - * Removes the listener from the collection of listeners who will be - * notified when the control is selected by the user. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.removeSelectionListener(this, listener); - } - - /** - * Sets the number of decimal places used by the receiver. - *

- * The digit setting is used to allow for floating point values in the - * receiver. For example, to set the selection to a floating point value of - * 1.37 call setDigits() with a value of 2 and setSelection() with a value - * of 137. Similarly, if getDigits() has a value of 2 and getSelection() - * returns 137 this should be interpreted as 1.37. This applies to all - * numeric APIs. - *

- * - * @param value the new digits (must be greater than or equal to zero) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the value is less than - * zero
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setDigits(final int value) { - checkWidget(); - digits = value; - convertSelectionToStringValue(); - } - - /** - * Sets the amount that the receiver's value will be modified by when the - * up/down arrows are pressed to the argument, which must be at least one. - * - * @param value the new increment (must be greater than zero) - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setIncrement(final int value) { - checkWidget(); - increment = value; - } - - /** - * Sets the maximum value that the receiver will allow. This new value will - * be ignored if it is less than the receiver's current minimum value. If - * the new maximum is applied then the receiver's selection value will be - * adjusted if necessary to fall within its new range. - * - * @param value the new maximum, which must be greater than or equal to the - * current minimum - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setMaximum(final int value) { - checkWidget(); - maximum = value; - } - - /** - * Sets the minimum value that the receiver will allow. This new value will - * be ignored if it is greater than the receiver's current maximum value. If - * the new minimum is applied then the receiver's selection value will be - * adjusted if necessary to fall within its new range. - * - * @param value the new minimum, which must be less than or equal to the - * current maximum - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setMinimum(final int value) { - checkWidget(); - minimum = value; - } - - /** - * Sets the amount that the receiver's position will be modified by when the - * page up/down keys are pressed to the argument, which must be at least - * one. - * - * @param value the page increment (must be greater than zero) - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setPageIncrement(final int value) { - checkWidget(); - pageIncrement = value; - } - - /** - * Sets the selection, which is the receiver's position, to the - * argument. If the argument is not within the range specified by minimum - * and maximum, it will be adjusted to fall within this range. - * - * @param value the new selection (must be zero or greater) - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setSelection(int selection) { - checkWidget(); - if (selection < minimum) { - selection = minimum; - } else if (selection > maximum) { - selection = maximum; - } - - storedValue = selection; - text.setText(convertSelectionToStringValue()); - } - - /** - * Convert the selection into a string - * - * @return the string representation of the selection - */ - private String convertSelectionToStringValue() { - if (getDigits() == 0) { - return String.valueOf(storedValue); - } - final StringBuilder unformatted = new StringBuilder(String.valueOf(storedValue * Math.pow(10, -1 * getDigits()))); - for (int i = 0; i < digits; i++) { - unformatted.append("0"); - } - final int position = unformatted.indexOf("."); - final String temp = unformatted.substring(0, position + 1 + digits); - return temp.replace('.', decimalFormatSeparator); - - } - - /** - * Sets the maximum number of characters that the receiver's text field is - * capable of holding to be the argument. - *

- * To reset this value to the default, use - * setTextLimit(Spinner.LIMIT). Specifying a limit value larger - * than Spinner.LIMIT sets the receiver's limit to - * Spinner.LIMIT. - *

- * - * @param limit new text limit - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_CANNOT_BE_ZERO - if the limit is zero
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see #LIMIT - */ - public void setTextLimit(final int limit) { - checkWidget(); - text.setTextLimit(limit); - } - - /** - * Sets the receiver's selection, minimum value, maximum value, digits, - * increment and page increment all at once. - *

- * Note: This is similar to setting the values individually using the - * appropriate methods, but may be implemented in a more efficient fashion - * on some platforms. - *

- * - * @param selection the new selection value - * @param minimum the new minimum value - * @param maximum the new maximum value - * @param digits the new digits value - * @param increment the new increment value - * @param pageIncrement the new pageIncrement value - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setValues(final int selection, final int minimum, final int maximum, final int digits, final int increment, final int pageIncrement) { - setMinimum(minimum); - setMaximum(maximum); - setDigits(digits); - setIncrement(increment); - setPageIncrement(pageIncrement); - setSelection(selection); - } - - /** - * Sets the receiver's drag detect state. If the argument is - * true, the receiver will detect drag gestures, otherwise - * these gestures will be ignored. - * - * @param dragDetect the new drag detect state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public boolean setFocus() { - checkWidget(); - return text.setFocus(); - } - - /** - * Forces the receiver to have the keyboard focus, causing all - * keyboard events to be delivered to it. - * - * @return true if the control got focus, and - * false if it was unable to. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see #setFocus - */ - @Override - public boolean forceFocus() { - checkWidget(); - return text.forceFocus(); - } - - /** - * Sets the receiver's background color to the color specified by the - * argument, or to the default system color for the control if the argument - * is null. - *

- * Note: This operation is a hint and may be overridden by the platform. For - * example, on Windows the background of a Button cannot be changed. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public void setBackground(final Color color) { - super.setBackground(color); - leftButton.setBackground(color); - rightButton.setBackground(color); - text.setBackground(color); - } - - /** - * Sets the receiver's background image to the image specified by the - * argument, or to the default system color for the control if the argument - * is null. The background image is tiled to fill the available space. - *

- * Note: This operation is a hint and may be overridden by the platform. For - * example, on Windows the background of a Button cannot be changed. - *

- * - * @param image the new image (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
  • ERROR_INVALID_ARGUMENT - if the argument is not a - * bitmap
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public void setBackgroundImage(final Image image) { - super.setBackgroundImage(image); - leftButton.setBackgroundImage(image); - rightButton.setBackgroundImage(image); - text.setBackgroundImage(image); - - } - - /** - * Sets the receiver's cursor to the cursor specified by the argument, or to - * the default cursor for that kind of control if the argument is null. - *

- * When the mouse pointer passes over a control its appearance is changed to - * match the control's cursor. - *

- * - * @param cursor the new cursor (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public void setCursor(final Cursor cursor) { - super.setCursor(cursor); - leftButton.setCursor(cursor); - rightButton.setCursor(cursor); - text.setCursor(cursor); - } - - /** - * Enables the receiver if the argument is true, and disables - * it otherwise. A disabled control is typically not selectable from the - * user interface and draws with an inactive or "grayed" look. - * - * @param enabled the new enabled state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public void setEnabled(final boolean enabled) { - super.setEnabled(enabled); - leftButton.setEnabled(enabled); - rightButton.setEnabled(enabled); - text.setEnabled(enabled); - } - - /** - * Sets the font that the receiver will use to paint textual information to - * the font specified by the argument, or to the default font for that kind - * of control if the argument is null. - * - * @param font the new font (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public void setFont(final Font font) { - super.setFont(font); - text.setFont(font); - } - - /** - * Sets the receiver's foreground color to the color specified by the - * argument, or to the default system color for the control if the argument - * is null. - *

- * Note: This operation is a hint and may be overridden by the platform. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been - * disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public void setForeground(final Color color) { - super.setForeground(color); - leftButton.setForeground(color); - rightButton.setForeground(color); - text.setForeground(color); - } - - /** - * Sets the receiver's pop up menu to the argument. All controls may - * optionally have a pop up menu that is displayed when the user requests - * one for the control. The sequence of key strokes, button presses and/or - * button releases that are used to request a pop up menu is platform - * specific. - *

- * Note: Disposing of a control that has a pop up menu will dispose of the - * menu. To avoid this behavior, set the menu to null before the control is - * disposed. - *

- * - * @param menu the new pop up menu - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu
  • - *
  • ERROR_INVALID_PARENT - if the menu is not in the same - * widget tree
  • - *
  • ERROR_INVALID_ARGUMENT - if the menu has been disposed - *
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public void setMenu(final Menu menu) { - super.setMenu(menu); - leftButton.setMenu(menu); - rightButton.setMenu(menu); - text.setMenu(menu); - } - - /** - * Sets the receiver's tool tip text to the argument, which may be null - * indicating that the default tool tip for the control will be shown. For a - * control that has a default tool tip, such as the Tree control on Windows, - * setting the tool tip text to an empty string replaces the default, - * causing no tool tip text to be shown. - *

- * The mnemonic indicator (character '&') is not displayed in a tool - * tip. To display a single '&' in the tool tip, the character '&' - * can be escaped by doubling it in the string. - *

- * - * @param string the new tool tip text (or null) - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - @Override - public void setToolTipText(final String tooltipText) { - super.setToolTipText(tooltipText); - leftButton.setToolTipText(tooltipText); - rightButton.setToolTipText(tooltipText); - text.setToolTipText(tooltipText); - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.horizontalspinner; + +import java.text.DecimalFormatSymbols; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; +import org.eclipse.nebula.widgets.opal.commons.StringUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Text; + +/** + * Instances of this class are selectable user interface objects that allow the + * user to enter and modify numeric values. + *

+ *

+ *
Styles:
+ *
READ_ONLY, FLAT
+ *
Events:
+ *
Selection, Modify
+ *
+ *

+ */ +public class HorizontalSpinner extends Composite { + + private enum ALIGNMENT { + LEFT, RIGHT, BOTH + }; + + private final List modifyListeners = new ArrayList(); + + private Button leftButton; + private Button rightButton; + private Text text; + private int digits = 0; + private int increment = 1; + private int maximum = 0; + private int minimum = 255; + private int pageIncrement = 10; + private int storedValue = 0; + private ALIGNMENT alignment = ALIGNMENT.BOTH; + + private final char decimalFormatSeparator; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
  • ERROR_INVALID_SUBCLASS - if this class is not an + * allowed subclass
  • + *
+ * + * @see SWT#READ_ONLY + * @see SWT#FLAT + */ + public HorizontalSpinner(final Composite parent, final int style) { + super(parent, style); + + if ((style & SWT.LEFT) == SWT.LEFT) { + alignment = ALIGNMENT.LEFT; + } + + if ((style & SWT.RIGHT) == SWT.RIGHT) { + alignment = ALIGNMENT.RIGHT; + } + + final GridLayout gd = new GridLayout(3, false); + gd.horizontalSpacing = gd.verticalSpacing = 0; + gd.marginWidth = gd.marginHeight = 0; + setLayout(gd); + + createContent(style); + addTextListeners(); + addButtonsListener(); + addModifyListeners(); + + decimalFormatSeparator = new DecimalFormatSymbols().getDecimalSeparator(); + } + + /** + * Create the content of the widget + * + * @param style style of the widget + */ + private void createContent(final int style) { + final boolean readOnly = (style & SWT.READ_ONLY) == SWT.READ_ONLY; + final boolean flat = (style & SWT.FLAT) == SWT.FLAT; + final int buttonStyle = SWT.ARROW | (flat ? SWT.FLAT : SWT.NONE); + + if (alignment == ALIGNMENT.BOTH) { + createMinusButton(buttonStyle); + createText(readOnly); + createPlusButton(buttonStyle); + } else if (alignment == ALIGNMENT.LEFT) { + createMinusButton(buttonStyle); + createPlusButton(buttonStyle); + createText(readOnly); + } else { + createText(readOnly); + createMinusButton(buttonStyle); + createPlusButton(buttonStyle); + } + } + + /** + * Create minus button + * + * @param buttonStyle button style + */ + private void createMinusButton(final int buttonStyle) { + leftButton = new Button(this, buttonStyle | SWT.LEFT); + leftButton.setFont(getFont()); + leftButton.setBackground(getBackground()); + leftButton.setCursor(getCursor()); + leftButton.setEnabled(getEnabled()); + leftButton.setFont(getFont()); + leftButton.setForeground(getForeground()); + leftButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + } + + /** + * Create the text zone + * + * @param readOnly if true, the text is read only + */ + private void createText(final boolean readOnly) { + text = new Text(this, readOnly ? SWT.READ_ONLY : SWT.NONE); + final GridData gd = new GridData(GridData.FILL, GridData.CENTER, true, false); + gd.minimumWidth = 40; + text.setLayoutData(gd); + } + + /** + * Create plus button + * + * @param buttonStyle button style + */ + private void createPlusButton(final int buttonStyle) { + rightButton = new Button(this, buttonStyle | SWT.RIGHT); + rightButton.setFont(getFont()); + rightButton.setBackground(getBackground()); + rightButton.setCursor(getCursor()); + rightButton.setEnabled(getEnabled()); + rightButton.setFont(getFont()); + rightButton.setForeground(getForeground()); + rightButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + } + + /** + * Add the text listeners + */ + private void addTextListeners() { + text.addListener(SWT.Verify, e -> { + if (e.character != 0 && !(Character.isDigit(e.character) || e.character == '-') && e.keyCode != SWT.BS && e.keyCode != SWT.DEL) { + e.doit = false; + return; + } + e.doit = verifyEntryAndStoreValue(e.text, e.keyCode); + }); + + text.addListener(SWT.KeyUp, e -> { + if (e.keyCode == SWT.ARROW_UP) { + increaseValue(increment); + } + if (e.keyCode == SWT.ARROW_DOWN) { + decreaseValue(increment); + } + if (e.keyCode == SWT.PAGE_UP) { + increaseValue(pageIncrement); + } + if (e.keyCode == SWT.PAGE_DOWN) { + decreaseValue(pageIncrement); + } + + }); + + text.addListener(SWT.FocusOut, e -> { + if (text.getText().trim().equals("")) { + setSelection(storedValue); + } + }); + } + + /** + * Verify the entry and store the value in the field storedValue + * + * @param entry entry to check + * @param keyCode code of the typed key + * @return true if the entry if correct, false + * otherwise + */ + private boolean verifyEntryAndStoreValue(final String entry, final int keyCode) { + final String work; + if (keyCode == SWT.DEL) { + work = StringUtil.removeCharAt(text.getText(), text.getCaretPosition()); + } else if (keyCode == SWT.BS && text.getCaretPosition() == 0) { + work = StringUtil.removeCharAt(text.getText(), text.getCaretPosition() - 1); + } else if (keyCode == 0) { + work = entry; + } else { + work = StringUtil.insertString(text.getText(), entry, text.getCaretPosition()); + } + + try { + final double d = Double.parseDouble(work.replace(decimalFormatSeparator, '.')); + storedValue = (int) (d * Math.pow(10, getDigits())); + } catch (final NumberFormatException nfe) { + return false; + } + + SelectionListenerUtil.fireSelectionListeners(this,null); + + return true; + } + + /** + * Add the listener to the buttons + */ + private void addButtonsListener() { + leftButton.addListener(SWT.Selection, e -> { + decreaseValue(increment); + }); + + rightButton.addListener(SWT.Selection, e -> { + increaseValue(increment); + }); + + } + + /** + * Increase the value stored in this snippet + * + * @param value value to increase + */ + private void increaseValue(final int value) { + setSelection(getSelection() + value); + + } + + /** + * Decrease the value stored in this snippet + * + * @param value value to decrease + */ + private void decreaseValue(final int value) { + setSelection(getSelection() - value); + } + + /** + * Add the modify listeners + */ + private void addModifyListeners() { + text.addModifyListener(e -> { + for (final ModifyListener m : modifyListeners) { + m.modifyText(e); + } + }); + + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the receiver's text is modified, by sending it one of the messages + * defined in the ModifyListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #removeModifyListener + * @see org.eclipse.swt.widgets.Spinner#addModifyListener(org.eclipse.swt.events.ModifyListener) + */ + + public void addModifyListener(final ModifyListener listener) { + checkWidget(); + modifyListeners.add(listener); + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the control is selected by the user, by sending it one of the + * messages defined in the SelectionListener interface. + *

+ * widgetSelected is not called for texts. + * widgetDefaultSelected is typically called when ENTER is + * pressed in a single-line text. + *

+ * + * @param listener the listener which should be notified when the control is + * selected by the user + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.addSelectionListener(this, listener); + } + + /** + * Copies the selected text. + *

+ * The current selection is copied to the clipboard. + *

+ * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void copy() { + checkWidget(); + text.copy(); + } + + /** + * Cuts the selected text. + *

+ * The current selection is first copied to the clipboard and then deleted + * from the widget. + *

+ * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void cut() { + checkWidget(); + text.cut(); + } + + /** + * Returns the number of decimal places used by the receiver. + * + * @return the digits + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getDigits() { + checkWidget(); + return digits; + } + + /** + * Returns the amount that the receiver's value will be modified by when the + * up/down arrows are pressed. + * + * @return the increment + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getIncrement() { + checkWidget(); + return increment; + } + + /** + * Returns the maximum value which the receiver will allow. + * + * @return the maximum + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getMaximum() { + checkWidget(); + return maximum; + } + + /** + * Returns the minimum value which the receiver will allow. + * + * @return the minimum + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getMinimum() { + checkWidget(); + return minimum; + } + + /** + * Returns the amount that the receiver's position will be modified by when + * the page up/down keys are pressed. + * + * @return the page increment + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getPageIncrement() { + checkWidget(); + return pageIncrement; + } + + /** + * Returns the selection, which is the receiver's position. + * + * @return the selection + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getSelection() { + checkWidget(); + return storedValue; + } + + /** + * Returns a string containing a copy of the contents of the receiver's text + * field, or an empty string if there are no contents. + * + * @return the receiver's text + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + */ + public String getText() { + checkWidget(); + return text.getText(); + } + + /** + * Returns the maximum number of characters that the receiver's text field + * is capable of holding. If this has not been changed by + * setTextLimit(), it will be the constant + * Spinner.LIMIT. + * + * @return the text limit + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see #LIMIT + */ + public int getTextLimit() { + checkWidget(); + return text.getTextLimit(); + } + + /** + * Pastes text from clipboard. + *

+ * The selected text is deleted from the widget and new text inserted from + * the clipboard. + *

+ * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void paste() { + checkWidget(); + text.paste(); + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the receiver's text is modified. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see ModifyListener + * @see #addModifyListener + */ + public void removeModifyListener(final ModifyListener listener) { + checkWidget(); + modifyListeners.remove(listener); + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.removeSelectionListener(this, listener); + } + + /** + * Sets the number of decimal places used by the receiver. + *

+ * The digit setting is used to allow for floating point values in the + * receiver. For example, to set the selection to a floating point value of + * 1.37 call setDigits() with a value of 2 and setSelection() with a value + * of 137. Similarly, if getDigits() has a value of 2 and getSelection() + * returns 137 this should be interpreted as 1.37. This applies to all + * numeric APIs. + *

+ * + * @param value the new digits (must be greater than or equal to zero) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the value is less than + * zero
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setDigits(final int value) { + checkWidget(); + digits = value; + convertSelectionToStringValue(); + } + + /** + * Sets the amount that the receiver's value will be modified by when the + * up/down arrows are pressed to the argument, which must be at least one. + * + * @param value the new increment (must be greater than zero) + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setIncrement(final int value) { + checkWidget(); + increment = value; + } + + /** + * Sets the maximum value that the receiver will allow. This new value will + * be ignored if it is less than the receiver's current minimum value. If + * the new maximum is applied then the receiver's selection value will be + * adjusted if necessary to fall within its new range. + * + * @param value the new maximum, which must be greater than or equal to the + * current minimum + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setMaximum(final int value) { + checkWidget(); + maximum = value; + } + + /** + * Sets the minimum value that the receiver will allow. This new value will + * be ignored if it is greater than the receiver's current maximum value. If + * the new minimum is applied then the receiver's selection value will be + * adjusted if necessary to fall within its new range. + * + * @param value the new minimum, which must be less than or equal to the + * current maximum + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setMinimum(final int value) { + checkWidget(); + minimum = value; + } + + /** + * Sets the amount that the receiver's position will be modified by when the + * page up/down keys are pressed to the argument, which must be at least + * one. + * + * @param value the page increment (must be greater than zero) + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setPageIncrement(final int value) { + checkWidget(); + pageIncrement = value; + } + + /** + * Sets the selection, which is the receiver's position, to the + * argument. If the argument is not within the range specified by minimum + * and maximum, it will be adjusted to fall within this range. + * + * @param value the new selection (must be zero or greater) + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSelection(int selection) { + checkWidget(); + if (selection < minimum) { + selection = minimum; + } else if (selection > maximum) { + selection = maximum; + } + + storedValue = selection; + text.setText(convertSelectionToStringValue()); + } + + /** + * Convert the selection into a string + * + * @return the string representation of the selection + */ + private String convertSelectionToStringValue() { + if (getDigits() == 0) { + return String.valueOf(storedValue); + } + final StringBuilder unformatted = new StringBuilder(String.valueOf(storedValue * Math.pow(10, -1 * getDigits()))); + for (int i = 0; i < digits; i++) { + unformatted.append("0"); + } + final int position = unformatted.indexOf("."); + final String temp = unformatted.substring(0, position + 1 + digits); + return temp.replace('.', decimalFormatSeparator); + + } + + /** + * Sets the maximum number of characters that the receiver's text field is + * capable of holding to be the argument. + *

+ * To reset this value to the default, use + * setTextLimit(Spinner.LIMIT). Specifying a limit value larger + * than Spinner.LIMIT sets the receiver's limit to + * Spinner.LIMIT. + *

+ * + * @param limit new text limit + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_CANNOT_BE_ZERO - if the limit is zero
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see #LIMIT + */ + public void setTextLimit(final int limit) { + checkWidget(); + text.setTextLimit(limit); + } + + /** + * Sets the receiver's selection, minimum value, maximum value, digits, + * increment and page increment all at once. + *

+ * Note: This is similar to setting the values individually using the + * appropriate methods, but may be implemented in a more efficient fashion + * on some platforms. + *

+ * + * @param selection the new selection value + * @param minimum the new minimum value + * @param maximum the new maximum value + * @param digits the new digits value + * @param increment the new increment value + * @param pageIncrement the new pageIncrement value + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setValues(final int selection, final int minimum, final int maximum, final int digits, final int increment, final int pageIncrement) { + setMinimum(minimum); + setMaximum(maximum); + setDigits(digits); + setIncrement(increment); + setPageIncrement(pageIncrement); + setSelection(selection); + } + + /** + * Sets the receiver's drag detect state. If the argument is + * true, the receiver will detect drag gestures, otherwise + * these gestures will be ignored. + * + * @param dragDetect the new drag detect state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public boolean setFocus() { + checkWidget(); + return text.setFocus(); + } + + /** + * Forces the receiver to have the keyboard focus, causing all + * keyboard events to be delivered to it. + * + * @return true if the control got focus, and + * false if it was unable to. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see #setFocus + */ + @Override + public boolean forceFocus() { + checkWidget(); + return text.forceFocus(); + } + + /** + * Sets the receiver's background color to the color specified by the + * argument, or to the default system color for the control if the argument + * is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. For + * example, on Windows the background of a Button cannot be changed. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public void setBackground(final Color color) { + super.setBackground(color); + leftButton.setBackground(color); + rightButton.setBackground(color); + text.setBackground(color); + } + + /** + * Sets the receiver's background image to the image specified by the + * argument, or to the default system color for the control if the argument + * is null. The background image is tiled to fill the available space. + *

+ * Note: This operation is a hint and may be overridden by the platform. For + * example, on Windows the background of a Button cannot be changed. + *

+ * + * @param image the new image (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
  • ERROR_INVALID_ARGUMENT - if the argument is not a + * bitmap
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public void setBackgroundImage(final Image image) { + super.setBackgroundImage(image); + leftButton.setBackgroundImage(image); + rightButton.setBackgroundImage(image); + text.setBackgroundImage(image); + + } + + /** + * Sets the receiver's cursor to the cursor specified by the argument, or to + * the default cursor for that kind of control if the argument is null. + *

+ * When the mouse pointer passes over a control its appearance is changed to + * match the control's cursor. + *

+ * + * @param cursor the new cursor (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public void setCursor(final Cursor cursor) { + super.setCursor(cursor); + leftButton.setCursor(cursor); + rightButton.setCursor(cursor); + text.setCursor(cursor); + } + + /** + * Enables the receiver if the argument is true, and disables + * it otherwise. A disabled control is typically not selectable from the + * user interface and draws with an inactive or "grayed" look. + * + * @param enabled the new enabled state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public void setEnabled(final boolean enabled) { + super.setEnabled(enabled); + leftButton.setEnabled(enabled); + rightButton.setEnabled(enabled); + text.setEnabled(enabled); + } + + /** + * Sets the font that the receiver will use to paint textual information to + * the font specified by the argument, or to the default font for that kind + * of control if the argument is null. + * + * @param font the new font (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public void setFont(final Font font) { + super.setFont(font); + text.setFont(font); + } + + /** + * Sets the receiver's foreground color to the color specified by the + * argument, or to the default system color for the control if the argument + * is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been + * disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public void setForeground(final Color color) { + super.setForeground(color); + leftButton.setForeground(color); + rightButton.setForeground(color); + text.setForeground(color); + } + + /** + * Sets the receiver's pop up menu to the argument. All controls may + * optionally have a pop up menu that is displayed when the user requests + * one for the control. The sequence of key strokes, button presses and/or + * button releases that are used to request a pop up menu is platform + * specific. + *

+ * Note: Disposing of a control that has a pop up menu will dispose of the + * menu. To avoid this behavior, set the menu to null before the control is + * disposed. + *

+ * + * @param menu the new pop up menu + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu
  • + *
  • ERROR_INVALID_PARENT - if the menu is not in the same + * widget tree
  • + *
  • ERROR_INVALID_ARGUMENT - if the menu has been disposed + *
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public void setMenu(final Menu menu) { + super.setMenu(menu); + leftButton.setMenu(menu); + rightButton.setMenu(menu); + text.setMenu(menu); + } + + /** + * Sets the receiver's tool tip text to the argument, which may be null + * indicating that the default tool tip for the control will be shown. For a + * control that has a default tool tip, such as the Tree control on Windows, + * setting the tool tip text to an empty string replaces the default, + * causing no tool tip text to be shown. + *

+ * The mnemonic indicator (character '&') is not displayed in a tool + * tip. To display a single '&' in the tool tip, the character '&' + * can be escaped by doubling it in the string. + *

+ * + * @param string the new tool tip text (or null) + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + @Override + public void setToolTipText(final String tooltipText) { + super.setToolTipText(tooltipText); + leftButton.setToolTipText(tooltipText); + rightButton.setToolTipText(tooltipText); + text.setToolTipText(tooltipText); + } + +} diff --git a/widgets/opal/horizontalspinner/pom.xml b/widgets/opal/horizontalspinner/pom.xml index d15d19ccf..9688fe9db 100644 --- a/widgets/opal/horizontalspinner/pom.xml +++ b/widgets/opal/horizontalspinner/pom.xml @@ -1,22 +1,22 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - opal - - - horizontalspinner - pom - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.opal.horizontalspinner - org.eclipse.nebula.widgets.opal.horizontalspinner.feature - org.eclipse.nebula.widgets.opal.horizontalspinner.snippets - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + opal + + + horizontalspinner + pom + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.opal.horizontalspinner + org.eclipse.nebula.widgets.opal.horizontalspinner.feature + org.eclipse.nebula.widgets.opal.horizontalspinner.snippets + + + diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/.project b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/.project index c147bce1e..472dd5c54 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/.project +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.launcher.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.launcher.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/build.properties b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/build.properties +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/feature.properties b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/feature.properties +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/feature.xml b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/feature.xml index 1442b348b..7678e059a 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/feature.xml +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/feature.xml @@ -1,33 +1,33 @@ - - - - - Launcher - - - - %license - - - - - - - - - - + + + + + Launcher + + + + %license + + + + + + + + + + diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/pom.xml b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/pom.xml index 119661498..16f7721d2 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/pom.xml +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - launcher - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.opal.launcher.feature - eclipse-feature - 1.0.0-SNAPSHOT - - Launcher Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + launcher + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.opal.launcher.feature + eclipse-feature + 1.0.0-SNAPSHOT + + Launcher Feature + + diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.classpath b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.classpath +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.project b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.project index 4aa0226d7..e6056b919 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.project +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.launcher.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - + + + org.eclipse.nebula.widgets.opal.launcher.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + \ No newline at end of file diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/META-INF/MANIFEST.MF b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/META-INF/MANIFEST.MF index de2aceccb..fab2ea576 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Launcher Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.launcher.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.launcher;bundle-version="1.0.0", - org.eclipse.nebula.widgets.opal.dialog;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.launcher.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Launcher Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.launcher.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.launcher;bundle-version="1.0.0", + org.eclipse.nebula.widgets.opal.dialog;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.launcher.snippets diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/build.properties b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/build.properties +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/pom.xml b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/pom.xml index a7eea5037..5731a6400 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/pom.xml +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - launcher - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.opal.launcher.snippets - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + launcher + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.opal.launcher.snippets + eclipse-plugin + + diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/src/org/eclipse/nebula/widgets/opal/launcher/snippets/LauncherSnippet.java b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/src/org/eclipse/nebula/widgets/opal/launcher/snippets/LauncherSnippet.java index 167dcf512..f553aaef5 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/src/org/eclipse/nebula/widgets/opal/launcher/snippets/LauncherSnippet.java +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/src/org/eclipse/nebula/widgets/opal/launcher/snippets/LauncherSnippet.java @@ -1,86 +1,86 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.launcher.snippets; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.dialog.Dialog; -import org.eclipse.nebula.widgets.opal.launcher.Launcher; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple snippet for the Launcher Widget - * - */ -public class LauncherSnippet { - - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(1, false)); - - final Label title = new Label(shell, SWT.NONE); - title.setText("Launcher"); - title.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - - final Launcher l = new Launcher(shell, SWT.NONE); - l.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - l.addItem("Address Book", createImage(shell, "x-office-address-book.png")); - l.addItem("Calendar", createImage(shell, "x-office-calendar.png")); - l.addItem("Presentation", createImage(shell, "x-office-presentation.png")); - l.addItem("Spreadsheet", createImage(shell, "x-office-spreadsheet.png")); - - l.addSelectionListener(new SelectionAdapter() { - - /** - * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) - */ - @Override - public void widgetSelected(final SelectionEvent e) { - Dialog.inform("Selection", "You have selected item #" + l.getSelection()); - } - - }); - - final Label under = new Label(shell, SWT.NONE); - under.setText("Double-click an icon to launch the program"); - under.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - - shell.setSize(new Point(436, 546)); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - - } - - private static Image createImage(Shell shell, String input) { - final Image img = new Image(shell.getDisplay(), LauncherSnippet.class.getResourceAsStream("icons/" + input)); - shell.addListener(SWT.Dispose, e -> SWTGraphicUtil.safeDispose(img)); - return img; - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.launcher.snippets; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.dialog.Dialog; +import org.eclipse.nebula.widgets.opal.launcher.Launcher; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple snippet for the Launcher Widget + * + */ +public class LauncherSnippet { + + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(1, false)); + + final Label title = new Label(shell, SWT.NONE); + title.setText("Launcher"); + title.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + + final Launcher l = new Launcher(shell, SWT.NONE); + l.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + l.addItem("Address Book", createImage(shell, "x-office-address-book.png")); + l.addItem("Calendar", createImage(shell, "x-office-calendar.png")); + l.addItem("Presentation", createImage(shell, "x-office-presentation.png")); + l.addItem("Spreadsheet", createImage(shell, "x-office-spreadsheet.png")); + + l.addSelectionListener(new SelectionAdapter() { + + /** + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(final SelectionEvent e) { + Dialog.inform("Selection", "You have selected item #" + l.getSelection()); + } + + }); + + final Label under = new Label(shell, SWT.NONE); + under.setText("Double-click an icon to launch the program"); + under.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + + shell.setSize(new Point(436, 546)); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + + } + + private static Image createImage(Shell shell, String input) { + final Image img = new Image(shell.getDisplay(), LauncherSnippet.class.getResourceAsStream("icons/" + input)); + shell.addListener(SWT.Dispose, e -> SWTGraphicUtil.safeDispose(img)); + return img; + } + +} diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/src/org/eclipse/nebula/widgets/opal/launcher/snippets/LauncherSnippetAdvanced.java b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/src/org/eclipse/nebula/widgets/opal/launcher/snippets/LauncherSnippetAdvanced.java index 8d1098eed..83548e86b 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/src/org/eclipse/nebula/widgets/opal/launcher/snippets/LauncherSnippetAdvanced.java +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher.snippets/src/org/eclipse/nebula/widgets/opal/launcher/snippets/LauncherSnippetAdvanced.java @@ -1,95 +1,95 @@ -/******************************************************************************* - * Copyright (c) 2011-2021 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.launcher.snippets; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.dialog.Dialog; -import org.eclipse.nebula.widgets.opal.launcher.Launcher; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple snippet for the Launcher Widget - * - */ -public class LauncherSnippetAdvanced { - - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(1, false)); - - final Label title = new Label(shell, SWT.NONE); - title.setText("Launcher"); - title.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - - final Launcher l = new Launcher(shell, SWT.NONE); - l.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); - - l.setItemBackgroundColor(display.getSystemColor(SWT.COLOR_RED)); - l.setSelectedItemBackgroundColor(display.getSystemColor(SWT.COLOR_YELLOW)); - l.setNumberOfColumns(4); - l.setSingleClickSelection(true); - - final Font defaultFont = new Font(display, "Consolas", 18, SWT.BOLD); - l.setFont(defaultFont); - SWTGraphicUtil.addDisposer(shell, defaultFont); - - l.addItem("Address Book", createImage(shell, "x-office-address-book.png")); - l.addItem("Calendar", createImage(shell, "x-office-calendar.png")); - l.addItem("Presentation", createImage(shell, "x-office-presentation.png")); - l.addItem("Spreadsheet", createImage(shell, "x-office-spreadsheet.png")); - - l.addItem("Ease", createImage(shell, "ease128.png")); - l.addItem("eGit", createImage(shell, "egit.png")); - l.addItem("EMF", createImage(shell, "emfstoreSmall.png")); - l.addItem("Glassfish", createImage(shell, "glassfish.png")); - l.addItem("IOT", createImage(shell, "iot_logo_large_transparent.png")); - l.addItem("Papyrus", createImage(shell, "Papyrus.gif")); - l.addItem("SWTBot", createImage(shell, "swtbot128.png")); - - l.addListener(SWT.Selection, e -> { - Dialog.inform("Selection", "You have selected item #" + l.getSelection()); - }); - - final Label under = new Label(shell, SWT.NONE); - under.setText("Double-click an icon to launch the program"); - under.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - - shell.layout(); - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - - } - - private static Image createImage(Shell shell, String input) { - final Image img = new Image(shell.getDisplay(), LauncherSnippetAdvanced.class.getResourceAsStream("icons/" + input)); - shell.addListener(SWT.Dispose, e -> SWTGraphicUtil.safeDispose(img)); - return img; - } - -} +/******************************************************************************* + * Copyright (c) 2011-2021 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.launcher.snippets; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.dialog.Dialog; +import org.eclipse.nebula.widgets.opal.launcher.Launcher; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple snippet for the Launcher Widget + * + */ +public class LauncherSnippetAdvanced { + + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(1, false)); + + final Label title = new Label(shell, SWT.NONE); + title.setText("Launcher"); + title.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + + final Launcher l = new Launcher(shell, SWT.NONE); + l.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + + l.setItemBackgroundColor(display.getSystemColor(SWT.COLOR_RED)); + l.setSelectedItemBackgroundColor(display.getSystemColor(SWT.COLOR_YELLOW)); + l.setNumberOfColumns(4); + l.setSingleClickSelection(true); + + final Font defaultFont = new Font(display, "Consolas", 18, SWT.BOLD); + l.setFont(defaultFont); + SWTGraphicUtil.addDisposer(shell, defaultFont); + + l.addItem("Address Book", createImage(shell, "x-office-address-book.png")); + l.addItem("Calendar", createImage(shell, "x-office-calendar.png")); + l.addItem("Presentation", createImage(shell, "x-office-presentation.png")); + l.addItem("Spreadsheet", createImage(shell, "x-office-spreadsheet.png")); + + l.addItem("Ease", createImage(shell, "ease128.png")); + l.addItem("eGit", createImage(shell, "egit.png")); + l.addItem("EMF", createImage(shell, "emfstoreSmall.png")); + l.addItem("Glassfish", createImage(shell, "glassfish.png")); + l.addItem("IOT", createImage(shell, "iot_logo_large_transparent.png")); + l.addItem("Papyrus", createImage(shell, "Papyrus.gif")); + l.addItem("SWTBot", createImage(shell, "swtbot128.png")); + + l.addListener(SWT.Selection, e -> { + Dialog.inform("Selection", "You have selected item #" + l.getSelection()); + }); + + final Label under = new Label(shell, SWT.NONE); + under.setText("Double-click an icon to launch the program"); + under.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + + shell.layout(); + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + + } + + private static Image createImage(Shell shell, String input) { + final Image img = new Image(shell.getDisplay(), LauncherSnippetAdvanced.class.getResourceAsStream("icons/" + input)); + shell.addListener(SWT.Dispose, e -> SWTGraphicUtil.safeDispose(img)); + return img; + } + +} diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.classpath b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.classpath +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.project b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.project index b89cabc36..0d807728a 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.project +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.launcher - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - + + + org.eclipse.nebula.widgets.opal.launcher + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + \ No newline at end of file diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/META-INF/MANIFEST.MF b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/META-INF/MANIFEST.MF index 5173d7cea..c5ebe0fd1 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/META-INF/MANIFEST.MF +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Launcher Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.launcher -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.launcher -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.launcher +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Launcher Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.launcher +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.launcher +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.launcher diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/build.properties b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/build.properties +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/pom.xml b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/pom.xml index 68094df15..060e62853 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/pom.xml +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - launcher - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.opal.launcher - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + launcher + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.opal.launcher + eclipse-plugin + + diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/Launcher.java b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/Launcher.java index 1f5039e3c..de9a488c6 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/Launcher.java +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/Launcher.java @@ -1,554 +1,554 @@ -/******************************************************************************* - * Copyright (c) 2011-2021 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.launcher; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; - -/** - * Instances of this class are a launcher composed of buttons. When one clicks - * on the button, an animation is started and a selection event is fired - *
- *
Styles:
- *
(none)
- *
Events:
- *
Selection
- *
- */ -public class Launcher extends Composite { - - private final List items; - private boolean needRedraw; - private int selection = -1; - private Color itemBackgroundColor, selectedItemBackgroundColor; - private int numberOfColumns = -1; - private boolean singleClickSelection = false; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must - * be built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT - * style constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - */ - public Launcher(final Composite parent, final int style) { - super(parent, style | SWT.BORDER); - items = new ArrayList(); - needRedraw = true; - setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - addListener(SWT.Resize, event -> { - drawLauncher(); - }); - - addListener(SWT.KeyUp, event -> { - handleKeyPressedEvent(event); - }); - - final Font original = super.getFont(); - final Font defaultFont = new Font(getDisplay(), original.getFontData()[0].getName(), 18, SWT.BOLD); - setFont(defaultFont); - SWTGraphicUtil.addDisposer(this, defaultFont); - } - - /** - * Add an item to the launcher - * - * @param title text associated to this item - * @param image image associated to this item - */ - public void addItem(final String title, final Image image) { - checkWidget(); - items.add(new LauncherItem(title, image)); - needRedraw = true; - } - - private void addListenerToLabel(final LauncherLabel label) { - label.addListener(SWT.KeyUp, event -> { - handleKeyPressedEvent(event); - }); - - label.addListener(SWT.MouseUp, event -> { - handleClickEvent(event); - }); - - label.addListener(SWT.MouseDoubleClick, event -> { - handleDoubleClickEvent(event); - }); - } - - /** - * Adds the listener to the collection of listeners who will be notified - * when the control is selected by the user, by sending it one of the - * messages defined in the SelectionListener interface. - *

- * widgetSelected is called when the control is selected by the - * user. widgetDefaultSelected is not called. - *

- * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - checkWidget(); - SelectionListenerUtil.addSelectionListener(this, listener); - } - - /** - * Change the background color of a given button - * - * @param index index of the button - * @param isSelected by default, if true, the background is the lightshadow. Otherwise, the background color is white - */ - private void changeColor(final int index, final boolean isSelected) { - if (index != -1 && items.get(index).label != null) { - final Color selectedItemColor = selectedItemBackgroundColor == null ? getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW) : selectedItemBackgroundColor; - final Color itemColor = itemBackgroundColor == null ? getDisplay().getSystemColor(SWT.COLOR_WHITE) : itemBackgroundColor; - items.get(index).label.setBackground(isSelected ? selectedItemColor : itemColor); - } - } - - /** - * Create the buttons that will compose the launcher - */ - private void createButtons() { - if (numberOfColumns == -1) { - numberOfColumns = items.size() / 2; - } - final GridLayout gridLayout = new GridLayout(numberOfColumns, true); - gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0; - setLayout(gridLayout); - Point widthHeightHint = new Point(0, 0); - - for (final LauncherItem item : items) { - createItem(item); - Point itemSize = item.label.computeSize(SWT.DEFAULT, SWT.DEFAULT); - widthHeightHint.x = Math.max(widthHeightHint.x, itemSize.x); - widthHeightHint.y = Math.max(widthHeightHint.y, itemSize.y); - } - - for (final LauncherItem item : items) { - GridData gd = (GridData) item.label.getLayoutData(); - gd.widthHint = widthHeightHint.x; - gd.heightHint = widthHeightHint.y; - } - - } - - private void createItem(final LauncherItem item) { - final LauncherLabel label = createLauncherLabel(item); - addListenerToLabel(label); - } - - private LauncherLabel createLauncherLabel(final LauncherItem item) { - final LauncherLabel label = new LauncherLabel(this, SWT.NONE); - label.setText(item.title); - label.setImage(item.image); - label.setBackground(itemBackgroundColor == null ? getDisplay().getSystemColor(SWT.COLOR_WHITE) : // - itemBackgroundColor); - final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false); - label.setLayoutData(gd); - - item.label = label; - label.setFont(getFont()); - return label; - } - - /** - * Dispose the content before a redraw - */ - private void disposePreviousContent() { - for (final Control c : getChildren()) { - c.dispose(); - } - } - - /** - * Draw the launcher - */ - private void drawLauncher() { - if (!needRedraw) { - return; - } - - disposePreviousContent(); - createButtons(); - pack(); - - needRedraw = false; - } - - /** - * Return the selected button - * - * @return the index of the selected button - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - */ - public int getSelection() { - checkWidget(); - return selection; - } - - /** - * Code executed when one clicks on the button - * - * @param event Event - */ - private void handleClickEvent(final Event event) { - for (int i = 0; i < items.size(); i++) { - final LauncherItem item = items.get(i); - if (item.label != null && item.label.equals(event.widget)) { - if (selection != i) { - changeColor(selection, false); - selection = i; - changeColor(selection, true); - } - if (singleClickSelection) { - startAnimation(i, event); - } - return; - } - } - } - - /** - * Code executed when one double-clicks on a button - * - * @param event Event - */ - private void handleDoubleClickEvent(final Event event) { - for (int i = 0; i < items.size(); i++) { - final LauncherItem item = items.get(i); - if (item.label != null && item.label.equals(event.widget)) { - if (selection != i) { - changeColor(selection, false); - selection = i; - changeColor(selection, true); - } - if (!singleClickSelection) { - startAnimation(i, event); - } - return; - } - } - } - - /** - * Code executed when a key is pressed - * - * @param event Event - */ - private void handleKeyPressedEvent(final Event event) { - switch (event.keyCode) { - case SWT.ARROW_LEFT: - if (selection == -1) { - selection = 0; - changeColor(selection, true); - return; - } - - if (selection % 2 != 0) { - changeColor(selection, false); - selection--; - changeColor(selection, true); - } - break; - case SWT.ARROW_UP: - if (selection == -1) { - selection = 0; - changeColor(selection, true); - return; - } - if (selection >= 2) { - changeColor(selection, false); - selection -= 2; - changeColor(selection, true); - } - break; - case SWT.ARROW_RIGHT: - if (selection == -1) { - selection = 0; - changeColor(selection, true); - return; - } - if (selection % 2 == 0) { - changeColor(selection, false); - selection++; - changeColor(selection, true); - } - break; - case SWT.ARROW_DOWN: - if (selection == -1) { - selection = 0; - changeColor(selection, true); - return; - } - if (selection <= items.size() - 2) { - changeColor(selection, false); - selection += 2; - changeColor(selection, true); - } - break; - case SWT.HOME: - changeColor(selection, false); - selection = 0; - changeColor(selection, true); - break; - case SWT.END: - changeColor(selection, false); - selection = items.size() - 1; - changeColor(selection, true); - break; - } - - } - - /** - * Removes the listener from the collection of listeners who will be - * notified when the control is selected by the user. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - checkWidget(); - if (listener == null) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - SelectionListenerUtil.removeSelectionListener(this, listener); - } - - /** - * Start the animation for a given button - * - * @param index index of the selected button - * @param event event (propagated to the selection listeners) - */ - private void startAnimation(final int index, final Event event) { - final LauncherLabel label = items.get(index).label; - getDisplay().timerExec(0, new Runnable() { - @Override - public void run() { - if (label.incrementAnimation()) { - getDisplay().timerExec(20, this); - } else { - SelectionListenerUtil.fireSelectionListeners(Launcher.this, event); - } - } - }); - - } - - /** - * @return the background color of the item, null if default value - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - */ - public Color getItemBackgroundColor() { - checkWidget(); - return itemBackgroundColor; - } - - /** - * Set the background color for the items. If null, the default value (white) is used - * - * @param color the new color to set - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - */ - public void setItemBackgroundColor(Color color) { - checkWidget(); - this.itemBackgroundColor = color; - } - - /** - * @return the background color of the item when it is selected, null if default value - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- * - */ - public Color getSelectedItemBackgroundColor() { - checkWidget(); - return selectedItemBackgroundColor; - } - - /** - * Set the background color for the items. If null, the default value (white) is used - * - * @param color the new color to set - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setSelectedItemBackgroundColor(Color color) { - checkWidget(); - this.selectedItemBackgroundColor = color; - } - - /** - * @return the number of columns (item size/2 by default) - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public int getNumberOfColumns() { - checkWidget(); - return numberOfColumns; - } - - /** - * @param numberOfColumns the number of column to display - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setNumberOfColumns(int numberOfColumns) { - checkWidget(); - this.numberOfColumns = numberOfColumns; - drawLauncher(); - } - - /** - * @return true if the animation (and selection event) is fired when one clicks - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public boolean isSingleClickSelection() { - checkWidget(); - return singleClickSelection; - } - - /** - * @param singleClickSelection if true, the animation (and selection event) is fired on a single click. If false the selection is performed on a double click - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been - * disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the receiver
  • - *
- */ - public void setSingleClickSelection(boolean singleClickSelection) { - checkWidget(); - this.singleClickSelection = singleClickSelection; - } - -} +/******************************************************************************* + * Copyright (c) 2011-2021 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.launcher; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.commons.SelectionListenerUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are a launcher composed of buttons. When one clicks + * on the button, an animation is started and a selection event is fired + *
+ *
Styles:
+ *
(none)
+ *
Events:
+ *
Selection
+ *
+ */ +public class Launcher extends Composite { + + private final List items; + private boolean needRedraw; + private int selection = -1; + private Color itemBackgroundColor, selectedItemBackgroundColor; + private int numberOfColumns = -1; + private boolean singleClickSelection = false; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + public Launcher(final Composite parent, final int style) { + super(parent, style | SWT.BORDER); + items = new ArrayList(); + needRedraw = true; + setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + addListener(SWT.Resize, event -> { + drawLauncher(); + }); + + addListener(SWT.KeyUp, event -> { + handleKeyPressedEvent(event); + }); + + final Font original = super.getFont(); + final Font defaultFont = new Font(getDisplay(), original.getFontData()[0].getName(), 18, SWT.BOLD); + setFont(defaultFont); + SWTGraphicUtil.addDisposer(this, defaultFont); + } + + /** + * Add an item to the launcher + * + * @param title text associated to this item + * @param image image associated to this item + */ + public void addItem(final String title, final Image image) { + checkWidget(); + items.add(new LauncherItem(title, image)); + needRedraw = true; + } + + private void addListenerToLabel(final LauncherLabel label) { + label.addListener(SWT.KeyUp, event -> { + handleKeyPressedEvent(event); + }); + + label.addListener(SWT.MouseUp, event -> { + handleClickEvent(event); + }); + + label.addListener(SWT.MouseDoubleClick, event -> { + handleDoubleClickEvent(event); + }); + } + + /** + * Adds the listener to the collection of listeners who will be notified + * when the control is selected by the user, by sending it one of the + * messages defined in the SelectionListener interface. + *

+ * widgetSelected is called when the control is selected by the + * user. widgetDefaultSelected is not called. + *

+ * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + checkWidget(); + SelectionListenerUtil.addSelectionListener(this, listener); + } + + /** + * Change the background color of a given button + * + * @param index index of the button + * @param isSelected by default, if true, the background is the lightshadow. Otherwise, the background color is white + */ + private void changeColor(final int index, final boolean isSelected) { + if (index != -1 && items.get(index).label != null) { + final Color selectedItemColor = selectedItemBackgroundColor == null ? getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW) : selectedItemBackgroundColor; + final Color itemColor = itemBackgroundColor == null ? getDisplay().getSystemColor(SWT.COLOR_WHITE) : itemBackgroundColor; + items.get(index).label.setBackground(isSelected ? selectedItemColor : itemColor); + } + } + + /** + * Create the buttons that will compose the launcher + */ + private void createButtons() { + if (numberOfColumns == -1) { + numberOfColumns = items.size() / 2; + } + final GridLayout gridLayout = new GridLayout(numberOfColumns, true); + gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0; + setLayout(gridLayout); + Point widthHeightHint = new Point(0, 0); + + for (final LauncherItem item : items) { + createItem(item); + Point itemSize = item.label.computeSize(SWT.DEFAULT, SWT.DEFAULT); + widthHeightHint.x = Math.max(widthHeightHint.x, itemSize.x); + widthHeightHint.y = Math.max(widthHeightHint.y, itemSize.y); + } + + for (final LauncherItem item : items) { + GridData gd = (GridData) item.label.getLayoutData(); + gd.widthHint = widthHeightHint.x; + gd.heightHint = widthHeightHint.y; + } + + } + + private void createItem(final LauncherItem item) { + final LauncherLabel label = createLauncherLabel(item); + addListenerToLabel(label); + } + + private LauncherLabel createLauncherLabel(final LauncherItem item) { + final LauncherLabel label = new LauncherLabel(this, SWT.NONE); + label.setText(item.title); + label.setImage(item.image); + label.setBackground(itemBackgroundColor == null ? getDisplay().getSystemColor(SWT.COLOR_WHITE) : // + itemBackgroundColor); + final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false); + label.setLayoutData(gd); + + item.label = label; + label.setFont(getFont()); + return label; + } + + /** + * Dispose the content before a redraw + */ + private void disposePreviousContent() { + for (final Control c : getChildren()) { + c.dispose(); + } + } + + /** + * Draw the launcher + */ + private void drawLauncher() { + if (!needRedraw) { + return; + } + + disposePreviousContent(); + createButtons(); + pack(); + + needRedraw = false; + } + + /** + * Return the selected button + * + * @return the index of the selected button + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + */ + public int getSelection() { + checkWidget(); + return selection; + } + + /** + * Code executed when one clicks on the button + * + * @param event Event + */ + private void handleClickEvent(final Event event) { + for (int i = 0; i < items.size(); i++) { + final LauncherItem item = items.get(i); + if (item.label != null && item.label.equals(event.widget)) { + if (selection != i) { + changeColor(selection, false); + selection = i; + changeColor(selection, true); + } + if (singleClickSelection) { + startAnimation(i, event); + } + return; + } + } + } + + /** + * Code executed when one double-clicks on a button + * + * @param event Event + */ + private void handleDoubleClickEvent(final Event event) { + for (int i = 0; i < items.size(); i++) { + final LauncherItem item = items.get(i); + if (item.label != null && item.label.equals(event.widget)) { + if (selection != i) { + changeColor(selection, false); + selection = i; + changeColor(selection, true); + } + if (!singleClickSelection) { + startAnimation(i, event); + } + return; + } + } + } + + /** + * Code executed when a key is pressed + * + * @param event Event + */ + private void handleKeyPressedEvent(final Event event) { + switch (event.keyCode) { + case SWT.ARROW_LEFT: + if (selection == -1) { + selection = 0; + changeColor(selection, true); + return; + } + + if (selection % 2 != 0) { + changeColor(selection, false); + selection--; + changeColor(selection, true); + } + break; + case SWT.ARROW_UP: + if (selection == -1) { + selection = 0; + changeColor(selection, true); + return; + } + if (selection >= 2) { + changeColor(selection, false); + selection -= 2; + changeColor(selection, true); + } + break; + case SWT.ARROW_RIGHT: + if (selection == -1) { + selection = 0; + changeColor(selection, true); + return; + } + if (selection % 2 == 0) { + changeColor(selection, false); + selection++; + changeColor(selection, true); + } + break; + case SWT.ARROW_DOWN: + if (selection == -1) { + selection = 0; + changeColor(selection, true); + return; + } + if (selection <= items.size() - 2) { + changeColor(selection, false); + selection += 2; + changeColor(selection, true); + } + break; + case SWT.HOME: + changeColor(selection, false); + selection = 0; + changeColor(selection, true); + break; + case SWT.END: + changeColor(selection, false); + selection = items.size() - 1; + changeColor(selection, true); + break; + } + + } + + /** + * Removes the listener from the collection of listeners who will be + * notified when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + checkWidget(); + if (listener == null) { + SWT.error(SWT.ERROR_NULL_ARGUMENT); + } + SelectionListenerUtil.removeSelectionListener(this, listener); + } + + /** + * Start the animation for a given button + * + * @param index index of the selected button + * @param event event (propagated to the selection listeners) + */ + private void startAnimation(final int index, final Event event) { + final LauncherLabel label = items.get(index).label; + getDisplay().timerExec(0, new Runnable() { + @Override + public void run() { + if (label.incrementAnimation()) { + getDisplay().timerExec(20, this); + } else { + SelectionListenerUtil.fireSelectionListeners(Launcher.this, event); + } + } + }); + + } + + /** + * @return the background color of the item, null if default value + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + */ + public Color getItemBackgroundColor() { + checkWidget(); + return itemBackgroundColor; + } + + /** + * Set the background color for the items. If null, the default value (white) is used + * + * @param color the new color to set + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + */ + public void setItemBackgroundColor(Color color) { + checkWidget(); + this.itemBackgroundColor = color; + } + + /** + * @return the background color of the item when it is selected, null if default value + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ * + */ + public Color getSelectedItemBackgroundColor() { + checkWidget(); + return selectedItemBackgroundColor; + } + + /** + * Set the background color for the items. If null, the default value (white) is used + * + * @param color the new color to set + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSelectedItemBackgroundColor(Color color) { + checkWidget(); + this.selectedItemBackgroundColor = color; + } + + /** + * @return the number of columns (item size/2 by default) + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public int getNumberOfColumns() { + checkWidget(); + return numberOfColumns; + } + + /** + * @param numberOfColumns the number of column to display + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setNumberOfColumns(int numberOfColumns) { + checkWidget(); + this.numberOfColumns = numberOfColumns; + drawLauncher(); + } + + /** + * @return true if the animation (and selection event) is fired when one clicks + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public boolean isSingleClickSelection() { + checkWidget(); + return singleClickSelection; + } + + /** + * @param singleClickSelection if true, the animation (and selection event) is fired on a single click. If false the selection is performed on a double click + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been + * disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the receiver
  • + *
+ */ + public void setSingleClickSelection(boolean singleClickSelection) { + checkWidget(); + this.singleClickSelection = singleClickSelection; + } + +} diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/LauncherItem.java b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/LauncherItem.java index 7cc2ab3f3..3a6d3e414 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/LauncherItem.java +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/LauncherItem.java @@ -1,36 +1,36 @@ -/******************************************************************************* - * Copyright (c) 2011-2021 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.launcher; - -import org.eclipse.swt.graphics.Image; - -/** - * Instances of this class are POJO to store information handled by the Launcher - */ -class LauncherItem { - String title; - Image image; - LauncherLabel label; - - /** - * Constructor - * - * @param title text associated to the item - * @param image image associated to the item - */ - LauncherItem(final String title, final Image image) { - this.title = title; - this.image = image; - } -} +/******************************************************************************* + * Copyright (c) 2011-2021 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.launcher; + +import org.eclipse.swt.graphics.Image; + +/** + * Instances of this class are POJO to store information handled by the Launcher + */ +class LauncherItem { + String title; + Image image; + LauncherLabel label; + + /** + * Constructor + * + * @param title text associated to the item + * @param image image associated to the item + */ + LauncherItem(final String title, final Image image) { + this.title = title; + this.image = image; + } +} diff --git a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/LauncherLabel.java b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/LauncherLabel.java index 6cb3f5ac3..4fdb905aa 100644 --- a/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/LauncherLabel.java +++ b/widgets/opal/launcher/org.eclipse.nebula.widgets.opal.launcher/src/org/eclipse/nebula/widgets/opal/launcher/LauncherLabel.java @@ -1,310 +1,310 @@ -/******************************************************************************* - * Copyright (c) 2011-2021 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.launcher; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.graphics.Font; -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.Canvas; -import org.eclipse.swt.widgets.Composite; - -/** - * Instance of this class are a button with text, image and a nice animation - * effect - */ -class LauncherLabel extends Canvas { - - private String text; - private Image image; - private Font font; - - static final int GAP = 12; - private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER; - private static final int DEFAULT_MARGIN = 5; - private int leftMargin = DEFAULT_MARGIN; - private int topMargin = DEFAULT_MARGIN; - private int rightMargin = DEFAULT_MARGIN; - private int bottomMargin = DEFAULT_MARGIN; - private Point textSize; - - private static final int MAX_NUMBER_OF_STEPS = 10; - private int animationStep = 0; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must - * be built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT - * style constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
- * - */ - LauncherLabel(final Composite parent, final int style) { - super(parent, style | SWT.BORDER | SWT.DOUBLE_BUFFERED); - - font = parent.getFont(); - - addPaintListener(event -> { - paintControl(event); - }); - - } - - /** - * Draw the content of the LLabel - * - * @param event paintevent - */ - private void paintControl(final PaintEvent event) { - final Rectangle rect = getClientArea(); - if (rect.width == 0 || rect.height == 0) { - return; - } - - final Image bufferImage = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height)); - - final GC gc = new GC(bufferImage); - gc.setForeground(getForeground()); - gc.setBackground(getBackground()); - - gc.fillRectangle(rect); - - final Point extent = getTotalSize(image.getBounds().width, image.getBounds().height); - final int xImage = (rect.width - image.getBounds().width) / 2; - final int yImage = (rect.height - extent.y) / 2; - gc.drawImage(image, xImage, yImage); - - gc.setFont(font); - final int xText = (rect.width - textSize.x) / 2; - final int yText = yImage + image.getBounds().height + GAP - textSize.y / 2; - gc.drawString(text, xText, yText); - - if (animationStep != 0) { - final float zoom = 1f + animationStep * (Math.max(extent.x, extent.y) - Math.max(image.getBounds().width, image.getBounds().height)) / MAX_NUMBER_OF_STEPS / 100f; - - final int newSizeX = (int) (image.getBounds().width * zoom); - final int newSizeY = (int) (image.getBounds().height * zoom); - - gc.setAntialias(SWT.ON); - gc.setInterpolation(SWT.HIGH); - - gc.setAlpha(255 - 255 / MAX_NUMBER_OF_STEPS * animationStep); - - final Point extentZoomedImage = getTotalSize(newSizeX, newSizeY); - final int xZoomedImage = (rect.width - newSizeX) / 2; - final int yZoomedImage = (rect.height - extentZoomedImage.y) / 2; - gc.drawImage(image, 0, 0, image.getBounds().width, image.getBounds().height, xZoomedImage, yZoomedImage, (int) (image.getBounds().width * zoom), (int) (image.getBounds().height * zoom)); - - } - - gc.dispose(); - - event.gc.drawImage(bufferImage, 0, 0); - - bufferImage.dispose(); - - } - - /** - * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean) - */ - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - checkWidget(); - final Point e = getTotalSize(image.getBounds().width, image.getBounds().height); - if (wHint == SWT.DEFAULT) { - e.x += leftMargin + rightMargin; - } else { - e.x = wHint; - } - if (hHint == SWT.DEFAULT) { - e.y += topMargin + bottomMargin; - } else { - e.y = hHint; - } - return e; - } - - /** - * Compute the size of the content (image + text + gap) - * - * @param imgWidth image width - * @param imgHeight image height - * @return the size of the content - */ - private Point getTotalSize(final int imgWidth, final int imgHeight) { - final Point size = new Point(0, 0); - - int textWidth = 0; - int textHeight = 0; - - if (textSize == null) { - final GC gc = new GC(this); - gc.setFont(font); - - textSize = gc.textExtent(text, DRAW_FLAGS); - gc.dispose(); - - } - textWidth = textSize.x; - textHeight = textSize.y; - - size.x = Math.max(imgWidth, textWidth); - size.y = imgHeight + GAP + textHeight; - - return size; - } - - /** - * @return the text - */ - String getText() { - return text; - } - - /** - * @param text the text to set - */ - void setText(final String text) { - this.text = text; - } - - /** - * @return the image - */ - Image getImage() { - return image; - } - - /** - * @param image the image to set - */ - void setImage(final Image image) { - this.image = image; - } - - /** - * @return the font - */ - @Override - public Font getFont() { - return font; - } - - /** - * @param font the font to set - */ - @Override - public void setFont(final Font font) { - this.font = font; - } - - /** - * Increment the steps of the animation - * - * @return true if animation keeps running, false otherwise - */ - boolean incrementAnimation() { - animationStep++; - final boolean stopAnimation = animationStep > MAX_NUMBER_OF_STEPS; - - if (stopAnimation) { - animationStep = 0; - } - if (!isDisposed()) { - redraw(); - } - return !stopAnimation; - } - - /** - * @return the left margin - */ - public int getLeftMargin() { - return leftMargin; - } - - /** - * @param leftMargin the left margin to set - */ - public void setLeftMargin(final int leftMargin) { - this.leftMargin = leftMargin; - } - - /** - * @return the top margin - */ - public int getTopMargin() { - return topMargin; - } - - /** - * @param topMargin the top margin to set - */ - public void setTopMargin(final int topMargin) { - this.topMargin = topMargin; - } - - /** - * @return the right margin - */ - public int getRightMargin() { - return rightMargin; - } - - /** - * @param rightMargin the right margin to set - */ - public void setRightMargin(final int rightMargin) { - this.rightMargin = rightMargin; - } - - /** - * @return the bottom margin - */ - public int getBottomMargin() { - return bottomMargin; - } - - /** - * @param bottomMargin the bottom margin to set - */ - public void setBottomMargin(final int bottomMargin) { - this.bottomMargin = bottomMargin; - } - -} +/******************************************************************************* + * Copyright (c) 2011-2021 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.launcher; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.Font; +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.Canvas; +import org.eclipse.swt.widgets.Composite; + +/** + * Instance of this class are a button with text, image and a nice animation + * effect + */ +class LauncherLabel extends Canvas { + + private String text; + private Image image; + private Font font; + + static final int GAP = 12; + private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER; + private static final int DEFAULT_MARGIN = 5; + private int leftMargin = DEFAULT_MARGIN; + private int topMargin = DEFAULT_MARGIN; + private int rightMargin = DEFAULT_MARGIN; + private int bottomMargin = DEFAULT_MARGIN; + private Point textSize; + + private static final int MAX_NUMBER_OF_STEPS = 10; + private int animationStep = 0; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + *

+ * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must + * be built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT + * style constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

+ * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
  • + *
+ * + */ + LauncherLabel(final Composite parent, final int style) { + super(parent, style | SWT.BORDER | SWT.DOUBLE_BUFFERED); + + font = parent.getFont(); + + addPaintListener(event -> { + paintControl(event); + }); + + } + + /** + * Draw the content of the LLabel + * + * @param event paintevent + */ + private void paintControl(final PaintEvent event) { + final Rectangle rect = getClientArea(); + if (rect.width == 0 || rect.height == 0) { + return; + } + + final Image bufferImage = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height)); + + final GC gc = new GC(bufferImage); + gc.setForeground(getForeground()); + gc.setBackground(getBackground()); + + gc.fillRectangle(rect); + + final Point extent = getTotalSize(image.getBounds().width, image.getBounds().height); + final int xImage = (rect.width - image.getBounds().width) / 2; + final int yImage = (rect.height - extent.y) / 2; + gc.drawImage(image, xImage, yImage); + + gc.setFont(font); + final int xText = (rect.width - textSize.x) / 2; + final int yText = yImage + image.getBounds().height + GAP - textSize.y / 2; + gc.drawString(text, xText, yText); + + if (animationStep != 0) { + final float zoom = 1f + animationStep * (Math.max(extent.x, extent.y) - Math.max(image.getBounds().width, image.getBounds().height)) / MAX_NUMBER_OF_STEPS / 100f; + + final int newSizeX = (int) (image.getBounds().width * zoom); + final int newSizeY = (int) (image.getBounds().height * zoom); + + gc.setAntialias(SWT.ON); + gc.setInterpolation(SWT.HIGH); + + gc.setAlpha(255 - 255 / MAX_NUMBER_OF_STEPS * animationStep); + + final Point extentZoomedImage = getTotalSize(newSizeX, newSizeY); + final int xZoomedImage = (rect.width - newSizeX) / 2; + final int yZoomedImage = (rect.height - extentZoomedImage.y) / 2; + gc.drawImage(image, 0, 0, image.getBounds().width, image.getBounds().height, xZoomedImage, yZoomedImage, (int) (image.getBounds().width * zoom), (int) (image.getBounds().height * zoom)); + + } + + gc.dispose(); + + event.gc.drawImage(bufferImage, 0, 0); + + bufferImage.dispose(); + + } + + /** + * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean) + */ + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + checkWidget(); + final Point e = getTotalSize(image.getBounds().width, image.getBounds().height); + if (wHint == SWT.DEFAULT) { + e.x += leftMargin + rightMargin; + } else { + e.x = wHint; + } + if (hHint == SWT.DEFAULT) { + e.y += topMargin + bottomMargin; + } else { + e.y = hHint; + } + return e; + } + + /** + * Compute the size of the content (image + text + gap) + * + * @param imgWidth image width + * @param imgHeight image height + * @return the size of the content + */ + private Point getTotalSize(final int imgWidth, final int imgHeight) { + final Point size = new Point(0, 0); + + int textWidth = 0; + int textHeight = 0; + + if (textSize == null) { + final GC gc = new GC(this); + gc.setFont(font); + + textSize = gc.textExtent(text, DRAW_FLAGS); + gc.dispose(); + + } + textWidth = textSize.x; + textHeight = textSize.y; + + size.x = Math.max(imgWidth, textWidth); + size.y = imgHeight + GAP + textHeight; + + return size; + } + + /** + * @return the text + */ + String getText() { + return text; + } + + /** + * @param text the text to set + */ + void setText(final String text) { + this.text = text; + } + + /** + * @return the image + */ + Image getImage() { + return image; + } + + /** + * @param image the image to set + */ + void setImage(final Image image) { + this.image = image; + } + + /** + * @return the font + */ + @Override + public Font getFont() { + return font; + } + + /** + * @param font the font to set + */ + @Override + public void setFont(final Font font) { + this.font = font; + } + + /** + * Increment the steps of the animation + * + * @return true if animation keeps running, false otherwise + */ + boolean incrementAnimation() { + animationStep++; + final boolean stopAnimation = animationStep > MAX_NUMBER_OF_STEPS; + + if (stopAnimation) { + animationStep = 0; + } + if (!isDisposed()) { + redraw(); + } + return !stopAnimation; + } + + /** + * @return the left margin + */ + public int getLeftMargin() { + return leftMargin; + } + + /** + * @param leftMargin the left margin to set + */ + public void setLeftMargin(final int leftMargin) { + this.leftMargin = leftMargin; + } + + /** + * @return the top margin + */ + public int getTopMargin() { + return topMargin; + } + + /** + * @param topMargin the top margin to set + */ + public void setTopMargin(final int topMargin) { + this.topMargin = topMargin; + } + + /** + * @return the right margin + */ + public int getRightMargin() { + return rightMargin; + } + + /** + * @param rightMargin the right margin to set + */ + public void setRightMargin(final int rightMargin) { + this.rightMargin = rightMargin; + } + + /** + * @return the bottom margin + */ + public int getBottomMargin() { + return bottomMargin; + } + + /** + * @param bottomMargin the bottom margin to set + */ + public void setBottomMargin(final int bottomMargin) { + this.bottomMargin = bottomMargin; + } + +} diff --git a/widgets/opal/launcher/pom.xml b/widgets/opal/launcher/pom.xml index 931a20078..c69004f7d 100644 --- a/widgets/opal/launcher/pom.xml +++ b/widgets/opal/launcher/pom.xml @@ -1,22 +1,22 @@ - - - 4.0.0 - - - org.eclipse.nebula - 1.0.0-SNAPSHOT - opal - - - launcher - pom - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.opal.launcher - org.eclipse.nebula.widgets.opal.launcher.feature - org.eclipse.nebula.widgets.opal.launcher.snippets - - - + + + 4.0.0 + + + org.eclipse.nebula + 1.0.0-SNAPSHOT + opal + + + launcher + pom + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.opal.launcher + org.eclipse.nebula.widgets.opal.launcher.feature + org.eclipse.nebula.widgets.opal.launcher.snippets + + + diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.feature/build.properties b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.feature/build.properties +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.feature/feature.properties b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.feature/feature.properties +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/.classpath b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/.classpath +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/META-INF/MANIFEST.MF b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/META-INF/MANIFEST.MF index aec274f6f..9e67565d3 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Log inDialog Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.logindialog.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.logindialog;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.logindialog.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Log inDialog Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.logindialog.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.logindialog;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.logindialog.snippets diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/build.properties b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/build.properties +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/src/org/eclipse/nebula/widgets/opal/loginDialog/snippets/LoginDialogSnippet.java b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/src/org/eclipse/nebula/widgets/opal/loginDialog/snippets/LoginDialogSnippet.java index db33d9351..d37b7e207 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/src/org/eclipse/nebula/widgets/opal/loginDialog/snippets/LoginDialogSnippet.java +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog.snippets/src/org/eclipse/nebula/widgets/opal/loginDialog/snippets/LoginDialogSnippet.java @@ -1,131 +1,131 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.loginDialog.snippets; - -import java.util.Locale; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.loginDialog.LoginDialog; -import org.eclipse.nebula.widgets.opal.loginDialog.LoginDialogVerifier; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * This snippet demonstrates the Login Dialog widget - * - */ -public class LoginDialogSnippet { - - /** - * @param args - */ - public static void main(final String[] args) { - - Locale.setDefault(Locale.ENGLISH); - - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setText("Login dialog snippet"); - shell.setLayout(new GridLayout(2, false)); - - // Basic Login dialog - final Label label1 = new Label(shell, SWT.WRAP); - label1.setText("This is the basic dialog box, \nwithout any customization"); - label1.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false)); - - final Button button1 = new Button(shell, SWT.PUSH); - button1.setText("Open basic dialog"); - button1.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, false)); - - final LoginDialogVerifier verifier = (login, password) -> { - if ("".equals(login)) { - throw new Exception("Please enter a login."); - } - - if ("".equals(password)) { - throw new Exception("Please enter a password."); - } - - if (!login.equalsIgnoreCase("laurent")) { - throw new Exception("Login unknown."); - } - - if (!password.equalsIgnoreCase("laurent")) { - throw new Exception("Authentication failed, please check your password."); - } - - }; - - button1.addListener(SWT.Selection, e -> { - final LoginDialog dialog = new LoginDialog(); - dialog.setVerifier(verifier); - - final boolean result = dialog.open(); - if (result) { - System.out.println("Login confirmed : " + dialog.getLogin()); - } else { - System.out.println("User canceled !"); - } - }); - - final Label separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL); - separator.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, false, 2, 1)); - - // Login dialog with image, description, default login, and no button - // "remember my password" - final Label label2 = new Label(shell, SWT.NONE); - label2.setText("This is a customized login (image, description, \ndefault login, multiple login values, \nno button 'remember my password'"); - label2.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false)); - - final Button button2 = new Button(shell, SWT.PUSH); - button2.setText("Open customized dialog"); - button2.setLayoutData(new GridData(GridData.END, GridData.BEGINNING, false, false)); - - button2.addListener(SWT.Selection, e -> { - - final LoginDialog dialog = new LoginDialog(); - dialog.setImage(new Image(display, LoginDialogSnippet.class.getResourceAsStream("image.png"))); - dialog.setDescription("Please login to our system...\nPlease remember that the password is the same as the login :)"); - dialog.setAutorizedLogin("Laurent", "Albert", "Erik", "Ulrich", "Luis"); - dialog.setLogin("Laurent"); - dialog.setDisplayRememberPassword(false); - dialog.setVerifier(verifier); - - final boolean result = dialog.open(); - if (result) { - System.out.println("Login confirmed : " + dialog.getLogin()); - } else { - System.out.println("User canceled !"); - } - }); - - shell.pack(); - shell.open(); - SWTGraphicUtil.centerShell(shell); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - display.dispose(); - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.loginDialog.snippets; + +import java.util.Locale; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.loginDialog.LoginDialog; +import org.eclipse.nebula.widgets.opal.loginDialog.LoginDialogVerifier; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * This snippet demonstrates the Login Dialog widget + * + */ +public class LoginDialogSnippet { + + /** + * @param args + */ + public static void main(final String[] args) { + + Locale.setDefault(Locale.ENGLISH); + + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setText("Login dialog snippet"); + shell.setLayout(new GridLayout(2, false)); + + // Basic Login dialog + final Label label1 = new Label(shell, SWT.WRAP); + label1.setText("This is the basic dialog box, \nwithout any customization"); + label1.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false)); + + final Button button1 = new Button(shell, SWT.PUSH); + button1.setText("Open basic dialog"); + button1.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, false)); + + final LoginDialogVerifier verifier = (login, password) -> { + if ("".equals(login)) { + throw new Exception("Please enter a login."); + } + + if ("".equals(password)) { + throw new Exception("Please enter a password."); + } + + if (!login.equalsIgnoreCase("laurent")) { + throw new Exception("Login unknown."); + } + + if (!password.equalsIgnoreCase("laurent")) { + throw new Exception("Authentication failed, please check your password."); + } + + }; + + button1.addListener(SWT.Selection, e -> { + final LoginDialog dialog = new LoginDialog(); + dialog.setVerifier(verifier); + + final boolean result = dialog.open(); + if (result) { + System.out.println("Login confirmed : " + dialog.getLogin()); + } else { + System.out.println("User canceled !"); + } + }); + + final Label separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL); + separator.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, false, 2, 1)); + + // Login dialog with image, description, default login, and no button + // "remember my password" + final Label label2 = new Label(shell, SWT.NONE); + label2.setText("This is a customized login (image, description, \ndefault login, multiple login values, \nno button 'remember my password'"); + label2.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false)); + + final Button button2 = new Button(shell, SWT.PUSH); + button2.setText("Open customized dialog"); + button2.setLayoutData(new GridData(GridData.END, GridData.BEGINNING, false, false)); + + button2.addListener(SWT.Selection, e -> { + + final LoginDialog dialog = new LoginDialog(); + dialog.setImage(new Image(display, LoginDialogSnippet.class.getResourceAsStream("image.png"))); + dialog.setDescription("Please login to our system...\nPlease remember that the password is the same as the login :)"); + dialog.setAutorizedLogin("Laurent", "Albert", "Erik", "Ulrich", "Luis"); + dialog.setLogin("Laurent"); + dialog.setDisplayRememberPassword(false); + dialog.setVerifier(verifier); + + final boolean result = dialog.open(); + if (result) { + System.out.println("Login confirmed : " + dialog.getLogin()); + } else { + System.out.println("User canceled !"); + } + }); + + shell.pack(); + shell.open(); + SWTGraphicUtil.centerShell(shell); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + display.dispose(); + } + +} diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/.classpath b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/.classpath +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/META-INF/MANIFEST.MF b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/META-INF/MANIFEST.MF index dda65dc5a..5b20a4bf9 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/META-INF/MANIFEST.MF +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/META-INF/MANIFEST.MF @@ -1,13 +1,13 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Login Dialog Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.logindialog -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.nebula.widgets.opal.dialog;bundle-version="1.0.0", - org.eclipse.swt -Import-Package: org.eclipse.nebula.widgets.opal.dialog -Export-Package: org.eclipse.nebula.widgets.opal.loginDialog -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.logindialog +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Login Dialog Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.logindialog +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.nebula.widgets.opal.dialog;bundle-version="1.0.0", + org.eclipse.swt +Import-Package: org.eclipse.nebula.widgets.opal.dialog +Export-Package: org.eclipse.nebula.widgets.opal.loginDialog +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.logindialog diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/build.properties b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/build.properties +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/src/org/eclipse/nebula/widgets/opal/loginDialog/LoginDialog.java b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/src/org/eclipse/nebula/widgets/opal/loginDialog/LoginDialog.java index 1eb1a820f..71711fc9b 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/src/org/eclipse/nebula/widgets/opal/loginDialog/LoginDialog.java +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/src/org/eclipse/nebula/widgets/opal/loginDialog/LoginDialog.java @@ -1,477 +1,477 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.loginDialog; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.commons.ResourceManager; -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.nebula.widgets.opal.dialog.Dialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Path; -import org.eclipse.swt.graphics.Pattern; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * Instances of this class are Login Dialog box, which is composed of - *

- *

- *
A login
- *
A password
- *
An image
- *
(optional)
- *
A description
- *
(optional)
- *
A checkbox "remember the password"
- *
(optional)
- *
- *

- */ -public class LoginDialog { - private Image image; - private String description; - private String login; - private String password; - private List autorizedLogin; - private boolean displayRememberPassword; - private boolean rememberPassword; - private LoginDialogVerifier verifier; - - private Shell shell; - private boolean returnedValue; - private Button buttonOk; - - /** - * Constructor - */ - public LoginDialog() { - displayRememberPassword = true; - } - - /** - * Open the Login box - * - * @return true if the authentication is OK, false - * if the user pressed on cancel. - */ - public boolean open() { - if (verifier == null) { - throw new IllegalArgumentException("Please set a verifier before opening the dialog box"); - } - - buildDialog(); - openShell(); - - return returnedValue; - } - - /** - * Build the dialog box - */ - private void buildDialog() { - buildShell(); - buildImage(); - buildDescription(); - buildLogin(); - buildPassword(); - if (displayRememberPassword) { - buildRememberPassword(); - } - buildButtons(); - } - - /** - * Build the shell - */ - private void buildShell() { - shell = new Shell(SWT.SYSTEM_MODAL | SWT.TITLE | SWT.BORDER); - shell.setText(ResourceManager.getLabel(ResourceManager.LOGIN)); - shell.setLayout(new GridLayout(4, false)); - } - - /** - * Build the image on top of the login box. If no image has been set, create - * a default image - */ - private void buildImage() { - final Canvas canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED); - final GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, false, 4, 1); - gridData.widthHint = 400; - gridData.heightHint = 60; - canvas.setLayoutData(gridData); - canvas.addPaintListener(e -> { - e.gc.drawImage(image == null ? createDefaultImage(e.width, e.height) : image, 0, 0); - }); - - } - - /** - * Create a default image. It is a port of the image used by the Login Box - * in the project SwingX - * - * @param w width - * @param h height - * @return a default image (blue wave) - */ - private Image createDefaultImage(final int w, final int h) { - final Display display = Display.getCurrent(); - final Color backgroundColor = new Color(display, 49, 121, 242); - final Color gradientColor1 = new Color(display, 155, 185, 245); - final Color gradientColor2 = new Color(display, 53, 123, 242); - - final Image img = new Image(display, w, h); - final GC gc = new GC(img); - gc.setAdvanced(true); - gc.setAntialias(SWT.ON); - gc.setBackground(backgroundColor); - gc.fillRectangle(0, 0, w, h); - - final Path curveShape = new Path(display); - curveShape.moveTo(0, h * .6f); - curveShape.cubicTo(w * .167f, h * 1.2f, w * .667f, h * -.5f, w, h * .75f); - curveShape.lineTo(w, h); - curveShape.lineTo(0, h); - curveShape.lineTo(0, h * .8f); - curveShape.close(); - - final Pattern pattern = new Pattern(display, 0, 0, 1, h * 1.2f, gradientColor1, gradientColor2); - gc.setBackgroundPattern(pattern); - gc.fillPath(curveShape); - - final Font font = new Font(display, "Arial Bold", 30, SWT.NONE); - gc.setFont(font); - gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); - final Point textSize = gc.stringExtent(ResourceManager.getLabel(ResourceManager.LOGIN)); - gc.drawString(ResourceManager.getLabel(ResourceManager.LOGIN), (int) (w * .05f), (h - textSize.y) / 2, true); - - font.dispose(); - curveShape.dispose(); - pattern.dispose(); - backgroundColor.dispose(); - gradientColor1.dispose(); - gradientColor2.dispose(); - gc.dispose(); - return img; - } - - /** - * Build the description part of the box - */ - private void buildDescription() { - final Label label = new Label(shell, SWT.NONE); - final GridData gridData = new GridData(GridData.FILL, GridData.BEGINNING, true, false, 4, 1); - gridData.verticalIndent = 5; - gridData.horizontalIndent = 5; - label.setLayoutData(gridData); - final Font bold = SWTGraphicUtil.buildFontFrom(label, SWT.BOLD); - label.setFont(bold); - SWTGraphicUtil.addDisposer(label, bold); - - if (description == null || description.trim().equals("")) { - label.setText(" "); - } else { - label.setText(description); - } - } - - /** - * Build the login part of the box - */ - private void buildLogin() { - final Label label = new Label(shell, SWT.NONE); - final GridData gridData = new GridData(GridData.END, GridData.END, false, false, 1, 1); - gridData.horizontalIndent = 35; - gridData.verticalIndent = 15; - label.setLayoutData(gridData); - label.setText(ResourceManager.getLabel(ResourceManager.NAME)); - - if (autorizedLogin != null && !autorizedLogin.isEmpty()) { - // Combo - buildLoginCombo(); - } else { - // Text - buildLoginText(); - } - - } - - private void buildLoginCombo() { - final Combo combo = new Combo(shell, SWT.BORDER | SWT.READ_ONLY); - - combo.setLayoutData(new GridData(GridData.FILL, GridData.END, true, false, 3, 1)); - for (final String loginToAdd : autorizedLogin) { - combo.add(loginToAdd); - } - combo.setText(login == null ? "" : login); - combo.setFocus(); - combo.addListener(SWT.Modify, e -> { - login = combo.getText(); - changeButtonOkState(); - }); - } - - private void buildLoginText() { - final Text text = new Text(shell, SWT.BORDER); - text.setText(login == null ? "" : login); - text.setLayoutData(new GridData(GridData.FILL, GridData.END, true, false, 3, 1)); - text.setFocus(); - text.addListener(SWT.Modify, e -> { - login = text.getText(); - changeButtonOkState(); - }); - } - - /** - * Build the password part of the box - */ - private void buildPassword() { - final Label label = new Label(shell, SWT.NONE); - final GridData gridData = new GridData(GridData.END, GridData.CENTER, false, false, 1, 1); - gridData.horizontalIndent = 35; - label.setLayoutData(gridData); - label.setText(ResourceManager.getLabel(ResourceManager.PASSWORD)); - - final Text text = new Text(shell, SWT.PASSWORD | SWT.BORDER); - text.setText(password == null ? "" : password); - text.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1)); - text.addListener(SWT.Modify, e -> { - password = text.getText(); - changeButtonOkState(); - }); - } - - /** - * Enable/Disable the button when the login and the password is empty (or - * not) - */ - private void changeButtonOkState() { - final boolean loginEntered = login != null && !login.trim().equals(""); - final boolean passwordEntered = password != null && !password.trim().equals(""); - buttonOk.setEnabled(loginEntered && passwordEntered); - } - - /** - * Build the "remember password" part of the box - */ - private void buildRememberPassword() { - final Button checkbox = new Button(shell, SWT.CHECK); - final GridData gridData = new GridData(GridData.BEGINNING, GridData.CENTER, true, false, 4, 1); - gridData.horizontalIndent = 35; - checkbox.setLayoutData(gridData); - checkbox.setText(ResourceManager.getLabel(ResourceManager.REMEMBER_PASSWORD)); - checkbox.setSelection(rememberPassword); - } - - /** - * Build the buttons - */ - private void buildButtons() { - buildOkButton(); - buildCancelButton(); - } - - private void buildOkButton() { - buttonOk = new Button(shell, SWT.PUSH); - final GridData gdOk = new GridData(GridData.END, GridData.CENTER, true, false, 3, 1); - gdOk.verticalIndent = 60; - gdOk.minimumWidth = 80; - buttonOk.setLayoutData(gdOk); - buttonOk.setText(ResourceManager.getLabel(ResourceManager.OK)); - buttonOk.setEnabled(false); - - buttonOk.addListener(SWT.Selection, event -> { - try { - verifier.authenticate(login, password); - returnedValue = true; - shell.dispose(); - } catch (final Exception e) { - Dialog.error(ResourceManager.getLabel(ResourceManager.LOGIN_FAILED), e.getMessage()); - for (final Control control : shell.getChildren()) { - if (control instanceof Text || control instanceof Combo) { - control.setFocus(); - break; - } - } - } - }); - } - - private void buildCancelButton() { - final Button buttonCancel = new Button(shell, SWT.PUSH); - final GridData gdCancel = new GridData(GridData.FILL, GridData.CENTER, false, false); - gdCancel.widthHint = 80; - gdCancel.verticalIndent = 60; - buttonCancel.setLayoutData(gdCancel); - buttonCancel.setText(ResourceManager.getLabel(ResourceManager.CANCEL)); - buttonCancel.addListener(SWT.Selection, event -> { - returnedValue = false; - shell.dispose(); - }); - } - - /** - * Open the shell - */ - private void openShell() { - shell.setDefaultButton(buttonOk); - shell.pack(); - shell.open(); - SWTGraphicUtil.centerShell(shell); - while (!shell.isDisposed()) { - if (!shell.getDisplay().readAndDispatch()) { - shell.getDisplay().sleep(); - } - } - } - - // ------------- Getters & Setters - /** - * @return the image - */ - public Image getImage() { - return image; - } - - /** - * @return the description - */ - public String getDescription() { - return description; - } - - /** - * @return the login - */ - public String getLogin() { - return login == null ? null : login.trim(); - } - - /** - * @return the password - */ - public String getPassword() { - return password == null ? null : password.trim(); - } - - /** - * @return the list of autorized logins - */ - public List getAutorizedLogin() { - return autorizedLogin; - } - - /** - * @return true if the checkbox "remember the password" is - * displayed, false otherwise - */ - public boolean isDisplayRememberPassword() { - return displayRememberPassword; - } - - /** - * @return true if the checkbox "remember the password" is - * checked, false otherwise - */ - public boolean isRememberPassword() { - return rememberPassword; - } - - /** - * @return the verifier associated to this box - */ - public LoginDialogVerifier getVerifier() { - return verifier; - } - - /** - * @param image the image to set - */ - public void setImage(final Image image) { - this.image = image; - } - - /** - * @param description the description to set - */ - public void setDescription(final String description) { - this.description = description; - } - - /** - * @param login the login to set - */ - public void setLogin(final String login) { - this.login = login; - } - - /** - * @param password the password to set - */ - public void setPassword(final String password) { - this.password = password; - } - - /** - * @param autorizedLogin the list of autorized logins to set - */ - public void setAutorizedLogin(final List autorizedLogin) { - this.autorizedLogin = autorizedLogin; - } - - /** - * @param autorizedLogin the list of autorized logins to set - */ - public void setAutorizedLogin(final String... autorizedLogin) { - this.autorizedLogin = Arrays.asList(autorizedLogin); - } - - /** - * @param displayRememberPassword if true, the checkbox - * "remember the password" is displayed - */ - public void setDisplayRememberPassword(final boolean displayRememberPassword) { - this.displayRememberPassword = displayRememberPassword; - } - - /** - * @param rememberPassword if true, the checkbox - * "remember the password" is selected - */ - public void setRememberPassword(final boolean rememberPassword) { - this.rememberPassword = rememberPassword; - } - - /** - * @param verifier the verifier to set - */ - public void setVerifier(final LoginDialogVerifier verifier) { - this.verifier = verifier; - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.loginDialog; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.commons.ResourceManager; +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.nebula.widgets.opal.dialog.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Path; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * Instances of this class are Login Dialog box, which is composed of + *

+ *

+ *
A login
+ *
A password
+ *
An image
+ *
(optional)
+ *
A description
+ *
(optional)
+ *
A checkbox "remember the password"
+ *
(optional)
+ *
+ *

+ */ +public class LoginDialog { + private Image image; + private String description; + private String login; + private String password; + private List autorizedLogin; + private boolean displayRememberPassword; + private boolean rememberPassword; + private LoginDialogVerifier verifier; + + private Shell shell; + private boolean returnedValue; + private Button buttonOk; + + /** + * Constructor + */ + public LoginDialog() { + displayRememberPassword = true; + } + + /** + * Open the Login box + * + * @return true if the authentication is OK, false + * if the user pressed on cancel. + */ + public boolean open() { + if (verifier == null) { + throw new IllegalArgumentException("Please set a verifier before opening the dialog box"); + } + + buildDialog(); + openShell(); + + return returnedValue; + } + + /** + * Build the dialog box + */ + private void buildDialog() { + buildShell(); + buildImage(); + buildDescription(); + buildLogin(); + buildPassword(); + if (displayRememberPassword) { + buildRememberPassword(); + } + buildButtons(); + } + + /** + * Build the shell + */ + private void buildShell() { + shell = new Shell(SWT.SYSTEM_MODAL | SWT.TITLE | SWT.BORDER); + shell.setText(ResourceManager.getLabel(ResourceManager.LOGIN)); + shell.setLayout(new GridLayout(4, false)); + } + + /** + * Build the image on top of the login box. If no image has been set, create + * a default image + */ + private void buildImage() { + final Canvas canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED); + final GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, false, 4, 1); + gridData.widthHint = 400; + gridData.heightHint = 60; + canvas.setLayoutData(gridData); + canvas.addPaintListener(e -> { + e.gc.drawImage(image == null ? createDefaultImage(e.width, e.height) : image, 0, 0); + }); + + } + + /** + * Create a default image. It is a port of the image used by the Login Box + * in the project SwingX + * + * @param w width + * @param h height + * @return a default image (blue wave) + */ + private Image createDefaultImage(final int w, final int h) { + final Display display = Display.getCurrent(); + final Color backgroundColor = new Color(display, 49, 121, 242); + final Color gradientColor1 = new Color(display, 155, 185, 245); + final Color gradientColor2 = new Color(display, 53, 123, 242); + + final Image img = new Image(display, w, h); + final GC gc = new GC(img); + gc.setAdvanced(true); + gc.setAntialias(SWT.ON); + gc.setBackground(backgroundColor); + gc.fillRectangle(0, 0, w, h); + + final Path curveShape = new Path(display); + curveShape.moveTo(0, h * .6f); + curveShape.cubicTo(w * .167f, h * 1.2f, w * .667f, h * -.5f, w, h * .75f); + curveShape.lineTo(w, h); + curveShape.lineTo(0, h); + curveShape.lineTo(0, h * .8f); + curveShape.close(); + + final Pattern pattern = new Pattern(display, 0, 0, 1, h * 1.2f, gradientColor1, gradientColor2); + gc.setBackgroundPattern(pattern); + gc.fillPath(curveShape); + + final Font font = new Font(display, "Arial Bold", 30, SWT.NONE); + gc.setFont(font); + gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); + final Point textSize = gc.stringExtent(ResourceManager.getLabel(ResourceManager.LOGIN)); + gc.drawString(ResourceManager.getLabel(ResourceManager.LOGIN), (int) (w * .05f), (h - textSize.y) / 2, true); + + font.dispose(); + curveShape.dispose(); + pattern.dispose(); + backgroundColor.dispose(); + gradientColor1.dispose(); + gradientColor2.dispose(); + gc.dispose(); + return img; + } + + /** + * Build the description part of the box + */ + private void buildDescription() { + final Label label = new Label(shell, SWT.NONE); + final GridData gridData = new GridData(GridData.FILL, GridData.BEGINNING, true, false, 4, 1); + gridData.verticalIndent = 5; + gridData.horizontalIndent = 5; + label.setLayoutData(gridData); + final Font bold = SWTGraphicUtil.buildFontFrom(label, SWT.BOLD); + label.setFont(bold); + SWTGraphicUtil.addDisposer(label, bold); + + if (description == null || description.trim().equals("")) { + label.setText(" "); + } else { + label.setText(description); + } + } + + /** + * Build the login part of the box + */ + private void buildLogin() { + final Label label = new Label(shell, SWT.NONE); + final GridData gridData = new GridData(GridData.END, GridData.END, false, false, 1, 1); + gridData.horizontalIndent = 35; + gridData.verticalIndent = 15; + label.setLayoutData(gridData); + label.setText(ResourceManager.getLabel(ResourceManager.NAME)); + + if (autorizedLogin != null && !autorizedLogin.isEmpty()) { + // Combo + buildLoginCombo(); + } else { + // Text + buildLoginText(); + } + + } + + private void buildLoginCombo() { + final Combo combo = new Combo(shell, SWT.BORDER | SWT.READ_ONLY); + + combo.setLayoutData(new GridData(GridData.FILL, GridData.END, true, false, 3, 1)); + for (final String loginToAdd : autorizedLogin) { + combo.add(loginToAdd); + } + combo.setText(login == null ? "" : login); + combo.setFocus(); + combo.addListener(SWT.Modify, e -> { + login = combo.getText(); + changeButtonOkState(); + }); + } + + private void buildLoginText() { + final Text text = new Text(shell, SWT.BORDER); + text.setText(login == null ? "" : login); + text.setLayoutData(new GridData(GridData.FILL, GridData.END, true, false, 3, 1)); + text.setFocus(); + text.addListener(SWT.Modify, e -> { + login = text.getText(); + changeButtonOkState(); + }); + } + + /** + * Build the password part of the box + */ + private void buildPassword() { + final Label label = new Label(shell, SWT.NONE); + final GridData gridData = new GridData(GridData.END, GridData.CENTER, false, false, 1, 1); + gridData.horizontalIndent = 35; + label.setLayoutData(gridData); + label.setText(ResourceManager.getLabel(ResourceManager.PASSWORD)); + + final Text text = new Text(shell, SWT.PASSWORD | SWT.BORDER); + text.setText(password == null ? "" : password); + text.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1)); + text.addListener(SWT.Modify, e -> { + password = text.getText(); + changeButtonOkState(); + }); + } + + /** + * Enable/Disable the button when the login and the password is empty (or + * not) + */ + private void changeButtonOkState() { + final boolean loginEntered = login != null && !login.trim().equals(""); + final boolean passwordEntered = password != null && !password.trim().equals(""); + buttonOk.setEnabled(loginEntered && passwordEntered); + } + + /** + * Build the "remember password" part of the box + */ + private void buildRememberPassword() { + final Button checkbox = new Button(shell, SWT.CHECK); + final GridData gridData = new GridData(GridData.BEGINNING, GridData.CENTER, true, false, 4, 1); + gridData.horizontalIndent = 35; + checkbox.setLayoutData(gridData); + checkbox.setText(ResourceManager.getLabel(ResourceManager.REMEMBER_PASSWORD)); + checkbox.setSelection(rememberPassword); + } + + /** + * Build the buttons + */ + private void buildButtons() { + buildOkButton(); + buildCancelButton(); + } + + private void buildOkButton() { + buttonOk = new Button(shell, SWT.PUSH); + final GridData gdOk = new GridData(GridData.END, GridData.CENTER, true, false, 3, 1); + gdOk.verticalIndent = 60; + gdOk.minimumWidth = 80; + buttonOk.setLayoutData(gdOk); + buttonOk.setText(ResourceManager.getLabel(ResourceManager.OK)); + buttonOk.setEnabled(false); + + buttonOk.addListener(SWT.Selection, event -> { + try { + verifier.authenticate(login, password); + returnedValue = true; + shell.dispose(); + } catch (final Exception e) { + Dialog.error(ResourceManager.getLabel(ResourceManager.LOGIN_FAILED), e.getMessage()); + for (final Control control : shell.getChildren()) { + if (control instanceof Text || control instanceof Combo) { + control.setFocus(); + break; + } + } + } + }); + } + + private void buildCancelButton() { + final Button buttonCancel = new Button(shell, SWT.PUSH); + final GridData gdCancel = new GridData(GridData.FILL, GridData.CENTER, false, false); + gdCancel.widthHint = 80; + gdCancel.verticalIndent = 60; + buttonCancel.setLayoutData(gdCancel); + buttonCancel.setText(ResourceManager.getLabel(ResourceManager.CANCEL)); + buttonCancel.addListener(SWT.Selection, event -> { + returnedValue = false; + shell.dispose(); + }); + } + + /** + * Open the shell + */ + private void openShell() { + shell.setDefaultButton(buttonOk); + shell.pack(); + shell.open(); + SWTGraphicUtil.centerShell(shell); + while (!shell.isDisposed()) { + if (!shell.getDisplay().readAndDispatch()) { + shell.getDisplay().sleep(); + } + } + } + + // ------------- Getters & Setters + /** + * @return the image + */ + public Image getImage() { + return image; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @return the login + */ + public String getLogin() { + return login == null ? null : login.trim(); + } + + /** + * @return the password + */ + public String getPassword() { + return password == null ? null : password.trim(); + } + + /** + * @return the list of autorized logins + */ + public List getAutorizedLogin() { + return autorizedLogin; + } + + /** + * @return true if the checkbox "remember the password" is + * displayed, false otherwise + */ + public boolean isDisplayRememberPassword() { + return displayRememberPassword; + } + + /** + * @return true if the checkbox "remember the password" is + * checked, false otherwise + */ + public boolean isRememberPassword() { + return rememberPassword; + } + + /** + * @return the verifier associated to this box + */ + public LoginDialogVerifier getVerifier() { + return verifier; + } + + /** + * @param image the image to set + */ + public void setImage(final Image image) { + this.image = image; + } + + /** + * @param description the description to set + */ + public void setDescription(final String description) { + this.description = description; + } + + /** + * @param login the login to set + */ + public void setLogin(final String login) { + this.login = login; + } + + /** + * @param password the password to set + */ + public void setPassword(final String password) { + this.password = password; + } + + /** + * @param autorizedLogin the list of autorized logins to set + */ + public void setAutorizedLogin(final List autorizedLogin) { + this.autorizedLogin = autorizedLogin; + } + + /** + * @param autorizedLogin the list of autorized logins to set + */ + public void setAutorizedLogin(final String... autorizedLogin) { + this.autorizedLogin = Arrays.asList(autorizedLogin); + } + + /** + * @param displayRememberPassword if true, the checkbox + * "remember the password" is displayed + */ + public void setDisplayRememberPassword(final boolean displayRememberPassword) { + this.displayRememberPassword = displayRememberPassword; + } + + /** + * @param rememberPassword if true, the checkbox + * "remember the password" is selected + */ + public void setRememberPassword(final boolean rememberPassword) { + this.rememberPassword = rememberPassword; + } + + /** + * @param verifier the verifier to set + */ + public void setVerifier(final LoginDialogVerifier verifier) { + this.verifier = verifier; + } + +} diff --git a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/src/org/eclipse/nebula/widgets/opal/loginDialog/LoginDialogVerifier.java b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/src/org/eclipse/nebula/widgets/opal/loginDialog/LoginDialogVerifier.java index b4ddcaa8a..153356c77 100644 --- a/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/src/org/eclipse/nebula/widgets/opal/loginDialog/LoginDialogVerifier.java +++ b/widgets/opal/logindialog/org.eclipse.nebula.widgets.opal.logindialog/src/org/eclipse/nebula/widgets/opal/loginDialog/LoginDialogVerifier.java @@ -1,33 +1,33 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.loginDialog; - -/** - * This interface describes a verifier for the LoginDialogWidget - */ -@FunctionalInterface -public interface LoginDialogVerifier { - /** - * Check if the couple login/password is correct - * - * @param login login entered by the user - * @param password password entered by the user - * @throws Exception if the couple login/password is wrong. The description - * of the exception contains the error message that is gonna be - * displayed. For instance, an implementation can throw the - * exception * - * new Exception("Unable to connect to the LDAP Server") - */ - void authenticate(String login, String password) throws Exception; -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.loginDialog; + +/** + * This interface describes a verifier for the LoginDialogWidget + */ +@FunctionalInterface +public interface LoginDialogVerifier { + /** + * Check if the couple login/password is correct + * + * @param login login entered by the user + * @param password password entered by the user + * @throws Exception if the couple login/password is wrong. The description + * of the exception contains the error message that is gonna be + * displayed. For instance, an implementation can throw the + * exception * + * new Exception("Unable to connect to the LDAP Server") + */ + void authenticate(String login, String password) throws Exception; +} diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/.project b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/.project index a7457b523..4c2560fcc 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/.project +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.opal.multichoice.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.opal.multichoice.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/build.properties b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/build.properties +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/feature.properties b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/feature.properties +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.classpath b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.classpath +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.project b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.project index 4bd2f6222..660b17015 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.project +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.multichoice.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.multichoice.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/META-INF/MANIFEST.MF b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/META-INF/MANIFEST.MF index fb4e2a7c1..e9fddeeea 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/META-INF/MANIFEST.MF +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Multichoice Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.multichoice.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.multichoice;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.multichoice.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Multichoice Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.multichoice.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.multichoice;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.multichoice.snippets diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/build.properties b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/build.properties +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/src/org/eclipse/nebula/widgets/opal/multichoice/snippets/Country.java b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/src/org/eclipse/nebula/widgets/opal/multichoice/snippets/Country.java index 65e20135a..d9725e758 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/src/org/eclipse/nebula/widgets/opal/multichoice/snippets/Country.java +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/src/org/eclipse/nebula/widgets/opal/multichoice/snippets/Country.java @@ -1,117 +1,117 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Laurent CARON (laurent.caron@gmail.com) - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.multichoice.snippets; - -/** - * This is a POJO that represents a country - */ -public class Country { - private String name; - private int population; - private String code; - - public Country(final String name, final int population) { - this.name = name; - this.population = population; - } - - public Country(final String name, final String code) { - this.name = name; - this.code = code; - } - - public String getName() { - return this.name; - } - - public void setName(final String name) { - this.name = name; - } - - public int getPopulation() { - return this.population; - } - - public void setPopulation(final int population) { - this.population = population; - } - - /** - * @return the code - */ - public String getCode() { - return this.code; - } - - /** - * @param code the code to set - */ - public void setCode(final String code) { - this.code = code; - } - - /** - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (this.code == null ? 0 : this.code.hashCode()); - result = prime * result + (this.name == null ? 0 : this.name.hashCode()); - result = prime * result + this.population; - return result; - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Country other = (Country) obj; - if (this.code == null) { - if (other.code != null) { - return false; - } - } else if (!this.code.equals(other.code)) { - return false; - } - if (this.name == null) { - if (other.name != null) { - return false; - } - } else if (!this.name.equals(other.name)) { - return false; - } - if (this.population != other.population) { - return false; - } - return true; - } - - @Override - public String toString() { - return this.name; - } - -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent CARON (laurent.caron@gmail.com) - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.multichoice.snippets; + +/** + * This is a POJO that represents a country + */ +public class Country { + private String name; + private int population; + private String code; + + public Country(final String name, final int population) { + this.name = name; + this.population = population; + } + + public Country(final String name, final String code) { + this.name = name; + this.code = code; + } + + public String getName() { + return this.name; + } + + public void setName(final String name) { + this.name = name; + } + + public int getPopulation() { + return this.population; + } + + public void setPopulation(final int population) { + this.population = population; + } + + /** + * @return the code + */ + public String getCode() { + return this.code; + } + + /** + * @param code the code to set + */ + public void setCode(final String code) { + this.code = code; + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (this.code == null ? 0 : this.code.hashCode()); + result = prime * result + (this.name == null ? 0 : this.name.hashCode()); + result = prime * result + this.population; + return result; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Country other = (Country) obj; + if (this.code == null) { + if (other.code != null) { + return false; + } + } else if (!this.code.equals(other.code)) { + return false; + } + if (this.name == null) { + if (other.name != null) { + return false; + } + } else if (!this.name.equals(other.name)) { + return false; + } + if (this.population != other.population) { + return false; + } + return true; + } + + @Override + public String toString() { + return this.name; + } + +} diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/src/org/eclipse/nebula/widgets/opal/multichoice/snippets/MultiChoiceSnippet.java b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/src/org/eclipse/nebula/widgets/opal/multichoice/snippets/MultiChoiceSnippet.java index ca72ecadb..e82177b4a 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/src/org/eclipse/nebula/widgets/opal/multichoice/snippets/MultiChoiceSnippet.java +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice.snippets/src/org/eclipse/nebula/widgets/opal/multichoice/snippets/MultiChoiceSnippet.java @@ -1,252 +1,252 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron@gmail.com) - *******************************************************************************/ -package org.eclipse.nebula.widgets.opal.multichoice.snippets; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.nebula.widgets.opal.multichoice.MultiChoice; -import org.eclipse.nebula.widgets.opal.multichoice.MultiChoiceSelectionListener; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; - -/** - * A simple snippet for the MultiChoice Widget - */ -public class MultiChoiceSnippet { - - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(4, false)); - shell.setText("MultiChoice Example"); - - // Data - final String[] euroZone = new String[] { "Austria", "Belgium", "Cyprus", "Estonia", "Finland", "France", "Germany", "Greece", "Ireland", "Italy", "Luxembourg", "Malta", "Netherlands", "Portugal", "Slovakia", "Slovenia", "Spain" }; - - final List membersOfEuropeanUnion = new ArrayList<>(); - membersOfEuropeanUnion.add(new Country("Austria", 8372930)); - membersOfEuropeanUnion.add(new Country("Belgium", 10827519)); - membersOfEuropeanUnion.add(new Country("Bulgaria", 7576751)); - membersOfEuropeanUnion.add(new Country("Cyprus", 801851)); - membersOfEuropeanUnion.add(new Country("Czech Republic", 10512397)); - membersOfEuropeanUnion.add(new Country("Denmark", 5547088)); - membersOfEuropeanUnion.add(new Country("Estonia", 1340274)); - membersOfEuropeanUnion.add(new Country("Finland", 5530575)); - membersOfEuropeanUnion.add(new Country("France", 64709480)); - membersOfEuropeanUnion.add(new Country("Germany", 81757595)); - membersOfEuropeanUnion.add(new Country("Greece", 11125179)); - membersOfEuropeanUnion.add(new Country("Hungary", 10013628)); - membersOfEuropeanUnion.add(new Country("Ireland", 4450878)); - membersOfEuropeanUnion.add(new Country("Italy", 60397353)); - membersOfEuropeanUnion.add(new Country("Latvia", 2248961)); - membersOfEuropeanUnion.add(new Country("Lithuania", 3329227)); - membersOfEuropeanUnion.add(new Country("Luxembourg", 502207)); - membersOfEuropeanUnion.add(new Country("Malta", 416333)); - membersOfEuropeanUnion.add(new Country("Netherlands", 16576800)); - membersOfEuropeanUnion.add(new Country("Poland", 38163895)); - membersOfEuropeanUnion.add(new Country("Portugal", 11317192)); - membersOfEuropeanUnion.add(new Country("Romania", 21466174)); - membersOfEuropeanUnion.add(new Country("Slovakia", 5424057)); - membersOfEuropeanUnion.add(new Country("Slovenia", 2054119)); - membersOfEuropeanUnion.add(new Country("Spain", 46087170)); - membersOfEuropeanUnion.add(new Country("Sweden", 9347899)); - membersOfEuropeanUnion.add(new Country("United Kingdom", 62041708)); - - final List membersOfEUSelectAll = new ArrayList<>(); - membersOfEUSelectAll.addAll(membersOfEuropeanUnion); - membersOfEUSelectAll.add(new Country("Select All", -1)); - - final List countryCodes = new ArrayList<>(); - countryCodes.add(new Country("France", "FR")); - countryCodes.add(new Country("United states", "US")); - countryCodes.add(new Country("United Kingdom", "UK")); - countryCodes.add(new Country("Germany", "DE")); - countryCodes.add(new Country("Belgium", "BE")); - countryCodes.add(new Country("Netherland", "NL")); - countryCodes.add(new Country("Italy", "IT")); - countryCodes.add(new Country("Spain", "ES")); - countryCodes.add(new Country("Portugal", "PT")); - - // Draw the window - drawLabel(shell, "Simple Multichoice :"); - final MultiChoice mcSimple = new MultiChoice<>(shell, SWT.READ_ONLY); - mcSimple.setEditable(false); - final GridData gridData = new GridData(GridData.FILL, GridData.BEGINNING, true, true); - gridData.widthHint = 200; - mcSimple.setLayoutData(gridData); - mcSimple.addAll(euroZone); - addButons(mcSimple); - - drawLabel(shell, "Simple Multichoice with select/deselect all links:"); - final MultiChoice mcSelectDeselectAll = new MultiChoice<>(shell, SWT.READ_ONLY); - mcSelectDeselectAll.setEditable(false); - mcSelectDeselectAll.setShowSelectUnselectAll(true); - final GridData gridDataSelectDeselectAll = new GridData(GridData.FILL, GridData.BEGINNING, true, true); - gridDataSelectDeselectAll.widthHint = 200; - mcSelectDeselectAll.setLayoutData(gridDataSelectDeselectAll); - mcSelectDeselectAll.addAll(euroZone); - addButons(mcSelectDeselectAll); - - drawLabel(shell, "Multichoice with beans :"); - final MultiChoice mcBeans = new MultiChoice<>(shell, SWT.READ_ONLY); - mcBeans.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); - mcBeans.addAll(membersOfEuropeanUnion); - mcBeans.setText("Non european country"); - addButons(mcBeans); - - drawLabel(shell, "Selection listener :"); - final MultiChoice mcSL = new MultiChoice<>(shell, SWT.READ_ONLY); - mcSL.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); - mcSL.setSelectionListener(new MultiChoiceSelectionListener(mcSL) { - - @Override - public void handle(final MultiChoice parent, final Country receiver, final boolean selection, final Shell popup) { - if ("Select All".equals(receiver.toString())) { - if (selection) { - parent.deselectAll(); - parent.selectAll(); - } else { - parent.deselectAll(); - } - popup.setVisible(false); - } - - } - }); - mcSL.addAll(membersOfEUSelectAll); - addButons(mcSL); - - drawLabel(shell, "3 columns :"); - final MultiChoice mc3Columns = new MultiChoice<>(shell, SWT.READ_ONLY); - mc3Columns.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); - mc3Columns.addAll(euroZone); - mc3Columns.setNumberOfColumns(3); - addButons(mc3Columns); - - drawLabel(shell, "Other separator :"); - final MultiChoice mcOtherSeparator = new MultiChoice<>(shell, SWT.READ_ONLY); - mcOtherSeparator.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); - mcOtherSeparator.addAll(euroZone); - mcOtherSeparator.setSeparator(" - "); - addButons(mcOtherSeparator); - - drawLabel(shell, "Modifiable combo :"); - final MultiChoice mcModify = new MultiChoice<>(shell, SWT.NONE); - mcModify.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); - mcModify.setLabelProvider(element -> { - if (element == null || !(element instanceof Country)) { - return ""; - } - return ((Country) element).getCode(); - }); - mcModify.addAll(countryCodes); - addButons(mcModify); - - drawLabel(shell, "Lot of data :"); - final List data = new ArrayList<>(); - for (int i = 0; i < 1000; i++) { - data.add("Data #" + i); - } - final MultiChoice mcLotOfData = new MultiChoice<>(shell, SWT.NONE); - mcLotOfData.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); - mcLotOfData.setLabelProvider(element -> { - if (element == null) { - return ""; - } - return (String) element; - }); - mcLotOfData.addAll(data); - addButons(mcLotOfData); - - drawLabel(shell, "Non Editable Multichoice :"); - final MultiChoice mcNotEditable = new MultiChoice<>(shell, SWT.READ_ONLY); - final GridData gridDataNotEditable = new GridData(GridData.FILL, GridData.BEGINNING, true, true); - gridDataNotEditable.widthHint = 200; - mcNotEditable.setLayoutData(gridDataNotEditable); - mcNotEditable.addAll(euroZone); - mcNotEditable.setEditable(false); - addButons(mcNotEditable); - - - drawLabel(shell, "Not Enabled Multichoice :"); - final MultiChoice mcNotEnabled = new MultiChoice<>(shell, SWT.READ_ONLY); - final GridData gridDataNotEnabled = new GridData(GridData.FILL, GridData.BEGINNING, true, true); - gridDataNotEnabled.widthHint = 200; - mcNotEnabled.setLayoutData(gridDataNotEnabled); - mcNotEnabled.addAll(euroZone); - mcNotEnabled.setEditable(false); - addButons(mcNotEnabled); - - // display the shell... - shell.open(); - shell.pack(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } - - private static void drawLabel(final Shell shell, final String text) { - final Label label = new Label(shell, SWT.NONE); - label.setText(text); - label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); - } - - private static void addButons(final MultiChoice mc) { - final Button buttonShowSelection = new Button(mc.getParent(), SWT.PUSH); - buttonShowSelection.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); - buttonShowSelection.setText("Show selection"); - buttonShowSelection.addListener(SWT.Selection, e -> { - final Iterator it = mc.getSelection().iterator(); - final StringBuilder sb = new StringBuilder(); - while (it.hasNext()) { - sb.append(it.next().toString()); - if (it.hasNext()) { - sb.append(", "); - } - } - final MessageBox mb = new MessageBox(mc.getShell(), SWT.OK); - mb.setMessage(sb.toString()); - mb.open(); - }); - - final Button buttonShowSelectedIndex = new Button(mc.getParent(), SWT.PUSH); - buttonShowSelectedIndex.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); - buttonShowSelectedIndex.setText("Show selected index"); - buttonShowSelectedIndex.addListener(SWT.Selection, e -> { - final StringBuilder sb = new StringBuilder(); - final int[] selectedIndex = mc.getSelectedIndex(); - if (selectedIndex.length > 0) { - sb.append(selectedIndex[0]); - for (int i = 1; i < selectedIndex.length; i++) { - sb.append(","); - sb.append(selectedIndex[i]); - } - } else { - sb.append("Empty"); - } - final MessageBox mb = new MessageBox(mc.getShell(), SWT.OK); - mb.setMessage(sb.toString()); - mb.open(); - }); - } -} +/******************************************************************************* + * Copyright (c) 2011 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron@gmail.com) + *******************************************************************************/ +package org.eclipse.nebula.widgets.opal.multichoice.snippets; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.nebula.widgets.opal.multichoice.MultiChoice; +import org.eclipse.nebula.widgets.opal.multichoice.MultiChoiceSelectionListener; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; + +/** + * A simple snippet for the MultiChoice Widget + */ +public class MultiChoiceSnippet { + + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(4, false)); + shell.setText("MultiChoice Example"); + + // Data + final String[] euroZone = new String[] { "Austria", "Belgium", "Cyprus", "Estonia", "Finland", "France", "Germany", "Greece", "Ireland", "Italy", "Luxembourg", "Malta", "Netherlands", "Portugal", "Slovakia", "Slovenia", "Spain" }; + + final List membersOfEuropeanUnion = new ArrayList<>(); + membersOfEuropeanUnion.add(new Country("Austria", 8372930)); + membersOfEuropeanUnion.add(new Country("Belgium", 10827519)); + membersOfEuropeanUnion.add(new Country("Bulgaria", 7576751)); + membersOfEuropeanUnion.add(new Country("Cyprus", 801851)); + membersOfEuropeanUnion.add(new Country("Czech Republic", 10512397)); + membersOfEuropeanUnion.add(new Country("Denmark", 5547088)); + membersOfEuropeanUnion.add(new Country("Estonia", 1340274)); + membersOfEuropeanUnion.add(new Country("Finland", 5530575)); + membersOfEuropeanUnion.add(new Country("France", 64709480)); + membersOfEuropeanUnion.add(new Country("Germany", 81757595)); + membersOfEuropeanUnion.add(new Country("Greece", 11125179)); + membersOfEuropeanUnion.add(new Country("Hungary", 10013628)); + membersOfEuropeanUnion.add(new Country("Ireland", 4450878)); + membersOfEuropeanUnion.add(new Country("Italy", 60397353)); + membersOfEuropeanUnion.add(new Country("Latvia", 2248961)); + membersOfEuropeanUnion.add(new Country("Lithuania", 3329227)); + membersOfEuropeanUnion.add(new Country("Luxembourg", 502207)); + membersOfEuropeanUnion.add(new Country("Malta", 416333)); + membersOfEuropeanUnion.add(new Country("Netherlands", 16576800)); + membersOfEuropeanUnion.add(new Country("Poland", 38163895)); + membersOfEuropeanUnion.add(new Country("Portugal", 11317192)); + membersOfEuropeanUnion.add(new Country("Romania", 21466174)); + membersOfEuropeanUnion.add(new Country("Slovakia", 5424057)); + membersOfEuropeanUnion.add(new Country("Slovenia", 2054119)); + membersOfEuropeanUnion.add(new Country("Spain", 46087170)); + membersOfEuropeanUnion.add(new Country("Sweden", 9347899)); + membersOfEuropeanUnion.add(new Country("United Kingdom", 62041708)); + + final List membersOfEUSelectAll = new ArrayList<>(); + membersOfEUSelectAll.addAll(membersOfEuropeanUnion); + membersOfEUSelectAll.add(new Country("Select All", -1)); + + final List countryCodes = new ArrayList<>(); + countryCodes.add(new Country("France", "FR")); + countryCodes.add(new Country("United states", "US")); + countryCodes.add(new Country("United Kingdom", "UK")); + countryCodes.add(new Country("Germany", "DE")); + countryCodes.add(new Country("Belgium", "BE")); + countryCodes.add(new Country("Netherland", "NL")); + countryCodes.add(new Country("Italy", "IT")); + countryCodes.add(new Country("Spain", "ES")); + countryCodes.add(new Country("Portugal", "PT")); + + // Draw the window + drawLabel(shell, "Simple Multichoice :"); + final MultiChoice mcSimple = new MultiChoice<>(shell, SWT.READ_ONLY); + mcSimple.setEditable(false); + final GridData gridData = new GridData(GridData.FILL, GridData.BEGINNING, true, true); + gridData.widthHint = 200; + mcSimple.setLayoutData(gridData); + mcSimple.addAll(euroZone); + addButons(mcSimple); + + drawLabel(shell, "Simple Multichoice with select/deselect all links:"); + final MultiChoice mcSelectDeselectAll = new MultiChoice<>(shell, SWT.READ_ONLY); + mcSelectDeselectAll.setEditable(false); + mcSelectDeselectAll.setShowSelectUnselectAll(true); + final GridData gridDataSelectDeselectAll = new GridData(GridData.FILL, GridData.BEGINNING, true, true); + gridDataSelectDeselectAll.widthHint = 200; + mcSelectDeselectAll.setLayoutData(gridDataSelectDeselectAll); + mcSelectDeselectAll.addAll(euroZone); + addButons(mcSelectDeselectAll); + + drawLabel(shell, "Multichoice with beans :"); + final MultiChoice mcBeans = new MultiChoice<>(shell, SWT.READ_ONLY); + mcBeans.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); + mcBeans.addAll(membersOfEuropeanUnion); + mcBeans.setText("Non european country"); + addButons(mcBeans); + + drawLabel(shell, "Selection listener :"); + final MultiChoice mcSL = new MultiChoice<>(shell, SWT.READ_ONLY); + mcSL.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); + mcSL.setSelectionListener(new MultiChoiceSelectionListener(mcSL) { + + @Override + public void handle(final MultiChoice parent, final Country receiver, final boolean selection, final Shell popup) { + if ("Select All".equals(receiver.toString())) { + if (selection) { + parent.deselectAll(); + parent.selectAll(); + } else { + parent.deselectAll(); + } + popup.setVisible(false); + } + + } + }); + mcSL.addAll(membersOfEUSelectAll); + addButons(mcSL); + + drawLabel(shell, "3 columns :"); + final MultiChoice mc3Columns = new MultiChoice<>(shell, SWT.READ_ONLY); + mc3Columns.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); + mc3Columns.addAll(euroZone); + mc3Columns.setNumberOfColumns(3); + addButons(mc3Columns); + + drawLabel(shell, "Other separator :"); + final MultiChoice mcOtherSeparator = new MultiChoice<>(shell, SWT.READ_ONLY); + mcOtherSeparator.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); + mcOtherSeparator.addAll(euroZone); + mcOtherSeparator.setSeparator(" - "); + addButons(mcOtherSeparator); + + drawLabel(shell, "Modifiable combo :"); + final MultiChoice mcModify = new MultiChoice<>(shell, SWT.NONE); + mcModify.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); + mcModify.setLabelProvider(element -> { + if (element == null || !(element instanceof Country)) { + return ""; + } + return ((Country) element).getCode(); + }); + mcModify.addAll(countryCodes); + addButons(mcModify); + + drawLabel(shell, "Lot of data :"); + final List data = new ArrayList<>(); + for (int i = 0; i < 1000; i++) { + data.add("Data #" + i); + } + final MultiChoice mcLotOfData = new MultiChoice<>(shell, SWT.NONE); + mcLotOfData.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, true)); + mcLotOfData.setLabelProvider(element -> { + if (element == null) { + return ""; + } + return (String) element; + }); + mcLotOfData.addAll(data); + addButons(mcLotOfData); + + drawLabel(shell, "Non Editable Multichoice :"); + final MultiChoice mcNotEditable = new MultiChoice<>(shell, SWT.READ_ONLY); + final GridData gridDataNotEditable = new GridData(GridData.FILL, GridData.BEGINNING, true, true); + gridDataNotEditable.widthHint = 200; + mcNotEditable.setLayoutData(gridDataNotEditable); + mcNotEditable.addAll(euroZone); + mcNotEditable.setEditable(false); + addButons(mcNotEditable); + + + drawLabel(shell, "Not Enabled Multichoice :"); + final MultiChoice mcNotEnabled = new MultiChoice<>(shell, SWT.READ_ONLY); + final GridData gridDataNotEnabled = new GridData(GridData.FILL, GridData.BEGINNING, true, true); + gridDataNotEnabled.widthHint = 200; + mcNotEnabled.setLayoutData(gridDataNotEnabled); + mcNotEnabled.addAll(euroZone); + mcNotEnabled.setEditable(false); + addButons(mcNotEnabled); + + // display the shell... + shell.open(); + shell.pack(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } + + private static void drawLabel(final Shell shell, final String text) { + final Label label = new Label(shell, SWT.NONE); + label.setText(text); + label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); + } + + private static void addButons(final MultiChoice mc) { + final Button buttonShowSelection = new Button(mc.getParent(), SWT.PUSH); + buttonShowSelection.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); + buttonShowSelection.setText("Show selection"); + buttonShowSelection.addListener(SWT.Selection, e -> { + final Iterator it = mc.getSelection().iterator(); + final StringBuilder sb = new StringBuilder(); + while (it.hasNext()) { + sb.append(it.next().toString()); + if (it.hasNext()) { + sb.append(", "); + } + } + final MessageBox mb = new MessageBox(mc.getShell(), SWT.OK); + mb.setMessage(sb.toString()); + mb.open(); + }); + + final Button buttonShowSelectedIndex = new Button(mc.getParent(), SWT.PUSH); + buttonShowSelectedIndex.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false)); + buttonShowSelectedIndex.setText("Show selected index"); + buttonShowSelectedIndex.addListener(SWT.Selection, e -> { + final StringBuilder sb = new StringBuilder(); + final int[] selectedIndex = mc.getSelectedIndex(); + if (selectedIndex.length > 0) { + sb.append(selectedIndex[0]); + for (int i = 1; i < selectedIndex.length; i++) { + sb.append(","); + sb.append(selectedIndex[i]); + } + } else { + sb.append("Empty"); + } + final MessageBox mb = new MessageBox(mc.getShell(), SWT.OK); + mb.setMessage(sb.toString()); + mb.open(); + }); + } +} diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.classpath b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.classpath +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.project b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.project index 89a0d95f8..584f8449c 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.project +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.opal.multichoice - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.opal.multichoice + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.settings/org.eclipse.jdt.core.prefs b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/META-INF/MANIFEST.MF b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/META-INF/MANIFEST.MF index 01160609d..5bbab2645 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/META-INF/MANIFEST.MF +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Opal Multichoice -Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.multichoice -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Export-Package: org.eclipse.nebula.widgets.opal.multichoice -Automatic-Module-Name: org.eclipse.nebula.widgets.opal.multichoice +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Opal Multichoice +Bundle-SymbolicName: org.eclipse.nebula.widgets.opal.multichoice +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Export-Package: org.eclipse.nebula.widgets.opal.multichoice +Automatic-Module-Name: org.eclipse.nebula.widgets.opal.multichoice diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/build.properties b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/build.properties +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/src/org/eclipse/nebula/widgets/opal/multichoice/MultiChoice.java b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/src/org/eclipse/nebula/widgets/opal/multichoice/MultiChoice.java index eb0afbaa3..9663c40d8 100644 --- a/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/src/org/eclipse/nebula/widgets/opal/multichoice/MultiChoice.java +++ b/widgets/opal/multichoice/org.eclipse.nebula.widgets.opal.multichoice/src/org/eclipse/nebula/widgets/opal/multichoice/MultiChoice.java @@ -1,1453 +1,1453 @@ -/******************************************************************************* - * Copyright (c) 2011 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron@gmail.com) - initial API and - * implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.opal.multichoice; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.nebula.widgets.opal.commons.ResourceManager; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Link; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * The MultiChoice class represents a selectable user interface object that - * combines a read-only text-field and a set of checkboxes. - * - *

- * Note that although this class is a subclass of Composite, it - * does not make sense to add children to it, or set a layout on it. - *

- *
- *
Styles: - *
NONE
- *
Events: - *
Selection
- *
- * - * @param Class of objects represented by this widget - */ -public class MultiChoice extends Composite { - - private Text text; - private Button arrow; - private Shell popup; - private ScrolledComposite scrolledComposite; - private Listener listener, filter; - private int numberOfColumns = 2; - private List elements; - private Set selection; - private List
{ - - /** default table style **/ - protected static final int DEFAULT_TABLE_STYLE = SWT.BORDER | SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL; - - /** the table viewer **/ - protected TableViewer viewer; - - /** the table style **/ - private final int tableStyle; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. Here default page size - * {@link PageableController#DEFAULT_PAGE_SIZE} and default table style - * SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL are used. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * - */ - public PageableTable(Composite parent, int style) { - this(parent, style, DEFAULT_TABLE_STYLE, - PageableController.DEFAULT_PAGE_SIZE); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param tableStyle - * the style of table to construct - * @param pageSize - * size of the page (number items displayed per page). - * - */ - public PageableTable(Composite parent, int style, int tableStyle, - int pageSize, IPageContentProvider pageContentProvider) { - this(parent, style, tableStyle, pageSize, pageContentProvider, - getDefaultPageRendererTopFactory(), - getDefaultPageRendererBottomFactory(), true); - } - - public PageableTable(Composite parent, int style, int tableStyle, - int pageSize) { - this(parent, style, tableStyle, pageSize, PageResultContentProvider - .getInstance(), getDefaultPageRendererTopFactory(), - getDefaultPageRendererBottomFactory(), true); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param tableStyle - * the style of table to construct - * @param pageSize - * size of the page (number items displayed per page). - * - * @param pageRendererTopFactory - * the page renderer factory used to create a SWT Composite on - * the top of the widget. Null if none Composite must be created. - * @param pageRendererBottomFactory - * the page renderer factory used to create a SWT Composite on - * the bottom of the widget. Null if none Composite must be - * created. - * - */ - public PageableTable(Composite parent, int style, int tableStyle, - int pageSize, IPageContentProvider pageContentProvider, - ICompositeRendererFactory pageRendererTopFactory, - ICompositeRendererFactory pageRendererBottomFactory) { - this(parent, style, tableStyle, pageSize, pageContentProvider, - pageRendererTopFactory, pageRendererBottomFactory, true); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param tableStyle - * the style of table to construct - * @param pageSize - * size of the page (number items displayed per page). - * - * @param pageRendererTopFactory - * the page renderer factory used to create a SWT Composite on - * the top of the widget. Null if none Composite must be created. - * @param pageRendererBottomFactory - * the page renderer factory used to create a SWT Composite on - * the bottom of the widget. Null if none Composite must be - * created. - * @param createUI - * true if the UI must be created and false otherwise. - * - */ - protected PageableTable(Composite parent, int style, int tableStyle, - int pageSize, IPageContentProvider pageContentProvider, - ICompositeRendererFactory pageRendererTopFactory, - ICompositeRendererFactory pageRendererBottomFactory, - boolean createUI) { - super(parent, style, pageSize, pageContentProvider, - pageRendererTopFactory, pageRendererBottomFactory, false); - this.tableStyle = tableStyle; - if (createUI) { - createUI(this); - } - } - - @Override - protected Table createWidget(Composite parent) { - Table table = createTable(parent); - this.viewer = new TableViewer(table); - return table; - } - - /** - * Create the table widget and layout it. - * - * @param parent - * @return - */ - protected Table createTable(Composite parent) { - Table table = createTable(parent, getTableStyle()); - table.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - return table; - } - - /** - * Returns the table style. - * - * @return - */ - protected int getTableStyle() { - return tableStyle; - } - - /** - * Returns the table viewer. - * - * @return - */ - public TableViewer getViewer() { - return viewer; - } - - /** - * Create a table. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of table to constr * @return - */ - protected Table createTable(Composite parent, int style) { - return new Table(parent, style); - } - - /** - * Returns the default page renderer factory for the top region. - * - * @return - */ - public static ICompositeRendererFactory getDefaultPageRendererTopFactory() { - return ResultAndNavigationPageLinksRendererFactory.getFactory(); - } - - /** - * Returns the default page renderer factory for the bottom region. - * - * @return - */ - public static ICompositeRendererFactory getDefaultPageRendererBottomFactory() { - return null; - } - - @Override - public void refreshPage() { - PageLoaderStrategyHelper.loadPageAndReplaceItems(getController(), - viewer, getPageLoader(), getPageContentProvider(), null); - } -} +/******************************************************************************* + * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Angelo ZERR - initial API and implementation + * Pascal Leclercq - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.pagination.table; + +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.nebula.widgets.pagination.AbstractPaginationWidget; +import org.eclipse.nebula.widgets.pagination.IPageContentProvider; +import org.eclipse.nebula.widgets.pagination.PageLoaderStrategyHelper; +import org.eclipse.nebula.widgets.pagination.PageableController; +import org.eclipse.nebula.widgets.pagination.collections.PageResultContentProvider; +import org.eclipse.nebula.widgets.pagination.renderers.ICompositeRendererFactory; +import org.eclipse.nebula.widgets.pagination.renderers.navigation.ResultAndNavigationPageLinksRendererFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; + +/** + * Abstract class SWT {@link Composite} which host a SWT {@link Table} linked to + * a pagination controller to display data with pagination. The + * {@link PageableTable#refreshPage()} must be implemented to load paginated + * data and update the total element of the controller. + * + * This composite is able to to add another {@link Composite} on the top and on + * the bottom of the table. For instance you can display navigation page links + * on the top of the table. + * + * @param + * the pagination controller. + */ +public class PageableTable extends AbstractPaginationWidget
{ + + /** default table style **/ + protected static final int DEFAULT_TABLE_STYLE = SWT.BORDER | SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL; + + /** the table viewer **/ + protected TableViewer viewer; + + /** the table style **/ + private final int tableStyle; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. Here default page size + * {@link PageableController#DEFAULT_PAGE_SIZE} and default table style + * SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL are used. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * + */ + public PageableTable(Composite parent, int style) { + this(parent, style, DEFAULT_TABLE_STYLE, + PageableController.DEFAULT_PAGE_SIZE); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param tableStyle + * the style of table to construct + * @param pageSize + * size of the page (number items displayed per page). + * + */ + public PageableTable(Composite parent, int style, int tableStyle, + int pageSize, IPageContentProvider pageContentProvider) { + this(parent, style, tableStyle, pageSize, pageContentProvider, + getDefaultPageRendererTopFactory(), + getDefaultPageRendererBottomFactory(), true); + } + + public PageableTable(Composite parent, int style, int tableStyle, + int pageSize) { + this(parent, style, tableStyle, pageSize, PageResultContentProvider + .getInstance(), getDefaultPageRendererTopFactory(), + getDefaultPageRendererBottomFactory(), true); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param tableStyle + * the style of table to construct + * @param pageSize + * size of the page (number items displayed per page). + * + * @param pageRendererTopFactory + * the page renderer factory used to create a SWT Composite on + * the top of the widget. Null if none Composite must be created. + * @param pageRendererBottomFactory + * the page renderer factory used to create a SWT Composite on + * the bottom of the widget. Null if none Composite must be + * created. + * + */ + public PageableTable(Composite parent, int style, int tableStyle, + int pageSize, IPageContentProvider pageContentProvider, + ICompositeRendererFactory pageRendererTopFactory, + ICompositeRendererFactory pageRendererBottomFactory) { + this(parent, style, tableStyle, pageSize, pageContentProvider, + pageRendererTopFactory, pageRendererBottomFactory, true); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param tableStyle + * the style of table to construct + * @param pageSize + * size of the page (number items displayed per page). + * + * @param pageRendererTopFactory + * the page renderer factory used to create a SWT Composite on + * the top of the widget. Null if none Composite must be created. + * @param pageRendererBottomFactory + * the page renderer factory used to create a SWT Composite on + * the bottom of the widget. Null if none Composite must be + * created. + * @param createUI + * true if the UI must be created and false otherwise. + * + */ + protected PageableTable(Composite parent, int style, int tableStyle, + int pageSize, IPageContentProvider pageContentProvider, + ICompositeRendererFactory pageRendererTopFactory, + ICompositeRendererFactory pageRendererBottomFactory, + boolean createUI) { + super(parent, style, pageSize, pageContentProvider, + pageRendererTopFactory, pageRendererBottomFactory, false); + this.tableStyle = tableStyle; + if (createUI) { + createUI(this); + } + } + + @Override + protected Table createWidget(Composite parent) { + Table table = createTable(parent); + this.viewer = new TableViewer(table); + return table; + } + + /** + * Create the table widget and layout it. + * + * @param parent + * @return + */ + protected Table createTable(Composite parent) { + Table table = createTable(parent, getTableStyle()); + table.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + return table; + } + + /** + * Returns the table style. + * + * @return + */ + protected int getTableStyle() { + return tableStyle; + } + + /** + * Returns the table viewer. + * + * @return + */ + public TableViewer getViewer() { + return viewer; + } + + /** + * Create a table. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of table to constr * @return + */ + protected Table createTable(Composite parent, int style) { + return new Table(parent, style); + } + + /** + * Returns the default page renderer factory for the top region. + * + * @return + */ + public static ICompositeRendererFactory getDefaultPageRendererTopFactory() { + return ResultAndNavigationPageLinksRendererFactory.getFactory(); + } + + /** + * Returns the default page renderer factory for the bottom region. + * + * @return + */ + public static ICompositeRendererFactory getDefaultPageRendererBottomFactory() { + return null; + } + + @Override + public void refreshPage() { + PageLoaderStrategyHelper.loadPageAndReplaceItems(getController(), + viewer, getPageLoader(), getPageContentProvider(), null); + } +} diff --git a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/table/SortTableColumnSelectionListener.java b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/table/SortTableColumnSelectionListener.java index ccf96fd42..3f294bb42 100644 --- a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/table/SortTableColumnSelectionListener.java +++ b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/table/SortTableColumnSelectionListener.java @@ -1,104 +1,104 @@ -/******************************************************************************* - * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Angelo ZERR - initial API and implementation - * Pascal Leclercq - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.pagination.table; - -import org.eclipse.nebula.widgets.pagination.AbstractSortColumnSelectionListener; -import org.eclipse.nebula.widgets.pagination.PageableController; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; - -/** - * - * {@link SelectionListener} implementation to sort a table column by using the - * attached pagination controller of the SWT {@link Table}. - * - */ -public class SortTableColumnSelectionListener extends - AbstractSortColumnSelectionListener { - - /** - * Constructor with property name and default sort (SWT.NONE). - * - * @param propertyName - * the sort property name. - */ - - public SortTableColumnSelectionListener(String propertyName) { - this(propertyName, SWT.NONE, null); - } - - /** - * Constructor with property name and default sort (SWT.NONE). - * - * @param propertyName - * the sort property name. - * @param controller - * the controller to update when sort is applied. - */ - public SortTableColumnSelectionListener(String propertyName, - PageableController controller) { - this(propertyName, SWT.NONE, controller); - } - - /** - * Constructor with property name and sort direction. - * - * @param propertyName - * the sort property name. - * @param sortDirection - * the sort direction {@link SWT.UP}, {@link SWT.DOWN}. - */ - public SortTableColumnSelectionListener(String propertyName, - int sortDirection) { - this(propertyName, sortDirection, null); - } - - /** - * Constructor with property name and sort direction. - * - * @param propertyName - * the sort property name. - * @param sortDirection - * the sort direction {@link SWT.UP}, {@link SWT.DOWN}. - * @param controller - * the controller to update when sort is applied. - */ - public SortTableColumnSelectionListener(String propertyName, - int sortDirection, PageableController controller) { - super(propertyName, sortDirection, controller); - } - - @Override - protected Table getParent(SelectionEvent e) { - // 1) Get table column which fire this selection event - TableColumn tableColumn = (TableColumn) e.getSource(); - // 2) Get the owner table - return tableColumn.getParent(); - } - - @Override - protected void sort(SelectionEvent e) { - // 1) Get table column which fire this selection event - TableColumn tableColumn = (TableColumn) e.getSource(); - // 2) Get the owner table - Table table = tableColumn.getParent(); - // 3) Modify the SWT Table sort - table.setSortColumn(tableColumn); - table.setSortDirection(getSortDirection()); - } -} +/******************************************************************************* + * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Angelo ZERR - initial API and implementation + * Pascal Leclercq - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.pagination.table; + +import org.eclipse.nebula.widgets.pagination.AbstractSortColumnSelectionListener; +import org.eclipse.nebula.widgets.pagination.PageableController; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; + +/** + * + * {@link SelectionListener} implementation to sort a table column by using the + * attached pagination controller of the SWT {@link Table}. + * + */ +public class SortTableColumnSelectionListener extends + AbstractSortColumnSelectionListener { + + /** + * Constructor with property name and default sort (SWT.NONE). + * + * @param propertyName + * the sort property name. + */ + + public SortTableColumnSelectionListener(String propertyName) { + this(propertyName, SWT.NONE, null); + } + + /** + * Constructor with property name and default sort (SWT.NONE). + * + * @param propertyName + * the sort property name. + * @param controller + * the controller to update when sort is applied. + */ + public SortTableColumnSelectionListener(String propertyName, + PageableController controller) { + this(propertyName, SWT.NONE, controller); + } + + /** + * Constructor with property name and sort direction. + * + * @param propertyName + * the sort property name. + * @param sortDirection + * the sort direction {@link SWT.UP}, {@link SWT.DOWN}. + */ + public SortTableColumnSelectionListener(String propertyName, + int sortDirection) { + this(propertyName, sortDirection, null); + } + + /** + * Constructor with property name and sort direction. + * + * @param propertyName + * the sort property name. + * @param sortDirection + * the sort direction {@link SWT.UP}, {@link SWT.DOWN}. + * @param controller + * the controller to update when sort is applied. + */ + public SortTableColumnSelectionListener(String propertyName, + int sortDirection, PageableController controller) { + super(propertyName, sortDirection, controller); + } + + @Override + protected Table getParent(SelectionEvent e) { + // 1) Get table column which fire this selection event + TableColumn tableColumn = (TableColumn) e.getSource(); + // 2) Get the owner table + return tableColumn.getParent(); + } + + @Override + protected void sort(SelectionEvent e) { + // 1) Get table column which fire this selection event + TableColumn tableColumn = (TableColumn) e.getSource(); + // 2) Get the owner table + Table table = tableColumn.getParent(); + // 3) Modify the SWT Table sort + table.setSortColumn(tableColumn); + table.setSortDirection(getSortDirection()); + } +} diff --git a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/table/forms/FormPageableTable.java b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/table/forms/FormPageableTable.java index 1467d5f44..d51f14f66 100644 --- a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/table/forms/FormPageableTable.java +++ b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/table/forms/FormPageableTable.java @@ -1,155 +1,155 @@ -/******************************************************************************* - * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Angelo ZERR - initial API and implementation - * Pascal Leclercq - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.pagination.table.forms; - -import org.eclipse.nebula.widgets.pagination.IPageContentProvider; -import org.eclipse.nebula.widgets.pagination.PageableController; -import org.eclipse.nebula.widgets.pagination.renderers.ICompositeRendererFactory; -import org.eclipse.nebula.widgets.pagination.table.PageableTable; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.ui.forms.widgets.FormToolkit; - -/** - * Implementation of the paginated SWT Forms Table {@link PageableTable}. - */ -public class FormPageableTable extends PageableTable { - - private final FormToolkit toolkit; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. Here default page size - * {@link PageableController#DEFAULT_PAGE_SIZE} and default tree style - * SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL are used. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param toolkit - * the {@link FormToolkit} used to create the SWT {@link Tree}. - */ - public FormPageableTable(Composite parent, int style, FormToolkit toolkit) { - this(parent, style, DEFAULT_TABLE_STYLE, toolkit, null); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param tableStyle - * the style of table to construct - * @param toolkit - * the {@link FormToolkit} used to create the SWT {@link Table}. - */ - public FormPageableTable(Composite parent, int style, int tableStyle, - FormToolkit toolkit, IPageContentProvider pageContentProvider, - ICompositeRendererFactory pageRendererTopFactory, - ICompositeRendererFactory pageRendererBottomFactory) { - this(parent, style, tableStyle, toolkit, - PageableController.DEFAULT_PAGE_SIZE, pageContentProvider, - pageRendererTopFactory, pageRendererBottomFactory); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param tableStyle - * the style of table to construct - * @param toolkit - * the {@link FormToolkit} used to create the SWT {@link Table}. - */ - public FormPageableTable(Composite parent, int style, int tableStyle, - FormToolkit toolkit, IPageContentProvider pageContentProvider) { - this(parent, style, tableStyle, toolkit, - PageableController.DEFAULT_PAGE_SIZE, pageContentProvider, - getDefaultPageRendererTopFactory(), - getDefaultPageRendererBottomFactory()); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param tableStyle - * the style of table to construct - * @param toolkit - * the {@link FormToolkit} used to create the SWT {@link Table}. - * @param pageSize - * size of the page (number items displayed per page). - * - * @param pageRendererTopFactory - * the page renderer factory used to create a SWT Composite on - * the top of the widget. Null if none Composite must be created. - * @param pageRendererBottomFactory - * the page renderer factory used to create a SWT Composite on - * the bottom of the widget. Null if none Composite must be - * created. - * - */ - public FormPageableTable(Composite parent, int style, int tableStyle, - FormToolkit toolkit, int pageSize, - IPageContentProvider pageContentProvider, - ICompositeRendererFactory pageRendererTopFactory, - ICompositeRendererFactory pageRendererBottomFactory) { - super(parent, style, tableStyle, pageSize, pageContentProvider, - pageRendererTopFactory, pageRendererBottomFactory, false); - this.toolkit = toolkit; - super.createUI(this); - toolkit.adapt(this); - } - - @Override - protected Table createTable(Composite parent, int style) { - return toolkit.createTable(parent, style); - } - - @Override - protected Composite createCompositeBottom(Composite parent) { - Composite bottom = super.createCompositeBottom(parent); - if (bottom != null) { - toolkit.adapt(bottom); - } - return bottom; - } - - @Override - protected Composite createCompositeTop(Composite parent) { - Composite top = super.createCompositeTop(parent); - if (top != null) { - toolkit.adapt(top); - } - return top; - } -} +/******************************************************************************* + * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Angelo ZERR - initial API and implementation + * Pascal Leclercq - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.pagination.table.forms; + +import org.eclipse.nebula.widgets.pagination.IPageContentProvider; +import org.eclipse.nebula.widgets.pagination.PageableController; +import org.eclipse.nebula.widgets.pagination.renderers.ICompositeRendererFactory; +import org.eclipse.nebula.widgets.pagination.table.PageableTable; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * Implementation of the paginated SWT Forms Table {@link PageableTable}. + */ +public class FormPageableTable extends PageableTable { + + private final FormToolkit toolkit; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. Here default page size + * {@link PageableController#DEFAULT_PAGE_SIZE} and default tree style + * SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL are used. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param toolkit + * the {@link FormToolkit} used to create the SWT {@link Tree}. + */ + public FormPageableTable(Composite parent, int style, FormToolkit toolkit) { + this(parent, style, DEFAULT_TABLE_STYLE, toolkit, null); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param tableStyle + * the style of table to construct + * @param toolkit + * the {@link FormToolkit} used to create the SWT {@link Table}. + */ + public FormPageableTable(Composite parent, int style, int tableStyle, + FormToolkit toolkit, IPageContentProvider pageContentProvider, + ICompositeRendererFactory pageRendererTopFactory, + ICompositeRendererFactory pageRendererBottomFactory) { + this(parent, style, tableStyle, toolkit, + PageableController.DEFAULT_PAGE_SIZE, pageContentProvider, + pageRendererTopFactory, pageRendererBottomFactory); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param tableStyle + * the style of table to construct + * @param toolkit + * the {@link FormToolkit} used to create the SWT {@link Table}. + */ + public FormPageableTable(Composite parent, int style, int tableStyle, + FormToolkit toolkit, IPageContentProvider pageContentProvider) { + this(parent, style, tableStyle, toolkit, + PageableController.DEFAULT_PAGE_SIZE, pageContentProvider, + getDefaultPageRendererTopFactory(), + getDefaultPageRendererBottomFactory()); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param tableStyle + * the style of table to construct + * @param toolkit + * the {@link FormToolkit} used to create the SWT {@link Table}. + * @param pageSize + * size of the page (number items displayed per page). + * + * @param pageRendererTopFactory + * the page renderer factory used to create a SWT Composite on + * the top of the widget. Null if none Composite must be created. + * @param pageRendererBottomFactory + * the page renderer factory used to create a SWT Composite on + * the bottom of the widget. Null if none Composite must be + * created. + * + */ + public FormPageableTable(Composite parent, int style, int tableStyle, + FormToolkit toolkit, int pageSize, + IPageContentProvider pageContentProvider, + ICompositeRendererFactory pageRendererTopFactory, + ICompositeRendererFactory pageRendererBottomFactory) { + super(parent, style, tableStyle, pageSize, pageContentProvider, + pageRendererTopFactory, pageRendererBottomFactory, false); + this.toolkit = toolkit; + super.createUI(this); + toolkit.adapt(this); + } + + @Override + protected Table createTable(Composite parent, int style) { + return toolkit.createTable(parent, style); + } + + @Override + protected Composite createCompositeBottom(Composite parent) { + Composite bottom = super.createCompositeBottom(parent); + if (bottom != null) { + toolkit.adapt(bottom); + } + return bottom; + } + + @Override + protected Composite createCompositeTop(Composite parent) { + Composite top = super.createCompositeTop(parent); + if (top != null) { + toolkit.adapt(top); + } + return top; + } +} diff --git a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/PageableTree.java b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/PageableTree.java index 49d7f95a5..f0231db97 100644 --- a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/PageableTree.java +++ b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/PageableTree.java @@ -1,243 +1,243 @@ -/******************************************************************************* - * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Angelo ZERR - initial API and implementation - * Pascal Leclercq - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.pagination.tree; - -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.nebula.widgets.pagination.AbstractPaginationWidget; -import org.eclipse.nebula.widgets.pagination.IPageContentProvider; -import org.eclipse.nebula.widgets.pagination.PageLoaderStrategyHelper; -import org.eclipse.nebula.widgets.pagination.PageableController; -import org.eclipse.nebula.widgets.pagination.collections.PageResultContentProvider; -import org.eclipse.nebula.widgets.pagination.renderers.ICompositeRendererFactory; -import org.eclipse.nebula.widgets.pagination.renderers.navigation.ResultAndNavigationPageLinksRendererFactory; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Tree; - -/** - * Abstract class SWT {@link Composite} which host a SWT {@link Tree} linked to - * a pagination controller to display data with pagination. The - * {@link PageableTree#refreshPage()} must be implemented to load paginated data - * and update the total element of the controller. - * - * This composite is able to to add another {@link Composite} on the top and on - * the bottom of the tree. For instance you can display navigation page links on - * the top of the tree. - * - * @param - * the pagination controller. - */ -public class PageableTree extends AbstractPaginationWidget { - - protected static final int DEFAULT_TREE_STYLE = SWT.BORDER | SWT.MULTI - | SWT.H_SCROLL | SWT.V_SCROLL; - - /** the tree viewer **/ - protected TreeViewer viewer; - - /** the tree style **/ - private final int treeStyle; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. Here default page size - * {@link PageableController#DEFAULT_PAGE_SIZE} and default tree style - * SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL are used. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * - */ - public PageableTree(Composite parent, int style) { - this(parent, style, DEFAULT_TREE_STYLE, - PageableController.DEFAULT_PAGE_SIZE); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. Here defaut page size is - * used. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param treeStyle - * the style of tree to construct - * @param pageSize - * size of the page (number items displayed per page). - * - */ - public PageableTree(Composite parent, int style, int treeStyle, - int pageSize, IPageContentProvider pageContentProvider) { - this(parent, style, treeStyle, pageSize, pageContentProvider, - getDefaultPageRendererTopFactory(), - getDefaultPageRendererBottomFactory(), true); - } - - public PageableTree(Composite parent, int style, int treeStyle, int pageSize) { - this(parent, style, treeStyle, pageSize, PageResultContentProvider - .getInstance(), getDefaultPageRendererTopFactory(), - getDefaultPageRendererBottomFactory(), true); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param treeStyle - * the style of tree to construct - * @param pageSize - * size of the page (number items displayed per page). - * - * @param pageRendererTopFactory - * the page renderer factory used to create a SWT Composite on - * the top of the widget. Null if none Composite must be created. - * @param pageRendererBottomFactory - * the page renderer factory used to create a SWT Composite on - * the bottom of the widget. Null if none Composite must be - * created. - * - */ - public PageableTree(Composite parent, int style, int treeStyle, - int pageSize, IPageContentProvider pageContentProvider, - ICompositeRendererFactory pageRendererTopFactory, - ICompositeRendererFactory pageRendererBottomFactory) { - this(parent, style, treeStyle, pageSize, pageContentProvider, - pageRendererTopFactory, pageRendererBottomFactory, true); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param treeStyle - * the style of tree to construct - * @param pageSize - * size of the page (number items displayed per page). - * - * @param pageRendererTopFactory - * the page renderer factory used to create a SWT Composite on - * the top of the widget. Null if none Composite must be created. - * @param pageRendererBottomFactory - * the page renderer factory used to create a SWT Composite on - * the bottom of the widget. Null if none Composite must be - * created. - * @param createUI - * true if the UI must be created and false otherwise. - * - */ - protected PageableTree(Composite parent, int style, int treeStyle, - int pageSize, IPageContentProvider pageContentProvider, - ICompositeRendererFactory pageRendererTopFactory, - ICompositeRendererFactory pageRendererBottomFactory, - boolean createUI) { - super(parent, style, pageSize, pageContentProvider, - pageRendererTopFactory, pageRendererBottomFactory, false); - this.treeStyle = treeStyle; - if (createUI) { - createUI(this); - } - } - - @Override - protected Tree createWidget(Composite parent) { - Tree tree = createTree(parent); - this.viewer = new TreeViewer(tree); - return tree; - } - - /** - * Create the tree widget and layout it. - * - * @param parent - * @return - */ - protected Tree createTree(Composite parent) { - Tree tree = createTree(parent, getTreeStyle()); - tree.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - return tree; - } - - /** - * Returns the tree style. - * - * @return - */ - protected int getTreeStyle() { - return treeStyle; - } - - /** - * Returns the tree viewer. - * - * @return - */ - public TreeViewer getViewer() { - return viewer; - } - - /** - * Create a tree. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of tree to constr * @return - */ - protected Tree createTree(Composite parent, int style) { - return new Tree(parent, style); - } - - /** - * Returns the default page renderer factory for the top region. - * - * @return - */ - public static ICompositeRendererFactory getDefaultPageRendererTopFactory() { - return ResultAndNavigationPageLinksRendererFactory.getFactory(); - } - - /** - * Returns the default page renderer factory for the bottom region. - * - * @return - */ - public static ICompositeRendererFactory getDefaultPageRendererBottomFactory() { - return null; - } - - @Override - public void refreshPage() { - PageLoaderStrategyHelper.loadPageAndReplaceItems(getController(), - viewer, getPageLoader(), getPageContentProvider(), null); - } -} +/******************************************************************************* + * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Angelo ZERR - initial API and implementation + * Pascal Leclercq - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.pagination.tree; + +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.nebula.widgets.pagination.AbstractPaginationWidget; +import org.eclipse.nebula.widgets.pagination.IPageContentProvider; +import org.eclipse.nebula.widgets.pagination.PageLoaderStrategyHelper; +import org.eclipse.nebula.widgets.pagination.PageableController; +import org.eclipse.nebula.widgets.pagination.collections.PageResultContentProvider; +import org.eclipse.nebula.widgets.pagination.renderers.ICompositeRendererFactory; +import org.eclipse.nebula.widgets.pagination.renderers.navigation.ResultAndNavigationPageLinksRendererFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; + +/** + * Abstract class SWT {@link Composite} which host a SWT {@link Tree} linked to + * a pagination controller to display data with pagination. The + * {@link PageableTree#refreshPage()} must be implemented to load paginated data + * and update the total element of the controller. + * + * This composite is able to to add another {@link Composite} on the top and on + * the bottom of the tree. For instance you can display navigation page links on + * the top of the tree. + * + * @param + * the pagination controller. + */ +public class PageableTree extends AbstractPaginationWidget { + + protected static final int DEFAULT_TREE_STYLE = SWT.BORDER | SWT.MULTI + | SWT.H_SCROLL | SWT.V_SCROLL; + + /** the tree viewer **/ + protected TreeViewer viewer; + + /** the tree style **/ + private final int treeStyle; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. Here default page size + * {@link PageableController#DEFAULT_PAGE_SIZE} and default tree style + * SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL are used. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * + */ + public PageableTree(Composite parent, int style) { + this(parent, style, DEFAULT_TREE_STYLE, + PageableController.DEFAULT_PAGE_SIZE); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. Here defaut page size is + * used. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param treeStyle + * the style of tree to construct + * @param pageSize + * size of the page (number items displayed per page). + * + */ + public PageableTree(Composite parent, int style, int treeStyle, + int pageSize, IPageContentProvider pageContentProvider) { + this(parent, style, treeStyle, pageSize, pageContentProvider, + getDefaultPageRendererTopFactory(), + getDefaultPageRendererBottomFactory(), true); + } + + public PageableTree(Composite parent, int style, int treeStyle, int pageSize) { + this(parent, style, treeStyle, pageSize, PageResultContentProvider + .getInstance(), getDefaultPageRendererTopFactory(), + getDefaultPageRendererBottomFactory(), true); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param treeStyle + * the style of tree to construct + * @param pageSize + * size of the page (number items displayed per page). + * + * @param pageRendererTopFactory + * the page renderer factory used to create a SWT Composite on + * the top of the widget. Null if none Composite must be created. + * @param pageRendererBottomFactory + * the page renderer factory used to create a SWT Composite on + * the bottom of the widget. Null if none Composite must be + * created. + * + */ + public PageableTree(Composite parent, int style, int treeStyle, + int pageSize, IPageContentProvider pageContentProvider, + ICompositeRendererFactory pageRendererTopFactory, + ICompositeRendererFactory pageRendererBottomFactory) { + this(parent, style, treeStyle, pageSize, pageContentProvider, + pageRendererTopFactory, pageRendererBottomFactory, true); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param treeStyle + * the style of tree to construct + * @param pageSize + * size of the page (number items displayed per page). + * + * @param pageRendererTopFactory + * the page renderer factory used to create a SWT Composite on + * the top of the widget. Null if none Composite must be created. + * @param pageRendererBottomFactory + * the page renderer factory used to create a SWT Composite on + * the bottom of the widget. Null if none Composite must be + * created. + * @param createUI + * true if the UI must be created and false otherwise. + * + */ + protected PageableTree(Composite parent, int style, int treeStyle, + int pageSize, IPageContentProvider pageContentProvider, + ICompositeRendererFactory pageRendererTopFactory, + ICompositeRendererFactory pageRendererBottomFactory, + boolean createUI) { + super(parent, style, pageSize, pageContentProvider, + pageRendererTopFactory, pageRendererBottomFactory, false); + this.treeStyle = treeStyle; + if (createUI) { + createUI(this); + } + } + + @Override + protected Tree createWidget(Composite parent) { + Tree tree = createTree(parent); + this.viewer = new TreeViewer(tree); + return tree; + } + + /** + * Create the tree widget and layout it. + * + * @param parent + * @return + */ + protected Tree createTree(Composite parent) { + Tree tree = createTree(parent, getTreeStyle()); + tree.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + return tree; + } + + /** + * Returns the tree style. + * + * @return + */ + protected int getTreeStyle() { + return treeStyle; + } + + /** + * Returns the tree viewer. + * + * @return + */ + public TreeViewer getViewer() { + return viewer; + } + + /** + * Create a tree. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of tree to constr * @return + */ + protected Tree createTree(Composite parent, int style) { + return new Tree(parent, style); + } + + /** + * Returns the default page renderer factory for the top region. + * + * @return + */ + public static ICompositeRendererFactory getDefaultPageRendererTopFactory() { + return ResultAndNavigationPageLinksRendererFactory.getFactory(); + } + + /** + * Returns the default page renderer factory for the bottom region. + * + * @return + */ + public static ICompositeRendererFactory getDefaultPageRendererBottomFactory() { + return null; + } + + @Override + public void refreshPage() { + PageLoaderStrategyHelper.loadPageAndReplaceItems(getController(), + viewer, getPageLoader(), getPageContentProvider(), null); + } +} diff --git a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/SortTreeColumnSelectionListener.java b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/SortTreeColumnSelectionListener.java index 049def953..60afd9937 100644 --- a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/SortTreeColumnSelectionListener.java +++ b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/SortTreeColumnSelectionListener.java @@ -1,104 +1,104 @@ -/******************************************************************************* - * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Angelo ZERR - initial API and implementation - * Pascal Leclercq - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.pagination.tree; - -import org.eclipse.nebula.widgets.pagination.AbstractSortColumnSelectionListener; -import org.eclipse.nebula.widgets.pagination.PageableController; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; - -/** - * - * {@link SelectionListener} implementation to sort a tree column by using the - * attached pagination controller of the SWT {@link Tree}. - * - */ -public class SortTreeColumnSelectionListener extends - AbstractSortColumnSelectionListener { - - /** - * Constructor with property name and default sort (SWT.NONE). - * - * @param propertyName - * the sort property name. - */ - - public SortTreeColumnSelectionListener(String propertyName) { - this(propertyName, SWT.NONE, null); - } - - /** - * Constructor with property name and default sort (SWT.NONE). - * - * @param propertyName - * the sort property name. - * @param controller - * the controller to update when sort is applied. - */ - public SortTreeColumnSelectionListener(String propertyName, - PageableController controller) { - this(propertyName, SWT.NONE, controller); - } - - /** - * Constructor with property name and sort direction. - * - * @param propertyName - * the sort property name. - * @param sortDirection - * the sort direction {@link SWT.UP}, {@link SWT.DOWN}. - */ - public SortTreeColumnSelectionListener(String propertyName, - int sortDirection) { - this(propertyName, sortDirection, null); - } - - /** - * Constructor with property name and sort direction. - * - * @param propertyName - * the sort property name. - * @param sortDirection - * the sort direction {@link SWT.UP}, {@link SWT.DOWN}. - * @param controller - * the controller to update when sort is applied. - */ - public SortTreeColumnSelectionListener(String propertyName, - int sortDirection, PageableController controller) { - super(propertyName, sortDirection, controller); - } - - @Override - protected Tree getParent(SelectionEvent e) { - // 1) Get tree column which fire this selection event - TreeColumn treeColumn = (TreeColumn) e.getSource(); - // 2) Get the owner tree - return treeColumn.getParent(); - } - - @Override - protected void sort(SelectionEvent e) { - // 1) Get tree column which fire this selection event - TreeColumn treeColumn = (TreeColumn) e.getSource(); - // 2) Get the owner tree - Tree tree = treeColumn.getParent(); - // 3) Modify the SWT Tree sort - tree.setSortColumn(treeColumn); - tree.setSortDirection(getSortDirection()); - } -} +/******************************************************************************* + * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Angelo ZERR - initial API and implementation + * Pascal Leclercq - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.pagination.tree; + +import org.eclipse.nebula.widgets.pagination.AbstractSortColumnSelectionListener; +import org.eclipse.nebula.widgets.pagination.PageableController; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; + +/** + * + * {@link SelectionListener} implementation to sort a tree column by using the + * attached pagination controller of the SWT {@link Tree}. + * + */ +public class SortTreeColumnSelectionListener extends + AbstractSortColumnSelectionListener { + + /** + * Constructor with property name and default sort (SWT.NONE). + * + * @param propertyName + * the sort property name. + */ + + public SortTreeColumnSelectionListener(String propertyName) { + this(propertyName, SWT.NONE, null); + } + + /** + * Constructor with property name and default sort (SWT.NONE). + * + * @param propertyName + * the sort property name. + * @param controller + * the controller to update when sort is applied. + */ + public SortTreeColumnSelectionListener(String propertyName, + PageableController controller) { + this(propertyName, SWT.NONE, controller); + } + + /** + * Constructor with property name and sort direction. + * + * @param propertyName + * the sort property name. + * @param sortDirection + * the sort direction {@link SWT.UP}, {@link SWT.DOWN}. + */ + public SortTreeColumnSelectionListener(String propertyName, + int sortDirection) { + this(propertyName, sortDirection, null); + } + + /** + * Constructor with property name and sort direction. + * + * @param propertyName + * the sort property name. + * @param sortDirection + * the sort direction {@link SWT.UP}, {@link SWT.DOWN}. + * @param controller + * the controller to update when sort is applied. + */ + public SortTreeColumnSelectionListener(String propertyName, + int sortDirection, PageableController controller) { + super(propertyName, sortDirection, controller); + } + + @Override + protected Tree getParent(SelectionEvent e) { + // 1) Get tree column which fire this selection event + TreeColumn treeColumn = (TreeColumn) e.getSource(); + // 2) Get the owner tree + return treeColumn.getParent(); + } + + @Override + protected void sort(SelectionEvent e) { + // 1) Get tree column which fire this selection event + TreeColumn treeColumn = (TreeColumn) e.getSource(); + // 2) Get the owner tree + Tree tree = treeColumn.getParent(); + // 3) Modify the SWT Tree sort + tree.setSortColumn(treeColumn); + tree.setSortDirection(getSortDirection()); + } +} diff --git a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/forms/FormPageableTree.java b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/forms/FormPageableTree.java index 07d04a55f..5f45033ca 100644 --- a/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/forms/FormPageableTree.java +++ b/widgets/pagination/org.eclipse.nebula.widgets.pagination/src/org/eclipse/nebula/widgets/pagination/tree/forms/FormPageableTree.java @@ -1,154 +1,154 @@ -/******************************************************************************* - * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Angelo ZERR - initial API and implementation - * Pascal Leclercq - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.pagination.tree.forms; - -import org.eclipse.nebula.widgets.pagination.IPageContentProvider; -import org.eclipse.nebula.widgets.pagination.PageableController; -import org.eclipse.nebula.widgets.pagination.renderers.ICompositeRendererFactory; -import org.eclipse.nebula.widgets.pagination.tree.PageableTree; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.ui.forms.widgets.FormToolkit; - -/** - * Implementation of the paginated SWT Forms Tree {@link PageableTree}. - */ -public class FormPageableTree extends PageableTree { - - private final FormToolkit toolkit; - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. Here default page size - * {@link PageableController#DEFAULT_PAGE_SIZE} and default tree style - * SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL are used. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param toolkit - * the {@link FormToolkit} used to create the SWT {@link Tree}. - */ - public FormPageableTree(Composite parent, int style, FormToolkit toolkit) { - this(parent, style, DEFAULT_TREE_STYLE, toolkit, null); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param treeStyle - * the style of tree to construct - * @param toolkit - * the {@link FormToolkit} used to create the SWT {@link Tree}. - */ - public FormPageableTree(Composite parent, int style, int treeStyle, - FormToolkit toolkit, IPageContentProvider pageContentProvider, - ICompositeRendererFactory pageRendererTopFactory, - ICompositeRendererFactory pageRendererBottomFactory) { - this(parent, style, treeStyle, toolkit, - PageableController.DEFAULT_PAGE_SIZE, pageContentProvider, - pageRendererTopFactory, pageRendererBottomFactory); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param treeStyle - * the style of tree to construct - * @param toolkit - * the {@link FormToolkit} used to create the SWT {@link Tree}. - */ - public FormPageableTree(Composite parent, int style, int treeStyle, - FormToolkit toolkit, IPageContentProvider pageContentProvider) { - this(parent, style, treeStyle, toolkit, - PageableController.DEFAULT_PAGE_SIZE, pageContentProvider, - getDefaultPageRendererTopFactory(), - getDefaultPageRendererBottomFactory()); - } - - /** - * Constructs a new instance of this class given its parent and a style - * value describing its behavior and appearance. - * - * @param parent - * a widget which will be the parent of the new instance (cannot - * be null) - * @param style - * the style of widget to construct - * @param treeStyle - * the style of tree to construct - * @param toolkit - * the {@link FormToolkit} used to create the SWT {@link Tree}. - * @param pageSize - * size of the page (number items displayed per page). - * - * @param pageRendererTopFactory - * the page renderer factory used to create a SWT Composite on - * the top of the widget. Null if none Composite must be created. - * @param pageRendererBottomFactory - * the page renderer factory used to create a SWT Composite on - * the bottom of the widget. Null if none Composite must be - * created. - * - */ - public FormPageableTree(Composite parent, int style, int treeStyle, - FormToolkit toolkit, int pageSize, - IPageContentProvider pageContentProvider, - ICompositeRendererFactory pageRendererTopFactory, - ICompositeRendererFactory pageRendererBottomFactory) { - super(parent, style, treeStyle, pageSize, pageContentProvider, - pageRendererTopFactory, pageRendererBottomFactory, false); - this.toolkit = toolkit; - super.createUI(this); - toolkit.adapt(this); - } - - @Override - protected Tree createTree(Composite parent, int style) { - return toolkit.createTree(parent, style); - } - - @Override - protected Composite createCompositeBottom(Composite parent) { - Composite bottom = super.createCompositeBottom(parent); - if (bottom != null) { - toolkit.adapt(bottom); - } - return bottom; - } - - @Override - protected Composite createCompositeTop(Composite parent) { - Composite top = super.createCompositeTop(parent); - if (top != null) { - toolkit.adapt(top); - } - return top; - } -} +/******************************************************************************* + * Copyright (C) 2011 Angelo Zerr , Pascal Leclercq + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Angelo ZERR - initial API and implementation + * Pascal Leclercq - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.pagination.tree.forms; + +import org.eclipse.nebula.widgets.pagination.IPageContentProvider; +import org.eclipse.nebula.widgets.pagination.PageableController; +import org.eclipse.nebula.widgets.pagination.renderers.ICompositeRendererFactory; +import org.eclipse.nebula.widgets.pagination.tree.PageableTree; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * Implementation of the paginated SWT Forms Tree {@link PageableTree}. + */ +public class FormPageableTree extends PageableTree { + + private final FormToolkit toolkit; + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. Here default page size + * {@link PageableController#DEFAULT_PAGE_SIZE} and default tree style + * SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL are used. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param toolkit + * the {@link FormToolkit} used to create the SWT {@link Tree}. + */ + public FormPageableTree(Composite parent, int style, FormToolkit toolkit) { + this(parent, style, DEFAULT_TREE_STYLE, toolkit, null); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param treeStyle + * the style of tree to construct + * @param toolkit + * the {@link FormToolkit} used to create the SWT {@link Tree}. + */ + public FormPageableTree(Composite parent, int style, int treeStyle, + FormToolkit toolkit, IPageContentProvider pageContentProvider, + ICompositeRendererFactory pageRendererTopFactory, + ICompositeRendererFactory pageRendererBottomFactory) { + this(parent, style, treeStyle, toolkit, + PageableController.DEFAULT_PAGE_SIZE, pageContentProvider, + pageRendererTopFactory, pageRendererBottomFactory); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param treeStyle + * the style of tree to construct + * @param toolkit + * the {@link FormToolkit} used to create the SWT {@link Tree}. + */ + public FormPageableTree(Composite parent, int style, int treeStyle, + FormToolkit toolkit, IPageContentProvider pageContentProvider) { + this(parent, style, treeStyle, toolkit, + PageableController.DEFAULT_PAGE_SIZE, pageContentProvider, + getDefaultPageRendererTopFactory(), + getDefaultPageRendererBottomFactory()); + } + + /** + * Constructs a new instance of this class given its parent and a style + * value describing its behavior and appearance. + * + * @param parent + * a widget which will be the parent of the new instance (cannot + * be null) + * @param style + * the style of widget to construct + * @param treeStyle + * the style of tree to construct + * @param toolkit + * the {@link FormToolkit} used to create the SWT {@link Tree}. + * @param pageSize + * size of the page (number items displayed per page). + * + * @param pageRendererTopFactory + * the page renderer factory used to create a SWT Composite on + * the top of the widget. Null if none Composite must be created. + * @param pageRendererBottomFactory + * the page renderer factory used to create a SWT Composite on + * the bottom of the widget. Null if none Composite must be + * created. + * + */ + public FormPageableTree(Composite parent, int style, int treeStyle, + FormToolkit toolkit, int pageSize, + IPageContentProvider pageContentProvider, + ICompositeRendererFactory pageRendererTopFactory, + ICompositeRendererFactory pageRendererBottomFactory) { + super(parent, style, treeStyle, pageSize, pageContentProvider, + pageRendererTopFactory, pageRendererBottomFactory, false); + this.toolkit = toolkit; + super.createUI(this); + toolkit.adapt(this); + } + + @Override + protected Tree createTree(Composite parent, int style) { + return toolkit.createTree(parent, style); + } + + @Override + protected Composite createCompositeBottom(Composite parent) { + Composite bottom = super.createCompositeBottom(parent); + if (bottom != null) { + toolkit.adapt(bottom); + } + return bottom; + } + + @Override + protected Composite createCompositeTop(Composite parent) { + Composite top = super.createCompositeTop(parent); + if (top != null) { + toolkit.adapt(top); + } + return top; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/.classpath b/widgets/paperclips/org.eclipse.nebula.paperclips.core/.classpath index 540ee9402..7aa94b021 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/.classpath +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/.settings/org.eclipse.jdt.core.prefs b/widgets/paperclips/org.eclipse.nebula.paperclips.core/.settings/org.eclipse.jdt.core.prefs index dae2c509f..9f3ae7705 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/.settings/org.eclipse.jdt.core.prefs @@ -1,367 +1,367 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true -org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true -org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true -org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true -org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.doc.comment.support=enabled +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning +org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag +org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true +org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true +org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true +org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true +org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/.settings/org.eclipse.jdt.ui.prefs b/widgets/paperclips/org.eclipse.nebula.paperclips.core/.settings/org.eclipse.jdt.ui.prefs index 74578e8fd..6b8b46165 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/.settings/org.eclipse.jdt.ui.prefs +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/.settings/org.eclipse.jdt.ui.prefs @@ -1,57 +1,57 @@ -#Tue Aug 11 15:05:57 MDT 2009 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile -formatter_settings_version=11 -org.eclipse.jdt.ui.javadoc=false -org.eclipse.jdt.ui.text.custom_code_templates= -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=true -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +#Tue Aug 11 15:05:57 MDT 2009 +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile +formatter_settings_version=11 +org.eclipse.jdt.ui.javadoc=false +org.eclipse.jdt.ui.text.custom_code_templates= +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=true +sp_cleanup.remove_unused_imports=true +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/META-INF/MANIFEST.MF b/widgets/paperclips/org.eclipse.nebula.paperclips.core/META-INF/MANIFEST.MF index 12c9a29ed..f3530c8cf 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/META-INF/MANIFEST.MF +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/META-INF/MANIFEST.MF @@ -1,21 +1,21 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Paperclips Core -Bundle-SymbolicName: org.eclipse.nebula.paperclips.core -Bundle-Version: 2.1.0.qualifier -Bundle-Vendor: Eclipse Nebula -Require-Bundle: org.eclipse.swt;bundle-version="[3.2.0,4.0.0)" -Export-Package: org.eclipse.nebula.paperclips.core, - org.eclipse.nebula.paperclips.core.border, - org.eclipse.nebula.paperclips.core.border.internal, - org.eclipse.nebula.paperclips.core.grid, - org.eclipse.nebula.paperclips.core.grid.internal;x-internal:=true, - org.eclipse.nebula.paperclips.core.internal;x-internal:=true, - org.eclipse.nebula.paperclips.core.internal.piece, - org.eclipse.nebula.paperclips.core.internal.util;x-internal:=true, - org.eclipse.nebula.paperclips.core.page, - org.eclipse.nebula.paperclips.core.text, - org.eclipse.nebula.paperclips.core.text.internal -Bundle-ClassPath: . -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Automatic-Module-Name: org.eclipse.nebula.paperclips.core +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Paperclips Core +Bundle-SymbolicName: org.eclipse.nebula.paperclips.core +Bundle-Version: 2.1.0.qualifier +Bundle-Vendor: Eclipse Nebula +Require-Bundle: org.eclipse.swt;bundle-version="[3.2.0,4.0.0)" +Export-Package: org.eclipse.nebula.paperclips.core, + org.eclipse.nebula.paperclips.core.border, + org.eclipse.nebula.paperclips.core.border.internal, + org.eclipse.nebula.paperclips.core.grid, + org.eclipse.nebula.paperclips.core.grid.internal;x-internal:=true, + org.eclipse.nebula.paperclips.core.internal;x-internal:=true, + org.eclipse.nebula.paperclips.core.internal.piece, + org.eclipse.nebula.paperclips.core.internal.util;x-internal:=true, + org.eclipse.nebula.paperclips.core.page, + org.eclipse.nebula.paperclips.core.text, + org.eclipse.nebula.paperclips.core.text.internal +Bundle-ClassPath: . +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Automatic-Module-Name: org.eclipse.nebula.paperclips.core diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/build.properties b/widgets/paperclips/org.eclipse.nebula.paperclips.core/build.properties index 68d58d51b..08373bf14 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/build.properties +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -bin.includes = META-INF/,\ - .,\ - about.html +source.. = src/ +bin.includes = META-INF/,\ + .,\ + about.html diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AbstractIterator.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AbstractIterator.java index 454915088..4eb72653a 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AbstractIterator.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AbstractIterator.java @@ -1,61 +1,61 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -/** - * An abstract PrintIterator class which maintains references to the device and - * gc arguments passed to {@link Print#iterator(Device, GC) }. - * - * @author Matthew Hall - */ -public abstract class AbstractIterator implements PrintIterator { - /** - * The device being printed to. - */ - protected final Device device; - - /** - * A GC used for measuring document elements. - */ - protected final GC gc; - - /** - * Constructs an AbstractIterator with the given Device and GC. - * - * @param device - * the device being printed to. - * @param gc - * a GC used for drawing on the print device. - */ - protected AbstractIterator(Device device, GC gc) { - Util.notNull(device, gc); - this.device = device; - this.gc = gc; - } - - /** - * Copy constructor. - * - * @param that - * the AbstractIterator being copied. - */ - protected AbstractIterator(AbstractIterator that) { - this.device = that.device; - this.gc = that.gc; - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +/** + * An abstract PrintIterator class which maintains references to the device and + * gc arguments passed to {@link Print#iterator(Device, GC) }. + * + * @author Matthew Hall + */ +public abstract class AbstractIterator implements PrintIterator { + /** + * The device being printed to. + */ + protected final Device device; + + /** + * A GC used for measuring document elements. + */ + protected final GC gc; + + /** + * Constructs an AbstractIterator with the given Device and GC. + * + * @param device + * the device being printed to. + * @param gc + * a GC used for drawing on the print device. + */ + protected AbstractIterator(Device device, GC gc) { + Util.notNull(device, gc); + this.device = device; + this.gc = gc; + } + + /** + * Copy constructor. + * + * @param that + * the AbstractIterator being copied. + */ + protected AbstractIterator(AbstractIterator that) { + this.device = that.device; + this.gc = that.gc; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AbstractPiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AbstractPiece.java index 697eea18e..cab9250d4 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AbstractPiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AbstractPiece.java @@ -1,66 +1,66 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * An abstract PrintPiece class. - * - * @author Matthew Hall - */ -public abstract class AbstractPiece implements PrintPiece { - /** - * The device being printed to. - */ - protected final Device device; - - private final Point size; - - /** - * Constructs an AbstractPiece. - * - * @param device - * the device being printed to. - * @param gc - * a GC for drawing on the print device. - * @param size - * the value to be returned by getSize(). - */ - protected AbstractPiece(Device device, GC gc, Point size) { - Util.notNull(device, gc, size); - this.device = device; - this.size = size; - } - - /** - * Constructos an AbstractPiece. - * - * @param iter - * an AbstractIterator containing references to a Device and GC - * which will be used for printing. - * @param size - * the value to be returned by getSize(). - */ - protected AbstractPiece(AbstractIterator iter, Point size) { - this(iter.device, iter.gc, size); - } - - public final Point getSize() { - return new Point(size.x, size.y); - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * An abstract PrintPiece class. + * + * @author Matthew Hall + */ +public abstract class AbstractPiece implements PrintPiece { + /** + * The device being printed to. + */ + protected final Device device; + + private final Point size; + + /** + * Constructs an AbstractPiece. + * + * @param device + * the device being printed to. + * @param gc + * a GC for drawing on the print device. + * @param size + * the value to be returned by getSize(). + */ + protected AbstractPiece(Device device, GC gc, Point size) { + Util.notNull(device, gc, size); + this.device = device; + this.size = size; + } + + /** + * Constructos an AbstractPiece. + * + * @param iter + * an AbstractIterator containing references to a Device and GC + * which will be used for printing. + * @param size + * the value to be returned by getSize(). + */ + protected AbstractPiece(AbstractIterator iter, Point size) { + this(iter.device, iter.gc, size); + } + + public final Point getSize() { + return new Point(size.x, size.y); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AlignPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AlignPrint.java index 7564cf297..add333034 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AlignPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/AlignPrint.java @@ -1,192 +1,192 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A wrapper print that aligns its target vertically and/or horizontally. An - * AlignPrint is vertically greedy when the vertical alignment is SWT.CENTER or - * SWT.BOTTOM, and horizontally greedy when the horizontal alignment is - * SWT.CENTER and SWT.RIGHT. - * - * @author Matthew Hall - */ -public class AlignPrint implements Print { - private static final int DEFAULT_HORIZONTAL_ALIGN = SWT.LEFT; - private static final int DEFAULT_VERTICAL_ALIGN = SWT.TOP; - - final Print target; - final int hAlign; - final int vAlign; - - /** - * Constructs a new AlignPrint. - * - * @param target - * the print being aligned. - * @param hAlign - * the horizontal alignment. One of SWT.LEFT, SWT.CENTER, - * SWT.RIGHT, or SWT.DEFAULT. - * @param vAlign - * the vertical alignment. One of SWT.TOP, SWT.CENTER, - * SWT.BOTTOM, or SWT.DEFAULT. - */ - public AlignPrint(Print target, int hAlign, int vAlign) { - Util.notNull(target); - this.target = target; - this.hAlign = checkHAlign(hAlign); - this.vAlign = checkVAlign(vAlign); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + hAlign; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - result = prime * result + vAlign; - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AlignPrint other = (AlignPrint) obj; - if (hAlign != other.hAlign) - return false; - if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) - return false; - if (vAlign != other.vAlign) - return false; - return true; - } - - /** - * Returns the wrapped print being aligned - * - * @return the wrapped print being aligned - */ - public Print getTarget() { - return target; - } - - /** - * Returns a Point with the x and y fields set to the horizontal and - * vertical alignment, respectively. - * - * @return a Point with the x and y fields set to the horizontal and - * vertical alignment, respectively. - */ - public Point getAlignment() { - return new Point(hAlign, vAlign); - } - - private static int checkHAlign(int hAlign) { - if (hAlign == SWT.LEFT || hAlign == SWT.CENTER || hAlign == SWT.RIGHT) - return hAlign; - if (hAlign == SWT.DEFAULT) - return DEFAULT_HORIZONTAL_ALIGN; - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "hAlign must be one of SWT.LEFT, SWT.CENTER or SWT.RIGHT"); //$NON-NLS-1$ - return hAlign; - } - - private static int checkVAlign(int vAlign) { - if (vAlign == SWT.TOP || vAlign == SWT.CENTER || vAlign == SWT.BOTTOM) - return vAlign; - if (vAlign == SWT.DEFAULT) - return DEFAULT_VERTICAL_ALIGN; - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "vAlign must be one of SWT.TOP, SWT.CENTER or SWT.BOTTOM"); //$NON-NLS-1$ - return vAlign; - } - - public PrintIterator iterator(Device device, GC gc) { - return new AlignIterator(this, device, gc); - } -} - -class AlignIterator implements PrintIterator { - private final PrintIterator target; - private final int hAlign; - private final int vAlign; - - AlignIterator(AlignPrint print, Device device, GC gc) { - this.target = print.target.iterator(device, gc); - this.hAlign = print.hAlign; - this.vAlign = print.vAlign; - } - - AlignIterator(AlignIterator that) { - this.target = that.target.copy(); - this.hAlign = that.hAlign; - this.vAlign = that.vAlign; - } - - public boolean hasNext() { - return target.hasNext(); - } - - public Point minimumSize() { - return target.minimumSize(); - } - - public Point preferredSize() { - return target.preferredSize(); - } - - public PrintPiece next(int width, int height) { - PrintPiece piece = PaperClips.next(target, width, height); - if (piece == null) - return null; - - Point size = piece.getSize(); - Point offset = new Point(0, 0); - - if (hAlign == SWT.CENTER) - offset.x = (width - size.x) / 2; - else if (hAlign == SWT.RIGHT) - offset.x = width - size.x; - - if (hAlign != SWT.LEFT) - size.x = width; - - if (vAlign == SWT.CENTER) - offset.y = (height - size.y) / 2; - else if (vAlign == SWT.BOTTOM) - offset.y = height - size.y; - - if (vAlign != SWT.TOP) - size.y = height; - - CompositeEntry entry = new CompositeEntry(piece, offset); - - return new CompositePiece(new CompositeEntry[] { entry }, size); - } - - public PrintIterator copy() { - return new AlignIterator(this); - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A wrapper print that aligns its target vertically and/or horizontally. An + * AlignPrint is vertically greedy when the vertical alignment is SWT.CENTER or + * SWT.BOTTOM, and horizontally greedy when the horizontal alignment is + * SWT.CENTER and SWT.RIGHT. + * + * @author Matthew Hall + */ +public class AlignPrint implements Print { + private static final int DEFAULT_HORIZONTAL_ALIGN = SWT.LEFT; + private static final int DEFAULT_VERTICAL_ALIGN = SWT.TOP; + + final Print target; + final int hAlign; + final int vAlign; + + /** + * Constructs a new AlignPrint. + * + * @param target + * the print being aligned. + * @param hAlign + * the horizontal alignment. One of SWT.LEFT, SWT.CENTER, + * SWT.RIGHT, or SWT.DEFAULT. + * @param vAlign + * the vertical alignment. One of SWT.TOP, SWT.CENTER, + * SWT.BOTTOM, or SWT.DEFAULT. + */ + public AlignPrint(Print target, int hAlign, int vAlign) { + Util.notNull(target); + this.target = target; + this.hAlign = checkHAlign(hAlign); + this.vAlign = checkVAlign(vAlign); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + hAlign; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + result = prime * result + vAlign; + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AlignPrint other = (AlignPrint) obj; + if (hAlign != other.hAlign) + return false; + if (target == null) { + if (other.target != null) + return false; + } else if (!target.equals(other.target)) + return false; + if (vAlign != other.vAlign) + return false; + return true; + } + + /** + * Returns the wrapped print being aligned + * + * @return the wrapped print being aligned + */ + public Print getTarget() { + return target; + } + + /** + * Returns a Point with the x and y fields set to the horizontal and + * vertical alignment, respectively. + * + * @return a Point with the x and y fields set to the horizontal and + * vertical alignment, respectively. + */ + public Point getAlignment() { + return new Point(hAlign, vAlign); + } + + private static int checkHAlign(int hAlign) { + if (hAlign == SWT.LEFT || hAlign == SWT.CENTER || hAlign == SWT.RIGHT) + return hAlign; + if (hAlign == SWT.DEFAULT) + return DEFAULT_HORIZONTAL_ALIGN; + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "hAlign must be one of SWT.LEFT, SWT.CENTER or SWT.RIGHT"); //$NON-NLS-1$ + return hAlign; + } + + private static int checkVAlign(int vAlign) { + if (vAlign == SWT.TOP || vAlign == SWT.CENTER || vAlign == SWT.BOTTOM) + return vAlign; + if (vAlign == SWT.DEFAULT) + return DEFAULT_VERTICAL_ALIGN; + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "vAlign must be one of SWT.TOP, SWT.CENTER or SWT.BOTTOM"); //$NON-NLS-1$ + return vAlign; + } + + public PrintIterator iterator(Device device, GC gc) { + return new AlignIterator(this, device, gc); + } +} + +class AlignIterator implements PrintIterator { + private final PrintIterator target; + private final int hAlign; + private final int vAlign; + + AlignIterator(AlignPrint print, Device device, GC gc) { + this.target = print.target.iterator(device, gc); + this.hAlign = print.hAlign; + this.vAlign = print.vAlign; + } + + AlignIterator(AlignIterator that) { + this.target = that.target.copy(); + this.hAlign = that.hAlign; + this.vAlign = that.vAlign; + } + + public boolean hasNext() { + return target.hasNext(); + } + + public Point minimumSize() { + return target.minimumSize(); + } + + public Point preferredSize() { + return target.preferredSize(); + } + + public PrintPiece next(int width, int height) { + PrintPiece piece = PaperClips.next(target, width, height); + if (piece == null) + return null; + + Point size = piece.getSize(); + Point offset = new Point(0, 0); + + if (hAlign == SWT.CENTER) + offset.x = (width - size.x) / 2; + else if (hAlign == SWT.RIGHT) + offset.x = width - size.x; + + if (hAlign != SWT.LEFT) + size.x = width; + + if (vAlign == SWT.CENTER) + offset.y = (height - size.y) / 2; + else if (vAlign == SWT.BOTTOM) + offset.y = height - size.y; + + if (vAlign != SWT.TOP) + size.y = height; + + CompositeEntry entry = new CompositeEntry(piece, offset); + + return new CompositePiece(new CompositeEntry[] { entry }, size); + } + + public PrintIterator copy() { + return new AlignIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BackgroundPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BackgroundPrint.java index 21b8b8f0f..793a697d1 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BackgroundPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BackgroundPrint.java @@ -1,186 +1,186 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; - -/** - * A decorator that paints a background color behind it's target. - * - * @author Matthew Hall - */ -public class BackgroundPrint implements Print { - Print target; - RGB background; - - /** - * Constructs a BackgroundPrint with the given target and background color. - * - * @param target - * the - * @param background - */ - public BackgroundPrint(Print target, RGB background) { - Util.notNull(target, background); - this.target = target; - this.background = background; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((background == null) ? 0 : background.hashCode()); - result = prime * result + ((target == null) ? 0 : target.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - BackgroundPrint other = (BackgroundPrint) obj; - if (background == null) { - if (other.background != null) - return false; - } else if (!background.equals(other.background)) - return false; - if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) - return false; - return true; - } - - /** - * Returns the wrapped print to which the background color is being applied. - * - * @return the wrapped print to which the background color is being applied. - */ - public Print getTarget() { - return target; - } - - /** - * Returns the background color. - * - * @return the background color. - */ - public RGB getBackground() { - return background; - } - - /** - * Sets the background color. - * - * @param background - * the new background color. - */ - public void setBackground(RGB background) { - Util.notNull(background); - this.background = background; - } - - public PrintIterator iterator(Device device, GC gc) { - return new BackgroundIterator(this, device, gc); - } -} - -class BackgroundIterator implements PrintIterator { - private final PrintIterator target; - private final RGB background; - private final Device device; - - BackgroundIterator(BackgroundPrint print, Device device, GC gc) { - Util.notNull(print, device, gc); - this.device = device; - this.target = print.target.iterator(device, gc); - this.background = print.background; - } - - BackgroundIterator(BackgroundIterator that) { - this.target = that.target.copy(); - this.background = that.background; - this.device = that.device; - } - - public Point minimumSize() { - return target.minimumSize(); - } - - public Point preferredSize() { - return target.preferredSize(); - } - - public boolean hasNext() { - return target.hasNext(); - } - - public PrintPiece next(int width, int height) { - PrintPiece targetPiece = PaperClips.next(target, width, height); - if (targetPiece == null) - return null; - return new BackgroundPiece(targetPiece, background, device); - } - - public PrintIterator copy() { - return new BackgroundIterator(this); - } -} - -class BackgroundPiece implements PrintPiece { - private final PrintPiece target; - private final Device device; - private final RGB background; - - BackgroundPiece(PrintPiece target, RGB background, Device device) { - Util.notNull(target, background, device); - this.target = target; - this.device = device; - this.background = background; - } - - public Point getSize() { - return target.getSize(); - } - - public void paint(GC gc, int x, int y) { - paintBackground(gc, x, y); - target.paint(gc, x, y); - } - - private void paintBackground(GC gc, int x, int y) { - Color oldBackground = gc.getBackground(); - - gc.setBackground(ResourcePool.forDevice(device).getColor(background)); - Point size = getSize(); - gc.fillRectangle(x, y, size.x, size.y); - - gc.setBackground(oldBackground); - } - - public void dispose() { - target.dispose(); - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; + +/** + * A decorator that paints a background color behind it's target. + * + * @author Matthew Hall + */ +public class BackgroundPrint implements Print { + Print target; + RGB background; + + /** + * Constructs a BackgroundPrint with the given target and background color. + * + * @param target + * the + * @param background + */ + public BackgroundPrint(Print target, RGB background) { + Util.notNull(target, background); + this.target = target; + this.background = background; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((background == null) ? 0 : background.hashCode()); + result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BackgroundPrint other = (BackgroundPrint) obj; + if (background == null) { + if (other.background != null) + return false; + } else if (!background.equals(other.background)) + return false; + if (target == null) { + if (other.target != null) + return false; + } else if (!target.equals(other.target)) + return false; + return true; + } + + /** + * Returns the wrapped print to which the background color is being applied. + * + * @return the wrapped print to which the background color is being applied. + */ + public Print getTarget() { + return target; + } + + /** + * Returns the background color. + * + * @return the background color. + */ + public RGB getBackground() { + return background; + } + + /** + * Sets the background color. + * + * @param background + * the new background color. + */ + public void setBackground(RGB background) { + Util.notNull(background); + this.background = background; + } + + public PrintIterator iterator(Device device, GC gc) { + return new BackgroundIterator(this, device, gc); + } +} + +class BackgroundIterator implements PrintIterator { + private final PrintIterator target; + private final RGB background; + private final Device device; + + BackgroundIterator(BackgroundPrint print, Device device, GC gc) { + Util.notNull(print, device, gc); + this.device = device; + this.target = print.target.iterator(device, gc); + this.background = print.background; + } + + BackgroundIterator(BackgroundIterator that) { + this.target = that.target.copy(); + this.background = that.background; + this.device = that.device; + } + + public Point minimumSize() { + return target.minimumSize(); + } + + public Point preferredSize() { + return target.preferredSize(); + } + + public boolean hasNext() { + return target.hasNext(); + } + + public PrintPiece next(int width, int height) { + PrintPiece targetPiece = PaperClips.next(target, width, height); + if (targetPiece == null) + return null; + return new BackgroundPiece(targetPiece, background, device); + } + + public PrintIterator copy() { + return new BackgroundIterator(this); + } +} + +class BackgroundPiece implements PrintPiece { + private final PrintPiece target; + private final Device device; + private final RGB background; + + BackgroundPiece(PrintPiece target, RGB background, Device device) { + Util.notNull(target, background, device); + this.target = target; + this.device = device; + this.background = background; + } + + public Point getSize() { + return target.getSize(); + } + + public void paint(GC gc, int x, int y) { + paintBackground(gc, x, y); + target.paint(gc, x, y); + } + + private void paintBackground(GC gc, int x, int y) { + Color oldBackground = gc.getBackground(); + + gc.setBackground(ResourcePool.forDevice(device).getColor(background)); + Point size = getSize(); + gc.fillRectangle(x, y, size.x, size.y); + + gc.setBackground(oldBackground); + } + + public void dispose() { + target.dispose(); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BigPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BigPrint.java index 140f5625b..f44044acf 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BigPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BigPrint.java @@ -1,222 +1,222 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Region; - -/** - * A wrapper for prints whose minimum size is too large to fit on one page. The - * target's content is divided across multiple pages like a spreadsheet. Pages - * are printed in order left-to-right, then top-to-bottom. - *

- * Note that this print lays out content under the assumption that every page will have the same - * pixel width and height. If a BigPrint is wrapped in a print that - * violates this expectation, it is likely that the output will skip and/or - * repeat certain portions of the target's content. Some examples of this - * behavior: - *

    - *
  • BorderPrint changes the available page height of the target, depending on - * whether the top and bottom borders are open or closed. - *
  • ColumnPrint often changes the width from column to column, if the total - * width is not evenly divisible by the number of columns. - *
- * - * @author Matthew Hall - */ -public final class BigPrint implements Print { - private final Print target; - - /** - * Constructs a BigPrint. - * - * @param target - */ - public BigPrint(Print target) { - Util.notNull(target); - this.target = target; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - BigPrint other = (BigPrint) obj; - if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) - return false; - return true; - } - - /** - * Returns the wrapped print which is being split across pages. - * - * @return the wrapped print which is being split across pages. - */ - public Print getTarget() { - return target; - } - - public PrintIterator iterator(Device device, GC gc) { - return new BigIterator(target, device, gc); - } -} - -class BigIterator implements PrintIterator { - private final PrintIterator target; - private final Device device; - - private PrintPiece currentPiece; - private int xOffset; - private int yOffset; - - BigIterator(Print target, Device device, GC gc) { - Util.notNull(device, gc, target); - this.target = target.iterator(device, gc); - this.device = device; - currentPiece = null; - xOffset = 0; - yOffset = 0; - } - - BigIterator(BigIterator that) { - this.target = that.target.copy(); - this.device = that.device; - - this.currentPiece = that.currentPiece; - this.xOffset = that.xOffset; - this.yOffset = that.yOffset; - } - - public Point minimumSize() { - return target.minimumSize(); - } - - public Point preferredSize() { - return target.preferredSize(); - } - - public boolean hasNext() { - return currentPiece != null || target.hasNext(); - } - - // Returns a point whose x and y fields represent the required pages wide - // and tall, respectively - private Point estimatePagesRequired(int width, int height) { - if (width <= 0 || height <= 0) - return new Point(0, 0); - - Point pref = target.preferredSize(); - Point prefPages = new Point(pref.x / width, pref.y / height); - - Point min = target.minimumSize(); - - // Adding width-1 rounds up page count w/out floating point op - // Same goes for adding height-1 - Point minPages = new Point(Math.max((min.x + width - 1) / width, 1), - Math.max((min.y + height - 1) / height, 1)); - - return new Point(Math.max(prefPages.x, minPages.x), Math.max( - prefPages.y, minPages.y)); - } - - public PrintPiece next(int width, int height) { - if (!hasNext()) - PaperClips.error("No more content"); //$NON-NLS-1$ - - if (currentPiece == null) { - Point pages = estimatePagesRequired(width, height); - currentPiece = PaperClips.next(target, width * pages.x, height - * pages.y); - if (currentPiece == null) - return null; // Iteration fails - - // Reset the offset for the new piece. - xOffset = 0; - yOffset = 0; - } - - PrintPiece result = new BigPiece(currentPiece, - new Point(width, height), xOffset, yOffset); - - // Advance cursor on current piece. - xOffset += width; - if (xOffset >= currentPiece.getSize().x) { - xOffset = 0; - yOffset += height; - } - if (yOffset >= currentPiece.getSize().y) { - currentPiece = null; - } - - return result; - } - - public PrintIterator copy() { - return new BigIterator(this); - } -} - -class BigPiece implements PrintPiece { - private final PrintPiece target; - private final Point size; - private final Point offset; - - BigPiece(PrintPiece target, Point size, int xOffset, int yOffset) { - Util.notNull(target, size); - this.target = target; - this.size = new Point(size.x, size.y); - this.offset = new Point(xOffset, yOffset); - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - public void paint(GC gc, int x, int y) { - // Remember clipping region - Region region = new Region(); - gc.getClipping(region); - - // Set clipping region so only the portion of the target we want is - // printed. - gc.setClipping(x, y, size.x, size.y); - - // Paint the target. - target.paint(gc, x - offset.x, y - offset.y); - - // Restore clipping region - gc.setClipping(region); - region.dispose(); - } - - public void dispose() { - target.dispose(); - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Region; + +/** + * A wrapper for prints whose minimum size is too large to fit on one page. The + * target's content is divided across multiple pages like a spreadsheet. Pages + * are printed in order left-to-right, then top-to-bottom. + *

+ * Note that this print lays out content under the assumption that every page will have the same + * pixel width and height. If a BigPrint is wrapped in a print that + * violates this expectation, it is likely that the output will skip and/or + * repeat certain portions of the target's content. Some examples of this + * behavior: + *

    + *
  • BorderPrint changes the available page height of the target, depending on + * whether the top and bottom borders are open or closed. + *
  • ColumnPrint often changes the width from column to column, if the total + * width is not evenly divisible by the number of columns. + *
+ * + * @author Matthew Hall + */ +public final class BigPrint implements Print { + private final Print target; + + /** + * Constructs a BigPrint. + * + * @param target + */ + public BigPrint(Print target) { + Util.notNull(target); + this.target = target; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BigPrint other = (BigPrint) obj; + if (target == null) { + if (other.target != null) + return false; + } else if (!target.equals(other.target)) + return false; + return true; + } + + /** + * Returns the wrapped print which is being split across pages. + * + * @return the wrapped print which is being split across pages. + */ + public Print getTarget() { + return target; + } + + public PrintIterator iterator(Device device, GC gc) { + return new BigIterator(target, device, gc); + } +} + +class BigIterator implements PrintIterator { + private final PrintIterator target; + private final Device device; + + private PrintPiece currentPiece; + private int xOffset; + private int yOffset; + + BigIterator(Print target, Device device, GC gc) { + Util.notNull(device, gc, target); + this.target = target.iterator(device, gc); + this.device = device; + currentPiece = null; + xOffset = 0; + yOffset = 0; + } + + BigIterator(BigIterator that) { + this.target = that.target.copy(); + this.device = that.device; + + this.currentPiece = that.currentPiece; + this.xOffset = that.xOffset; + this.yOffset = that.yOffset; + } + + public Point minimumSize() { + return target.minimumSize(); + } + + public Point preferredSize() { + return target.preferredSize(); + } + + public boolean hasNext() { + return currentPiece != null || target.hasNext(); + } + + // Returns a point whose x and y fields represent the required pages wide + // and tall, respectively + private Point estimatePagesRequired(int width, int height) { + if (width <= 0 || height <= 0) + return new Point(0, 0); + + Point pref = target.preferredSize(); + Point prefPages = new Point(pref.x / width, pref.y / height); + + Point min = target.minimumSize(); + + // Adding width-1 rounds up page count w/out floating point op + // Same goes for adding height-1 + Point minPages = new Point(Math.max((min.x + width - 1) / width, 1), + Math.max((min.y + height - 1) / height, 1)); + + return new Point(Math.max(prefPages.x, minPages.x), Math.max( + prefPages.y, minPages.y)); + } + + public PrintPiece next(int width, int height) { + if (!hasNext()) + PaperClips.error("No more content"); //$NON-NLS-1$ + + if (currentPiece == null) { + Point pages = estimatePagesRequired(width, height); + currentPiece = PaperClips.next(target, width * pages.x, height + * pages.y); + if (currentPiece == null) + return null; // Iteration fails + + // Reset the offset for the new piece. + xOffset = 0; + yOffset = 0; + } + + PrintPiece result = new BigPiece(currentPiece, + new Point(width, height), xOffset, yOffset); + + // Advance cursor on current piece. + xOffset += width; + if (xOffset >= currentPiece.getSize().x) { + xOffset = 0; + yOffset += height; + } + if (yOffset >= currentPiece.getSize().y) { + currentPiece = null; + } + + return result; + } + + public PrintIterator copy() { + return new BigIterator(this); + } +} + +class BigPiece implements PrintPiece { + private final PrintPiece target; + private final Point size; + private final Point offset; + + BigPiece(PrintPiece target, Point size, int xOffset, int yOffset) { + Util.notNull(target, size); + this.target = target; + this.size = new Point(size.x, size.y); + this.offset = new Point(xOffset, yOffset); + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + public void paint(GC gc, int x, int y) { + // Remember clipping region + Region region = new Region(); + gc.getClipping(region); + + // Set clipping region so only the portion of the target we want is + // printed. + gc.setClipping(x, y, size.x, size.y); + + // Paint the target. + target.paint(gc, x - offset.x, y - offset.y); + + // Restore clipping region + gc.setClipping(region); + region.dispose(); + } + + public void dispose() { + target.dispose(); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BreakPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BreakPrint.java index 672e2c504..91fcbaafc 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BreakPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/BreakPrint.java @@ -1,82 +1,82 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.piece.EmptyPiece; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A print which inserts a page break (or a column break, if inside a - * ColumnPrint). - *

- * This class is horizontally and vertically greedy. Greedy prints take up all - * the available space on the page. - * - * @author Matthew Hall - */ -public class BreakPrint implements Print { - /** - * Constructs a BreakPrint. - */ - public BreakPrint() { - // Nothing to do - } - - public boolean equals(Object obj) { - return Util.sameClass(this, obj); - } - - public int hashCode() { - return 39 * 29; - } - - public PrintIterator iterator(Device device, GC gc) { - return new BreakIterator(); - } -} - -class BreakIterator implements PrintIterator { - boolean hasNext; - - BreakIterator() { - hasNext = true; - } - - public PrintIterator copy() { - return hasNext ? new BreakIterator() : this; - } - - public boolean hasNext() { - return hasNext; - } - - public Point minimumSize() { - return new Point(0, 0); - } - - public Point preferredSize() { - return new Point(0, 0); - } - - public PrintPiece next(int width, int height) { - if (!hasNext) - PaperClips.error("No more content"); //$NON-NLS-1$ - - hasNext = false; - return new EmptyPiece(new Point(width, height)); - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.piece.EmptyPiece; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A print which inserts a page break (or a column break, if inside a + * ColumnPrint). + *

+ * This class is horizontally and vertically greedy. Greedy prints take up all + * the available space on the page. + * + * @author Matthew Hall + */ +public class BreakPrint implements Print { + /** + * Constructs a BreakPrint. + */ + public BreakPrint() { + // Nothing to do + } + + public boolean equals(Object obj) { + return Util.sameClass(this, obj); + } + + public int hashCode() { + return 39 * 29; + } + + public PrintIterator iterator(Device device, GC gc) { + return new BreakIterator(); + } +} + +class BreakIterator implements PrintIterator { + boolean hasNext; + + BreakIterator() { + hasNext = true; + } + + public PrintIterator copy() { + return hasNext ? new BreakIterator() : this; + } + + public boolean hasNext() { + return hasNext; + } + + public Point minimumSize() { + return new Point(0, 0); + } + + public Point preferredSize() { + return new Point(0, 0); + } + + public PrintPiece next(int width, int height) { + if (!hasNext) + PaperClips.error("No more content"); //$NON-NLS-1$ + + hasNext = false; + return new EmptyPiece(new Point(width, height)); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ColumnPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ColumnPrint.java index 78a45d3a6..1062a9c73 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ColumnPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ColumnPrint.java @@ -1,351 +1,351 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A wrapper Print which splits its child print into multiple columns. - *

- * This class is horizontally greedy. Greedy prints take up all the available - * space on the page. - *

- * ColumnPrint attempts to use the minimum possible vertical space on the page - * if isCompressed() returns true (the default). This behavior can be disabled - * by calling setCompressed(false). - * - * @author Matthew Hall - */ -public class ColumnPrint implements Print { - final Print target; - final int columns; - final int spacing; - - boolean compressed; - - /** - * Constructs a ColumnPrint with the given target, number of columns, and - * column spacing (expressed in points). 72 points = 1". - * - * @param target - * the print which will be split into columns. - * @param columns - * the number of columns to display - * @param spacing - * the spacing between each column. - */ - public ColumnPrint(Print target, int columns, int spacing) { - this(target, columns, spacing, true); - } - - /** - * Constructs a ColumnPrint with the given target, column count, column - * spacing, and compression. - * - * @param target - * the print to display in columns. - * @param columns - * the number of columns to display. - * @param spacing - * the spacing between each column, expressed in points. 72 - * points = 1". - * @param compressed - * whether the columns on the final page are to be - */ - public ColumnPrint(Print target, int columns, int spacing, - boolean compressed) { - Util.notNull(target); - if (spacing < 0) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "spacing must be >= 0"); //$NON-NLS-1$ - if (columns < 2) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "columns must be >= 2"); //$NON-NLS-1$ - - this.target = target; - this.spacing = spacing; - this.columns = columns; - this.compressed = compressed; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + columns; - result = prime * result + (compressed ? 1231 : 1237); - result = prime * result + spacing; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ColumnPrint other = (ColumnPrint) obj; - if (columns != other.columns) - return false; - if (compressed != other.compressed) - return false; - if (spacing != other.spacing) - return false; - if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) - return false; - return true; - } - - /** - * Returns the target print being split into columns. - * - * @return the target print being split into columns. - */ - public Print getTarget() { - return target; - } - - /** - * Returns the number of columns per page. - * - * @return the number of columns per page. - */ - public int getColumnCount() { - return columns; - } - - /** - * Returns the spacing between columns, in points. 72 points = 1". - * - * @return the spacing between columns, in points. - */ - public int getColumnSpacing() { - return spacing; - } - - /** - * Returns whether the columns are compressed to the smallest possible - * height on the last page. - * - * @return whether the columns are compressed to the smallest possible - * height on the last page. - */ - public boolean isCompressed() { - return compressed; - } - - /** - * Sets whether the columns are compressed to the smallest possible height - * on the last page. - * - * @param compressed - * whether to compress the columns. - */ - public void setCompressed(boolean compressed) { - this.compressed = compressed; - } - - public PrintIterator iterator(Device device, GC gc) { - return new ColumnIterator(this, device, gc); - } -} - -class ColumnIterator implements PrintIterator { - private PrintIterator target; - private final int columns; - private final int spacing; - private final boolean compressed; - - ColumnIterator(ColumnPrint print, Device device, GC gc) { - this.target = print.target.iterator(device, gc); - this.columns = print.columns; - this.spacing = Math.round(print.spacing * device.getDPI().x / 72f); - this.compressed = print.compressed; - } - - ColumnIterator(ColumnIterator that) { - this.target = that.target.copy(); - this.columns = that.columns; - this.spacing = that.spacing; - this.compressed = that.compressed; - } - - public Point minimumSize() { - return computeSize(target.minimumSize()); - } - - public Point preferredSize() { - return computeSize(target.preferredSize()); - } - - private Point computeSize(Point targetSize) { - return new Point(targetSize.x * columns + spacing * (columns - 1), - targetSize.y); - } - - public boolean hasNext() { - return target.hasNext(); - } - - int[] computeColSizes(int width) { - int[] colSizes = new int[columns]; - int availableWidth = width - spacing * (columns - 1); - for (int i = 0; i < colSizes.length; i++) { - colSizes[i] = availableWidth / (columns - i); - availableWidth -= colSizes[i]; - } - return colSizes; - } - - Point[] computeColOffsets(int[] colSizes) { - Point[] colOffsets = new Point[columns]; - int xOffset = 0; - for (int i = 0; i < columns; i++) { - colOffsets[i] = new Point(xOffset, 0); - xOffset += colSizes[i] + spacing; - } - return colOffsets; - } - - /** - * Iterates across the given column sizes and returns an array of - * PrintPieces to fill those columns, or null if there was insufficient room - * to continue iterating. A backup of the given iterator should be taken - * before invoking this method! If null is returned, the given iterator is - * corrupt and should no longer be used! - * - * @param colSizes - * an array of column sizes - * @param height - * the height - * @return an array of PrintPieces for the given column sizes, or null - */ - PrintPiece[] nextColumns(PrintIterator iterator, int[] colSizes, - int height) { - List pieces = new ArrayList<>(); - for (int i = 0; i < columns && iterator.hasNext(); i++) { - PrintPiece piece = PaperClips.next(iterator, colSizes[i], height); - - if (piece == null) - return disposePieces(pieces); - - pieces.add(piece); - } - - return pieces.toArray(new PrintPiece[pieces.size()]); - } - - private PrintPiece[] disposePieces(List pieces) { - for (Iterator iter = pieces.iterator(); iter.hasNext();) { - PrintPiece piece = iter.next(); - piece.dispose(); - } - return null; - } - - PrintPiece createResult(PrintPiece[] pieces, int[] colSizes) { - CompositeEntry[] entries = new CompositeEntry[pieces.length]; - - Point[] offsets = computeColOffsets(colSizes); - for (int i = 0; i < pieces.length; i++) - entries[i] = new CompositeEntry(pieces[i], offsets[i]); - - return new CompositePiece(entries); - } - - public PrintPiece next(int width, int height) { - int[] colSizes = computeColSizes(width); - - // Iterate on a copy in case any column fails to layout. - PrintIterator iter = target.copy(); - PrintPiece[] columns = nextColumns(iter, colSizes, height); - if (columns == null) - return null; - - // The target was completely consumed. If compressed property is true, - // close the gap until we find the - // smallest height that completely consumes the target's contents. - if (!iter.hasNext() && compressed) - return nextCompressed(colSizes, iter, columns); - - this.target = iter; - return createResult(columns, colSizes); - } - - private PrintPiece nextCompressed(int[] colSizes, PrintIterator iter, - PrintPiece[] columns) { - int highestInvalidHeight = 0; - int lowestValidHeight = getMaxHeight(columns); - - // Remember the best results - PrintIterator bestIteration = iter; - PrintPiece[] bestColumns = columns; - - while (lowestValidHeight > highestInvalidHeight + 1) { - int testHeight = (lowestValidHeight + highestInvalidHeight + 1) / 2; - - iter = target.copy(); - columns = nextColumns(iter, colSizes, testHeight); - - if (columns == null) { - highestInvalidHeight = testHeight; - } else if (iter.hasNext()) { - highestInvalidHeight = testHeight; - disposePieces(columns); - } else { - disposePieces(bestColumns); - - bestIteration = iter; - bestColumns = columns; - lowestValidHeight = getMaxHeight(bestColumns); - } - } - - // Now that we've narrowed down the target's best iteration, we can - // update the state of this iterator and - // return the result. - this.target = bestIteration; - return createResult(bestColumns, colSizes); - } - - private int getMaxHeight(PrintPiece[] pieces) { - int result = 0; - for (int i = 0; i < pieces.length; i++) - result = Math.max(result, pieces[i].getSize().y); - return result; - } - - private void disposePieces(PrintPiece[] pieces) { - for (int i = 0; i < pieces.length; i++) - pieces[i].dispose(); - } - - public PrintIterator copy() { - return new ColumnIterator(this); - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A wrapper Print which splits its child print into multiple columns. + *

+ * This class is horizontally greedy. Greedy prints take up all the available + * space on the page. + *

+ * ColumnPrint attempts to use the minimum possible vertical space on the page + * if isCompressed() returns true (the default). This behavior can be disabled + * by calling setCompressed(false). + * + * @author Matthew Hall + */ +public class ColumnPrint implements Print { + final Print target; + final int columns; + final int spacing; + + boolean compressed; + + /** + * Constructs a ColumnPrint with the given target, number of columns, and + * column spacing (expressed in points). 72 points = 1". + * + * @param target + * the print which will be split into columns. + * @param columns + * the number of columns to display + * @param spacing + * the spacing between each column. + */ + public ColumnPrint(Print target, int columns, int spacing) { + this(target, columns, spacing, true); + } + + /** + * Constructs a ColumnPrint with the given target, column count, column + * spacing, and compression. + * + * @param target + * the print to display in columns. + * @param columns + * the number of columns to display. + * @param spacing + * the spacing between each column, expressed in points. 72 + * points = 1". + * @param compressed + * whether the columns on the final page are to be + */ + public ColumnPrint(Print target, int columns, int spacing, + boolean compressed) { + Util.notNull(target); + if (spacing < 0) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "spacing must be >= 0"); //$NON-NLS-1$ + if (columns < 2) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "columns must be >= 2"); //$NON-NLS-1$ + + this.target = target; + this.spacing = spacing; + this.columns = columns; + this.compressed = compressed; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + columns; + result = prime * result + (compressed ? 1231 : 1237); + result = prime * result + spacing; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ColumnPrint other = (ColumnPrint) obj; + if (columns != other.columns) + return false; + if (compressed != other.compressed) + return false; + if (spacing != other.spacing) + return false; + if (target == null) { + if (other.target != null) + return false; + } else if (!target.equals(other.target)) + return false; + return true; + } + + /** + * Returns the target print being split into columns. + * + * @return the target print being split into columns. + */ + public Print getTarget() { + return target; + } + + /** + * Returns the number of columns per page. + * + * @return the number of columns per page. + */ + public int getColumnCount() { + return columns; + } + + /** + * Returns the spacing between columns, in points. 72 points = 1". + * + * @return the spacing between columns, in points. + */ + public int getColumnSpacing() { + return spacing; + } + + /** + * Returns whether the columns are compressed to the smallest possible + * height on the last page. + * + * @return whether the columns are compressed to the smallest possible + * height on the last page. + */ + public boolean isCompressed() { + return compressed; + } + + /** + * Sets whether the columns are compressed to the smallest possible height + * on the last page. + * + * @param compressed + * whether to compress the columns. + */ + public void setCompressed(boolean compressed) { + this.compressed = compressed; + } + + public PrintIterator iterator(Device device, GC gc) { + return new ColumnIterator(this, device, gc); + } +} + +class ColumnIterator implements PrintIterator { + private PrintIterator target; + private final int columns; + private final int spacing; + private final boolean compressed; + + ColumnIterator(ColumnPrint print, Device device, GC gc) { + this.target = print.target.iterator(device, gc); + this.columns = print.columns; + this.spacing = Math.round(print.spacing * device.getDPI().x / 72f); + this.compressed = print.compressed; + } + + ColumnIterator(ColumnIterator that) { + this.target = that.target.copy(); + this.columns = that.columns; + this.spacing = that.spacing; + this.compressed = that.compressed; + } + + public Point minimumSize() { + return computeSize(target.minimumSize()); + } + + public Point preferredSize() { + return computeSize(target.preferredSize()); + } + + private Point computeSize(Point targetSize) { + return new Point(targetSize.x * columns + spacing * (columns - 1), + targetSize.y); + } + + public boolean hasNext() { + return target.hasNext(); + } + + int[] computeColSizes(int width) { + int[] colSizes = new int[columns]; + int availableWidth = width - spacing * (columns - 1); + for (int i = 0; i < colSizes.length; i++) { + colSizes[i] = availableWidth / (columns - i); + availableWidth -= colSizes[i]; + } + return colSizes; + } + + Point[] computeColOffsets(int[] colSizes) { + Point[] colOffsets = new Point[columns]; + int xOffset = 0; + for (int i = 0; i < columns; i++) { + colOffsets[i] = new Point(xOffset, 0); + xOffset += colSizes[i] + spacing; + } + return colOffsets; + } + + /** + * Iterates across the given column sizes and returns an array of + * PrintPieces to fill those columns, or null if there was insufficient room + * to continue iterating. A backup of the given iterator should be taken + * before invoking this method! If null is returned, the given iterator is + * corrupt and should no longer be used! + * + * @param colSizes + * an array of column sizes + * @param height + * the height + * @return an array of PrintPieces for the given column sizes, or null + */ + PrintPiece[] nextColumns(PrintIterator iterator, int[] colSizes, + int height) { + List pieces = new ArrayList<>(); + for (int i = 0; i < columns && iterator.hasNext(); i++) { + PrintPiece piece = PaperClips.next(iterator, colSizes[i], height); + + if (piece == null) + return disposePieces(pieces); + + pieces.add(piece); + } + + return pieces.toArray(new PrintPiece[pieces.size()]); + } + + private PrintPiece[] disposePieces(List pieces) { + for (Iterator iter = pieces.iterator(); iter.hasNext();) { + PrintPiece piece = iter.next(); + piece.dispose(); + } + return null; + } + + PrintPiece createResult(PrintPiece[] pieces, int[] colSizes) { + CompositeEntry[] entries = new CompositeEntry[pieces.length]; + + Point[] offsets = computeColOffsets(colSizes); + for (int i = 0; i < pieces.length; i++) + entries[i] = new CompositeEntry(pieces[i], offsets[i]); + + return new CompositePiece(entries); + } + + public PrintPiece next(int width, int height) { + int[] colSizes = computeColSizes(width); + + // Iterate on a copy in case any column fails to layout. + PrintIterator iter = target.copy(); + PrintPiece[] columns = nextColumns(iter, colSizes, height); + if (columns == null) + return null; + + // The target was completely consumed. If compressed property is true, + // close the gap until we find the + // smallest height that completely consumes the target's contents. + if (!iter.hasNext() && compressed) + return nextCompressed(colSizes, iter, columns); + + this.target = iter; + return createResult(columns, colSizes); + } + + private PrintPiece nextCompressed(int[] colSizes, PrintIterator iter, + PrintPiece[] columns) { + int highestInvalidHeight = 0; + int lowestValidHeight = getMaxHeight(columns); + + // Remember the best results + PrintIterator bestIteration = iter; + PrintPiece[] bestColumns = columns; + + while (lowestValidHeight > highestInvalidHeight + 1) { + int testHeight = (lowestValidHeight + highestInvalidHeight + 1) / 2; + + iter = target.copy(); + columns = nextColumns(iter, colSizes, testHeight); + + if (columns == null) { + highestInvalidHeight = testHeight; + } else if (iter.hasNext()) { + highestInvalidHeight = testHeight; + disposePieces(columns); + } else { + disposePieces(bestColumns); + + bestIteration = iter; + bestColumns = columns; + lowestValidHeight = getMaxHeight(bestColumns); + } + } + + // Now that we've narrowed down the target's best iteration, we can + // update the state of this iterator and + // return the result. + this.target = bestIteration; + return createResult(bestColumns, colSizes); + } + + private int getMaxHeight(PrintPiece[] pieces) { + int result = 0; + for (int i = 0; i < pieces.length; i++) + result = Math.max(result, pieces[i].getSize().y); + return result; + } + + private void disposePieces(PrintPiece[] pieces) { + for (int i = 0; i < pieces.length; i++) + pieces[i].dispose(); + } + + public PrintIterator copy() { + return new ColumnIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/CompositeEntry.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/CompositeEntry.java index 4d81b987c..4601fc9ea 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/CompositeEntry.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/CompositeEntry.java @@ -1,57 +1,57 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; - -/** - * An entry in a CompositePiece. - * - * @author Matthew Hall - */ -public class CompositeEntry { - final PrintPiece piece; - final Point offset; - - /** - * Constructs a CompositeEntry with the given PrintPiece and offset. - * - * @param piece - * the PrintPiece for this entry. - * @param offset - * the painting offset within the CompositePrint. - */ - public CompositeEntry(PrintPiece piece, Point offset) { - Util.notNull(piece, offset); - checkOffset(offset); - - this.piece = piece; - this.offset = offset; - } - - private void checkOffset(Point offset) { - if (offset.x < 0 || offset.y < 0) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Offset cannot be negative: " + offset); //$NON-NLS-1$ - } - - /** - * Disposes this entry's print piece. - */ - public void dispose() { - piece.dispose(); - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; + +/** + * An entry in a CompositePiece. + * + * @author Matthew Hall + */ +public class CompositeEntry { + final PrintPiece piece; + final Point offset; + + /** + * Constructs a CompositeEntry with the given PrintPiece and offset. + * + * @param piece + * the PrintPiece for this entry. + * @param offset + * the painting offset within the CompositePrint. + */ + public CompositeEntry(PrintPiece piece, Point offset) { + Util.notNull(piece, offset); + checkOffset(offset); + + this.piece = piece; + this.offset = offset; + } + + private void checkOffset(Point offset) { + if (offset.x < 0 || offset.y < 0) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Offset cannot be negative: " + offset); //$NON-NLS-1$ + } + + /** + * Disposes this entry's print piece. + */ + public void dispose() { + piece.dispose(); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/CompositePiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/CompositePiece.java index 2b7f0a00b..3b8003546 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/CompositePiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/CompositePiece.java @@ -1,126 +1,126 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A composite PrintPiece for displaying child PrintPieces. This class is - * especially useful for Print implementations that perform layout of multiple - * child Prints. - * - * @author Matthew Hall - */ -public class CompositePiece implements PrintPiece { - private final Point size; - - private final CompositeEntry[] entries; - - /** - * Constructs a CompositePiece with the given entries. - * - * @param entries - * an array of entries that make up this PrintPiece. - */ - public CompositePiece(CompositeEntry[] entries) { - this(createList(entries)); - } - - /** - * Constructs a CompositePrintPiece with the given entries and explicit - * size. This constructor will increase the explicit size to completely - * contain any child entries which extend outside the given size. - * - * @param entries - * an array of entries that make up this PrintPiece. - * @param size - */ - public CompositePiece(CompositeEntry[] entries, Point size) { - this(createList(entries), size); - } - - private static List createList(CompositeEntry[] entries) { - List result = new ArrayList<>(); - for (int i = 0; i < entries.length; i++) - result.add(entries[i]); - return result; - } - - /** - * Constructs a composite PrintPiece with the given entries. - * - * @param entries - * an array of entries that make up this PrintPiece. - */ - public CompositePiece(List entries) { - this(entries, new Point(0, 0)); - } - - /** - * Constructs a composite PrintPiece with the given entries and minimum - * size. - * - * @param entries - * a list of CompositeEntry objects describing the child - * PrintPieces. - * @param size - * a hint indicating the minimum size that should be reported - * from getSize(). This constructor increase this size to fit any - * entries that extend outside the given size. - */ - public CompositePiece(List entries, Point size) { - Util.noNulls(entries); - - this.entries = entries.toArray(new CompositeEntry[entries.size()]); - this.size = new Point(size.x, size.y); - - for (int i = 0; i < this.entries.length; i++) { - CompositeEntry entry = this.entries[i]; - Point pieceSize = entry.piece.getSize(); - this.size.x = Math.max(this.size.x, entry.offset.x + pieceSize.x); - this.size.y = Math.max(this.size.y, entry.offset.y + pieceSize.y); - } - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - public void paint(GC gc, int x, int y) { - // SWT on OSX has problems with the clipping. A GC(Printer) always - // returns a clipping rectangle of - // [0,0,0,0] so that inhibits our ability to check each entry against - // the hit rectangle. In addition it - // appears that a GC(Image(Printer))'s clipping on OSX is not affected - // by the GC's transform, so that - // screws up the hit clip as well. For this reason we are no longer - // checking entries to see if they - // intersect the clipping region before drawing them. - - for (int i = 0; i < entries.length; i++) { - CompositeEntry entry = entries[i]; - entry.piece.paint(gc, x + entry.offset.x, y + entry.offset.y); - } - } - - public void dispose() { - for (int i = 0; i < entries.length; i++) - entries[i].dispose(); - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A composite PrintPiece for displaying child PrintPieces. This class is + * especially useful for Print implementations that perform layout of multiple + * child Prints. + * + * @author Matthew Hall + */ +public class CompositePiece implements PrintPiece { + private final Point size; + + private final CompositeEntry[] entries; + + /** + * Constructs a CompositePiece with the given entries. + * + * @param entries + * an array of entries that make up this PrintPiece. + */ + public CompositePiece(CompositeEntry[] entries) { + this(createList(entries)); + } + + /** + * Constructs a CompositePrintPiece with the given entries and explicit + * size. This constructor will increase the explicit size to completely + * contain any child entries which extend outside the given size. + * + * @param entries + * an array of entries that make up this PrintPiece. + * @param size + */ + public CompositePiece(CompositeEntry[] entries, Point size) { + this(createList(entries), size); + } + + private static List createList(CompositeEntry[] entries) { + List result = new ArrayList<>(); + for (int i = 0; i < entries.length; i++) + result.add(entries[i]); + return result; + } + + /** + * Constructs a composite PrintPiece with the given entries. + * + * @param entries + * an array of entries that make up this PrintPiece. + */ + public CompositePiece(List entries) { + this(entries, new Point(0, 0)); + } + + /** + * Constructs a composite PrintPiece with the given entries and minimum + * size. + * + * @param entries + * a list of CompositeEntry objects describing the child + * PrintPieces. + * @param size + * a hint indicating the minimum size that should be reported + * from getSize(). This constructor increase this size to fit any + * entries that extend outside the given size. + */ + public CompositePiece(List entries, Point size) { + Util.noNulls(entries); + + this.entries = entries.toArray(new CompositeEntry[entries.size()]); + this.size = new Point(size.x, size.y); + + for (int i = 0; i < this.entries.length; i++) { + CompositeEntry entry = this.entries[i]; + Point pieceSize = entry.piece.getSize(); + this.size.x = Math.max(this.size.x, entry.offset.x + pieceSize.x); + this.size.y = Math.max(this.size.y, entry.offset.y + pieceSize.y); + } + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + public void paint(GC gc, int x, int y) { + // SWT on OSX has problems with the clipping. A GC(Printer) always + // returns a clipping rectangle of + // [0,0,0,0] so that inhibits our ability to check each entry against + // the hit rectangle. In addition it + // appears that a GC(Image(Printer))'s clipping on OSX is not affected + // by the GC's transform, so that + // screws up the hit clip as well. For this reason we are no longer + // checking entries to see if they + // intersect the clipping region before drawing them. + + for (int i = 0; i < entries.length; i++) { + CompositeEntry entry = entries[i]; + entry.piece.paint(gc, x + entry.offset.x, y + entry.offset.y); + } + } + + public void dispose() { + for (int i = 0; i < entries.length; i++) + entries[i].dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/DebugPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/DebugPrint.java index f00ed4bde..8673b5e90 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/DebugPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/DebugPrint.java @@ -1,93 +1,93 @@ -/* - * Copyright (c) 2009 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * Helper Print for debugging documents which fail to layout. Clients may set - * breakpoints inside the methods in this class (as well as DebugIterator and - * DebugPiece), then step into the target object's methods to trace the problem. - * - * @author Matthew Hall - * @deprecated Reminder to remove references to DebugPrint when you're done - * debugging a print job. - */ -public class DebugPrint implements Print { - private final Print target; - - /** - * @param target - * the Print object to debug - */ - public DebugPrint(Print target) { - this.target = target; - } - - public PrintIterator iterator(Device device, GC gc) { - PrintIterator iterator = target.iterator(device, gc); - return new DebugIterator(iterator); - } -} - -class DebugIterator implements PrintIterator { - private final PrintIterator target; - - DebugIterator(PrintIterator target) { - this.target = target; - } - - public PrintIterator copy() { - return new DebugIterator(target.copy()); - } - - public boolean hasNext() { - return target.hasNext(); - } - - public Point minimumSize() { - return target.minimumSize(); - } - - public PrintPiece next(int width, int height) { - PrintPiece piece = target.next(width, height); - return piece == null ? null : new DebugPiece(piece); - } - - public Point preferredSize() { - return target.preferredSize(); - } -} - -class DebugPiece implements PrintPiece { - private final PrintPiece target; - - DebugPiece(PrintPiece target) { - this.target = target; - } - - public void dispose() { - target.dispose(); - } - - public Point getSize() { - return target.getSize(); - } - - public void paint(GC gc, int x, int y) { - target.paint(gc, x, y); - } +/* + * Copyright (c) 2009 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * Helper Print for debugging documents which fail to layout. Clients may set + * breakpoints inside the methods in this class (as well as DebugIterator and + * DebugPiece), then step into the target object's methods to trace the problem. + * + * @author Matthew Hall + * @deprecated Reminder to remove references to DebugPrint when you're done + * debugging a print job. + */ +public class DebugPrint implements Print { + private final Print target; + + /** + * @param target + * the Print object to debug + */ + public DebugPrint(Print target) { + this.target = target; + } + + public PrintIterator iterator(Device device, GC gc) { + PrintIterator iterator = target.iterator(device, gc); + return new DebugIterator(iterator); + } +} + +class DebugIterator implements PrintIterator { + private final PrintIterator target; + + DebugIterator(PrintIterator target) { + this.target = target; + } + + public PrintIterator copy() { + return new DebugIterator(target.copy()); + } + + public boolean hasNext() { + return target.hasNext(); + } + + public Point minimumSize() { + return target.minimumSize(); + } + + public PrintPiece next(int width, int height) { + PrintPiece piece = target.next(width, height); + return piece == null ? null : new DebugPiece(piece); + } + + public Point preferredSize() { + return target.preferredSize(); + } +} + +class DebugPiece implements PrintPiece { + private final PrintPiece target; + + DebugPiece(PrintPiece target) { + this.target = target; + } + + public void dispose() { + target.dispose(); + } + + public Point getSize() { + return target.getSize(); + } + + public void paint(GC gc, int x, int y) { + target.paint(gc, x, y); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/EmptyPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/EmptyPrint.java index baf1c9427..5d7775eee 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/EmptyPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/EmptyPrint.java @@ -1,146 +1,146 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.piece.EmptyPiece; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A Print which displays nothing but takes up space. Useful for putting blank - * cells in a GridPrint. - * - * @author Matthew - */ -public class EmptyPrint implements Print { - final int width; - final int height; - - /** - * Constructs an EmptyPrint with size (0, 0). - */ - public EmptyPrint() { - this(0, 0); - } - - /** - * Constructs an EmptyPrint with the given size. - * - * @param width - * width of the Print, in points (72pts = 1"). - * @param height - * height of the Print, in points (72pts = 1"). - */ - public EmptyPrint(int width, int height) { - this.width = checkDimension(width); - this.height = checkDimension(height); - } - - /** - * Constructs an EmptyPrint with the given size. - * - * @param size - * the size, in points (72pts = 1"). - */ - public EmptyPrint(Point size) { - this(size.x, size.y); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + height; - result = prime * result + width; - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - EmptyPrint other = (EmptyPrint) obj; - if (height != other.height) - return false; - if (width != other.width) - return false; - return true; - } - - /** - * Returns the size of the empty space. - * - * @return the size of the empty space. - */ - public Point getSize() { - return new Point(width, height); - } - - private int checkDimension(int dim) { - if (dim < 0) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "EmptyPrint dimensions must be >= 0"); //$NON-NLS-1$ - return dim; - } - - public PrintIterator iterator(Device device, GC gc) { - return new EmptyIterator(device, this); - } -} - -class EmptyIterator implements PrintIterator { - private final Point size; - - private boolean hasNext = true; - - EmptyIterator(Device device, EmptyPrint target) { - Point dpi = device.getDPI(); - this.size = new Point(Math.round(target.width * dpi.x / 72f), Math - .round(target.height * dpi.y / 72f)); - } - - EmptyIterator(EmptyIterator that) { - this.size = that.size; - this.hasNext = that.hasNext; - } - - public boolean hasNext() { - return hasNext; - } - - public PrintPiece next(int width, int height) { - if (size.x > width || size.y > height) - return null; - - hasNext = false; - - return new EmptyPiece(size); - } - - public Point minimumSize() { - return new Point(size.x, size.y); - } - - public Point preferredSize() { - return new Point(size.x, size.y); - } - - public PrintIterator copy() { - return new EmptyIterator(this); - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.piece.EmptyPiece; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A Print which displays nothing but takes up space. Useful for putting blank + * cells in a GridPrint. + * + * @author Matthew + */ +public class EmptyPrint implements Print { + final int width; + final int height; + + /** + * Constructs an EmptyPrint with size (0, 0). + */ + public EmptyPrint() { + this(0, 0); + } + + /** + * Constructs an EmptyPrint with the given size. + * + * @param width + * width of the Print, in points (72pts = 1"). + * @param height + * height of the Print, in points (72pts = 1"). + */ + public EmptyPrint(int width, int height) { + this.width = checkDimension(width); + this.height = checkDimension(height); + } + + /** + * Constructs an EmptyPrint with the given size. + * + * @param size + * the size, in points (72pts = 1"). + */ + public EmptyPrint(Point size) { + this(size.x, size.y); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + height; + result = prime * result + width; + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EmptyPrint other = (EmptyPrint) obj; + if (height != other.height) + return false; + if (width != other.width) + return false; + return true; + } + + /** + * Returns the size of the empty space. + * + * @return the size of the empty space. + */ + public Point getSize() { + return new Point(width, height); + } + + private int checkDimension(int dim) { + if (dim < 0) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "EmptyPrint dimensions must be >= 0"); //$NON-NLS-1$ + return dim; + } + + public PrintIterator iterator(Device device, GC gc) { + return new EmptyIterator(device, this); + } +} + +class EmptyIterator implements PrintIterator { + private final Point size; + + private boolean hasNext = true; + + EmptyIterator(Device device, EmptyPrint target) { + Point dpi = device.getDPI(); + this.size = new Point(Math.round(target.width * dpi.x / 72f), Math + .round(target.height * dpi.y / 72f)); + } + + EmptyIterator(EmptyIterator that) { + this.size = that.size; + this.hasNext = that.hasNext; + } + + public boolean hasNext() { + return hasNext; + } + + public PrintPiece next(int width, int height) { + if (size.x > width || size.y > height) + return null; + + hasNext = false; + + return new EmptyPiece(size); + } + + public Point minimumSize() { + return new Point(size.x, size.y); + } + + public Point preferredSize() { + return new Point(size.x, size.y); + } + + public PrintIterator copy() { + return new EmptyIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ImagePrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ImagePrint.java index cb99ff2e3..3303e6ac6 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ImagePrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ImagePrint.java @@ -1,259 +1,259 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.SWTUtil; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; - -/** - * A Print for displaying images. - * - * @author Matthew Hall - */ -public class ImagePrint implements Print { - ImageData imageData; - Point dpi; - Point size; - - /** - * Constructs an ImagePrint with the given imageData, initialized at 72dpi. - * - * @param imageData - * the image to be displayed. - */ - public ImagePrint(ImageData imageData) { - this(imageData, new Point(72, 72)); - } - - /** - * Constructs an ImagePrint with the given imageData and dpi. - * - * @param imageData - * the image to be displayed. - * @param dpi - * the DPI that the image will be displayed at. - */ - public ImagePrint(ImageData imageData, Point dpi) { - Util.notNull(imageData, dpi); - this.imageData = imageData; - setDPI(dpi); - } - - /** - * Returns the ImageData of the image being printed. - * - * @return the ImageData of the image being printed. - */ - public ImageData getImageData() { - return imageData; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - - ImagePrint that = (ImagePrint) obj; - return Util.equal(this.dpi, that.dpi) - && Util.equal(this.size, that.size) - && SWTUtil.equal(this.imageData, that.imageData); - } - - public int hashCode() { - int prime = 31; - int result = 1; - result = prime * result + dpi.hashCode(); - result = prime * result + size.hashCode(); - result = prime * result + SWTUtil.hashCode(imageData); - return result; - } - - /** - * Sets the ImagePrint to render the image at the given size, in points. 72 - * points = 1". - * - * @param size - * the explicit size, in points, that the image be printed at. - */ - public void setSize(Point size) { - // The DPI is rounded up, so that the specified width and height will - // not be exceeded. - Util.notNull(size); - dpi = new Point((int) Math.ceil(imageData.width * 72d / size.x), - (int) Math.ceil(imageData.height * 72d / size.y)); - this.size = size; - } - - /** - * Sets the ImagePrint to render the image at the given size, in points. 72 - * points = 1". - * - * @param width - * the explicit width, in points, that the image will be printed - * at. - * @param height - * the explicit height, in points, that the image will be printed - * at. - */ - public void setSize(int width, int height) { - setSize(new Point(width, height)); - } - - /** - * Returns the size that the image will be rendered at, in points. 72 points - * = 1". - * - * @return the size of the image, in points. - */ - public Point getSize() { - return size; - } - - /** - * Sets the ImagePrint to render the image at the DPI of the argument. - * - * @param dpi - * the DPI of the image. - */ - public void setDPI(Point dpi) { - Util.notNull(dpi); - this.dpi = dpi; - size = new Point((int) Math.ceil(imageData.width * 72d / dpi.x), - (int) Math.ceil(imageData.height * 72d / dpi.y)); - } - - /** - * Sets the ImagePrint to render the image at the given DPI. - * - * @param dpiX - * the horizontal DPI the image will be rendered at. - * @param dpiY - * the vertical DPI the image will be rendered at. - */ - public void setDPI(int dpiX, int dpiY) { - setDPI(new Point(dpiX, dpiY)); - } - - /** - * Returns the DPI that this image will be rendered at. - * - * @return the DPI the image will be rendered at. - */ - public Point getDPI() { - return dpi; - } - - public PrintIterator iterator(Device device, GC gc) { - return new ImageIterator(this, device); - } -} - -class ImageIterator implements PrintIterator { - final Device device; - - final ImageData imageData; - final Point size; - - boolean hasNext; - - ImageIterator(ImagePrint print, Device device) { - Util.notNull(print, device); - this.device = device; - this.imageData = print.imageData; - Point dpi = device.getDPI(); - this.size = new Point(print.size.x * dpi.x / 72, print.size.y * dpi.y - / 72); - this.hasNext = true; - } - - ImageIterator(ImageIterator that) { - this.device = that.device; - this.imageData = that.imageData; - this.size = that.size; - this.hasNext = that.hasNext; - } - - public boolean hasNext() { - return hasNext; - } - - public PrintPiece next(int width, int height) { - if (!hasNext()) - PaperClips.error("No more content."); //$NON-NLS-1$ - - if (width < size.x || height < size.y) - return null; - - hasNext = false; - - return new ImagePiece(device, imageData, size); - } - - public Point minimumSize() { - return new Point(size.x, size.y); - } - - public Point preferredSize() { - return new Point(size.x, size.y); - } - - public PrintIterator copy() { - return hasNext ? new ImageIterator(this) : this; - } -} - -class ImagePiece implements PrintPiece { - private final Device device; - private final ImageData imageData; - private final Point size; - - private Image image; - - ImagePiece(Device device, ImageData imageData, Point size) { - Util.notNull(device, imageData, size); - this.device = device; - this.imageData = imageData; - this.size = size; - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - private Image getImage() { - if (image == null) - image = new Image(device, imageData); - return image; - } - - public void paint(GC gc, int x, int y) { - gc.drawImage(getImage(), 0, 0, imageData.width, imageData.height, x, y, - size.x, size.y); - } - - public void dispose() { - if (image != null) { - image.dispose(); - image = null; - } - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.SWTUtil; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; + +/** + * A Print for displaying images. + * + * @author Matthew Hall + */ +public class ImagePrint implements Print { + ImageData imageData; + Point dpi; + Point size; + + /** + * Constructs an ImagePrint with the given imageData, initialized at 72dpi. + * + * @param imageData + * the image to be displayed. + */ + public ImagePrint(ImageData imageData) { + this(imageData, new Point(72, 72)); + } + + /** + * Constructs an ImagePrint with the given imageData and dpi. + * + * @param imageData + * the image to be displayed. + * @param dpi + * the DPI that the image will be displayed at. + */ + public ImagePrint(ImageData imageData, Point dpi) { + Util.notNull(imageData, dpi); + this.imageData = imageData; + setDPI(dpi); + } + + /** + * Returns the ImageData of the image being printed. + * + * @return the ImageData of the image being printed. + */ + public ImageData getImageData() { + return imageData; + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + ImagePrint that = (ImagePrint) obj; + return Util.equal(this.dpi, that.dpi) + && Util.equal(this.size, that.size) + && SWTUtil.equal(this.imageData, that.imageData); + } + + public int hashCode() { + int prime = 31; + int result = 1; + result = prime * result + dpi.hashCode(); + result = prime * result + size.hashCode(); + result = prime * result + SWTUtil.hashCode(imageData); + return result; + } + + /** + * Sets the ImagePrint to render the image at the given size, in points. 72 + * points = 1". + * + * @param size + * the explicit size, in points, that the image be printed at. + */ + public void setSize(Point size) { + // The DPI is rounded up, so that the specified width and height will + // not be exceeded. + Util.notNull(size); + dpi = new Point((int) Math.ceil(imageData.width * 72d / size.x), + (int) Math.ceil(imageData.height * 72d / size.y)); + this.size = size; + } + + /** + * Sets the ImagePrint to render the image at the given size, in points. 72 + * points = 1". + * + * @param width + * the explicit width, in points, that the image will be printed + * at. + * @param height + * the explicit height, in points, that the image will be printed + * at. + */ + public void setSize(int width, int height) { + setSize(new Point(width, height)); + } + + /** + * Returns the size that the image will be rendered at, in points. 72 points + * = 1". + * + * @return the size of the image, in points. + */ + public Point getSize() { + return size; + } + + /** + * Sets the ImagePrint to render the image at the DPI of the argument. + * + * @param dpi + * the DPI of the image. + */ + public void setDPI(Point dpi) { + Util.notNull(dpi); + this.dpi = dpi; + size = new Point((int) Math.ceil(imageData.width * 72d / dpi.x), + (int) Math.ceil(imageData.height * 72d / dpi.y)); + } + + /** + * Sets the ImagePrint to render the image at the given DPI. + * + * @param dpiX + * the horizontal DPI the image will be rendered at. + * @param dpiY + * the vertical DPI the image will be rendered at. + */ + public void setDPI(int dpiX, int dpiY) { + setDPI(new Point(dpiX, dpiY)); + } + + /** + * Returns the DPI that this image will be rendered at. + * + * @return the DPI the image will be rendered at. + */ + public Point getDPI() { + return dpi; + } + + public PrintIterator iterator(Device device, GC gc) { + return new ImageIterator(this, device); + } +} + +class ImageIterator implements PrintIterator { + final Device device; + + final ImageData imageData; + final Point size; + + boolean hasNext; + + ImageIterator(ImagePrint print, Device device) { + Util.notNull(print, device); + this.device = device; + this.imageData = print.imageData; + Point dpi = device.getDPI(); + this.size = new Point(print.size.x * dpi.x / 72, print.size.y * dpi.y + / 72); + this.hasNext = true; + } + + ImageIterator(ImageIterator that) { + this.device = that.device; + this.imageData = that.imageData; + this.size = that.size; + this.hasNext = that.hasNext; + } + + public boolean hasNext() { + return hasNext; + } + + public PrintPiece next(int width, int height) { + if (!hasNext()) + PaperClips.error("No more content."); //$NON-NLS-1$ + + if (width < size.x || height < size.y) + return null; + + hasNext = false; + + return new ImagePiece(device, imageData, size); + } + + public Point minimumSize() { + return new Point(size.x, size.y); + } + + public Point preferredSize() { + return new Point(size.x, size.y); + } + + public PrintIterator copy() { + return hasNext ? new ImageIterator(this) : this; + } +} + +class ImagePiece implements PrintPiece { + private final Device device; + private final ImageData imageData; + private final Point size; + + private Image image; + + ImagePiece(Device device, ImageData imageData, Point size) { + Util.notNull(device, imageData, size); + this.device = device; + this.imageData = imageData; + this.size = size; + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + private Image getImage() { + if (image == null) + image = new Image(device, imageData); + return image; + } + + public void paint(GC gc, int x, int y) { + gc.drawImage(getImage(), 0, 0, imageData.width, imageData.height, x, y, + size.x, size.y); + } + + public void dispose() { + if (image != null) { + image.dispose(); + image = null; + } + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LayerEntry.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LayerEntry.java index 3cad07e5e..a4cbf5bdd 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LayerEntry.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LayerEntry.java @@ -1,47 +1,47 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -/** - * Instances implementing this interface are representing an entry in a - * LayerPrint. - * - * @author Matthew Hall - */ -public interface LayerEntry { - - /** - * Returns the target print of this entry. - * - * @return the target print of this entry. - */ - Print getTarget(); - - /** - * Returns the horizontal alignment applied to the target. - * - * @return the horizontal alignment applied to the target. - */ - int getHorizontalAlignment(); - - /** - * @param device - * @param gc - * @return the associated iterator for this entry - */ - LayerEntryIterator iterator(Device device, GC gc); +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +/** + * Instances implementing this interface are representing an entry in a + * LayerPrint. + * + * @author Matthew Hall + */ +public interface LayerEntry { + + /** + * Returns the target print of this entry. + * + * @return the target print of this entry. + */ + Print getTarget(); + + /** + * Returns the horizontal alignment applied to the target. + * + * @return the horizontal alignment applied to the target. + */ + int getHorizontalAlignment(); + + /** + * @param device + * @param gc + * @return the associated iterator for this entry + */ + LayerEntryIterator iterator(Device device, GC gc); } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LayerPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LayerPrint.java index f4045d30c..58567619a 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LayerPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LayerPrint.java @@ -1,106 +1,106 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.internal.LayerEntryImpl; -import org.eclipse.nebula.paperclips.core.internal.LayerIterator; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -/** - * A Print which displays its child Prints on top each other. - * - * @author Matthew Hall - */ -public class LayerPrint implements Print { - /** - * Constant for the default alignment of child Prints. Value is SWT.LEFT. - */ - public static final int DEFAULT_ALIGN = SWT.LEFT; - - // List - final List entries = new ArrayList<>(); - - /** - * Constructs a new LayerPrint. - */ - public LayerPrint() { - } - - /** - * Adds the given Print to this LayerPrint using the default alignment. - * - * @param print - * the Print to add. - * @see #DEFAULT_ALIGN - */ - public void add(Print print) { - entries.add(new LayerEntryImpl(print, DEFAULT_ALIGN)); - } - - /** - * Adds the given Print to this LayerPrint using the specified alignment. - * - * @param print - * the Print to add. - * @param align - * the alignment for the Print. May be one of SWT.LEFT, - * SWT.CENTER, or SWT.RIGHT. - */ - public void add(Print print, int align) { - entries.add(new LayerEntryImpl(print, align)); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((entries == null) ? 0 : entries.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LayerPrint other = (LayerPrint) obj; - if (entries == null) { - if (other.entries != null) - return false; - } else if (!entries.equals(other.entries)) - return false; - return true; - } - - /** - * Returns an array of entries in this LayerPrint. - * - * @return an array of entries in this LayerPrint. - */ - public LayerEntry[] getEntries() { - return entries.toArray(new LayerEntry[entries.size()]); - } - - public PrintIterator iterator(Device device, GC gc) { - return new LayerIterator(this, device, gc); - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.internal.LayerEntryImpl; +import org.eclipse.nebula.paperclips.core.internal.LayerIterator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +/** + * A Print which displays its child Prints on top each other. + * + * @author Matthew Hall + */ +public class LayerPrint implements Print { + /** + * Constant for the default alignment of child Prints. Value is SWT.LEFT. + */ + public static final int DEFAULT_ALIGN = SWT.LEFT; + + // List + final List entries = new ArrayList<>(); + + /** + * Constructs a new LayerPrint. + */ + public LayerPrint() { + } + + /** + * Adds the given Print to this LayerPrint using the default alignment. + * + * @param print + * the Print to add. + * @see #DEFAULT_ALIGN + */ + public void add(Print print) { + entries.add(new LayerEntryImpl(print, DEFAULT_ALIGN)); + } + + /** + * Adds the given Print to this LayerPrint using the specified alignment. + * + * @param print + * the Print to add. + * @param align + * the alignment for the Print. May be one of SWT.LEFT, + * SWT.CENTER, or SWT.RIGHT. + */ + public void add(Print print, int align) { + entries.add(new LayerEntryImpl(print, align)); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((entries == null) ? 0 : entries.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LayerPrint other = (LayerPrint) obj; + if (entries == null) { + if (other.entries != null) + return false; + } else if (!entries.equals(other.entries)) + return false; + return true; + } + + /** + * Returns an array of entries in this LayerPrint. + * + * @return an array of entries in this LayerPrint. + */ + public LayerEntry[] getEntries() { + return entries.toArray(new LayerEntry[entries.size()]); + } + + public PrintIterator iterator(Device device, GC gc) { + return new LayerIterator(this, device, gc); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LinePrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LinePrint.java index 78a5c955c..3121340ce 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LinePrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/LinePrint.java @@ -1,271 +1,271 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; - -/** - * A Print for drawing horizontal and vertical lines. - *

- * LinePrints are either horizontally or vertically greedy, according to the - * orientation of the line. Greedy prints take up all the available space on the - * page. - * - * @author Matthew Hall - */ -public class LinePrint implements Print { - final int orientation; - - double thickness; - - RGB rgb = new RGB(0, 0, 0); - - /** - * Constructs a horizontal LinePrint. - */ - public LinePrint() { - this(SWT.HORIZONTAL); - } - - /** - * Constructs a LinePrint with the given orientation and 1-point thickness. - * - * @param orientation - * one of SWT#HORIZONTAL or SWT#VERTICAL. - */ - public LinePrint(int orientation) { - this(orientation, 1.0); - } - - /** - * Constructs a LinePrint with the given orientation and thickness. - * - * @param orientation - * one of SWT#HORIZONTAL or SWT#VERTICAL. - * @param thickness - * the line thickness, expressed in points. - */ - public LinePrint(int orientation, double thickness) { - this.orientation = checkOrientation(orientation); - this.thickness = checkThickness(thickness); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + orientation; - result = prime * result + ((rgb == null) ? 0 : rgb.hashCode()); - long temp; - temp = Double.doubleToLongBits(thickness); - result = prime * result + (int) (temp ^ (temp >>> 32)); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LinePrint other = (LinePrint) obj; - if (orientation != other.orientation) - return false; - if (rgb == null) { - if (other.rgb != null) - return false; - } else if (!rgb.equals(other.rgb)) - return false; - if (Double.doubleToLongBits(thickness) != Double - .doubleToLongBits(other.thickness)) - return false; - return true; - } - - /** - * Returns the line orientation (one of {@link SWT#HORIZONTAL} or - * {@link SWT#VERTICAL}). - * - * @return the line orientation. - */ - public int getOrientation() { - return orientation; - } - - private int checkOrientation(int orientation) { - if ((orientation & SWT.HORIZONTAL) == SWT.HORIZONTAL) - return SWT.HORIZONTAL; - else if ((orientation & SWT.VERTICAL) == SWT.VERTICAL) - return SWT.VERTICAL; - else - return SWT.HORIZONTAL; - } - - private double checkThickness(double thickness) { - if (thickness < 0) - return 0; - return thickness; - } - - /** - * Returns the line thickness, in points. 72 points = 1". - * - * @return the line thickness, in points. - */ - public double getThickness() { - return thickness; - } - - /** - * Sets the line thickness, in points. 72 points = 1". - * - * @param thickness - * the line thickness, in points. - */ - public void setThickness(double thickness) { - this.thickness = thickness; - } - - /** - * Sets the line color to the argument. - * - * @param foreground - * the new line color. - */ - public void setRGB(RGB foreground) { - Util.notNull(foreground); - this.rgb = foreground; - } - - /** - * Returns the line color. - * - * @return the line color. - */ - public RGB getRGB() { - return rgb; - } - - public PrintIterator iterator(Device device, GC gc) { - return new LineIterator(this, device, gc); - } -} - -class LineIterator implements PrintIterator { - private final Device device; - private final GC gc; - - final int orientation; - final Point thickness; - final RGB rgb; - - private boolean hasNext = true; - - LineIterator(LinePrint print, Device device, GC gc) { - this.device = device; - this.gc = gc; - - this.orientation = print.orientation; - this.rgb = print.rgb; - Point dpi = device.getDPI(); - - // (convert from points to pixels on device) - this.thickness = new Point(Math.max(1, (int) Math.round(print.thickness - * dpi.x / 72)), Math.max(1, (int) Math.round(print.thickness - * dpi.y / 72))); - } - - LineIterator(LineIterator that) { - this.device = that.device; - this.gc = that.gc; - - this.orientation = that.orientation; - this.rgb = that.rgb; - this.hasNext = that.hasNext; - this.thickness = that.thickness; - } - - public boolean hasNext() { - return hasNext; - } - - Point getSize(int width, int height) { - return orientation == SWT.VERTICAL ? new Point(thickness.x, height) - : new Point(width, thickness.y); - } - - public PrintPiece next(int width, int height) { - if (!hasNext()) - PaperClips.error("No more content"); //$NON-NLS-1$ - - // Make sure the line fits :) - Point size = getSize(width, height); - if (size.x > width || size.y > height) - return null; - - PrintPiece result = new LinePiece(device, size, rgb); - hasNext = false; - - return result; - } - - public Point minimumSize() { - return new Point(thickness.x, thickness.y); - } - - public Point preferredSize() { - return new Point(thickness.x, thickness.y); - } - - public PrintIterator copy() { - return new LineIterator(this); - } -} - -class LinePiece implements PrintPiece { - private final Device device; - private final Point size; - private final RGB rgb; - - LinePiece(Device device, Point size, RGB rgb) { - this.device = device; - this.size = size; - this.rgb = rgb; - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - public void paint(GC gc, int x, int y) { - Color oldBackground = gc.getBackground(); - Point size = getSize(); - try { - gc.setBackground(ResourcePool.forDevice(device).getColor(rgb)); - gc.fillRectangle(x, y, size.x, size.y); - } finally { - gc.setBackground(oldBackground); - } - } - - public void dispose() { - } // Shared resources, nothing to dispose +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; + +/** + * A Print for drawing horizontal and vertical lines. + *

+ * LinePrints are either horizontally or vertically greedy, according to the + * orientation of the line. Greedy prints take up all the available space on the + * page. + * + * @author Matthew Hall + */ +public class LinePrint implements Print { + final int orientation; + + double thickness; + + RGB rgb = new RGB(0, 0, 0); + + /** + * Constructs a horizontal LinePrint. + */ + public LinePrint() { + this(SWT.HORIZONTAL); + } + + /** + * Constructs a LinePrint with the given orientation and 1-point thickness. + * + * @param orientation + * one of SWT#HORIZONTAL or SWT#VERTICAL. + */ + public LinePrint(int orientation) { + this(orientation, 1.0); + } + + /** + * Constructs a LinePrint with the given orientation and thickness. + * + * @param orientation + * one of SWT#HORIZONTAL or SWT#VERTICAL. + * @param thickness + * the line thickness, expressed in points. + */ + public LinePrint(int orientation, double thickness) { + this.orientation = checkOrientation(orientation); + this.thickness = checkThickness(thickness); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + orientation; + result = prime * result + ((rgb == null) ? 0 : rgb.hashCode()); + long temp; + temp = Double.doubleToLongBits(thickness); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LinePrint other = (LinePrint) obj; + if (orientation != other.orientation) + return false; + if (rgb == null) { + if (other.rgb != null) + return false; + } else if (!rgb.equals(other.rgb)) + return false; + if (Double.doubleToLongBits(thickness) != Double + .doubleToLongBits(other.thickness)) + return false; + return true; + } + + /** + * Returns the line orientation (one of {@link SWT#HORIZONTAL} or + * {@link SWT#VERTICAL}). + * + * @return the line orientation. + */ + public int getOrientation() { + return orientation; + } + + private int checkOrientation(int orientation) { + if ((orientation & SWT.HORIZONTAL) == SWT.HORIZONTAL) + return SWT.HORIZONTAL; + else if ((orientation & SWT.VERTICAL) == SWT.VERTICAL) + return SWT.VERTICAL; + else + return SWT.HORIZONTAL; + } + + private double checkThickness(double thickness) { + if (thickness < 0) + return 0; + return thickness; + } + + /** + * Returns the line thickness, in points. 72 points = 1". + * + * @return the line thickness, in points. + */ + public double getThickness() { + return thickness; + } + + /** + * Sets the line thickness, in points. 72 points = 1". + * + * @param thickness + * the line thickness, in points. + */ + public void setThickness(double thickness) { + this.thickness = thickness; + } + + /** + * Sets the line color to the argument. + * + * @param foreground + * the new line color. + */ + public void setRGB(RGB foreground) { + Util.notNull(foreground); + this.rgb = foreground; + } + + /** + * Returns the line color. + * + * @return the line color. + */ + public RGB getRGB() { + return rgb; + } + + public PrintIterator iterator(Device device, GC gc) { + return new LineIterator(this, device, gc); + } +} + +class LineIterator implements PrintIterator { + private final Device device; + private final GC gc; + + final int orientation; + final Point thickness; + final RGB rgb; + + private boolean hasNext = true; + + LineIterator(LinePrint print, Device device, GC gc) { + this.device = device; + this.gc = gc; + + this.orientation = print.orientation; + this.rgb = print.rgb; + Point dpi = device.getDPI(); + + // (convert from points to pixels on device) + this.thickness = new Point(Math.max(1, (int) Math.round(print.thickness + * dpi.x / 72)), Math.max(1, (int) Math.round(print.thickness + * dpi.y / 72))); + } + + LineIterator(LineIterator that) { + this.device = that.device; + this.gc = that.gc; + + this.orientation = that.orientation; + this.rgb = that.rgb; + this.hasNext = that.hasNext; + this.thickness = that.thickness; + } + + public boolean hasNext() { + return hasNext; + } + + Point getSize(int width, int height) { + return orientation == SWT.VERTICAL ? new Point(thickness.x, height) + : new Point(width, thickness.y); + } + + public PrintPiece next(int width, int height) { + if (!hasNext()) + PaperClips.error("No more content"); //$NON-NLS-1$ + + // Make sure the line fits :) + Point size = getSize(width, height); + if (size.x > width || size.y > height) + return null; + + PrintPiece result = new LinePiece(device, size, rgb); + hasNext = false; + + return result; + } + + public Point minimumSize() { + return new Point(thickness.x, thickness.y); + } + + public Point preferredSize() { + return new Point(thickness.x, thickness.y); + } + + public PrintIterator copy() { + return new LineIterator(this); + } +} + +class LinePiece implements PrintPiece { + private final Device device; + private final Point size; + private final RGB rgb; + + LinePiece(Device device, Point size, RGB rgb) { + this.device = device; + this.size = size; + this.rgb = rgb; + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + public void paint(GC gc, int x, int y) { + Color oldBackground = gc.getBackground(); + Point size = getSize(); + try { + gc.setBackground(ResourcePool.forDevice(device).getColor(rgb)); + gc.fillRectangle(x, y, size.x, size.y); + } finally { + gc.setBackground(oldBackground); + } + } + + public void dispose() { + } // Shared resources, nothing to dispose } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Margins.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Margins.java index 5a2b8aa68..a250af6a5 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Margins.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Margins.java @@ -1,98 +1,98 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -/** - * Instances of this class represent the page margins to follow when processing - * a print job. - * - * @author Matthew Hall - */ -public class Margins { - /** The top margin. */ - public int top; - - /** The left margin. */ - public int left; - - /** The right margin. */ - public int right; - - /** The bottom margin. */ - public int bottom; - - /** - * Constructs a Margins with all sides set to 1" margins. - */ - public Margins() { - this(72); - } - - /** - * Constructs a Margins with all sides set to the argument. - * - * @param margins - * the page margins, expressed in points. 72 points = 1". - */ - public Margins(int margins) { - top = left = right = bottom = margins; - } - - /** - * Returns a Margins that is the result of rotating this Margins - * counter-clockwise 90 degrees. A job which is rotated 90 degrees (e.g. for - * landscape printing) needs to have its margins rotated to match. This is a - * convenience method for that purpose. - * - * @return a Margins that is the result of rotating this Margins - * counter-clockwise 90 degrees. - */ - public Margins rotate() { - Margins result = new Margins(); - result.top = right; - result.left = top; - result.right = bottom; - result.bottom = left; - return result; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + bottom; - result = prime * result + left; - result = prime * result + right; - result = prime * result + top; - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Margins other = (Margins) obj; - if (bottom != other.bottom) - return false; - if (left != other.left) - return false; - if (right != other.right) - return false; - if (top != other.top) - return false; - return true; - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +/** + * Instances of this class represent the page margins to follow when processing + * a print job. + * + * @author Matthew Hall + */ +public class Margins { + /** The top margin. */ + public int top; + + /** The left margin. */ + public int left; + + /** The right margin. */ + public int right; + + /** The bottom margin. */ + public int bottom; + + /** + * Constructs a Margins with all sides set to 1" margins. + */ + public Margins() { + this(72); + } + + /** + * Constructs a Margins with all sides set to the argument. + * + * @param margins + * the page margins, expressed in points. 72 points = 1". + */ + public Margins(int margins) { + top = left = right = bottom = margins; + } + + /** + * Returns a Margins that is the result of rotating this Margins + * counter-clockwise 90 degrees. A job which is rotated 90 degrees (e.g. for + * landscape printing) needs to have its margins rotated to match. This is a + * convenience method for that purpose. + * + * @return a Margins that is the result of rotating this Margins + * counter-clockwise 90 degrees. + */ + public Margins rotate() { + Margins result = new Margins(); + result.top = right; + result.left = top; + result.right = bottom; + result.bottom = left; + return result; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + bottom; + result = prime * result + left; + result = prime * result + right; + result = prime * result + top; + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Margins other = (Margins) obj; + if (bottom != other.bottom) + return false; + if (left != other.left) + return false; + if (right != other.right) + return false; + if (top != other.top) + return false; + return true; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Messages.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Messages.java index b81166b3a..1d6fd3447 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Messages.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Messages.java @@ -1,53 +1,53 @@ -/* - * Copyright (c) 2008 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -/** - * Convenience methods for retrieving locale-specific messages. - * - * @author Matthew Hall - * @since 1.0.4 - */ -public class Messages { - private static final String BUNDLE_NAME = "org.eclipse.nebula.paperclips.core.messages"; //$NON-NLS-1$ - - private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle - .getBundle(BUNDLE_NAME); - - /** - * Key for "Page {x} of {y}" used by DefaultPageNumberFormat. - */ - public static final String PAGE_X_OF_Y = "PAGE_X_OF_Y"; //$NON-NLS-1$ - - private Messages() { - } - - /** - * Returns the locale-specific messages for the given key. - * - * @param key - * the key identifying the string to be retrieved. - * @return the locale-specific messages for the given key. - */ - public static String getString(String key) { - try { - return RESOURCE_BUNDLE.getString(key); - } catch (MissingResourceException e) { - return '!' + key + '!'; - } - } -} +/* + * Copyright (c) 2008 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * Convenience methods for retrieving locale-specific messages. + * + * @author Matthew Hall + * @since 1.0.4 + */ +public class Messages { + private static final String BUNDLE_NAME = "org.eclipse.nebula.paperclips.core.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + /** + * Key for "Page {x} of {y}" used by DefaultPageNumberFormat. + */ + public static final String PAGE_X_OF_Y = "PAGE_X_OF_Y"; //$NON-NLS-1$ + + private Messages() { + } + + /** + * Returns the locale-specific messages for the given key. + * + * @param key + * the key identifying the string to be retrieved. + * @return the locale-specific messages for the given key. + */ + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/NoBreakPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/NoBreakPrint.java index 1a4ee5edc..5b1dd6734 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/NoBreakPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/NoBreakPrint.java @@ -1,123 +1,123 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A print wrapper which prevents its target from being broken into multiple - * pieces when printed. If there isn't enough room to print the target in one - * piece on the current page (or column, if it's inside a ColumnPrint), it will - * be printed on the next page (or column). - * - *

- * Care must be taken when using this class to avoid unprintable documents. If - * the target of a NoBreakPrint does not fit in the available space on the print - * device, the entire document will fail to print. - * - * @author Matthew Hall - */ -public class NoBreakPrint implements Print { - private final Print target; - - /** - * Constructs a NoBreakPrint with the given target. - * - * @param target - * the print to - */ - public NoBreakPrint(Print target) { - Util.notNull(target); - this.target = target; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - NoBreakPrint other = (NoBreakPrint) obj; - if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) - return false; - return true; - } - - /** - * Returns the print which will not be broken across pages. - * - * @return the print which will not be broken across pages. - */ - public Print getTarget() { - return target; - } - - public PrintIterator iterator(Device device, GC gc) { - return new NoBreakIterator(target.iterator(device, gc)); - } -} - -class NoBreakIterator implements PrintIterator { - private PrintIterator target; - - NoBreakIterator(PrintIterator target) { - Util.notNull(target); - this.target = target; - } - - public PrintIterator copy() { - return new NoBreakIterator(target.copy()); - } - - public boolean hasNext() { - return target.hasNext(); - } - - public Point minimumSize() { - return target.minimumSize(); - } - - public Point preferredSize() { - return target.preferredSize(); - } - - public PrintPiece next(int width, int height) { - // Use a test iterator so we preserve the original iterator - PrintIterator iter = target.copy(); - - PrintPiece result = PaperClips.next(iter, width, height); - if (result == null) - return result; - - if (iter.hasNext()) // Failed to layout the whole target in one piece - return null; - - this.target = iter; - return result; - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A print wrapper which prevents its target from being broken into multiple + * pieces when printed. If there isn't enough room to print the target in one + * piece on the current page (or column, if it's inside a ColumnPrint), it will + * be printed on the next page (or column). + * + *

+ * Care must be taken when using this class to avoid unprintable documents. If + * the target of a NoBreakPrint does not fit in the available space on the print + * device, the entire document will fail to print. + * + * @author Matthew Hall + */ +public class NoBreakPrint implements Print { + private final Print target; + + /** + * Constructs a NoBreakPrint with the given target. + * + * @param target + * the print to + */ + public NoBreakPrint(Print target) { + Util.notNull(target); + this.target = target; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NoBreakPrint other = (NoBreakPrint) obj; + if (target == null) { + if (other.target != null) + return false; + } else if (!target.equals(other.target)) + return false; + return true; + } + + /** + * Returns the print which will not be broken across pages. + * + * @return the print which will not be broken across pages. + */ + public Print getTarget() { + return target; + } + + public PrintIterator iterator(Device device, GC gc) { + return new NoBreakIterator(target.iterator(device, gc)); + } +} + +class NoBreakIterator implements PrintIterator { + private PrintIterator target; + + NoBreakIterator(PrintIterator target) { + Util.notNull(target); + this.target = target; + } + + public PrintIterator copy() { + return new NoBreakIterator(target.copy()); + } + + public boolean hasNext() { + return target.hasNext(); + } + + public Point minimumSize() { + return target.minimumSize(); + } + + public Point preferredSize() { + return target.preferredSize(); + } + + public PrintPiece next(int width, int height) { + // Use a test iterator so we preserve the original iterator + PrintIterator iter = target.copy(); + + PrintPiece result = PaperClips.next(iter, width, height); + if (result == null) + return result; + + if (iter.hasNext()) // Failed to layout the whole target in one piece + return null; + + this.target = iter; + return result; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/NullPrintPiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/NullPrintPiece.java index abc267387..cb4de19ae 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/NullPrintPiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/NullPrintPiece.java @@ -1,30 +1,30 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ - -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -final class NullPrintPiece implements PrintPiece { - public Point getSize() { - return new Point(0, 0); - } - - public void paint(GC gc, int x, int y) { - } - - public void dispose() { - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ + +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +final class NullPrintPiece implements PrintPiece { + public Point getSize() { + return new Point(0, 0); + } + + public void paint(GC gc, int x, int y) { + } + + public void dispose() { + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PageEnumeration.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PageEnumeration.java index 277e59060..8cc6fe98e 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PageEnumeration.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PageEnumeration.java @@ -1,116 +1,116 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.printing.Printer; - -/** - * An enumeration of pages for given print job on the given printer device. Each - * element in the enumeration has already had the page orientation and page - * margins applied. Therefore, when calling the paint(GC, int, int) method on - * each page, the printer's trim should be provided as the x and y arguments. In - * other words, the trim is taken as a minimum margin while applying calculating - * margins, but the position where the page's content is drawn is determined - * solely by the margin, and is not offset by the trim. This behavior is helpful - * for screen display, and is already compensated for in the - * {@link PaperClips#print(PrintJob, Printer) } method. - * - * @see PaperClips#getPages(PrintJob, Printer) - * @author Matthew Hall - */ -public class PageEnumeration { - private PrintIterator document; - private Rectangle marginBounds; - private Rectangle paperBounds; - - private boolean hasNext; - - PageEnumeration(PrintJob job, Printer printer, GC gc) { - // Rotate the document (and margins with it) depending on print job - // orientation. - job = applyOrientation(job, printer); - Margins margins = job.getMargins(); - - marginBounds = PaperClips.getMarginBounds(margins, printer); - paperBounds = PaperClips.getPaperBounds(printer); - - document = job.getDocument().iterator(printer, gc); - hasNext = document.hasNext(); - } - - /** - * Returns whether any pages remain. - * - * @return whether any pages remain. - */ - public boolean hasNext() { - return hasNext; - } - - /** - * Returns the next page. - * - * @return the next page. - */ - public PrintPiece nextPage() { - if (!hasNext) - return null; - - PrintPiece page = PaperClips.next(document, marginBounds.width, - marginBounds.height); - hasNext = notNull(page) && notDebugPiece(page) && document.hasNext(); - PrintPiece result = page == null ? null : createPagePiece(page); - if (!hasNext) { - document = null; - marginBounds = null; - paperBounds = null; - } - return result; - } - - private PrintPiece createPagePiece(PrintPiece page) { - Point offset = new Point(marginBounds.x - paperBounds.x, marginBounds.y - - paperBounds.y); - CompositeEntry entry = new CompositeEntry(page, offset); - Point size = new Point(paperBounds.width, paperBounds.height); - return new CompositePiece(new CompositeEntry[] { entry }, size); - } - - private static boolean notNull(PrintPiece page) { - return page != null; - } - - private static boolean notDebugPiece(PrintPiece page) { - return !(PaperClips.debug && page instanceof NullPrintPiece); - } - - private static PrintJob applyOrientation(PrintJob printJob, Printer printer) { - int orientation = printJob.getOrientation(); - - Rectangle paperBounds = PaperClips.getPaperBounds(printer); - if (((orientation == PaperClips.ORIENTATION_LANDSCAPE) && (paperBounds.width < paperBounds.height)) - || ((orientation == PaperClips.ORIENTATION_PORTRAIT) && (paperBounds.height < paperBounds.width))) { - String name = printJob.getName(); - Print document = new RotatePrint(printJob.getDocument()); - Margins margins = printJob.getMargins().rotate(); - printJob = new PrintJob(name, document).setMargins(margins) - .setOrientation(PaperClips.ORIENTATION_DEFAULT); - } - - return printJob; - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.printing.Printer; + +/** + * An enumeration of pages for given print job on the given printer device. Each + * element in the enumeration has already had the page orientation and page + * margins applied. Therefore, when calling the paint(GC, int, int) method on + * each page, the printer's trim should be provided as the x and y arguments. In + * other words, the trim is taken as a minimum margin while applying calculating + * margins, but the position where the page's content is drawn is determined + * solely by the margin, and is not offset by the trim. This behavior is helpful + * for screen display, and is already compensated for in the + * {@link PaperClips#print(PrintJob, Printer) } method. + * + * @see PaperClips#getPages(PrintJob, Printer) + * @author Matthew Hall + */ +public class PageEnumeration { + private PrintIterator document; + private Rectangle marginBounds; + private Rectangle paperBounds; + + private boolean hasNext; + + PageEnumeration(PrintJob job, Printer printer, GC gc) { + // Rotate the document (and margins with it) depending on print job + // orientation. + job = applyOrientation(job, printer); + Margins margins = job.getMargins(); + + marginBounds = PaperClips.getMarginBounds(margins, printer); + paperBounds = PaperClips.getPaperBounds(printer); + + document = job.getDocument().iterator(printer, gc); + hasNext = document.hasNext(); + } + + /** + * Returns whether any pages remain. + * + * @return whether any pages remain. + */ + public boolean hasNext() { + return hasNext; + } + + /** + * Returns the next page. + * + * @return the next page. + */ + public PrintPiece nextPage() { + if (!hasNext) + return null; + + PrintPiece page = PaperClips.next(document, marginBounds.width, + marginBounds.height); + hasNext = notNull(page) && notDebugPiece(page) && document.hasNext(); + PrintPiece result = page == null ? null : createPagePiece(page); + if (!hasNext) { + document = null; + marginBounds = null; + paperBounds = null; + } + return result; + } + + private PrintPiece createPagePiece(PrintPiece page) { + Point offset = new Point(marginBounds.x - paperBounds.x, marginBounds.y + - paperBounds.y); + CompositeEntry entry = new CompositeEntry(page, offset); + Point size = new Point(paperBounds.width, paperBounds.height); + return new CompositePiece(new CompositeEntry[] { entry }, size); + } + + private static boolean notNull(PrintPiece page) { + return page != null; + } + + private static boolean notDebugPiece(PrintPiece page) { + return !(PaperClips.debug && page instanceof NullPrintPiece); + } + + private static PrintJob applyOrientation(PrintJob printJob, Printer printer) { + int orientation = printJob.getOrientation(); + + Rectangle paperBounds = PaperClips.getPaperBounds(printer); + if (((orientation == PaperClips.ORIENTATION_LANDSCAPE) && (paperBounds.width < paperBounds.height)) + || ((orientation == PaperClips.ORIENTATION_PORTRAIT) && (paperBounds.height < paperBounds.width))) { + String name = printJob.getName(); + Print document = new RotatePrint(printJob.getDocument()); + Margins margins = printJob.getMargins().rotate(); + printJob = new PrintJob(name, document).setMargins(margins) + .setOrientation(PaperClips.ORIENTATION_DEFAULT); + } + + return printJob; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PaperClips.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PaperClips.java index f6b6e80cb..c1fdcca03 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PaperClips.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PaperClips.java @@ -1,510 +1,510 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.printing.PrinterData; - -/** - * This class contains static constants and methods for preparing and printing - * documents. Methods in this class supersede those in PrintUtil. - * - * @author Matthew Hall - */ -public class PaperClips { - private PaperClips() { - } // no instances - - static boolean debug = false; - - /** - * Indicates that the printer's default page orientation should be used. - */ - public static final int ORIENTATION_DEFAULT = SWT.DEFAULT; - - /** - * Indicates portrait page orientation. - */ - public static final int ORIENTATION_PORTRAIT = SWT.VERTICAL; - - /** - * Indicates landscape page orientation. - */ - public static final int ORIENTATION_LANDSCAPE = SWT.HORIZONTAL; - - /** - * Triggers an appropriate exception based on the passed in error code. - * - * @param code - * the SWT error code. - */ - public static void error(int code) { - SWT.error(code, null); - } - - /** - * Triggers an unspecified exception with the passed in detail. - * - * @param detail - * more information about error. - */ - public static void error(String detail) { - SWT.error(SWT.ERROR_UNSPECIFIED, null, detail); - } - - /** - * Triggers an appropriate exception based on the passed in error code. - * - * @param code - * the SWT error code. - * @param detail - * more information about error. - */ - public static void error(int code, String detail) { - SWT.error(code, null, detail); - } - - /** - * EXPERIMENTAL: Sets whether debug mode is enabled. This mode may be - * used for troubleshooting documents that cannot be laid out for some - * reason (e.g. "Cannot layout page x" error occurs). - * - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @param debug - * true to enable debug mode, false to disable it. - */ - public static void setDebug(boolean debug) { - PaperClips.debug = debug; - } - - /** - * EXPERIMENTAL: Returns whether debug mode is enabled. - * - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @return whether debug mode is enabled. - */ - public static boolean getDebug() { - return debug; - } - - /** - * Returns a PrinterData for the system-default printer, or the first - * printer if no default printer is configured. - * - * @return a PrinterData for the system-default printer, or the first - * printer if no default printer is configured. - */ - public static PrinterData getDefaultPrinterData() { - PrinterData printerData = Printer.getDefaultPrinterData(); - if (printerData == null) { - // Linux may have one or more printers without a default printer - PrinterData[] list = Printer.getPrinterList(); - if (list.length > 0) - printerData = list[0]; - } - return printerData; - } - - /** - * Calls iterator.next(width, height) and returns the result. This method - * checks multiple conditions to ensure proper usage and behavior of - * PrintIterators. - *

- * This method is intended to be used by PrintIterator classes, as a - * results-checking alternative to calling next(int, int) directly on the - * target iterator. All PrintIterator classes in the PaperClips library use - * this method instead of directly calling the - * {@link PrintIterator#next(int, int)} method. - * - * @param iterator - * the PrintIterator - * @param width - * the available width. - * @param height - * the available height. - * @return the next portion of the Print, or null if the width and height - * are not enough to display any of the iterator's contents. - */ - public static PrintPiece next(PrintIterator iterator, int width, int height) { - Util.notNull(iterator); - if (width < 0 || height < 0) - error(SWT.ERROR_INVALID_ARGUMENT, - "PrintPiece size " + width + "x" + height + " not possible"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (!iterator.hasNext()) - error("Iterator " + iterator + " has no more content."); //$NON-NLS-1$ //$NON-NLS-2$ - - PrintPiece result = iterator.next(width, height); - - if (result != null) { - Point size = result.getSize(); - if (size.x > width || size.y > height) - error("Iterator " + iterator + " produced a " + size.x + "x" + size.y + " piece for a " + width //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - + "x" + height + " area."); //$NON-NLS-1$//$NON-NLS-2$ - } else if (debug) { - return new NullPrintPiece(); - } - return result; - } - - /** - * Prints the print job to the given printer. This method constructs a - * Printer, forwards to {@link #print(PrintJob, Printer)}, and disposes the - * printer before returning. - * - * @param printJob - * the print job. - * @param printerData - * the PrinterData of the selected printer. - */ - public static void print(PrintJob printJob, PrinterData printerData) { - Printer printer = new Printer(printerData); - try { - print(printJob, printer); - } finally { - printer.dispose(); - } - } - - /** - * Prints the print job to the given printer. - * - * @param printJob - * the print job. - * @param printer - * the printer device. - */ - public static void print(PrintJob printJob, Printer printer) { - // Bug in SWT on OSX: If Printer.startJob() is not called first, the GC - // will be disposed by - // default. - startJob(printer, printJob.getName()); - - boolean completed = false; - try { - GC gc = createAndConfigureGC(printer); - try { - print(printJob, printer, gc); - } finally { - gc.dispose(); - } - printer.endJob(); - completed = true; - } finally { - if (!completed) - cancelJob(printer); - } - } - - private static void startJob(Printer printer, String jobName) { - if (!printer.startJob(jobName)) - error("Unable to start print job"); //$NON-NLS-1$ - } - - private static void cancelJob(Printer printer) { - if (isGTK()) - printer.endJob(); // Printer.cancelJob() not implemented on GTK - else - printer.cancelJob(); - } - - private static GC createAndConfigureGC(Printer printer) { - GC gc = new GC(printer); - gc.setAdvanced(true); - return gc; - } - - /** - * Prints the print job to the specified printer using the GC. This method - * does not manage the print job lifecycle (it does not call startJob or - * endJob). - * - * @param printJob - * the print job - * @param printer - * the printer - * @param gc - * the GC - */ - private static void print(PrintJob printJob, Printer printer, final GC gc) { - final PrinterData printerData = printer.getPrinterData(); - - PrintPiece[] pages = getPages(printJob, printer, gc); - - int startPage = 0; - int endPage = pages.length - 1; - if (printerData.scope == PrinterData.PAGE_RANGE) { - // Convert from PrinterData's one-based indices to our zero-based - // indices - startPage = Math.max(startPage, printerData.startPage - 1); - endPage = Math.min(endPage, printerData.endPage - 1); - } - - final int collatedCopies; - final int noncollatedCopies; - if (printerData.collate) { // always false if printer driver performs - // collation - collatedCopies = printerData.copyCount; // always 1 if printer - // driver handles copy count - noncollatedCopies = 1; - } else { - noncollatedCopies = printerData.copyCount; // always 1 if printer - // driver handles copy - // count - collatedCopies = 1; - } - - printPages(printer, gc, pages, startPage, endPage, collatedCopies, - noncollatedCopies); - } - - private static void printPages(final Printer printer, final GC gc, - final PrintPiece[] pages, final int startPage, final int endPage, - final int collatedCopies, final int noncollatedCopies) { - disposeUnusedPages(pages, startPage, endPage); - - Rectangle paperBounds = getPaperBounds(printer); - final int x = paperBounds.x; - final int y = paperBounds.y; - - try { - for (int collated = 0; collated < collatedCopies; collated++) { - for (int pageIndex = startPage; pageIndex <= endPage; pageIndex++) { - for (int noncollated = 0; noncollated < noncollatedCopies; noncollated++) { - if (printer.startPage()) { - pages[pageIndex].paint(gc, x, y); - pages[pageIndex].dispose(); - printer.endPage(); - } else { - error("Unable to start page " + pageIndex); //$NON-NLS-1$ - } - } - } - } - } finally { - PaperClipsUtil.dispose(pages); - } - } - - private static void disposeUnusedPages(PrintPiece[] pages, int startPage, - int endPage) { - PaperClipsUtil.dispose(pages, 0, startPage); - PaperClipsUtil.dispose(pages, endPage + 1, pages.length); - } - - /** - * Processes the print job and returns an array of pages for the given - * printer device. Each element in the returned array has already had the - * page orientation and page margins applied. Therefore, when calling the - * paint(GC, int, int) method on each page, the printer's trim should be - * provided as the x and y arguments. In other words, the trim is taken as a - * minimum margin while applying calculating margins, but the position where - * the page's content is drawn is determined solely by the margin, and is - * not offset by the trim. This behavior is helpful for screen display, and - * is already compensated for in the {@link #print(PrintJob, Printer)} - * method. - * - * @param printer - * the printing device. - * @param printJob - * the print job. - * @return an array of all pages of the print job. Each element of the - * returned array represents one page in the printed document. - */ - public static PrintPiece[] getPages(PrintJob printJob, Printer printer) { - startDummyJob(printer, printJob.getName()); - - try { - GC gc = createAndConfigureGC(printer); - try { - return getPages(printJob, printer, gc); - } finally { - gc.dispose(); - } - } finally { - endDummyJob(printer); - } - } - - /** - * Starts a dummy job on the given Printer if the platform requires it. - * Dummy jobs allow the various Print components of PaperClips to perform - * measurements required for document layout, without actually sending a job - * to the printer. Only Mac OS X Carbon and Linux GTK+ are known to require - * dummy jobs. - * - * @param printer - * the Printer hosting the dummy print job. - * @param name - * the name of the dummy print job. - */ - public static void startDummyJob(Printer printer, String name) { - // On Mac OS X Carbon and Linux GTK+, created GC is disposed unless - // Printer.startJob() is called - // first. - if (isCarbon() || isGTK()) - startJob(printer, name); - } - - /** - * Ends a dummy job on the given Printer if the platform requires a dummy - * job. - * - * @param printer - * the Printer hosting the dummy print job. - */ - public static void endDummyJob(Printer printer) { - if (isGTK()) { // Linux GTK - // Printer.cancelJob() is not implemented in SWT since GTK has no - // API for cancelling a print job. For now we must use endJob(), - // even though it spits out an empty page. - - // printer.cancelJob(); // Not implemented in SWT on GTK - printer.endJob(); - - // See also: - // http://bugzilla.gnome.org/show_bug.cgi?id=339323 - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=212594 - } else if (isCarbon()) // Mac OSX - // 2007-04-30: A bug in SWT on Mac OSX prior to 3.3 renders Printer - // instances useless after a call to cancelJob(). - // Therefore on Mac OSX we call endJob() instead of cancelJob(). - if (SWT.getVersion() < 3346) { // Version 3.3 - printer.endJob(); - } else { - printer.cancelJob(); - } - } - - private static boolean isCarbon() { - return SWT.getPlatform().equals("carbon"); //$NON-NLS-1$ - } - - private static boolean isGTK() { - return SWT.getPlatform().equals("gtk"); //$NON-NLS-1$ - } - - private static PrintPiece[] getPages(PrintJob printJob, Printer printer, - GC gc) { - PageEnumeration enumeration = new PageEnumeration(printJob, printer, gc); - List pages = new ArrayList<>(); - while (enumeration.hasNext()) { - PrintPiece page = enumeration.nextPage(); - if (page == null) { - int pageNumber = pages.size() + 1; - PaperClipsUtil.dispose(pages); - error("Unable to layout page " + pageNumber); //$NON-NLS-1$ - } - pages.add(page); - } - - return (PrintPiece[]) pages.toArray(new PrintPiece[pages.size()]); - } - - /** - * Returns a {@link PageEnumeration} for the passed in PrintJob on the given - * Printer, using the given GC. The Printer and GC must not be disposed - * while the enumeration is in use. - * - * @param printJob - * the print job - * @param printer - * the Printer device, which must not be disposed while the - * PageEnumeration is in use. - * @param gc - * the GC, which must not be disposed while the PageEnumeration - * is in use. - * @return a {@link PageEnumeration} for the passed in PrintJob. - */ - public static PageEnumeration getPageEnumeration(PrintJob printJob, - Printer printer, GC gc) { - return new PageEnumeration(printJob, printer, gc); - } - - /** - * Returns the bounding rectangle of the paper, including non-printable - * margins. - * - * @param printer - * the printer device. - * @return a rectangle whose edges correspond to the edges of the paper. - */ - public static Rectangle getPaperBounds(Printer printer) { - Rectangle rect = getPrintableBounds(printer); - return printer.computeTrim(rect.x, rect.y, rect.width, rect.height); - } - - /** - * Returns the bounding rectangle of the printable area on the paper. - * - * @param printer - * the printer device. - * @return the bounding rectangle of the printable area on the paper. - */ - public static Rectangle getPrintableBounds(Printer printer) { - return printer.getClientArea(); - } - - /** - * Returns the bounding rectangle of the printable area which is inside the - * given margins on the paper. The printer's minimum margins are reflected - * in the returned rectangle. - * - * @param printer - * the printer device. - * @param margins - * the desired page margins. - * @return the bounding rectangle on the printable area which is within the - * margins. - */ - public static Rectangle getMarginBounds(Margins margins, Printer printer) { - Rectangle paperBounds = getPaperBounds(printer); - - // Calculate the pixel coordinates for the margins - Point dpi = printer.getDPI(); - int top = paperBounds.y + (margins.top * dpi.y / 72); - int left = paperBounds.x + (margins.left * dpi.x / 72); - int right = paperBounds.x + paperBounds.width - - (margins.right * dpi.x / 72); - int bottom = paperBounds.y + paperBounds.height - - (margins.bottom * dpi.y / 72); - - // Enforce the printer's minimum margins. - Rectangle printableBounds = getPrintableBounds(printer); - if (top < printableBounds.y) - top = printableBounds.y; - if (left < printableBounds.x) - left = printableBounds.x; - if (right > printableBounds.x + printableBounds.width) - right = printableBounds.x + printableBounds.width; - if (bottom > printableBounds.y + printableBounds.height) - bottom = printableBounds.y + printableBounds.height; - - return new Rectangle(left, top, right - left, bottom - top); - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.printing.PrinterData; + +/** + * This class contains static constants and methods for preparing and printing + * documents. Methods in this class supersede those in PrintUtil. + * + * @author Matthew Hall + */ +public class PaperClips { + private PaperClips() { + } // no instances + + static boolean debug = false; + + /** + * Indicates that the printer's default page orientation should be used. + */ + public static final int ORIENTATION_DEFAULT = SWT.DEFAULT; + + /** + * Indicates portrait page orientation. + */ + public static final int ORIENTATION_PORTRAIT = SWT.VERTICAL; + + /** + * Indicates landscape page orientation. + */ + public static final int ORIENTATION_LANDSCAPE = SWT.HORIZONTAL; + + /** + * Triggers an appropriate exception based on the passed in error code. + * + * @param code + * the SWT error code. + */ + public static void error(int code) { + SWT.error(code, null); + } + + /** + * Triggers an unspecified exception with the passed in detail. + * + * @param detail + * more information about error. + */ + public static void error(String detail) { + SWT.error(SWT.ERROR_UNSPECIFIED, null, detail); + } + + /** + * Triggers an appropriate exception based on the passed in error code. + * + * @param code + * the SWT error code. + * @param detail + * more information about error. + */ + public static void error(int code, String detail) { + SWT.error(code, null, detail); + } + + /** + * EXPERIMENTAL: Sets whether debug mode is enabled. This mode may be + * used for troubleshooting documents that cannot be laid out for some + * reason (e.g. "Cannot layout page x" error occurs). + * + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @param debug + * true to enable debug mode, false to disable it. + */ + public static void setDebug(boolean debug) { + PaperClips.debug = debug; + } + + /** + * EXPERIMENTAL: Returns whether debug mode is enabled. + * + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @return whether debug mode is enabled. + */ + public static boolean getDebug() { + return debug; + } + + /** + * Returns a PrinterData for the system-default printer, or the first + * printer if no default printer is configured. + * + * @return a PrinterData for the system-default printer, or the first + * printer if no default printer is configured. + */ + public static PrinterData getDefaultPrinterData() { + PrinterData printerData = Printer.getDefaultPrinterData(); + if (printerData == null) { + // Linux may have one or more printers without a default printer + PrinterData[] list = Printer.getPrinterList(); + if (list.length > 0) + printerData = list[0]; + } + return printerData; + } + + /** + * Calls iterator.next(width, height) and returns the result. This method + * checks multiple conditions to ensure proper usage and behavior of + * PrintIterators. + *

+ * This method is intended to be used by PrintIterator classes, as a + * results-checking alternative to calling next(int, int) directly on the + * target iterator. All PrintIterator classes in the PaperClips library use + * this method instead of directly calling the + * {@link PrintIterator#next(int, int)} method. + * + * @param iterator + * the PrintIterator + * @param width + * the available width. + * @param height + * the available height. + * @return the next portion of the Print, or null if the width and height + * are not enough to display any of the iterator's contents. + */ + public static PrintPiece next(PrintIterator iterator, int width, int height) { + Util.notNull(iterator); + if (width < 0 || height < 0) + error(SWT.ERROR_INVALID_ARGUMENT, + "PrintPiece size " + width + "x" + height + " not possible"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (!iterator.hasNext()) + error("Iterator " + iterator + " has no more content."); //$NON-NLS-1$ //$NON-NLS-2$ + + PrintPiece result = iterator.next(width, height); + + if (result != null) { + Point size = result.getSize(); + if (size.x > width || size.y > height) + error("Iterator " + iterator + " produced a " + size.x + "x" + size.y + " piece for a " + width //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + + "x" + height + " area."); //$NON-NLS-1$//$NON-NLS-2$ + } else if (debug) { + return new NullPrintPiece(); + } + return result; + } + + /** + * Prints the print job to the given printer. This method constructs a + * Printer, forwards to {@link #print(PrintJob, Printer)}, and disposes the + * printer before returning. + * + * @param printJob + * the print job. + * @param printerData + * the PrinterData of the selected printer. + */ + public static void print(PrintJob printJob, PrinterData printerData) { + Printer printer = new Printer(printerData); + try { + print(printJob, printer); + } finally { + printer.dispose(); + } + } + + /** + * Prints the print job to the given printer. + * + * @param printJob + * the print job. + * @param printer + * the printer device. + */ + public static void print(PrintJob printJob, Printer printer) { + // Bug in SWT on OSX: If Printer.startJob() is not called first, the GC + // will be disposed by + // default. + startJob(printer, printJob.getName()); + + boolean completed = false; + try { + GC gc = createAndConfigureGC(printer); + try { + print(printJob, printer, gc); + } finally { + gc.dispose(); + } + printer.endJob(); + completed = true; + } finally { + if (!completed) + cancelJob(printer); + } + } + + private static void startJob(Printer printer, String jobName) { + if (!printer.startJob(jobName)) + error("Unable to start print job"); //$NON-NLS-1$ + } + + private static void cancelJob(Printer printer) { + if (isGTK()) + printer.endJob(); // Printer.cancelJob() not implemented on GTK + else + printer.cancelJob(); + } + + private static GC createAndConfigureGC(Printer printer) { + GC gc = new GC(printer); + gc.setAdvanced(true); + return gc; + } + + /** + * Prints the print job to the specified printer using the GC. This method + * does not manage the print job lifecycle (it does not call startJob or + * endJob). + * + * @param printJob + * the print job + * @param printer + * the printer + * @param gc + * the GC + */ + private static void print(PrintJob printJob, Printer printer, final GC gc) { + final PrinterData printerData = printer.getPrinterData(); + + PrintPiece[] pages = getPages(printJob, printer, gc); + + int startPage = 0; + int endPage = pages.length - 1; + if (printerData.scope == PrinterData.PAGE_RANGE) { + // Convert from PrinterData's one-based indices to our zero-based + // indices + startPage = Math.max(startPage, printerData.startPage - 1); + endPage = Math.min(endPage, printerData.endPage - 1); + } + + final int collatedCopies; + final int noncollatedCopies; + if (printerData.collate) { // always false if printer driver performs + // collation + collatedCopies = printerData.copyCount; // always 1 if printer + // driver handles copy count + noncollatedCopies = 1; + } else { + noncollatedCopies = printerData.copyCount; // always 1 if printer + // driver handles copy + // count + collatedCopies = 1; + } + + printPages(printer, gc, pages, startPage, endPage, collatedCopies, + noncollatedCopies); + } + + private static void printPages(final Printer printer, final GC gc, + final PrintPiece[] pages, final int startPage, final int endPage, + final int collatedCopies, final int noncollatedCopies) { + disposeUnusedPages(pages, startPage, endPage); + + Rectangle paperBounds = getPaperBounds(printer); + final int x = paperBounds.x; + final int y = paperBounds.y; + + try { + for (int collated = 0; collated < collatedCopies; collated++) { + for (int pageIndex = startPage; pageIndex <= endPage; pageIndex++) { + for (int noncollated = 0; noncollated < noncollatedCopies; noncollated++) { + if (printer.startPage()) { + pages[pageIndex].paint(gc, x, y); + pages[pageIndex].dispose(); + printer.endPage(); + } else { + error("Unable to start page " + pageIndex); //$NON-NLS-1$ + } + } + } + } + } finally { + PaperClipsUtil.dispose(pages); + } + } + + private static void disposeUnusedPages(PrintPiece[] pages, int startPage, + int endPage) { + PaperClipsUtil.dispose(pages, 0, startPage); + PaperClipsUtil.dispose(pages, endPage + 1, pages.length); + } + + /** + * Processes the print job and returns an array of pages for the given + * printer device. Each element in the returned array has already had the + * page orientation and page margins applied. Therefore, when calling the + * paint(GC, int, int) method on each page, the printer's trim should be + * provided as the x and y arguments. In other words, the trim is taken as a + * minimum margin while applying calculating margins, but the position where + * the page's content is drawn is determined solely by the margin, and is + * not offset by the trim. This behavior is helpful for screen display, and + * is already compensated for in the {@link #print(PrintJob, Printer)} + * method. + * + * @param printer + * the printing device. + * @param printJob + * the print job. + * @return an array of all pages of the print job. Each element of the + * returned array represents one page in the printed document. + */ + public static PrintPiece[] getPages(PrintJob printJob, Printer printer) { + startDummyJob(printer, printJob.getName()); + + try { + GC gc = createAndConfigureGC(printer); + try { + return getPages(printJob, printer, gc); + } finally { + gc.dispose(); + } + } finally { + endDummyJob(printer); + } + } + + /** + * Starts a dummy job on the given Printer if the platform requires it. + * Dummy jobs allow the various Print components of PaperClips to perform + * measurements required for document layout, without actually sending a job + * to the printer. Only Mac OS X Carbon and Linux GTK+ are known to require + * dummy jobs. + * + * @param printer + * the Printer hosting the dummy print job. + * @param name + * the name of the dummy print job. + */ + public static void startDummyJob(Printer printer, String name) { + // On Mac OS X Carbon and Linux GTK+, created GC is disposed unless + // Printer.startJob() is called + // first. + if (isCarbon() || isGTK()) + startJob(printer, name); + } + + /** + * Ends a dummy job on the given Printer if the platform requires a dummy + * job. + * + * @param printer + * the Printer hosting the dummy print job. + */ + public static void endDummyJob(Printer printer) { + if (isGTK()) { // Linux GTK + // Printer.cancelJob() is not implemented in SWT since GTK has no + // API for cancelling a print job. For now we must use endJob(), + // even though it spits out an empty page. + + // printer.cancelJob(); // Not implemented in SWT on GTK + printer.endJob(); + + // See also: + // http://bugzilla.gnome.org/show_bug.cgi?id=339323 + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=212594 + } else if (isCarbon()) // Mac OSX + // 2007-04-30: A bug in SWT on Mac OSX prior to 3.3 renders Printer + // instances useless after a call to cancelJob(). + // Therefore on Mac OSX we call endJob() instead of cancelJob(). + if (SWT.getVersion() < 3346) { // Version 3.3 + printer.endJob(); + } else { + printer.cancelJob(); + } + } + + private static boolean isCarbon() { + return SWT.getPlatform().equals("carbon"); //$NON-NLS-1$ + } + + private static boolean isGTK() { + return SWT.getPlatform().equals("gtk"); //$NON-NLS-1$ + } + + private static PrintPiece[] getPages(PrintJob printJob, Printer printer, + GC gc) { + PageEnumeration enumeration = new PageEnumeration(printJob, printer, gc); + List pages = new ArrayList<>(); + while (enumeration.hasNext()) { + PrintPiece page = enumeration.nextPage(); + if (page == null) { + int pageNumber = pages.size() + 1; + PaperClipsUtil.dispose(pages); + error("Unable to layout page " + pageNumber); //$NON-NLS-1$ + } + pages.add(page); + } + + return (PrintPiece[]) pages.toArray(new PrintPiece[pages.size()]); + } + + /** + * Returns a {@link PageEnumeration} for the passed in PrintJob on the given + * Printer, using the given GC. The Printer and GC must not be disposed + * while the enumeration is in use. + * + * @param printJob + * the print job + * @param printer + * the Printer device, which must not be disposed while the + * PageEnumeration is in use. + * @param gc + * the GC, which must not be disposed while the PageEnumeration + * is in use. + * @return a {@link PageEnumeration} for the passed in PrintJob. + */ + public static PageEnumeration getPageEnumeration(PrintJob printJob, + Printer printer, GC gc) { + return new PageEnumeration(printJob, printer, gc); + } + + /** + * Returns the bounding rectangle of the paper, including non-printable + * margins. + * + * @param printer + * the printer device. + * @return a rectangle whose edges correspond to the edges of the paper. + */ + public static Rectangle getPaperBounds(Printer printer) { + Rectangle rect = getPrintableBounds(printer); + return printer.computeTrim(rect.x, rect.y, rect.width, rect.height); + } + + /** + * Returns the bounding rectangle of the printable area on the paper. + * + * @param printer + * the printer device. + * @return the bounding rectangle of the printable area on the paper. + */ + public static Rectangle getPrintableBounds(Printer printer) { + return printer.getClientArea(); + } + + /** + * Returns the bounding rectangle of the printable area which is inside the + * given margins on the paper. The printer's minimum margins are reflected + * in the returned rectangle. + * + * @param printer + * the printer device. + * @param margins + * the desired page margins. + * @return the bounding rectangle on the printable area which is within the + * margins. + */ + public static Rectangle getMarginBounds(Margins margins, Printer printer) { + Rectangle paperBounds = getPaperBounds(printer); + + // Calculate the pixel coordinates for the margins + Point dpi = printer.getDPI(); + int top = paperBounds.y + (margins.top * dpi.y / 72); + int left = paperBounds.x + (margins.left * dpi.x / 72); + int right = paperBounds.x + paperBounds.width + - (margins.right * dpi.x / 72); + int bottom = paperBounds.y + paperBounds.height + - (margins.bottom * dpi.y / 72); + + // Enforce the printer's minimum margins. + Rectangle printableBounds = getPrintableBounds(printer); + if (top < printableBounds.y) + top = printableBounds.y; + if (left < printableBounds.x) + left = printableBounds.x; + if (right > printableBounds.x + printableBounds.width) + right = printableBounds.x + printableBounds.width; + if (bottom > printableBounds.y + printableBounds.height) + bottom = printableBounds.y + printableBounds.height; + + return new Rectangle(left, top, right - left, bottom - top); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Print.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Print.java index 283ee6166..0e7bc9ec1 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Print.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/Print.java @@ -1,39 +1,39 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -/** - * Interface for printable elements. - * - * @author Matthew Hall - */ -public interface Print { - /** - * Returns a PrintIterator for laying out the contents of this Print. The - * iterator uses a snapshot of the print at the time this method is invoked, - * so subsequent changes to the Print will not affect the output of the - * iterator. - * - * @param device - * the graphics device this Print will be drawn onto. - * @param gc - * the graphics context to be used for calculating layout and - * drawing the Print's contents. - * @return a PrintIterator for laying out the contents of this Print. - */ - public PrintIterator iterator(Device device, GC gc); +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +/** + * Interface for printable elements. + * + * @author Matthew Hall + */ +public interface Print { + /** + * Returns a PrintIterator for laying out the contents of this Print. The + * iterator uses a snapshot of the print at the time this method is invoked, + * so subsequent changes to the Print will not affect the output of the + * iterator. + * + * @param device + * the graphics device this Print will be drawn onto. + * @param gc + * the graphics context to be used for calculating layout and + * drawing the Print's contents. + * @return a PrintIterator for laying out the contents of this Print. + */ + public PrintIterator iterator(Device device, GC gc); } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintIterator.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintIterator.java index f237c6299..daaaa3f06 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintIterator.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintIterator.java @@ -1,114 +1,114 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * Splits a Print into multiple PrintPieces, according to the space available on - * the graphics device. PrintIterators are created by - * {@link Print#iterator(Device, GC)}, and are initialized with the graphics - * device passed to that method. - * - * @author Matthew Hall - */ -public interface PrintIterator { - /** - * Identifies whether any PrintPieces remain. - * - * @return whether any PrintPieces remain. - */ - public boolean hasNext(); - - /** - * Returns the next PrintPiece for the Print. - *

- * If all of the remaining contents of the Print will fit in the given - * space, the returned PrintPiece will include all remaining contents, and - * subsequent calls to {@link PrintIterator#hasNext() } will return - * false. - *

- * If some, but not all of the remaining contents will fit in the given - * space, the returned PrintPiece will contain as much of the contents as - * possible, and subsequent calls to {@link PrintIterator#hasNext() } will - * return true. - *

- * If there is insufficient space for any of the remaining contents in the - * given space, null is returned, and subsequent calls to - * {@link PrintIterator#hasNext() } will return true. - *

- * If subsequent calls to PrintIterator#hasNext() return true, - * this PrintIterator cannot fit any more in the given print area. Future - * calls to this method should provide a fresh print area. At the top level, - * each returned PrintPiece contains an entire page. - *

- * Note: PrintIterator classes should call - * {@link PaperClips#next(PrintIterator, int, int)} instead of calling this - * method directly, to gain automatic results checking to ensure all Print - * classes are well-behaved. - * - * @param width - * the width available on the graphics device for this iteration. - * @param height - * the height available on the graphics device for this - * iteration. - * @return a PrintPiece that paints the next part of the Print, or null if - * the print area is too small. The size of the returned PrintPiece - * must NOT exceed the width and height indicated. - */ - public PrintPiece next(int width, int height); - - /** - * Returns the minimum size PrintPiece that this Print should be broken - * into. - *

- * Note that the size calculated by this method is a "preferred minimum," or - * the smallest size that the Print should normally be broken into. For a - * TextPrint, this is the size of the widest individual word, in pixels. - *

- * This is distinct from the "absolute minimum," which is the smallest size - * that a Print could possibly be broken into. For a TextPrint, this is the - * size of the widest individual letter, in pixels. - * - * @return a Point indicating the minimum size PrintPiece this PrintIterator - * should be broken into. - */ - public Point minimumSize(); - - /** - * Returns the smallest size PrintPiece that this Print would be broken into - * if print space was unlimited. - *

- * For a TextPrint, this is the size of the widest line (or the whole - * TextPrint, if there are no line breaks), in pixels. - * - * @return a Point indicating the smallest size PrintPiece that this Print - * would be broken into if print space was unlimited. - */ - public Point preferredSize(); - - /** - * Returns a copy of this PrintIterator, with all relevant internal states. - * This method allows a containing iterator to "back up" the current state - * of its child iterators before invoking next(int, int) on - * them. The containing iterator can then safely attempt iterating its - * child(ren) in a variety of ways before selecting which way is the most - * appropriate. - * - * @return a deep clone of the target with all relevant internal states. - */ - public PrintIterator copy(); +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * Splits a Print into multiple PrintPieces, according to the space available on + * the graphics device. PrintIterators are created by + * {@link Print#iterator(Device, GC)}, and are initialized with the graphics + * device passed to that method. + * + * @author Matthew Hall + */ +public interface PrintIterator { + /** + * Identifies whether any PrintPieces remain. + * + * @return whether any PrintPieces remain. + */ + public boolean hasNext(); + + /** + * Returns the next PrintPiece for the Print. + *

+ * If all of the remaining contents of the Print will fit in the given + * space, the returned PrintPiece will include all remaining contents, and + * subsequent calls to {@link PrintIterator#hasNext() } will return + * false. + *

+ * If some, but not all of the remaining contents will fit in the given + * space, the returned PrintPiece will contain as much of the contents as + * possible, and subsequent calls to {@link PrintIterator#hasNext() } will + * return true. + *

+ * If there is insufficient space for any of the remaining contents in the + * given space, null is returned, and subsequent calls to + * {@link PrintIterator#hasNext() } will return true. + *

+ * If subsequent calls to PrintIterator#hasNext() return true, + * this PrintIterator cannot fit any more in the given print area. Future + * calls to this method should provide a fresh print area. At the top level, + * each returned PrintPiece contains an entire page. + *

+ * Note: PrintIterator classes should call + * {@link PaperClips#next(PrintIterator, int, int)} instead of calling this + * method directly, to gain automatic results checking to ensure all Print + * classes are well-behaved. + * + * @param width + * the width available on the graphics device for this iteration. + * @param height + * the height available on the graphics device for this + * iteration. + * @return a PrintPiece that paints the next part of the Print, or null if + * the print area is too small. The size of the returned PrintPiece + * must NOT exceed the width and height indicated. + */ + public PrintPiece next(int width, int height); + + /** + * Returns the minimum size PrintPiece that this Print should be broken + * into. + *

+ * Note that the size calculated by this method is a "preferred minimum," or + * the smallest size that the Print should normally be broken into. For a + * TextPrint, this is the size of the widest individual word, in pixels. + *

+ * This is distinct from the "absolute minimum," which is the smallest size + * that a Print could possibly be broken into. For a TextPrint, this is the + * size of the widest individual letter, in pixels. + * + * @return a Point indicating the minimum size PrintPiece this PrintIterator + * should be broken into. + */ + public Point minimumSize(); + + /** + * Returns the smallest size PrintPiece that this Print would be broken into + * if print space was unlimited. + *

+ * For a TextPrint, this is the size of the widest line (or the whole + * TextPrint, if there are no line breaks), in pixels. + * + * @return a Point indicating the smallest size PrintPiece that this Print + * would be broken into if print space was unlimited. + */ + public Point preferredSize(); + + /** + * Returns a copy of this PrintIterator, with all relevant internal states. + * This method allows a containing iterator to "back up" the current state + * of its child iterators before invoking next(int, int) on + * them. The containing iterator can then safely attempt iterating its + * child(ren) in a variety of ways before selecting which way is the most + * appropriate. + * + * @return a deep clone of the target with all relevant internal states. + */ + public PrintIterator copy(); } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintJob.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintJob.java index 8f63b2237..68cfd7db3 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintJob.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintJob.java @@ -1,173 +1,173 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; - -/** - * Instances of this class represent a prepared print job. - * - * @author Matthew Hall - */ -public class PrintJob { - private final String name; - private final Print document; - - private Margins margins = new Margins(); - - private int orientation = PaperClips.ORIENTATION_DEFAULT; - - /** - * Constructs a PrintJob for the given document. - * - * @param name - * the name of the print job, which will appear in the print - * queue of the operating system. - * @param document - * the document to be printed. - */ - public PrintJob(String name, Print document) { - Util.notNull(name, document); - this.name = name; - this.document = document; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((document == null) ? 0 : document.hashCode()); - result = prime * result + ((margins == null) ? 0 : margins.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + orientation; - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PrintJob other = (PrintJob) obj; - if (document == null) { - if (other.document != null) - return false; - } else if (!document.equals(other.document)) - return false; - if (margins == null) { - if (other.margins != null) - return false; - } else if (!margins.equals(other.margins)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (orientation != other.orientation) - return false; - return true; - } - - /** - * Returns the name of the print job. - * - * @return the name of the print job. - */ - public String getName() { - return name; - } - - /** - * Returns the document to be printed. - * - * @return the document to be printed. - */ - public Print getDocument() { - return document; - } - - /** - * Returns the page orientation. - * - * @return the page orientation. - */ - public int getOrientation() { - return orientation; - } - - /** - * Sets the page orientation. - * - * @param orientation - * the page orientation. Must be one of - * {@link PaperClips#ORIENTATION_DEFAULT }, - * {@link PaperClips#ORIENTATION_PORTRAIT } or - * {@link PaperClips#ORIENTATION_LANDSCAPE }. Values other than - * these choices will be automatically changed to - * {@link PaperClips#ORIENTATION_DEFAULT }. - * @return this PrintJob (for chaining method calls) - */ - public PrintJob setOrientation(int orientation) { - this.orientation = checkOrientation(orientation); - return this; - } - - private int checkOrientation(int orientation) { - switch (orientation) { - case PaperClips.ORIENTATION_LANDSCAPE: - case PaperClips.ORIENTATION_PORTRAIT: - case PaperClips.ORIENTATION_DEFAULT: - return orientation; - default: - return PaperClips.ORIENTATION_DEFAULT; - } - } - - /** - * Returns the page margins, expressed in points. 72 points = 1". - * - * @return the page margins, expressed in points. 72 points = 1". - */ - public Margins getMargins() { - return margins; - } - - /** - * Sets the page margins. - * - * @param margins - * the new page margins. - * @return this PrintJob (for chaining method calls) - */ - public PrintJob setMargins(Margins margins) { - Util.notNull(margins); - this.margins = margins; - return this; - } - - /** - * Sets the top, left, right, and bottom margins to the argument. - * - * @param margins - * the margins, in points. 72 points = 1 inch. - * @return this PrintJob (for chaining method calls) - */ - public PrintJob setMargins(int margins) { - this.margins = new Margins(margins); - return this; - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; + +/** + * Instances of this class represent a prepared print job. + * + * @author Matthew Hall + */ +public class PrintJob { + private final String name; + private final Print document; + + private Margins margins = new Margins(); + + private int orientation = PaperClips.ORIENTATION_DEFAULT; + + /** + * Constructs a PrintJob for the given document. + * + * @param name + * the name of the print job, which will appear in the print + * queue of the operating system. + * @param document + * the document to be printed. + */ + public PrintJob(String name, Print document) { + Util.notNull(name, document); + this.name = name; + this.document = document; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((document == null) ? 0 : document.hashCode()); + result = prime * result + ((margins == null) ? 0 : margins.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + orientation; + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PrintJob other = (PrintJob) obj; + if (document == null) { + if (other.document != null) + return false; + } else if (!document.equals(other.document)) + return false; + if (margins == null) { + if (other.margins != null) + return false; + } else if (!margins.equals(other.margins)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (orientation != other.orientation) + return false; + return true; + } + + /** + * Returns the name of the print job. + * + * @return the name of the print job. + */ + public String getName() { + return name; + } + + /** + * Returns the document to be printed. + * + * @return the document to be printed. + */ + public Print getDocument() { + return document; + } + + /** + * Returns the page orientation. + * + * @return the page orientation. + */ + public int getOrientation() { + return orientation; + } + + /** + * Sets the page orientation. + * + * @param orientation + * the page orientation. Must be one of + * {@link PaperClips#ORIENTATION_DEFAULT }, + * {@link PaperClips#ORIENTATION_PORTRAIT } or + * {@link PaperClips#ORIENTATION_LANDSCAPE }. Values other than + * these choices will be automatically changed to + * {@link PaperClips#ORIENTATION_DEFAULT }. + * @return this PrintJob (for chaining method calls) + */ + public PrintJob setOrientation(int orientation) { + this.orientation = checkOrientation(orientation); + return this; + } + + private int checkOrientation(int orientation) { + switch (orientation) { + case PaperClips.ORIENTATION_LANDSCAPE: + case PaperClips.ORIENTATION_PORTRAIT: + case PaperClips.ORIENTATION_DEFAULT: + return orientation; + default: + return PaperClips.ORIENTATION_DEFAULT; + } + } + + /** + * Returns the page margins, expressed in points. 72 points = 1". + * + * @return the page margins, expressed in points. 72 points = 1". + */ + public Margins getMargins() { + return margins; + } + + /** + * Sets the page margins. + * + * @param margins + * the new page margins. + * @return this PrintJob (for chaining method calls) + */ + public PrintJob setMargins(Margins margins) { + Util.notNull(margins); + this.margins = margins; + return this; + } + + /** + * Sets the top, left, right, and bottom margins to the argument. + * + * @param margins + * the margins, in points. 72 points = 1 inch. + * @return this PrintJob (for chaining method calls) + */ + public PrintJob setMargins(int margins) { + this.margins = new Margins(margins); + return this; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintPiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintPiece.java index ad8337c92..76be2aab7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintPiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/PrintPiece.java @@ -1,53 +1,53 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A piece of a Print, which is capable of drawing itself on a graphics device. - * PrintPiece objects are created by a PrintIterator. - * - * @author Matthew - */ -public interface PrintPiece { - /** - * Returns the dimensions of this PrintPiece, in pixels. - * - * @return the dimensions of this PrintPiece, in pixels. - */ - public Point getSize(); - - /** - * Draws this PrintPiece on the given graphics device, at the given - * coordinates. - * - * @param gc - * a graphics context for the graphics device. - * @param x - * the x coordinate where this PrintPiece will be drawn. - * @param y - * the x coordinate where this PrintPiece will be drawn. - */ - public void paint(GC gc, int x, int y); - - /** - * Disposes the system resources allocated by this PrintPiece. The dispose - * method is not a permanent disposal of a PrintPiece. It is intended - * to reclaim system resources, however future calls to paint(GC,int,int) - * may require that the resources be allocated again. - */ - public void dispose(); -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A piece of a Print, which is capable of drawing itself on a graphics device. + * PrintPiece objects are created by a PrintIterator. + * + * @author Matthew + */ +public interface PrintPiece { + /** + * Returns the dimensions of this PrintPiece, in pixels. + * + * @return the dimensions of this PrintPiece, in pixels. + */ + public Point getSize(); + + /** + * Draws this PrintPiece on the given graphics device, at the given + * coordinates. + * + * @param gc + * a graphics context for the graphics device. + * @param x + * the x coordinate where this PrintPiece will be drawn. + * @param y + * the x coordinate where this PrintPiece will be drawn. + */ + public void paint(GC gc, int x, int y); + + /** + * Disposes the system resources allocated by this PrintPiece. The dispose + * method is not a permanent disposal of a PrintPiece. It is intended + * to reclaim system resources, however future calls to paint(GC,int,int) + * may require that the resources be allocated again. + */ + public void dispose(); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/RotatePrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/RotatePrint.java index 9f59f9d8d..f6d25abbf 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/RotatePrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/RotatePrint.java @@ -1,213 +1,213 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.RotatePiece; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A decorator print that rotates it's target by increments of 90 degrees. - *

- * Note: On Windows, this class depends on a bugfix available as of - * Eclipse build 3.2, release candidate 3 (2006-04-28). Prior to this release, - * using RotatePrint triggers the bug, causing the document to scale very large - * on paper. This bug only manifests itself on paper, not with on-screen - * viewing. - *

- * RotatePrints are horizontally and vertically greedy. Greedy prints take up - * all the available space on the page. - * - * @author Matthew Hall - */ -public final class RotatePrint implements Print { - private final Print target; - private final int angle; - - /** - * Constructs a RotatePrint that rotates it's target 90 degrees - * counter-clockwise. - * - * @param target - * the print to rotate. - */ - public RotatePrint(Print target) { - this(target, 90); - } - - /** - * Constructs a RotatePrint. - * - * @param target - * the print to rotate. - * @param angle - * the angle by which the target will be rotated, expressed in - * degrees counter-clockwise. Positive values rotate - * counter-clockwise, and negative values rotate clockwise. Must - * be a multiple of 90. - */ - public RotatePrint(Print target, int angle) { - Util.notNull(target); - this.target = target; - this.angle = checkAngle(angle); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + angle; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - RotatePrint other = (RotatePrint) obj; - if (angle != other.angle) - return false; - if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) - return false; - return true; - } - - /** - * Returns the print to be rotated. - * - * @return the print to be rotated. - */ - public Print getTarget() { - return target; - } - - /** - * Returns the angle by which the target will be rotated (one of 0, 90, 180, - * or 270). - * - * @return the angle by which the target will be rotated. - */ - public int getAngle() { - return angle; - } - - private static int checkAngle(int angle) { - // Make sure angle is a multiple of 90. - if (Math.abs(angle) % 90 != 0) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Angle must be a multiple of 90 degrees"); //$NON-NLS-1$ - - // Bring angle within the range [0, 360) - if (angle < 0) - angle = 360 - (-angle % 360); - if (angle >= 360) - angle = angle % 360; - - return angle; - } - - public PrintIterator iterator(Device device, GC gc) { - if (angle == 0) - return target.iterator(device, gc); - return new RotateIterator(target, angle, device, gc); - } -} - -final class RotateIterator implements PrintIterator { - private final Device device; - private final PrintIterator target; - private final int angle; - - private final Point minimumSize; - private final Point preferredSize; - - RotateIterator(Print target, int angle, Device device, GC gc) { - Util.notNull(target, device, gc); - - this.device = device; - this.target = target.iterator(device, gc); - this.angle = checkAngle(angle); // returns 90, 180, or 270 only - - Point min = this.target.minimumSize(); - Point pref = this.target.preferredSize(); - - if (this.angle == 180) { - this.minimumSize = new Point(min.x, min.y); - this.preferredSize = new Point(pref.x, pref.y); - } else { // flip x and y sizes if rotating by 90 or 270 degrees - this.minimumSize = new Point(min.y, min.x); - this.preferredSize = new Point(pref.y, pref.x); - } - } - - private RotateIterator(RotateIterator that) { - this.device = that.device; - this.target = that.target.copy(); - this.angle = that.angle; - this.minimumSize = that.minimumSize; - this.preferredSize = that.preferredSize; - } - - private static int checkAngle(int angle) { - switch (angle) { - case 90: - case 180: - case 270: - break; - default: - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Angle must be 90, 180, or 270"); //$NON-NLS-1$ - } - return angle; - } - - public Point minimumSize() { - return new Point(minimumSize.x, minimumSize.y); - } - - public Point preferredSize() { - return new Point(preferredSize.x, preferredSize.y); - } - - public boolean hasNext() { - return target.hasNext(); - } - - public PrintPiece next(int width, int height) { - PrintPiece target; - if (angle == 180) // angle may only be init'd to 90, 180, of 270 - target = PaperClips.next(this.target, width, height); - else - // flip width and height if rotating by 90 or 270 - target = PaperClips.next(this.target, height, width); - - if (target == null) - return null; - - return new RotatePiece(device, target, angle, new Point(width, height)); - } - - public PrintIterator copy() { - return new RotateIterator(this); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.RotatePiece; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A decorator print that rotates it's target by increments of 90 degrees. + *

+ * Note: On Windows, this class depends on a bugfix available as of + * Eclipse build 3.2, release candidate 3 (2006-04-28). Prior to this release, + * using RotatePrint triggers the bug, causing the document to scale very large + * on paper. This bug only manifests itself on paper, not with on-screen + * viewing. + *

+ * RotatePrints are horizontally and vertically greedy. Greedy prints take up + * all the available space on the page. + * + * @author Matthew Hall + */ +public final class RotatePrint implements Print { + private final Print target; + private final int angle; + + /** + * Constructs a RotatePrint that rotates it's target 90 degrees + * counter-clockwise. + * + * @param target + * the print to rotate. + */ + public RotatePrint(Print target) { + this(target, 90); + } + + /** + * Constructs a RotatePrint. + * + * @param target + * the print to rotate. + * @param angle + * the angle by which the target will be rotated, expressed in + * degrees counter-clockwise. Positive values rotate + * counter-clockwise, and negative values rotate clockwise. Must + * be a multiple of 90. + */ + public RotatePrint(Print target, int angle) { + Util.notNull(target); + this.target = target; + this.angle = checkAngle(angle); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + angle; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RotatePrint other = (RotatePrint) obj; + if (angle != other.angle) + return false; + if (target == null) { + if (other.target != null) + return false; + } else if (!target.equals(other.target)) + return false; + return true; + } + + /** + * Returns the print to be rotated. + * + * @return the print to be rotated. + */ + public Print getTarget() { + return target; + } + + /** + * Returns the angle by which the target will be rotated (one of 0, 90, 180, + * or 270). + * + * @return the angle by which the target will be rotated. + */ + public int getAngle() { + return angle; + } + + private static int checkAngle(int angle) { + // Make sure angle is a multiple of 90. + if (Math.abs(angle) % 90 != 0) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Angle must be a multiple of 90 degrees"); //$NON-NLS-1$ + + // Bring angle within the range [0, 360) + if (angle < 0) + angle = 360 - (-angle % 360); + if (angle >= 360) + angle = angle % 360; + + return angle; + } + + public PrintIterator iterator(Device device, GC gc) { + if (angle == 0) + return target.iterator(device, gc); + return new RotateIterator(target, angle, device, gc); + } +} + +final class RotateIterator implements PrintIterator { + private final Device device; + private final PrintIterator target; + private final int angle; + + private final Point minimumSize; + private final Point preferredSize; + + RotateIterator(Print target, int angle, Device device, GC gc) { + Util.notNull(target, device, gc); + + this.device = device; + this.target = target.iterator(device, gc); + this.angle = checkAngle(angle); // returns 90, 180, or 270 only + + Point min = this.target.minimumSize(); + Point pref = this.target.preferredSize(); + + if (this.angle == 180) { + this.minimumSize = new Point(min.x, min.y); + this.preferredSize = new Point(pref.x, pref.y); + } else { // flip x and y sizes if rotating by 90 or 270 degrees + this.minimumSize = new Point(min.y, min.x); + this.preferredSize = new Point(pref.y, pref.x); + } + } + + private RotateIterator(RotateIterator that) { + this.device = that.device; + this.target = that.target.copy(); + this.angle = that.angle; + this.minimumSize = that.minimumSize; + this.preferredSize = that.preferredSize; + } + + private static int checkAngle(int angle) { + switch (angle) { + case 90: + case 180: + case 270: + break; + default: + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Angle must be 90, 180, or 270"); //$NON-NLS-1$ + } + return angle; + } + + public Point minimumSize() { + return new Point(minimumSize.x, minimumSize.y); + } + + public Point preferredSize() { + return new Point(preferredSize.x, preferredSize.y); + } + + public boolean hasNext() { + return target.hasNext(); + } + + public PrintPiece next(int width, int height) { + PrintPiece target; + if (angle == 180) // angle may only be init'd to 90, 180, of 270 + target = PaperClips.next(this.target, width, height); + else + // flip width and height if rotating by 90 or 270 + target = PaperClips.next(this.target, height, width); + + if (target == null) + return null; + + return new RotatePiece(device, target, angle, new Point(width, height)); + } + + public PrintIterator copy() { + return new RotateIterator(this); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ScalePrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ScalePrint.java index 427629fe0..f1c577442 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ScalePrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/ScalePrint.java @@ -1,265 +1,265 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Transform; - -/** - * A decorator print that scales it's target larger or smaller. - *

- * Note: On Windows, this class depends on a bugfix available as of - * Eclipse build 3.2, release candidate 3 (2006-04-28). Prior to this release, - * using ScalePrint triggers the bug, causing the document to scale very large - * on paper. This bug manifests itself only on paper, not with on-screen - * viewing. - * - * @author Matthew Hall - */ -public class ScalePrint implements Print { - final Print target; - final Double scale; - - /** - * Constructs a ScalePrint which scales down it's target to print at it's - * preferred size. This constructor is equivalent to calling new - * ScalePrint(target, null). - * - * @param target - * the print to scale down. - */ - public ScalePrint(Print target) { - this(target, null); - } - - /** - * Constructs a ScalePrint which scales it's target by the given factor. - * - * @param target - * @param scale - * the scale factor (must be >0). A value of 2.0 draws at double - * the size, and a value of 0.5 draws at half the size. A null - * value automatically scales down so the target is rendered at - * it's preferred size. - */ - public ScalePrint(Print target, Double scale) { - Util.notNull(target); - if (scale != null && !(scale.doubleValue() > 0)) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Scale " + scale + " must be > 0"); //$NON-NLS-1$ //$NON-NLS-2$ - - this.target = target; - this.scale = scale; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((scale == null) ? 0 : scale.hashCode()); - result = prime * result + ((target == null) ? 0 : target.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ScalePrint other = (ScalePrint) obj; - if (scale == null) { - if (other.scale != null) - return false; - } else if (!scale.equals(other.scale)) - return false; - if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) - return false; - return true; - } - - /** - * Returns the print being scaled. - * - * @return the print being scaled. - */ - public Print getTarget() { - return target; - } - - /** - * Returns the scale by which the target will be scaled, or null (indicating - * automatic scale down to fit). - * - * @return the scale by which the target will be scaled, or null (indicating - * automatic scale down to fit). - */ - public Double getScale() { - return scale; - } - - public PrintIterator iterator(Device device, GC gc) { - return new ScaleIterator(this, device, gc); - } -} - -class ScaleIterator implements PrintIterator { - private final Device device; - private final PrintIterator target; - private final Double scale; - - private final Point minimumSize; - private final Point preferredSize; - - ScaleIterator(ScalePrint print, Device device, GC gc) { - Util.notNull(print, device, gc); - - this.device = device; - this.target = print.target.iterator(device, gc); - this.scale = print.scale; - - Point min = target.minimumSize(); - Point pref = target.preferredSize(); - if (scale == null) { // auto-scale - minimumSize = new Point(1, 1); - preferredSize = pref; - } else { // specific scale - double s = scale.doubleValue(); - minimumSize = new Point((int) Math.ceil(min.x * s), (int) Math - .ceil(min.y * s)); - preferredSize = new Point((int) Math.ceil(pref.x * s), (int) Math - .ceil(pref.y * s)); - } - } - - private ScaleIterator(ScaleIterator that) { - this.device = that.device; - this.target = that.target.copy(); - this.scale = that.scale; - - this.minimumSize = that.minimumSize; - this.preferredSize = that.preferredSize; - } - - public Point minimumSize() { - return minimumSize; - } - - public Point preferredSize() { - return preferredSize; - } - - public boolean hasNext() { - return target.hasNext(); - } - - public PrintPiece next(int width, int height) { - // Find out what scale we're going to iterate at. - double scale; - Point pref = target.preferredSize(); - if (this.scale == null) - scale = Math.min(Math.min((double) width / (double) pref.x, - (double) height / (double) pref.y), 1.0); - else - scale = this.scale.doubleValue(); - - // Calculate the width and height to be passed to the target. - final int scaledWidth = (int) Math.ceil(width / scale); - final int scaledHeight = (int) Math.ceil(height / scale); - - PrintPiece target = PaperClips.next(this.target, scaledWidth, - scaledHeight); - - if (target == null) - return null; - - return new ScalePiece(device, target, scale, width, height); - } - - public PrintIterator copy() { - return new ScaleIterator(this); - } -} - -final class ScalePiece implements PrintPiece { - private final Device device; - private final PrintPiece target; - private final double scale; - private final Point size; - - private Transform oldTransform; - private Transform transform; - - ScalePiece(Device device, PrintPiece target, double scale, int maxWidth, - int maxHeight) { - Util.notNull(device, target); - this.device = device; - this.target = target; - this.scale = scale; - Point targetSize = target.getSize(); - this.size = new Point(Math.min((int) Math.ceil(targetSize.x * scale), - maxWidth), Math.min((int) Math.ceil(targetSize.y * scale), - maxHeight)); - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - private Transform getOldTransform() { - if (oldTransform == null) - oldTransform = new Transform(device); - return oldTransform; - } - - private Transform getTransform() { - if (transform == null) - transform = new Transform(device); - return transform; - } - - public void paint(GC gc, int x, int y) { - Transform oldTransform = getOldTransform(); - gc.getTransform(oldTransform); - - Transform transform = getTransform(); - gc.getTransform(transform); - transform.translate(x, y); - transform.scale((float) scale, (float) scale); - gc.setTransform(transform); - - target.paint(gc, 0, 0); - - gc.setTransform(oldTransform); - } - - public void dispose() { - if (oldTransform != null) { - oldTransform.dispose(); - oldTransform = null; - } - if (transform != null) { - transform.dispose(); - transform = null; - } - target.dispose(); - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Transform; + +/** + * A decorator print that scales it's target larger or smaller. + *

+ * Note: On Windows, this class depends on a bugfix available as of + * Eclipse build 3.2, release candidate 3 (2006-04-28). Prior to this release, + * using ScalePrint triggers the bug, causing the document to scale very large + * on paper. This bug manifests itself only on paper, not with on-screen + * viewing. + * + * @author Matthew Hall + */ +public class ScalePrint implements Print { + final Print target; + final Double scale; + + /** + * Constructs a ScalePrint which scales down it's target to print at it's + * preferred size. This constructor is equivalent to calling new + * ScalePrint(target, null). + * + * @param target + * the print to scale down. + */ + public ScalePrint(Print target) { + this(target, null); + } + + /** + * Constructs a ScalePrint which scales it's target by the given factor. + * + * @param target + * @param scale + * the scale factor (must be >0). A value of 2.0 draws at double + * the size, and a value of 0.5 draws at half the size. A null + * value automatically scales down so the target is rendered at + * it's preferred size. + */ + public ScalePrint(Print target, Double scale) { + Util.notNull(target); + if (scale != null && !(scale.doubleValue() > 0)) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Scale " + scale + " must be > 0"); //$NON-NLS-1$ //$NON-NLS-2$ + + this.target = target; + this.scale = scale; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((scale == null) ? 0 : scale.hashCode()); + result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ScalePrint other = (ScalePrint) obj; + if (scale == null) { + if (other.scale != null) + return false; + } else if (!scale.equals(other.scale)) + return false; + if (target == null) { + if (other.target != null) + return false; + } else if (!target.equals(other.target)) + return false; + return true; + } + + /** + * Returns the print being scaled. + * + * @return the print being scaled. + */ + public Print getTarget() { + return target; + } + + /** + * Returns the scale by which the target will be scaled, or null (indicating + * automatic scale down to fit). + * + * @return the scale by which the target will be scaled, or null (indicating + * automatic scale down to fit). + */ + public Double getScale() { + return scale; + } + + public PrintIterator iterator(Device device, GC gc) { + return new ScaleIterator(this, device, gc); + } +} + +class ScaleIterator implements PrintIterator { + private final Device device; + private final PrintIterator target; + private final Double scale; + + private final Point minimumSize; + private final Point preferredSize; + + ScaleIterator(ScalePrint print, Device device, GC gc) { + Util.notNull(print, device, gc); + + this.device = device; + this.target = print.target.iterator(device, gc); + this.scale = print.scale; + + Point min = target.minimumSize(); + Point pref = target.preferredSize(); + if (scale == null) { // auto-scale + minimumSize = new Point(1, 1); + preferredSize = pref; + } else { // specific scale + double s = scale.doubleValue(); + minimumSize = new Point((int) Math.ceil(min.x * s), (int) Math + .ceil(min.y * s)); + preferredSize = new Point((int) Math.ceil(pref.x * s), (int) Math + .ceil(pref.y * s)); + } + } + + private ScaleIterator(ScaleIterator that) { + this.device = that.device; + this.target = that.target.copy(); + this.scale = that.scale; + + this.minimumSize = that.minimumSize; + this.preferredSize = that.preferredSize; + } + + public Point minimumSize() { + return minimumSize; + } + + public Point preferredSize() { + return preferredSize; + } + + public boolean hasNext() { + return target.hasNext(); + } + + public PrintPiece next(int width, int height) { + // Find out what scale we're going to iterate at. + double scale; + Point pref = target.preferredSize(); + if (this.scale == null) + scale = Math.min(Math.min((double) width / (double) pref.x, + (double) height / (double) pref.y), 1.0); + else + scale = this.scale.doubleValue(); + + // Calculate the width and height to be passed to the target. + final int scaledWidth = (int) Math.ceil(width / scale); + final int scaledHeight = (int) Math.ceil(height / scale); + + PrintPiece target = PaperClips.next(this.target, scaledWidth, + scaledHeight); + + if (target == null) + return null; + + return new ScalePiece(device, target, scale, width, height); + } + + public PrintIterator copy() { + return new ScaleIterator(this); + } +} + +final class ScalePiece implements PrintPiece { + private final Device device; + private final PrintPiece target; + private final double scale; + private final Point size; + + private Transform oldTransform; + private Transform transform; + + ScalePiece(Device device, PrintPiece target, double scale, int maxWidth, + int maxHeight) { + Util.notNull(device, target); + this.device = device; + this.target = target; + this.scale = scale; + Point targetSize = target.getSize(); + this.size = new Point(Math.min((int) Math.ceil(targetSize.x * scale), + maxWidth), Math.min((int) Math.ceil(targetSize.y * scale), + maxHeight)); + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + private Transform getOldTransform() { + if (oldTransform == null) + oldTransform = new Transform(device); + return oldTransform; + } + + private Transform getTransform() { + if (transform == null) + transform = new Transform(device); + return transform; + } + + public void paint(GC gc, int x, int y) { + Transform oldTransform = getOldTransform(); + gc.getTransform(oldTransform); + + Transform transform = getTransform(); + gc.getTransform(transform); + transform.translate(x, y); + transform.scale((float) scale, (float) scale); + gc.setTransform(transform); + + target.paint(gc, 0, 0); + + gc.setTransform(oldTransform); + } + + public void dispose() { + if (oldTransform != null) { + oldTransform.dispose(); + oldTransform = null; + } + if (transform != null) { + transform.dispose(); + transform = null; + } + target.dispose(); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/SeriesPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/SeriesPrint.java index 961966469..dbb465891 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/SeriesPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/SeriesPrint.java @@ -1,169 +1,169 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A Print which displays its child prints in series. Each element in the series - * is displayed one at a time (no more than one child per page, although one - * Print may span several pages). - *

- * Use this class as the top-level Print when several distinct Prints should be - * batched into one print job, but printed on separate pages. - * - * @author Matthew Hall - */ -public class SeriesPrint implements Print { - final List items = new ArrayList<>(); - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((items == null) ? 0 : items.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SeriesPrint other = (SeriesPrint) obj; - if (items == null) { - if (other.items != null) - return false; - } else if (!items.equals(other.items)) - return false; - return true; - } - - /** - * Adds the given prints to this SeriesPrint. - * - * @param items - * the Prints to add - */ - public void add(Print[] items) { - Util.noNulls(items); - for (int i = 0; i < items.length; i++) - this.items.add(items[i]); - } - - /** - * Adds the given print to this SeriesPrint. - * - * @param item - * the Print to add - */ - public void add(Print item) { - Util.notNull(item); - items.add(item); - } - - /** - * Returns the number of Prints that have been added to this SeriesPrint. - * - * @return the number of Prints that have been added to this SeriesPrint. - */ - public int size() { - return items.size(); - } - - /** - * Returns an array of items in the series. - * - * @return an array of items in the series. - */ - public Print[] getItems() { - return items.toArray(new Print[items.size()]); - } - - public PrintIterator iterator(Device device, GC gc) { - return new SeriesIterator(this, device, gc); - } -} - -class SeriesIterator implements PrintIterator { - final PrintIterator[] iters; - int index; - - SeriesIterator(SeriesPrint print, Device device, GC gc) { - this.iters = new PrintIterator[print.items.size()]; - for (int i = 0; i < iters.length; i++) - iters[i] = print.items.get(i).iterator(device, gc); - - this.index = 0; - } - - SeriesIterator(SeriesIterator that) { - this.iters = that.iters.clone(); - for (int i = index; i < iters.length; i++) - this.iters[i] = that.iters[i].copy(); - - this.index = that.index; - } - - public boolean hasNext() { - return index < iters.length; - } - - private Point computeSize(PrintSizeStrategy strategy) { - int width = 0; - int height = 0; - for (int i = 0; i < iters.length; i++) { - PrintIterator iter = iters[i]; - Point printSize = strategy.computeSize(iter); - width = Math.max(width, printSize.x); - height = Math.max(height, printSize.y); - } - return new Point(width, height); - } - - public Point minimumSize() { - return computeSize(PrintSizeStrategy.MINIMUM); - } - - public Point preferredSize() { - return computeSize(PrintSizeStrategy.PREFERRED); - } - - public PrintPiece next(int width, int height) { - if (!hasNext()) - PaperClips.error("No more content"); //$NON-NLS-1$ - - PrintIterator iter = iters[index]; - PrintPiece printPiece = PaperClips.next(iter, width, height); - - if (printPiece != null && !iter.hasNext()) - index++; - - return printPiece; - } - - public PrintIterator copy() { - return new SeriesIterator(this); - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A Print which displays its child prints in series. Each element in the series + * is displayed one at a time (no more than one child per page, although one + * Print may span several pages). + *

+ * Use this class as the top-level Print when several distinct Prints should be + * batched into one print job, but printed on separate pages. + * + * @author Matthew Hall + */ +public class SeriesPrint implements Print { + final List items = new ArrayList<>(); + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((items == null) ? 0 : items.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SeriesPrint other = (SeriesPrint) obj; + if (items == null) { + if (other.items != null) + return false; + } else if (!items.equals(other.items)) + return false; + return true; + } + + /** + * Adds the given prints to this SeriesPrint. + * + * @param items + * the Prints to add + */ + public void add(Print[] items) { + Util.noNulls(items); + for (int i = 0; i < items.length; i++) + this.items.add(items[i]); + } + + /** + * Adds the given print to this SeriesPrint. + * + * @param item + * the Print to add + */ + public void add(Print item) { + Util.notNull(item); + items.add(item); + } + + /** + * Returns the number of Prints that have been added to this SeriesPrint. + * + * @return the number of Prints that have been added to this SeriesPrint. + */ + public int size() { + return items.size(); + } + + /** + * Returns an array of items in the series. + * + * @return an array of items in the series. + */ + public Print[] getItems() { + return items.toArray(new Print[items.size()]); + } + + public PrintIterator iterator(Device device, GC gc) { + return new SeriesIterator(this, device, gc); + } +} + +class SeriesIterator implements PrintIterator { + final PrintIterator[] iters; + int index; + + SeriesIterator(SeriesPrint print, Device device, GC gc) { + this.iters = new PrintIterator[print.items.size()]; + for (int i = 0; i < iters.length; i++) + iters[i] = print.items.get(i).iterator(device, gc); + + this.index = 0; + } + + SeriesIterator(SeriesIterator that) { + this.iters = that.iters.clone(); + for (int i = index; i < iters.length; i++) + this.iters[i] = that.iters[i].copy(); + + this.index = that.index; + } + + public boolean hasNext() { + return index < iters.length; + } + + private Point computeSize(PrintSizeStrategy strategy) { + int width = 0; + int height = 0; + for (int i = 0; i < iters.length; i++) { + PrintIterator iter = iters[i]; + Point printSize = strategy.computeSize(iter); + width = Math.max(width, printSize.x); + height = Math.max(height, printSize.y); + } + return new Point(width, height); + } + + public Point minimumSize() { + return computeSize(PrintSizeStrategy.MINIMUM); + } + + public Point preferredSize() { + return computeSize(PrintSizeStrategy.PREFERRED); + } + + public PrintPiece next(int width, int height) { + if (!hasNext()) + PaperClips.error("No more content"); //$NON-NLS-1$ + + PrintIterator iter = iters[index]; + PrintPiece printPiece = PaperClips.next(iter, width, height); + + if (printPiece != null && !iter.hasNext()) + index++; + + return printPiece; + } + + public PrintIterator copy() { + return new SeriesIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/SidewaysPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/SidewaysPrint.java index b76946aa7..856c75948 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/SidewaysPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/SidewaysPrint.java @@ -1,217 +1,217 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.RotatePiece; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A decorator print that rotates it's target by increments of 90 degrees. - *

- * Note: On Windows, this class depends on a bugfix available as of - * Eclipse build 3.2, release candidate 3 (2006-04-28). Prior to this release, - * using SidewaysPrint triggers the bug, causing the document to scale very - * large on paper. This bug only manifests itself on paper, not with on-screen - * viewing. - *

- * SidewaysPrint, unlike RotatePrint, is neither horizontally nor vertically - * greedy. Greedy prints take up all the available space on the page. - * - * @author Matthew Hall - */ -public final class SidewaysPrint implements Print { - private final Print target; - private final int angle; - - /** - * Constructs a SidewaysPrint that rotates it's target 90 degrees - * counter-clockwise. - * - * @param target - * the print to rotate. - */ - public SidewaysPrint(Print target) { - this(target, 90); - } - - /** - * Constructs a SidewaysPrint. - * - * @param target - * the print to rotate. - * @param angle - * the angle by which the target will be rotated, expressed in - * degrees counter-clockwise. Positive values rotate - * counter-clockwise, and negative values rotate clockwise. Must - * be a multiple of 90. - */ - public SidewaysPrint(Print target, int angle) { - Util.notNull(target); - this.target = target; - this.angle = checkAngle(angle); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + angle; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SidewaysPrint other = (SidewaysPrint) obj; - if (angle != other.angle) - return false; - if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) - return false; - return true; - } - - private static int checkAngle(int angle) { - // Make sure angle is a multiple of 90. - if (Math.abs(angle) % 90 != 0) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Angle must be a multiple of 90 degrees"); //$NON-NLS-1$ - - // Bring angle within the range [0, 360) - if (angle < 0) - angle = 360 - (-angle % 360); - if (angle >= 360) - angle = angle % 360; - - return angle; - } - - /** - * Returns the print to be rotated. - * - * @return the print to be rotated. - */ - public Print getTarget() { - return target; - } - - /** - * Returns the angle by which the target will be rotated (one of 0, 90, 180, - * or 270). - * - * @return the angle by which the target will be rotated. - */ - public int getAngle() { - return angle; - } - - public PrintIterator iterator(Device device, GC gc) { - if (angle == 0) - return target.iterator(device, gc); - return new SidewaysIterator(target, angle, device, gc); - } -} - -final class SidewaysIterator implements PrintIterator { - private final Device device; - private final PrintIterator target; - private final int angle; - - private final Point minimumSize; - private final Point preferredSize; - - SidewaysIterator(Print target, int angle, Device device, GC gc) { - Util.notNull(target, device, gc); - - this.device = device; - this.target = target.iterator(device, gc); - this.angle = checkAngle(angle); // returns 90, 180, or 270 only - - Point min = this.target.minimumSize(); - Point pref = this.target.preferredSize(); - - if (this.angle == 180) { - this.minimumSize = new Point(min.x, min.y); - this.preferredSize = new Point(pref.x, pref.y); - } else { // flip x and y sizes if rotating by 90 or 270 degrees - this.minimumSize = new Point(min.y, min.x); - this.preferredSize = new Point(pref.y, pref.x); - } - } - - private SidewaysIterator(SidewaysIterator that) { - this.device = that.device; - this.target = that.target.copy(); - this.angle = that.angle; - this.minimumSize = that.minimumSize; - this.preferredSize = that.preferredSize; - } - - private static int checkAngle(int angle) { - switch (angle) { - case 90: - case 180: - case 270: - break; - default: - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Angle must be 90, 180, or 270"); //$NON-NLS-1$ - } - return angle; - } - - public Point minimumSize() { - return new Point(minimumSize.x, minimumSize.y); - } - - public Point preferredSize() { - return new Point(preferredSize.x, preferredSize.y); - } - - public boolean hasNext() { - return target.hasNext(); - } - - public PrintPiece next(int width, int height) { - PrintPiece target; - if (angle == 180) - target = PaperClips.next(this.target, width, height); - else - // flip width and height if rotating by 90 or 270 - target = PaperClips.next(this.target, height, width); - - if (target == null) - return null; - - Point size = target.getSize(); - if (angle == 90 || angle == 270) - size = new Point(size.y, size.x); - - return new RotatePiece(device, target, angle, size); - } - - public PrintIterator copy() { - return new SidewaysIterator(this); - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.RotatePiece; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A decorator print that rotates it's target by increments of 90 degrees. + *

+ * Note: On Windows, this class depends on a bugfix available as of + * Eclipse build 3.2, release candidate 3 (2006-04-28). Prior to this release, + * using SidewaysPrint triggers the bug, causing the document to scale very + * large on paper. This bug only manifests itself on paper, not with on-screen + * viewing. + *

+ * SidewaysPrint, unlike RotatePrint, is neither horizontally nor vertically + * greedy. Greedy prints take up all the available space on the page. + * + * @author Matthew Hall + */ +public final class SidewaysPrint implements Print { + private final Print target; + private final int angle; + + /** + * Constructs a SidewaysPrint that rotates it's target 90 degrees + * counter-clockwise. + * + * @param target + * the print to rotate. + */ + public SidewaysPrint(Print target) { + this(target, 90); + } + + /** + * Constructs a SidewaysPrint. + * + * @param target + * the print to rotate. + * @param angle + * the angle by which the target will be rotated, expressed in + * degrees counter-clockwise. Positive values rotate + * counter-clockwise, and negative values rotate clockwise. Must + * be a multiple of 90. + */ + public SidewaysPrint(Print target, int angle) { + Util.notNull(target); + this.target = target; + this.angle = checkAngle(angle); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + angle; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SidewaysPrint other = (SidewaysPrint) obj; + if (angle != other.angle) + return false; + if (target == null) { + if (other.target != null) + return false; + } else if (!target.equals(other.target)) + return false; + return true; + } + + private static int checkAngle(int angle) { + // Make sure angle is a multiple of 90. + if (Math.abs(angle) % 90 != 0) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Angle must be a multiple of 90 degrees"); //$NON-NLS-1$ + + // Bring angle within the range [0, 360) + if (angle < 0) + angle = 360 - (-angle % 360); + if (angle >= 360) + angle = angle % 360; + + return angle; + } + + /** + * Returns the print to be rotated. + * + * @return the print to be rotated. + */ + public Print getTarget() { + return target; + } + + /** + * Returns the angle by which the target will be rotated (one of 0, 90, 180, + * or 270). + * + * @return the angle by which the target will be rotated. + */ + public int getAngle() { + return angle; + } + + public PrintIterator iterator(Device device, GC gc) { + if (angle == 0) + return target.iterator(device, gc); + return new SidewaysIterator(target, angle, device, gc); + } +} + +final class SidewaysIterator implements PrintIterator { + private final Device device; + private final PrintIterator target; + private final int angle; + + private final Point minimumSize; + private final Point preferredSize; + + SidewaysIterator(Print target, int angle, Device device, GC gc) { + Util.notNull(target, device, gc); + + this.device = device; + this.target = target.iterator(device, gc); + this.angle = checkAngle(angle); // returns 90, 180, or 270 only + + Point min = this.target.minimumSize(); + Point pref = this.target.preferredSize(); + + if (this.angle == 180) { + this.minimumSize = new Point(min.x, min.y); + this.preferredSize = new Point(pref.x, pref.y); + } else { // flip x and y sizes if rotating by 90 or 270 degrees + this.minimumSize = new Point(min.y, min.x); + this.preferredSize = new Point(pref.y, pref.x); + } + } + + private SidewaysIterator(SidewaysIterator that) { + this.device = that.device; + this.target = that.target.copy(); + this.angle = that.angle; + this.minimumSize = that.minimumSize; + this.preferredSize = that.preferredSize; + } + + private static int checkAngle(int angle) { + switch (angle) { + case 90: + case 180: + case 270: + break; + default: + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Angle must be 90, 180, or 270"); //$NON-NLS-1$ + } + return angle; + } + + public Point minimumSize() { + return new Point(minimumSize.x, minimumSize.y); + } + + public Point preferredSize() { + return new Point(preferredSize.x, preferredSize.y); + } + + public boolean hasNext() { + return target.hasNext(); + } + + public PrintPiece next(int width, int height) { + PrintPiece target; + if (angle == 180) + target = PaperClips.next(this.target, width, height); + else + // flip width and height if rotating by 90 or 270 + target = PaperClips.next(this.target, height, width); + + if (target == null) + return null; + + Point size = target.getSize(); + if (angle == 90 || angle == 270) + size = new Point(size.y, size.x); + + return new RotatePiece(device, target, angle, size); + } + + public PrintIterator copy() { + return new SidewaysIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/AbstractBorderPainter.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/AbstractBorderPainter.java index 96ea1d366..c3adde8e1 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/AbstractBorderPainter.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/AbstractBorderPainter.java @@ -1,74 +1,74 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.border; - -import org.eclipse.swt.graphics.GC; - -/** - * Abstract implementation of BorderPainter providing implementation of helper - * methods. - * - * @author Matthew Hall - */ -public abstract class AbstractBorderPainter implements BorderPainter { - /** - * Paints a border around the specified region. Depending on the type of - * border, the top and bottom of may be painted differently depending on the - * values of topOpen and bottomOpen. - */ - public abstract void paint(GC gc, int x, int y, int width, int height, - boolean topOpen, boolean bottomOpen); - - /** - * Returns the border inset, in pixels, from the left. - */ - public abstract int getLeft(); - - /** - * Returns the border inset, in pixels, from the right. - */ - public abstract int getRight(); - - /** - * Returns the sum of the left and right border insets. - */ - public final int getWidth() { - return getLeft() + getRight(); - } - - /** - * Returns the border inset, in pixels, from the top. - */ - public abstract int getTop(boolean open); - - /** - * Returns the border inset, in pixels, from the bottom. - */ - public abstract int getBottom(boolean open); - - /** - * Returns the sum of the top and bottom border insets. - */ - public final int getHeight(boolean topOpen, boolean bottomOpen) { - return getTop(topOpen) + getBottom(bottomOpen); - } - - /** - * Returns the sum of the maximum top and bottom border insets. - */ - public final int getMaxHeight() { - return Math.max(getTop(false), getTop(true)) - + Math.max(getBottom(false), getBottom(true)); - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.border; + +import org.eclipse.swt.graphics.GC; + +/** + * Abstract implementation of BorderPainter providing implementation of helper + * methods. + * + * @author Matthew Hall + */ +public abstract class AbstractBorderPainter implements BorderPainter { + /** + * Paints a border around the specified region. Depending on the type of + * border, the top and bottom of may be painted differently depending on the + * values of topOpen and bottomOpen. + */ + public abstract void paint(GC gc, int x, int y, int width, int height, + boolean topOpen, boolean bottomOpen); + + /** + * Returns the border inset, in pixels, from the left. + */ + public abstract int getLeft(); + + /** + * Returns the border inset, in pixels, from the right. + */ + public abstract int getRight(); + + /** + * Returns the sum of the left and right border insets. + */ + public final int getWidth() { + return getLeft() + getRight(); + } + + /** + * Returns the border inset, in pixels, from the top. + */ + public abstract int getTop(boolean open); + + /** + * Returns the border inset, in pixels, from the bottom. + */ + public abstract int getBottom(boolean open); + + /** + * Returns the sum of the top and bottom border insets. + */ + public final int getHeight(boolean topOpen, boolean bottomOpen) { + return getTop(topOpen) + getBottom(bottomOpen); + } + + /** + * Returns the sum of the maximum top and bottom border insets. + */ + public final int getMaxHeight() { + return Math.max(getTop(false), getTop(true)) + + Math.max(getBottom(false), getBottom(true)); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/Border.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/Border.java index 5204aaae0..2e0095cda 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/Border.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/Border.java @@ -1,37 +1,37 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.border; - -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -/** - * Interface for drawing borders, used by BorderPaint and GridPrint for drawing - * borders a child print and grid cells, respectively. - * - * @author Matthew Hall - */ -public interface Border { - /** - * Creates a BorderPainter which uses the given Device and GC. - * - * @param device - * the print device. - * @param gc - * a GC for drawing to the print device. - * @return a BorderPainter for painting the border on the given Device and - * GC. - */ - public BorderPainter createPainter(Device device, GC gc); -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.border; + +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +/** + * Interface for drawing borders, used by BorderPaint and GridPrint for drawing + * borders a child print and grid cells, respectively. + * + * @author Matthew Hall + */ +public interface Border { + /** + * Creates a BorderPainter which uses the given Device and GC. + * + * @param device + * the print device. + * @param gc + * a GC for drawing to the print device. + * @return a BorderPainter for painting the border on the given Device and + * GC. + */ + public BorderPainter createPainter(Device device, GC gc); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/BorderPainter.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/BorderPainter.java index 385803692..b6383fc30 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/BorderPainter.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/BorderPainter.java @@ -1,136 +1,136 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.border; - -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * Interface for calculating and drawing borders in a BorderPrint. - * - * @author Matthew Hall - */ -public interface BorderPainter { - /** - * Returns the border inset, in pixels, from the left. - * - * @return the border inset, in pixels, from the left. - */ - public int getLeft(); - - /** - * Returns the border inset, in pixels, from the right. - * - * @return the border inset, in pixels, from the right. - */ - public int getRight(); - - /** - * Returns the sum of the left and right border insets. - * - * @return the sum of the left and right border insets. - */ - public int getWidth(); - - /** - * Returns the border inset, in pixels, from the top. - * - * @param open - * If true, the inset of an open border will be returned. If - * false, the inset of a closed border will be returned. - * @return the border inset, in pixels, from the top. - */ - public int getTop(boolean open); - - /** - * Returns the border inset, in pixels, from the bottom. - * - * @param open - * If true, the inset of an open border will be returned. If - * false, the inset of a closed border will be returned. - * @return the border inset, in pixels, from the bottom. - */ - public int getBottom(boolean open); - - /** - * Returns the sum of the top and bottom border insets. - * - * @param topOpen - * If true, the inset of an open border will be returned. If - * false, the inset of a closed border will be returned. - * @param bottomOpen - * If true, the inset of an open border will be returned. If - * false, the inset of a closed border will be returned. - * @return the sum of the top and bottom border insets. - */ - public int getHeight(boolean topOpen, boolean bottomOpen); - - /** - * Returns the sum of the maximum top and bottom border insets. - * - * @return the sum of the maximum top and bottom border insets. - */ - public int getMaxHeight(); - - /** - * Returns the x and y distance that two of the same BorderPainters would - * overlap to create the appearance of a single border between the two. This - * method is used by GridPrint whenever the horizontal and/or vertical - * spacing fields are set to {@link GridPrint#BORDER_OVERLAP }. - * - * @return the distance that this border painter would overlap an adjacent - * one. - */ - public Point getOverlap(); - - /** - * Paints a border around the specified region. Depending on the type of - * border, the top and bottom of may be painted differently depending on the - * values of topOpen and bottomOpen. - * - * @param gc - * The graphics context to paint on. - * @param x - * The x coordinate of the top left corner of the border. - * @param y - * The y coordinate of the top left corner of the border. - * @param width - * The width of the border to paint - * @param height - * The height of the border to paint - * @param topOpen - * If true, the top border should be drawn "open," to indicate - * that this is the continuation of a border in a previous - * iteration. If false, the border should be drawn "closed" to - * indicate that this is the first iteration on the BorderPrint's - * target. - * @param bottomOpen - * If true, the bottom border should be drawn "open," to indicate - * that the BorderPrint's target was not consumed in this - * iteration. If false, the bottom border should be drawn - * "closed," to indicate that the BorderPrint's target completed - * during this iteration. - */ - public void paint(GC gc, int x, int y, int width, int height, - boolean topOpen, boolean bottomOpen); - - /** - * Disposes the system resources allocated by this BorderPainter. The - * dispose method is not a permanent disposal of a BorderPainter. It - * is intended to reclaim system resources, however future calls to - * paint(GC,int,int) may require that the resources be allocated again. - */ - public void dispose(); +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.border; + +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * Interface for calculating and drawing borders in a BorderPrint. + * + * @author Matthew Hall + */ +public interface BorderPainter { + /** + * Returns the border inset, in pixels, from the left. + * + * @return the border inset, in pixels, from the left. + */ + public int getLeft(); + + /** + * Returns the border inset, in pixels, from the right. + * + * @return the border inset, in pixels, from the right. + */ + public int getRight(); + + /** + * Returns the sum of the left and right border insets. + * + * @return the sum of the left and right border insets. + */ + public int getWidth(); + + /** + * Returns the border inset, in pixels, from the top. + * + * @param open + * If true, the inset of an open border will be returned. If + * false, the inset of a closed border will be returned. + * @return the border inset, in pixels, from the top. + */ + public int getTop(boolean open); + + /** + * Returns the border inset, in pixels, from the bottom. + * + * @param open + * If true, the inset of an open border will be returned. If + * false, the inset of a closed border will be returned. + * @return the border inset, in pixels, from the bottom. + */ + public int getBottom(boolean open); + + /** + * Returns the sum of the top and bottom border insets. + * + * @param topOpen + * If true, the inset of an open border will be returned. If + * false, the inset of a closed border will be returned. + * @param bottomOpen + * If true, the inset of an open border will be returned. If + * false, the inset of a closed border will be returned. + * @return the sum of the top and bottom border insets. + */ + public int getHeight(boolean topOpen, boolean bottomOpen); + + /** + * Returns the sum of the maximum top and bottom border insets. + * + * @return the sum of the maximum top and bottom border insets. + */ + public int getMaxHeight(); + + /** + * Returns the x and y distance that two of the same BorderPainters would + * overlap to create the appearance of a single border between the two. This + * method is used by GridPrint whenever the horizontal and/or vertical + * spacing fields are set to {@link GridPrint#BORDER_OVERLAP }. + * + * @return the distance that this border painter would overlap an adjacent + * one. + */ + public Point getOverlap(); + + /** + * Paints a border around the specified region. Depending on the type of + * border, the top and bottom of may be painted differently depending on the + * values of topOpen and bottomOpen. + * + * @param gc + * The graphics context to paint on. + * @param x + * The x coordinate of the top left corner of the border. + * @param y + * The y coordinate of the top left corner of the border. + * @param width + * The width of the border to paint + * @param height + * The height of the border to paint + * @param topOpen + * If true, the top border should be drawn "open," to indicate + * that this is the continuation of a border in a previous + * iteration. If false, the border should be drawn "closed" to + * indicate that this is the first iteration on the BorderPrint's + * target. + * @param bottomOpen + * If true, the bottom border should be drawn "open," to indicate + * that the BorderPrint's target was not consumed in this + * iteration. If false, the bottom border should be drawn + * "closed," to indicate that the BorderPrint's target completed + * during this iteration. + */ + public void paint(GC gc, int x, int y, int width, int height, + boolean topOpen, boolean bottomOpen); + + /** + * Disposes the system resources allocated by this BorderPainter. The + * dispose method is not a permanent disposal of a BorderPainter. It + * is intended to reclaim system resources, however future calls to + * paint(GC,int,int) may require that the resources be allocated again. + */ + public void dispose(); } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/BorderPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/BorderPrint.java index 34ca88b1b..3c40d85bd 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/BorderPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/BorderPrint.java @@ -1,96 +1,96 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.border; - -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.border.internal.BorderIterator; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -/** - * A decorator that draws a border around the target print. - * - * @author Matthew Hall - */ -public class BorderPrint implements Print { - final Print target; - final Border border; - - /** - * Constructs a BorderPrint with the given target and border. - * - * @param target - * the print to decorate with a border. - * @param border - * the border which will be drawn around the target. - */ - public BorderPrint(Print target, Border border) { - Util.notNull(target, border); - this.target = target; - this.border = border; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((border == null) ? 0 : border.hashCode()); - result = prime * result + ((target == null) ? 0 : target.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - BorderPrint other = (BorderPrint) obj; - if (border == null) { - if (other.border != null) - return false; - } else if (!border.equals(other.border)) - return false; - if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) - return false; - return true; - } - - /** - * Returns the wrapped print to which the border is being applied. - * - * @return the wrapped print to which the border is being applied. - */ - public Print getTarget() { - return target; - } - - /** - * Returns the border being applied to the target. - * - * @return the border being applied to the target. - */ - public Border getBorder() { - return border; - } - - public PrintIterator iterator(Device device, GC gc) { - return new BorderIterator(this, device, gc); - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.border; + +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.border.internal.BorderIterator; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +/** + * A decorator that draws a border around the target print. + * + * @author Matthew Hall + */ +public class BorderPrint implements Print { + final Print target; + final Border border; + + /** + * Constructs a BorderPrint with the given target and border. + * + * @param target + * the print to decorate with a border. + * @param border + * the border which will be drawn around the target. + */ + public BorderPrint(Print target, Border border) { + Util.notNull(target, border); + this.target = target; + this.border = border; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((border == null) ? 0 : border.hashCode()); + result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BorderPrint other = (BorderPrint) obj; + if (border == null) { + if (other.border != null) + return false; + } else if (!border.equals(other.border)) + return false; + if (target == null) { + if (other.target != null) + return false; + } else if (!target.equals(other.target)) + return false; + return true; + } + + /** + * Returns the wrapped print to which the border is being applied. + * + * @return the wrapped print to which the border is being applied. + */ + public Print getTarget() { + return target; + } + + /** + * Returns the border being applied to the target. + * + * @return the border being applied to the target. + */ + public Border getBorder() { + return border; + } + + public PrintIterator iterator(Device device, GC gc) { + return new BorderIterator(this, device, gc); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/GapBorder.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/GapBorder.java index c3ab09290..61c9d08a0 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/GapBorder.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/GapBorder.java @@ -1,181 +1,181 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.border; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A border which leaves a gap around the target Print. - * - * @author Matthew Hall - */ -public class GapBorder implements Border { - /** The top gap of a closed border, expressed in points. */ - public int top = 0; - - /** The bottom gap of a closed border, expressed in points. */ - public int bottom = 0; - - /** The left side gap, expressed in points. */ - public int left = 0; - - /** The right side gap, expressed in points. */ - public int right = 0; - - /** The top gap of an open border, expressed in points. */ - public int openTop = 0; - - /** The bottom gap of an open border, expressed in points. */ - public int openBottom = 0; - - /** - * Constructs a GapBorder with 0 gap around all sides. - */ - public GapBorder() { - this(0); - } - - /** - * Constructs a GapBorder with the given gap around all sides. - * - * @param gap - * the gap, expressed in points. - */ - public GapBorder(int gap) { - setGap(gap); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + bottom; - result = prime * result + left; - result = prime * result + openBottom; - result = prime * result + openTop; - result = prime * result + right; - result = prime * result + top; - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - GapBorder other = (GapBorder) obj; - if (bottom != other.bottom) - return false; - if (left != other.left) - return false; - if (openBottom != other.openBottom) - return false; - if (openTop != other.openTop) - return false; - if (right != other.right) - return false; - if (top != other.top) - return false; - return true; - } - - /** - * Sets the left, right, closed top and closed bottom gaps to he argument. - * - * @param gap - * the gap, expressed in points. - */ - public void setGap(int gap) { - top = left = bottom = right = checkGap(gap); - } - - int checkGap(int gap) { - if (gap < 0) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Gap must be >= 0"); //$NON-NLS-1$ - return gap; - } - - public BorderPainter createPainter(Device device, GC gc) { - return new GapBorderPainter(this, device); - } -} - -class GapBorderPainter extends AbstractBorderPainter { - final int top; - final int openTop; - final int bottom; - final int openBottom; - final int left; - final int right; - - GapBorderPainter(GapBorder target, Device device) { - Point dpi = device.getDPI(); - - this.top = toPixels(target.top, dpi.y); - this.bottom = toPixels(target.bottom, dpi.y); - this.openTop = toPixels(target.openTop, dpi.y); - this.openBottom = toPixels(target.openBottom, dpi.y); - - this.left = toPixels(target.left, dpi.x); - this.right = toPixels(target.right, dpi.x); - } - - GapBorderPainter(GapBorderPainter that) { - this.top = that.top; - this.bottom = that.bottom; - this.left = that.left; - this.right = that.right; - - this.openTop = that.openTop; - this.openBottom = that.openBottom; - } - - static int toPixels(int points, int dpi) { - return Math.max(0, points) * dpi / 72; - } - - public int getBottom(boolean open) { - return open ? openBottom : bottom; - } - - public int getLeft() { - return left; - } - - public int getRight() { - return right; - } - - public int getTop(boolean open) { - return open ? openTop : top; - } - - public Point getOverlap() { - return new Point(Math.min(left, right), Math.max(top, bottom)); - } - - public void paint(GC gc, int x, int y, int width, int height, - boolean topOpen, boolean bottomOpen) { - // Nothing to paint. - } - - public void dispose() { - // Nothing to dispose - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.border; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A border which leaves a gap around the target Print. + * + * @author Matthew Hall + */ +public class GapBorder implements Border { + /** The top gap of a closed border, expressed in points. */ + public int top = 0; + + /** The bottom gap of a closed border, expressed in points. */ + public int bottom = 0; + + /** The left side gap, expressed in points. */ + public int left = 0; + + /** The right side gap, expressed in points. */ + public int right = 0; + + /** The top gap of an open border, expressed in points. */ + public int openTop = 0; + + /** The bottom gap of an open border, expressed in points. */ + public int openBottom = 0; + + /** + * Constructs a GapBorder with 0 gap around all sides. + */ + public GapBorder() { + this(0); + } + + /** + * Constructs a GapBorder with the given gap around all sides. + * + * @param gap + * the gap, expressed in points. + */ + public GapBorder(int gap) { + setGap(gap); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + bottom; + result = prime * result + left; + result = prime * result + openBottom; + result = prime * result + openTop; + result = prime * result + right; + result = prime * result + top; + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + GapBorder other = (GapBorder) obj; + if (bottom != other.bottom) + return false; + if (left != other.left) + return false; + if (openBottom != other.openBottom) + return false; + if (openTop != other.openTop) + return false; + if (right != other.right) + return false; + if (top != other.top) + return false; + return true; + } + + /** + * Sets the left, right, closed top and closed bottom gaps to he argument. + * + * @param gap + * the gap, expressed in points. + */ + public void setGap(int gap) { + top = left = bottom = right = checkGap(gap); + } + + int checkGap(int gap) { + if (gap < 0) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Gap must be >= 0"); //$NON-NLS-1$ + return gap; + } + + public BorderPainter createPainter(Device device, GC gc) { + return new GapBorderPainter(this, device); + } +} + +class GapBorderPainter extends AbstractBorderPainter { + final int top; + final int openTop; + final int bottom; + final int openBottom; + final int left; + final int right; + + GapBorderPainter(GapBorder target, Device device) { + Point dpi = device.getDPI(); + + this.top = toPixels(target.top, dpi.y); + this.bottom = toPixels(target.bottom, dpi.y); + this.openTop = toPixels(target.openTop, dpi.y); + this.openBottom = toPixels(target.openBottom, dpi.y); + + this.left = toPixels(target.left, dpi.x); + this.right = toPixels(target.right, dpi.x); + } + + GapBorderPainter(GapBorderPainter that) { + this.top = that.top; + this.bottom = that.bottom; + this.left = that.left; + this.right = that.right; + + this.openTop = that.openTop; + this.openBottom = that.openBottom; + } + + static int toPixels(int points, int dpi) { + return Math.max(0, points) * dpi / 72; + } + + public int getBottom(boolean open) { + return open ? openBottom : bottom; + } + + public int getLeft() { + return left; + } + + public int getRight() { + return right; + } + + public int getTop(boolean open) { + return open ? openTop : top; + } + + public Point getOverlap() { + return new Point(Math.min(left, right), Math.max(top, bottom)); + } + + public void paint(GC gc, int x, int y, int width, int height, + boolean topOpen, boolean bottomOpen) { + // Nothing to paint. + } + + public void dispose() { + // Nothing to dispose + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/LineBorder.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/LineBorder.java index af878560d..a450789c9 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/LineBorder.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/LineBorder.java @@ -1,215 +1,215 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.border; - -import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; - -/** - * A border that draws a rectangle around a print. - * - * @author Matthew Hall - */ -public class LineBorder implements Border { - RGB rgb; - int lineWidth = 1; // in points - int gapSize = 5; // in points - - /** - * Constructs a LineBorder with a black border and 5-pt insets. (72 pts = - * 1") - */ - public LineBorder() { - this(new RGB(0, 0, 0)); // black - } - - /** - * Constructs a LineBorder with 5-pt insets. (72 pts = 1") - * - * @param rgb - * the color to use for the border. - */ - public LineBorder(RGB rgb) { - setRGB(rgb); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + gapSize; - result = prime * result + lineWidth; - result = prime * result + ((rgb == null) ? 0 : rgb.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LineBorder other = (LineBorder) obj; - if (gapSize != other.gapSize) - return false; - if (lineWidth != other.lineWidth) - return false; - if (rgb == null) { - if (other.rgb != null) - return false; - } else if (!rgb.equals(other.rgb)) - return false; - return true; - } - - /** - * Sets the border color to the argument. - * - * @param rgb - * the new border color. - */ - public void setRGB(RGB rgb) { - this.rgb = new RGB(rgb.red, rgb.green, rgb.blue); - } - - /** - * Returns the border color. - * - * @return the border color. - */ - public RGB getRGB() { - return new RGB(rgb.red, rgb.green, rgb.blue); - } - - /** - * Sets the line width to the argument. - * - * @param points - * the line width, in points. - */ - public void setLineWidth(int points) { - if (points < 1) - points = 1; - - this.lineWidth = points; - } - - /** - * Returns the line width of the border, expressed in points. - * - * @return the line width of the border, expressed in points. - */ - public int getLineWidth() { - return lineWidth; - } - - /** - * Sets the size of the gap between the line border and the target print. - * - * @param points - * the gap size, expressed in points. - */ - public void setGapSize(int points) { - if (points < 1) - points = 1; - - this.gapSize = points; - } - - /** - * Returns the size of the gap between the line border and the target print, - * expressed in points. - * - * @return the gap size between the line border and the target print. - */ - public int getGapSize() { - return Math.max(lineWidth, gapSize); - } - - public BorderPainter createPainter(Device device, GC gc) { - return new LineBorderPainter(this, device, gc); - } -} - -class LineBorderPainter extends AbstractBorderPainter { - private final Device device; - private final RGB rgb; - private final Point lineWidth; - private final Point borderWidth; - - LineBorderPainter(LineBorder border, Device device, GC gc) { - Util.notNull(border, device, gc); - this.rgb = border.rgb; - this.device = device; - - int lineWidthPoints = border.getLineWidth(); - int borderWidthPoints = border.getGapSize(); - - Point dpi = device.getDPI(); - lineWidth = new Point(Math.round(lineWidthPoints * dpi.x / 72f), Math - .round(lineWidthPoints * dpi.y / 72f)); - borderWidth = new Point(Math.round(borderWidthPoints * dpi.x / 72f), - Math.round(borderWidthPoints * dpi.y / 72f)); - } - - public int getLeft() { - return borderWidth.x; - } - - public int getRight() { - return borderWidth.x; - } - - public int getTop(boolean open) { - return open ? 0 : borderWidth.y; - } - - public int getBottom(boolean open) { - return open ? 0 : borderWidth.y; - } - - public void paint(GC gc, int x, int y, int width, int height, - boolean topOpen, boolean bottomOpen) { - Color oldColor = gc.getBackground(); - - try { - gc.setBackground(ResourcePool.forDevice(device).getColor(rgb)); - - // Left & right - gc.fillRectangle(x, y, lineWidth.x, height); - gc.fillRectangle(x + width - lineWidth.x, y, lineWidth.x, height); - - // Top & bottom - if (!topOpen) - gc.fillRectangle(x, y, width, lineWidth.y); - if (!bottomOpen) - gc.fillRectangle(x, y + height - lineWidth.y, width, - lineWidth.y); - } finally { - gc.setBackground(oldColor); - } - } - - public Point getOverlap() { - return new Point(lineWidth.x, lineWidth.y); - } - - public void dispose() { - } // Shared resources -- nothing to dispose -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.border; + +import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; + +/** + * A border that draws a rectangle around a print. + * + * @author Matthew Hall + */ +public class LineBorder implements Border { + RGB rgb; + int lineWidth = 1; // in points + int gapSize = 5; // in points + + /** + * Constructs a LineBorder with a black border and 5-pt insets. (72 pts = + * 1") + */ + public LineBorder() { + this(new RGB(0, 0, 0)); // black + } + + /** + * Constructs a LineBorder with 5-pt insets. (72 pts = 1") + * + * @param rgb + * the color to use for the border. + */ + public LineBorder(RGB rgb) { + setRGB(rgb); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + gapSize; + result = prime * result + lineWidth; + result = prime * result + ((rgb == null) ? 0 : rgb.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LineBorder other = (LineBorder) obj; + if (gapSize != other.gapSize) + return false; + if (lineWidth != other.lineWidth) + return false; + if (rgb == null) { + if (other.rgb != null) + return false; + } else if (!rgb.equals(other.rgb)) + return false; + return true; + } + + /** + * Sets the border color to the argument. + * + * @param rgb + * the new border color. + */ + public void setRGB(RGB rgb) { + this.rgb = new RGB(rgb.red, rgb.green, rgb.blue); + } + + /** + * Returns the border color. + * + * @return the border color. + */ + public RGB getRGB() { + return new RGB(rgb.red, rgb.green, rgb.blue); + } + + /** + * Sets the line width to the argument. + * + * @param points + * the line width, in points. + */ + public void setLineWidth(int points) { + if (points < 1) + points = 1; + + this.lineWidth = points; + } + + /** + * Returns the line width of the border, expressed in points. + * + * @return the line width of the border, expressed in points. + */ + public int getLineWidth() { + return lineWidth; + } + + /** + * Sets the size of the gap between the line border and the target print. + * + * @param points + * the gap size, expressed in points. + */ + public void setGapSize(int points) { + if (points < 1) + points = 1; + + this.gapSize = points; + } + + /** + * Returns the size of the gap between the line border and the target print, + * expressed in points. + * + * @return the gap size between the line border and the target print. + */ + public int getGapSize() { + return Math.max(lineWidth, gapSize); + } + + public BorderPainter createPainter(Device device, GC gc) { + return new LineBorderPainter(this, device, gc); + } +} + +class LineBorderPainter extends AbstractBorderPainter { + private final Device device; + private final RGB rgb; + private final Point lineWidth; + private final Point borderWidth; + + LineBorderPainter(LineBorder border, Device device, GC gc) { + Util.notNull(border, device, gc); + this.rgb = border.rgb; + this.device = device; + + int lineWidthPoints = border.getLineWidth(); + int borderWidthPoints = border.getGapSize(); + + Point dpi = device.getDPI(); + lineWidth = new Point(Math.round(lineWidthPoints * dpi.x / 72f), Math + .round(lineWidthPoints * dpi.y / 72f)); + borderWidth = new Point(Math.round(borderWidthPoints * dpi.x / 72f), + Math.round(borderWidthPoints * dpi.y / 72f)); + } + + public int getLeft() { + return borderWidth.x; + } + + public int getRight() { + return borderWidth.x; + } + + public int getTop(boolean open) { + return open ? 0 : borderWidth.y; + } + + public int getBottom(boolean open) { + return open ? 0 : borderWidth.y; + } + + public void paint(GC gc, int x, int y, int width, int height, + boolean topOpen, boolean bottomOpen) { + Color oldColor = gc.getBackground(); + + try { + gc.setBackground(ResourcePool.forDevice(device).getColor(rgb)); + + // Left & right + gc.fillRectangle(x, y, lineWidth.x, height); + gc.fillRectangle(x + width - lineWidth.x, y, lineWidth.x, height); + + // Top & bottom + if (!topOpen) + gc.fillRectangle(x, y, width, lineWidth.y); + if (!bottomOpen) + gc.fillRectangle(x, y + height - lineWidth.y, width, + lineWidth.y); + } finally { + gc.setBackground(oldColor); + } + } + + public Point getOverlap() { + return new Point(lineWidth.x, lineWidth.y); + } + + public void dispose() { + } // Shared resources -- nothing to dispose +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/internal/BorderIterator.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/internal/BorderIterator.java index 191df7a67..2c1525bea 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/internal/BorderIterator.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/internal/BorderIterator.java @@ -1,152 +1,152 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ - -package org.eclipse.nebula.paperclips.core.border.internal; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.border.BorderPainter; -import org.eclipse.nebula.paperclips.core.border.BorderPrint; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -public class BorderIterator implements PrintIterator { - private final BorderPainter border; - - private PrintIterator target; - private boolean opened; - - public BorderIterator(BorderPrint print, Device device, GC gc) { - this.border = print.getBorder().createPainter(device, gc); - - this.target = print.getTarget().iterator(device, gc); - this.opened = false; - } - - public BorderIterator(BorderIterator that) { - this.border = that.border; - - this.target = that.target.copy(); - this.opened = that.opened; - } - - public boolean hasNext() { - return target.hasNext(); - } - - public Point minimumSize() { - return addBorderMargin(target.minimumSize()); - } - - public Point preferredSize() { - return addBorderMargin(target.preferredSize()); - } - - private Point addBorderMargin(Point targetSize) { - return new Point(targetSize.x + border.getWidth(), targetSize.y - + border.getMaxHeight()); - } - - public PrintPiece next(int width, int height) { - if (!hasNext()) - PaperClips.error("No more content"); //$NON-NLS-1$ - - PrintPiece piece = next(width, height, false /* closed bottom border */); - - if (piece == null) - piece = next(width, height, true /* open bottom border */); - - if (piece != null) - opened = true; - - return piece; - } - - private PrintPiece next(int width, int height, boolean bottomBorderOpen) { - // Adjust iteration area for border dimensions. - width -= border.getWidth(); - height -= border.getHeight(opened, bottomBorderOpen); - if (width < 0 || height < 0) - return null; - - PrintIterator iter = target.copy(); - PrintPiece piece = PaperClips.next(iter, width, height); - if (piece == null) - return null; - - if (bottomBorderOpen && !iter.hasNext()) { - // The target content was consumed, but the bottom border is open - // (suggesting that there is more - // content): find the largest piece that *doesn't* consume all the - // target's content, and show it with - // an open bottom border. - piece.dispose(); - piece = getTallestPieceNotCompletelyConsumingTarget(width, height); - if (piece == null) - return null; - } else if (!bottomBorderOpen && iter.hasNext()) { - // Bottom border is closed but the target has more content: fail so - // calling method can try again with - // an open bottom border. - piece.dispose(); - return null; - } else { - this.target = iter; - } - - // Decorate the target print piece with border - piece = new BorderPiece(piece, border, opened, bottomBorderOpen); - - return piece; - } - - private PrintPiece getTallestPieceNotCompletelyConsumingTarget( - final int width, final int height) { - int low = 0; - int high = height - 1; - - PrintIterator bestIterator = null; - PrintPiece bestPiece = null; - while (low + 1 < high) { - int testHeight = (low + high + 1) / 2; - - PrintIterator testIterator = target.copy(); - PrintPiece testPiece = PaperClips.next(testIterator, width, - testHeight); - - if (testPiece == null) { - low = testHeight + 1; - } else if (testIterator.hasNext()) { - low = testHeight; - - if (bestPiece != null) - bestPiece.dispose(); - bestIterator = testIterator; - bestPiece = testPiece; - } else { // !testIterator.hasNext() - high = testPiece.getSize().y - 1; - } - } - - if (bestPiece != null) - this.target = bestIterator; - return bestPiece; - } - - public PrintIterator copy() { - return new BorderIterator(this); - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ + +package org.eclipse.nebula.paperclips.core.border.internal; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.border.BorderPainter; +import org.eclipse.nebula.paperclips.core.border.BorderPrint; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +public class BorderIterator implements PrintIterator { + private final BorderPainter border; + + private PrintIterator target; + private boolean opened; + + public BorderIterator(BorderPrint print, Device device, GC gc) { + this.border = print.getBorder().createPainter(device, gc); + + this.target = print.getTarget().iterator(device, gc); + this.opened = false; + } + + public BorderIterator(BorderIterator that) { + this.border = that.border; + + this.target = that.target.copy(); + this.opened = that.opened; + } + + public boolean hasNext() { + return target.hasNext(); + } + + public Point minimumSize() { + return addBorderMargin(target.minimumSize()); + } + + public Point preferredSize() { + return addBorderMargin(target.preferredSize()); + } + + private Point addBorderMargin(Point targetSize) { + return new Point(targetSize.x + border.getWidth(), targetSize.y + + border.getMaxHeight()); + } + + public PrintPiece next(int width, int height) { + if (!hasNext()) + PaperClips.error("No more content"); //$NON-NLS-1$ + + PrintPiece piece = next(width, height, false /* closed bottom border */); + + if (piece == null) + piece = next(width, height, true /* open bottom border */); + + if (piece != null) + opened = true; + + return piece; + } + + private PrintPiece next(int width, int height, boolean bottomBorderOpen) { + // Adjust iteration area for border dimensions. + width -= border.getWidth(); + height -= border.getHeight(opened, bottomBorderOpen); + if (width < 0 || height < 0) + return null; + + PrintIterator iter = target.copy(); + PrintPiece piece = PaperClips.next(iter, width, height); + if (piece == null) + return null; + + if (bottomBorderOpen && !iter.hasNext()) { + // The target content was consumed, but the bottom border is open + // (suggesting that there is more + // content): find the largest piece that *doesn't* consume all the + // target's content, and show it with + // an open bottom border. + piece.dispose(); + piece = getTallestPieceNotCompletelyConsumingTarget(width, height); + if (piece == null) + return null; + } else if (!bottomBorderOpen && iter.hasNext()) { + // Bottom border is closed but the target has more content: fail so + // calling method can try again with + // an open bottom border. + piece.dispose(); + return null; + } else { + this.target = iter; + } + + // Decorate the target print piece with border + piece = new BorderPiece(piece, border, opened, bottomBorderOpen); + + return piece; + } + + private PrintPiece getTallestPieceNotCompletelyConsumingTarget( + final int width, final int height) { + int low = 0; + int high = height - 1; + + PrintIterator bestIterator = null; + PrintPiece bestPiece = null; + while (low + 1 < high) { + int testHeight = (low + high + 1) / 2; + + PrintIterator testIterator = target.copy(); + PrintPiece testPiece = PaperClips.next(testIterator, width, + testHeight); + + if (testPiece == null) { + low = testHeight + 1; + } else if (testIterator.hasNext()) { + low = testHeight; + + if (bestPiece != null) + bestPiece.dispose(); + bestIterator = testIterator; + bestPiece = testPiece; + } else { // !testIterator.hasNext() + high = testPiece.getSize().y - 1; + } + } + + if (bestPiece != null) + this.target = bestIterator; + return bestPiece; + } + + public PrintIterator copy() { + return new BorderIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/internal/BorderPiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/internal/BorderPiece.java index 3e3205db2..a594edefe 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/internal/BorderPiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/border/internal/BorderPiece.java @@ -1,61 +1,61 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ - -package org.eclipse.nebula.paperclips.core.border.internal; - -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.border.BorderPainter; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -public class BorderPiece implements PrintPiece { - private final PrintPiece target; - - private final BorderPainter border; - - private final boolean topOpen; - - private final boolean bottomOpen; - - private final Point size; - - public BorderPiece(PrintPiece target, BorderPainter border, - boolean topOpen, boolean bottomOpen) { - Util.notNull(target, border); - this.target = target; - this.border = border; - - this.topOpen = topOpen; - this.bottomOpen = bottomOpen; - - Point targetSize = target.getSize(); - this.size = new Point(targetSize.x + border.getWidth(), targetSize.y - + border.getHeight(topOpen, bottomOpen)); - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - public void paint(GC gc, int x, int y) { - border.paint(gc, x, y, size.x, size.y, topOpen, bottomOpen); - target.paint(gc, x + border.getLeft(), y + border.getTop(topOpen)); - } - - public void dispose() { - border.dispose(); - target.dispose(); - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ + +package org.eclipse.nebula.paperclips.core.border.internal; + +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.border.BorderPainter; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +public class BorderPiece implements PrintPiece { + private final PrintPiece target; + + private final BorderPainter border; + + private final boolean topOpen; + + private final boolean bottomOpen; + + private final Point size; + + public BorderPiece(PrintPiece target, BorderPainter border, + boolean topOpen, boolean bottomOpen) { + Util.notNull(target, border); + this.target = target; + this.border = border; + + this.topOpen = topOpen; + this.bottomOpen = bottomOpen; + + Point targetSize = target.getSize(); + this.size = new Point(targetSize.x + border.getWidth(), targetSize.y + + border.getHeight(topOpen, bottomOpen)); + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + public void paint(GC gc, int x, int y) { + border.paint(gc, x, y, size.x, size.y, topOpen, bottomOpen); + target.paint(gc, x + border.getLeft(), y + border.getTop(topOpen)); + } + + public void dispose() { + border.dispose(); + target.dispose(); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/BasicGridLookPainter.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/BasicGridLookPainter.java index d5e1e9ba7..fe8f5a4cf 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/BasicGridLookPainter.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/BasicGridLookPainter.java @@ -1,253 +1,253 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Rectangle; - -/** - * A abstract GridLookPainter which simplifies implementation of custom - * GridLooks. - *

- * Subclasses must have the following methods implemented: - *

    - *
  • getMargins() - these margins are referenced by GridPrint for determining - * proper layout of the cells, as well as by the paint() method. - *
  • paintHeaderCell() - will be called by the paint() method for each header - * cell. - *
  • paintBodyCell() - will be called by the paint() method for each body - * cell. - *
  • paintFooterCell() - will be called by the paint() method for each footer - * cell. - *
  • dispose() - must dispose any SWT resources created by the subclass. - *
- * - * @author Matthew Hall - */ -public abstract class BasicGridLookPainter implements GridLookPainter { - /** - * The printer device on which the look is being painted. This is the device - * that was passed as an argument to the constructor. - */ - protected final Device device; - - /** - * Constructs a BasicGridLook painter. - * - * @param device - * the printer device (may not be null). This argument will be - * saved in the protected {@link #device} field. - */ - public BasicGridLookPainter(Device device) { - Util.notNull(device); - this.device = device; - } - - public void paint(GC gc, int x, int y, int[] columns, int[] headerRows, - int[][] headerColSpans, int firstRowIndex, boolean topOpen, - int[] bodyRows, int[][] bodyColSpans, boolean bottomOpen, - int[] footerRows, int[][] footerColSpans) { - GridMargins margins = getMargins(); - - final boolean headerPresent = headerRows.length > 0; - final boolean footerPresent = footerRows.length > 0; - - x += margins.getLeft(); - - if (headerPresent) - y = paintHeader(gc, x, y, columns, headerRows, headerColSpans); - - y += margins.getBodyTop(headerPresent, topOpen); - y = paintBody(gc, x, y, columns, bodyRows, bodyColSpans, firstRowIndex, - topOpen, bottomOpen); - y += margins.getBodyBottom(footerPresent, bottomOpen); - - if (footerPresent) - paintFooter(gc, x, y, columns, footerRows, footerColSpans); - } - - private int paintHeader(GC gc, int x, int y, int[] columns, int[] rows, - int[][] colSpans) { - GridMargins margins = getMargins(); - - y += margins.getHeaderTop(); - - for (int i = 0; i < rows.length; i++) { - int h = rows[i]; - - paintHeaderRow(gc, x, y, columns, h, i, colSpans[i]); - - y += h; - if (i < rows.length - 1) - y += margins.getHeaderVerticalSpacing(); - } - - return y; - } - - private int paintBody(GC gc, int x, int y, int[] columns, int[] rows, - int[][] colSpans, int firstRowIndex, boolean topOpen, - boolean bottomOpen) { - GridMargins margins = getMargins(); - - for (int i = 0; i < rows.length; i++) { - final int h = rows[i]; - - paintBodyRow(gc, x, y, columns, h, colSpans[i], firstRowIndex + i, - i == 0 && topOpen, i == rows.length - 1 && bottomOpen); - - y += h; - if (i < rows.length - 1) - y += margins.getBodyVerticalSpacing(); - } - return y; - } - - private void paintFooter(GC gc, final int x, int y, int[] columns, - int[] rows, int[][] colSpans) { - GridMargins margins = getMargins(); - - for (int i = 0; i < rows.length; i++) { - final int h = rows[i]; - - paintFooterRow(gc, x, y, columns, h, i, colSpans[i]); - - y += h; - y += margins.getFooterVerticalSpacing(); - } - } - - private void paintHeaderRow(GC gc, int x, int y, int[] columns, - final int h, int rowIndex, int[] colSpans) { - GridMargins margins = getMargins(); - - int col = 0; - for (int i = 0; i < colSpans.length; i++) { - final int colSpan = colSpans[i]; - final int w = sum(columns, col, colSpan) + (colSpan - 1) - * margins.getHorizontalSpacing(); - - paintHeaderCell(gc, new Rectangle(x, y, w, h), rowIndex, col, - colSpan); - - col += colSpan; - x += w + margins.getHorizontalSpacing(); - } - } - - private void paintBodyRow(GC gc, int x, int y, int[] columns, final int h, - int[] colSpans, int rowIndex, final boolean topOpen, - final boolean bottomOpen) { - GridMargins margins = getMargins(); - - int col = 0; - for (int i = 0; i < colSpans.length; i++) { - final int colSpan = colSpans[i]; - final int w = sum(columns, col, colSpan) + (colSpan - 1) - * margins.getHorizontalSpacing(); - - paintBodyCell(gc, new Rectangle(x, y, w, h), rowIndex, col, - colSpan, topOpen, bottomOpen); - - col += colSpan; - x += w + margins.getHorizontalSpacing(); - } - } - - private void paintFooterRow(GC gc, int x, int y, int[] columns, - final int h, int rowIndex, int[] colSpans) { - GridMargins margins = getMargins(); - - int col = 0; - for (int i = 0; i < colSpans.length; i++) { - final int colSpan = colSpans[i]; - final int w = sum(columns, col, colSpan) + (colSpan - 1) - * margins.getHorizontalSpacing(); - - paintFooterCell(gc, new Rectangle(x, y, w, h), rowIndex, col, - colSpan); - - col += colSpan; - x += w + margins.getHorizontalSpacing(); - } - } - - private int sum(int[] elements, int start, int length) { - int sum = 0; - for (int j = 0; j < length; j++) - sum += elements[start + j]; - return sum; - } - - /** - * Paint the decorations for the described header cell. - * - * @param gc - * the graphics context to use for painting. - * @param bounds - * the bounds of the cell, excluding margins. - * @param row - * the row offset of the cell within the header. - * @param col - * the column offset of the cell within the header. - * @param colspan - * the number of columns that this cell spans. - */ - protected abstract void paintHeaderCell(GC gc, Rectangle bounds, int row, - int col, int colspan); - - /** - * Paint the decorations for the described body cell. - * - * @param gc - * the graphics context to use for painting. - * @param bounds - * the bounds of the cell, excluding margins. - * @param row - * the row offset of the cell within the header. - * @param col - * the column offset of the cell within the header. - * @param colspan - * the number of columns that this cell spans. - * @param topOpen - * whether the cell should be drawn with the top edge of the cell - * border "open." An open top border is a visual cue that the - * cell is being continued from the previous page. - * @param bottomOpen - * whether the cell should be drawn with the bottom edge of the - * cell border "open." An open bottom border is a visual cue that - * the cell will be continued on the next page. - */ - protected abstract void paintBodyCell(GC gc, Rectangle bounds, int row, - int col, int colspan, boolean topOpen, boolean bottomOpen); - - /** - * Paint the decorations for the described footer cell. - * - * @param gc - * the graphics context to use for painting. - * @param bounds - * the bounds of the cell, excluding margins. - * @param row - * the row offset of the cell within the header. - * @param col - * the column offset of the cell within the header. - * @param colspan - * the number of columns that this cell spans. - */ - protected abstract void paintFooterCell(GC gc, Rectangle bounds, int row, - int col, int colspan); +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Rectangle; + +/** + * A abstract GridLookPainter which simplifies implementation of custom + * GridLooks. + *

+ * Subclasses must have the following methods implemented: + *

    + *
  • getMargins() - these margins are referenced by GridPrint for determining + * proper layout of the cells, as well as by the paint() method. + *
  • paintHeaderCell() - will be called by the paint() method for each header + * cell. + *
  • paintBodyCell() - will be called by the paint() method for each body + * cell. + *
  • paintFooterCell() - will be called by the paint() method for each footer + * cell. + *
  • dispose() - must dispose any SWT resources created by the subclass. + *
+ * + * @author Matthew Hall + */ +public abstract class BasicGridLookPainter implements GridLookPainter { + /** + * The printer device on which the look is being painted. This is the device + * that was passed as an argument to the constructor. + */ + protected final Device device; + + /** + * Constructs a BasicGridLook painter. + * + * @param device + * the printer device (may not be null). This argument will be + * saved in the protected {@link #device} field. + */ + public BasicGridLookPainter(Device device) { + Util.notNull(device); + this.device = device; + } + + public void paint(GC gc, int x, int y, int[] columns, int[] headerRows, + int[][] headerColSpans, int firstRowIndex, boolean topOpen, + int[] bodyRows, int[][] bodyColSpans, boolean bottomOpen, + int[] footerRows, int[][] footerColSpans) { + GridMargins margins = getMargins(); + + final boolean headerPresent = headerRows.length > 0; + final boolean footerPresent = footerRows.length > 0; + + x += margins.getLeft(); + + if (headerPresent) + y = paintHeader(gc, x, y, columns, headerRows, headerColSpans); + + y += margins.getBodyTop(headerPresent, topOpen); + y = paintBody(gc, x, y, columns, bodyRows, bodyColSpans, firstRowIndex, + topOpen, bottomOpen); + y += margins.getBodyBottom(footerPresent, bottomOpen); + + if (footerPresent) + paintFooter(gc, x, y, columns, footerRows, footerColSpans); + } + + private int paintHeader(GC gc, int x, int y, int[] columns, int[] rows, + int[][] colSpans) { + GridMargins margins = getMargins(); + + y += margins.getHeaderTop(); + + for (int i = 0; i < rows.length; i++) { + int h = rows[i]; + + paintHeaderRow(gc, x, y, columns, h, i, colSpans[i]); + + y += h; + if (i < rows.length - 1) + y += margins.getHeaderVerticalSpacing(); + } + + return y; + } + + private int paintBody(GC gc, int x, int y, int[] columns, int[] rows, + int[][] colSpans, int firstRowIndex, boolean topOpen, + boolean bottomOpen) { + GridMargins margins = getMargins(); + + for (int i = 0; i < rows.length; i++) { + final int h = rows[i]; + + paintBodyRow(gc, x, y, columns, h, colSpans[i], firstRowIndex + i, + i == 0 && topOpen, i == rows.length - 1 && bottomOpen); + + y += h; + if (i < rows.length - 1) + y += margins.getBodyVerticalSpacing(); + } + return y; + } + + private void paintFooter(GC gc, final int x, int y, int[] columns, + int[] rows, int[][] colSpans) { + GridMargins margins = getMargins(); + + for (int i = 0; i < rows.length; i++) { + final int h = rows[i]; + + paintFooterRow(gc, x, y, columns, h, i, colSpans[i]); + + y += h; + y += margins.getFooterVerticalSpacing(); + } + } + + private void paintHeaderRow(GC gc, int x, int y, int[] columns, + final int h, int rowIndex, int[] colSpans) { + GridMargins margins = getMargins(); + + int col = 0; + for (int i = 0; i < colSpans.length; i++) { + final int colSpan = colSpans[i]; + final int w = sum(columns, col, colSpan) + (colSpan - 1) + * margins.getHorizontalSpacing(); + + paintHeaderCell(gc, new Rectangle(x, y, w, h), rowIndex, col, + colSpan); + + col += colSpan; + x += w + margins.getHorizontalSpacing(); + } + } + + private void paintBodyRow(GC gc, int x, int y, int[] columns, final int h, + int[] colSpans, int rowIndex, final boolean topOpen, + final boolean bottomOpen) { + GridMargins margins = getMargins(); + + int col = 0; + for (int i = 0; i < colSpans.length; i++) { + final int colSpan = colSpans[i]; + final int w = sum(columns, col, colSpan) + (colSpan - 1) + * margins.getHorizontalSpacing(); + + paintBodyCell(gc, new Rectangle(x, y, w, h), rowIndex, col, + colSpan, topOpen, bottomOpen); + + col += colSpan; + x += w + margins.getHorizontalSpacing(); + } + } + + private void paintFooterRow(GC gc, int x, int y, int[] columns, + final int h, int rowIndex, int[] colSpans) { + GridMargins margins = getMargins(); + + int col = 0; + for (int i = 0; i < colSpans.length; i++) { + final int colSpan = colSpans[i]; + final int w = sum(columns, col, colSpan) + (colSpan - 1) + * margins.getHorizontalSpacing(); + + paintFooterCell(gc, new Rectangle(x, y, w, h), rowIndex, col, + colSpan); + + col += colSpan; + x += w + margins.getHorizontalSpacing(); + } + } + + private int sum(int[] elements, int start, int length) { + int sum = 0; + for (int j = 0; j < length; j++) + sum += elements[start + j]; + return sum; + } + + /** + * Paint the decorations for the described header cell. + * + * @param gc + * the graphics context to use for painting. + * @param bounds + * the bounds of the cell, excluding margins. + * @param row + * the row offset of the cell within the header. + * @param col + * the column offset of the cell within the header. + * @param colspan + * the number of columns that this cell spans. + */ + protected abstract void paintHeaderCell(GC gc, Rectangle bounds, int row, + int col, int colspan); + + /** + * Paint the decorations for the described body cell. + * + * @param gc + * the graphics context to use for painting. + * @param bounds + * the bounds of the cell, excluding margins. + * @param row + * the row offset of the cell within the header. + * @param col + * the column offset of the cell within the header. + * @param colspan + * the number of columns that this cell spans. + * @param topOpen + * whether the cell should be drawn with the top edge of the cell + * border "open." An open top border is a visual cue that the + * cell is being continued from the previous page. + * @param bottomOpen + * whether the cell should be drawn with the bottom edge of the + * cell border "open." An open bottom border is a visual cue that + * the cell will be continued on the next page. + */ + protected abstract void paintBodyCell(GC gc, Rectangle bounds, int row, + int col, int colspan, boolean topOpen, boolean bottomOpen); + + /** + * Paint the decorations for the described footer cell. + * + * @param gc + * the graphics context to use for painting. + * @param bounds + * the bounds of the cell, excluding margins. + * @param row + * the row offset of the cell within the header. + * @param col + * the column offset of the cell within the header. + * @param colspan + * the number of columns that this cell spans. + */ + protected abstract void paintFooterCell(GC gc, Rectangle bounds, int row, + int col, int colspan); } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/CellBackgroundProvider.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/CellBackgroundProvider.java index 92b389e79..b8e82dd41 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/CellBackgroundProvider.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/CellBackgroundProvider.java @@ -1,39 +1,39 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import org.eclipse.swt.graphics.RGB; - -/** - * Instances of this interface provide background colors to be drawn behind - * cells in a grid. This interface is used by DefaultGridLook to provide - * pluggable cell background behavior. - * - * @author Matthew Hall - */ -public interface CellBackgroundProvider { - /** - * Returns the background color to display for the given grid cell. - * - * @param row - * the row index (zero-based) - * @param column - * the column index (zero-based). This is the grid column index, - * not the cell index within the row. - * @param colspan - * the number of grid columns that the cell occupies. - * @return the background color to display for the given header cell. - */ - public RGB getCellBackground(int row, int column, int colspan); -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import org.eclipse.swt.graphics.RGB; + +/** + * Instances of this interface provide background colors to be drawn behind + * cells in a grid. This interface is used by DefaultGridLook to provide + * pluggable cell background behavior. + * + * @author Matthew Hall + */ +public interface CellBackgroundProvider { + /** + * Returns the background color to display for the given grid cell. + * + * @param row + * the row index (zero-based) + * @param column + * the column index (zero-based). This is the grid column index, + * not the cell index within the row. + * @param colspan + * the number of grid columns that the cell occupies. + * @return the background color to display for the given header cell. + */ + public RGB getCellBackground(int row, int column, int colspan); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/DefaultCellBackgroundProvider.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/DefaultCellBackgroundProvider.java index e926ff873..4842803a1 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/DefaultCellBackgroundProvider.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/DefaultCellBackgroundProvider.java @@ -1,112 +1,112 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import org.eclipse.swt.graphics.RGB; - -/** - * Default implementation of the CellBackgroundProvider interface. - * - * @author Matthew Hall - */ -public class DefaultCellBackgroundProvider implements CellBackgroundProvider { - private final CellBackgroundProvider chain; - - private RGB background; - - /** - * Constructs a DefaultGridBackgroundProvider with a null background. - */ - public DefaultCellBackgroundProvider() { - this.chain = null; - - this.background = null; - } - - /** - * Constructs a DefaultGridBackgroundProvider which chains to the argument - * if this instance has a null background color. (DefaultGridLook uses this - * constructor to cause header and footer background colors to default to - * the body background color.) - * - * @param chain - * the provider to chain a getCellBackground(...) call to if this - * instance would return null. Ignored if null. - */ - public DefaultCellBackgroundProvider(CellBackgroundProvider chain) { - this.chain = chain; - this.background = null; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((background == null) ? 0 : background.hashCode()); - result = prime * result + ((chain == null) ? 0 : chain.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DefaultCellBackgroundProvider other = (DefaultCellBackgroundProvider) obj; - if (background == null) { - if (other.background != null) - return false; - } else if (!background.equals(other.background)) - return false; - if (chain == null) { - if (other.chain != null) - return false; - } else if (!chain.equals(other.chain)) - return false; - return true; - } - - /** - * Returns the value in the background property. If the background property - * is null, the chained provider will be consulted to obtain a background - * color. - */ - public RGB getCellBackground(int row, int column, int colspan) { - RGB result = getBackground(); - if (result == null && chain != null) - result = chain.getCellBackground(row, column, colspan); - return result; - } - - /** - * Returns the background color. - * - * @return the background color. - */ - public RGB getBackground() { - return background; - } - - /** - * Sets the background color to the argument. - * - * @param background - * the new background color. - */ - public void setBackground(RGB background) { - this.background = background; - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import org.eclipse.swt.graphics.RGB; + +/** + * Default implementation of the CellBackgroundProvider interface. + * + * @author Matthew Hall + */ +public class DefaultCellBackgroundProvider implements CellBackgroundProvider { + private final CellBackgroundProvider chain; + + private RGB background; + + /** + * Constructs a DefaultGridBackgroundProvider with a null background. + */ + public DefaultCellBackgroundProvider() { + this.chain = null; + + this.background = null; + } + + /** + * Constructs a DefaultGridBackgroundProvider which chains to the argument + * if this instance has a null background color. (DefaultGridLook uses this + * constructor to cause header and footer background colors to default to + * the body background color.) + * + * @param chain + * the provider to chain a getCellBackground(...) call to if this + * instance would return null. Ignored if null. + */ + public DefaultCellBackgroundProvider(CellBackgroundProvider chain) { + this.chain = chain; + this.background = null; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((background == null) ? 0 : background.hashCode()); + result = prime * result + ((chain == null) ? 0 : chain.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DefaultCellBackgroundProvider other = (DefaultCellBackgroundProvider) obj; + if (background == null) { + if (other.background != null) + return false; + } else if (!background.equals(other.background)) + return false; + if (chain == null) { + if (other.chain != null) + return false; + } else if (!chain.equals(other.chain)) + return false; + return true; + } + + /** + * Returns the value in the background property. If the background property + * is null, the chained provider will be consulted to obtain a background + * color. + */ + public RGB getCellBackground(int row, int column, int colspan) { + RGB result = getBackground(); + if (result == null && chain != null) + result = chain.getCellBackground(row, column, colspan); + return result; + } + + /** + * Returns the background color. + * + * @return the background color. + */ + public RGB getBackground() { + return background; + } + + /** + * Sets the background color to the argument. + * + * @param background + * the new background color. + */ + public void setBackground(RGB background) { + this.background = background; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/DefaultGridLook.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/DefaultGridLook.java index 7fe168c94..8f57c9b60 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/DefaultGridLook.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/DefaultGridLook.java @@ -1,457 +1,457 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import org.eclipse.nebula.paperclips.core.border.Border; -import org.eclipse.nebula.paperclips.core.border.GapBorder; -import org.eclipse.nebula.paperclips.core.grid.internal.DefaultGridLookPainter; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; - -/** - * A GridLook which draws a border around grid cells, with configurable - * background colors for body, header, and footer cells. - * - * @author Matthew Hall - */ -public class DefaultGridLook implements GridLook { - /** - * Constant cell spacing value indicating that the borders of adjacent cells - * should overlap so the appear continuous. - */ - public static final int BORDER_OVERLAP = -1; - - Point cellSpacing = new Point(BORDER_OVERLAP, BORDER_OVERLAP); - Rectangle cellPadding = new Rectangle(0, 0, 0, 0); - int headerGap = BORDER_OVERLAP; - int footerGap = BORDER_OVERLAP; - - Border cellBorder = new GapBorder(); - - DefaultCellBackgroundProvider defaultBodyBackgroundProvider; - DefaultCellBackgroundProvider defaultHeaderBackgroundProvider; - DefaultCellBackgroundProvider defaultFooterBackgroundProvider; - - CellBackgroundProvider bodyBackgroundProvider; - CellBackgroundProvider headerBackgroundProvider; - CellBackgroundProvider footerBackgroundProvider; - - /** - * Constructs a DefaultGridLook with no border, no cell spacing, and no - * background colors. - */ - public DefaultGridLook() { - this.bodyBackgroundProvider = defaultBodyBackgroundProvider = new DefaultCellBackgroundProvider(); - this.headerBackgroundProvider = defaultHeaderBackgroundProvider = new DefaultCellBackgroundProvider( - bodyBackgroundProvider); - this.footerBackgroundProvider = defaultFooterBackgroundProvider = new DefaultCellBackgroundProvider( - bodyBackgroundProvider); - } - - /** - * Constructs a DefaultGridLook with the given cell spacing, and no border - * or background colors. - * - * @param horizontalSpacing - * the horizontal cell spacing. - * @param verticalSpacing - * the vertical cell spacing. - */ - public DefaultGridLook(int horizontalSpacing, int verticalSpacing) { - this(); - setCellSpacing(horizontalSpacing, verticalSpacing); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime - * result - + ((bodyBackgroundProvider == null) ? 0 - : bodyBackgroundProvider.hashCode()); - result = prime * result - + ((cellBorder == null) ? 0 : cellBorder.hashCode()); - result = prime * result - + ((cellPadding == null) ? 0 : cellPadding.hashCode()); - result = prime * result - + ((cellSpacing == null) ? 0 : cellSpacing.hashCode()); - result = prime - * result - + ((footerBackgroundProvider == null) ? 0 - : footerBackgroundProvider.hashCode()); - result = prime * result + footerGap; - result = prime - * result - + ((headerBackgroundProvider == null) ? 0 - : headerBackgroundProvider.hashCode()); - result = prime * result + headerGap; - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DefaultGridLook other = (DefaultGridLook) obj; - if (bodyBackgroundProvider == null) { - if (other.bodyBackgroundProvider != null) - return false; - } else if (!bodyBackgroundProvider.equals(other.bodyBackgroundProvider)) - return false; - if (cellBorder == null) { - if (other.cellBorder != null) - return false; - } else if (!cellBorder.equals(other.cellBorder)) - return false; - if (cellPadding == null) { - if (other.cellPadding != null) - return false; - } else if (!cellPadding.equals(other.cellPadding)) - return false; - if (cellSpacing == null) { - if (other.cellSpacing != null) - return false; - } else if (!cellSpacing.equals(other.cellSpacing)) - return false; - if (footerBackgroundProvider == null) { - if (other.footerBackgroundProvider != null) - return false; - } else if (!footerBackgroundProvider - .equals(other.footerBackgroundProvider)) - return false; - if (footerGap != other.footerGap) - return false; - if (headerBackgroundProvider == null) { - if (other.headerBackgroundProvider != null) - return false; - } else if (!headerBackgroundProvider - .equals(other.headerBackgroundProvider)) - return false; - if (headerGap != other.headerGap) - return false; - return true; - } - - /** - * Returns the cell border. Default is an empty border with no margins. - * - * @return the cell border. - */ - public Border getCellBorder() { - return cellBorder; - } - - /** - * Sets the cell border. - * - * @param border - * the cell border. - */ - public void setCellBorder(Border border) { - this.cellBorder = border; - } - - /** - * Returns the border spacing, in points, between adjacent grid cells. - * Default is (x=BORDER_OVERLAP, y=BORDER_OVERLAP). - * - * @return the border spacing, in points, between adjacent grid cells. - */ - public Point getCellSpacing() { - return new Point(cellSpacing.x, cellSpacing.y); - } - - /** - * Sets the border spacing, in points, between adjacent grid cells. A value - * of {@link #BORDER_OVERLAP} causes the borders to overlap, making the - * border appear continuous throughout the grid. A value of 0 or more causes - * the cell borders to be spaced that many points apart. 72 points = 1". - * - * @param cellSpacing - * a point whose x and y elements indicate the horizontal and - * vertical spacing between grid cells. - */ - public void setCellSpacing(Point cellSpacing) { - setCellSpacing(cellSpacing.x, cellSpacing.y); - } - - /** - * Sets the border spacing, in points, between adjacent grid cells. A value - * of {@link #BORDER_OVERLAP} causes the borders to overlap, making the - * border appear continuous throughout the grid. A value of 0 or more causes - * the cell borders to be spaced that many points apart. 72 points = 1". - * - * @param horizontal - * the horizontal cell spacing. - * @param vertical - * the vertical cell spacing. - */ - public void setCellSpacing(int horizontal, int vertical) { - if (horizontal == BORDER_OVERLAP || horizontal >= 0) - this.cellSpacing.x = horizontal; - if (vertical == BORDER_OVERLAP || vertical >= 0) - this.cellSpacing.y = vertical; - } - - /** - * Returns a rectangle whose public fields denote the left (x), top (y), - * right (width) and bottom (height) cell padding, expressed in points. 72 - * points = 1" = 2.54cm. - * - * @return a rectangle whose public fields denote the cell padding at each - * edge. - */ - public Rectangle getCellPadding() { - return new Rectangle(cellPadding.x, cellPadding.y, cellPadding.width, - cellPadding.height); - } - - /** - * Sets the cell padding to the values in the public fields of the argument. - * - * @param cellPadding - * the new cell padding. - */ - public void setCellPadding(Rectangle cellPadding) { - setCellPadding(cellPadding.x, cellPadding.y, cellPadding.width, - cellPadding.height); - } - - /** - * Sets the cell padding to the given horizontal and vertical values. This - * is equivalent to calling setCellPadding(horizontalPadding, - * verticalPadding, horizontalPadding, verticalPadding). - * - * @param horizontalPadding - * the amount of padding to add to the left and right of each - * cell, in points. - * @param verticalPadding - * the amount padding to add to the top and bottom each cell, in - * points. - */ - public void setCellPadding(int horizontalPadding, int verticalPadding) { - setCellPadding(horizontalPadding, verticalPadding, horizontalPadding, - verticalPadding); - } - - /** - * Sets the cell padding to the specified values. - * - * @param left - * the left cell padding, in points. - * @param top - * the top cell padding, in points. - * @param right - * the right cell padding, in points. - * @param bottom - * the bottom cell padding, in points. - */ - public void setCellPadding(int left, int top, int right, int bottom) { - cellPadding.x = left; - cellPadding.y = top; - cellPadding.width = right; - cellPadding.height = bottom; - } - - /** - * Returns the header background color. If null, the body background color - * is used. Default is null. - * - * @return the header background color. - */ - public RGB getHeaderBackground() { - return defaultHeaderBackgroundProvider.getBackground(); - } - - /** - * Sets the header background color. Calls to this method override any - * previous calls to setHeaderBackgroundProvider(...). - * - * @param headerBackground - * the new background color. If null, the body background color - * will be used. - */ - public void setHeaderBackground(RGB headerBackground) { - defaultHeaderBackgroundProvider.setBackground(headerBackground); - this.headerBackgroundProvider = defaultHeaderBackgroundProvider; - } - - /** - * Returns the header background color provider. - * - * @return the header background color provider. - */ - public CellBackgroundProvider getHeaderBackgroundProvider() { - return headerBackgroundProvider; - } - - /** - * Sets the header background color provider. Calls to this method override - * any previous calls to setHeaderBackground(RGB). Setting this property to - * null restores the default background provider. - * - * @param headerBackgroundProvider - * the new background color provider. - */ - public void setHeaderBackgroundProvider( - CellBackgroundProvider headerBackgroundProvider) { - this.headerBackgroundProvider = headerBackgroundProvider == null ? defaultHeaderBackgroundProvider - : headerBackgroundProvider; - } - - /** - * Returns the vertical gap between the header and body cells. Default is - * BORDER_OVERLAP. - * - * @return the vertical gap between the header and body cells. - */ - public int getHeaderGap() { - return headerGap; - } - - /** - * Sets the vertical gap between the header and body cells. A value of - * {@link #BORDER_OVERLAP} causes the borders to overlap, making the border - * appear continuous in the transition from the header cells to the body - * cells. - * - * @param headerGap - * the new header gap. - */ - public void setHeaderGap(int headerGap) { - this.headerGap = headerGap; - } - - /** - * Returns the body background color. Default is null (no background color). - * - * @return the body background color. - */ - public RGB getBodyBackground() { - return defaultBodyBackgroundProvider.getBackground(); - } - - /** - * Sets the body background color. Calls to this method override any - * previous calls to setBodyBackgroundProvider(...). - * - * @param bodyBackground - * the new background color. - */ - public void setBodyBackground(RGB bodyBackground) { - defaultBodyBackgroundProvider.setBackground(bodyBackground); - this.bodyBackgroundProvider = defaultBodyBackgroundProvider; - } - - /** - * Returns the body background color provider. - * - * @return the body background color provider. - */ - public CellBackgroundProvider getBodyBackgroundProvider() { - return bodyBackgroundProvider; - } - - /** - * Sets the body background color provider. Calls to this method override - * any previous calls to setBodyBackground(RGB). Setting this property to - * null restores the default background provider. - * - * @param bodyBackgroundProvider - * the new background color provider. - */ - public void setBodyBackgroundProvider( - CellBackgroundProvider bodyBackgroundProvider) { - this.bodyBackgroundProvider = bodyBackgroundProvider == null ? defaultBodyBackgroundProvider - : bodyBackgroundProvider; - } - - /** - * Returns the vertical gap between the body and footer cells. Default is - * BORDER_OVERLAP. - * - * @return the vertical gap between the header and body cells. - */ - public int getFooterGap() { - return footerGap; - } - - /** - * Sets the vertical gap between the header and body cells. A value of - * {@link #BORDER_OVERLAP} causes the borders to overlap, making the border - * appear continuous in the transition from the body cells to the footer - * cells. - * - * @param footerGap - */ - public void setFooterGap(int footerGap) { - this.footerGap = footerGap; - } - - /** - * Returns the footer background color. If null, the body background color - * is used. Default is null. - * - * @return the footer background color. - */ - public RGB getFooterBackground() { - return defaultFooterBackgroundProvider.getBackground(); - } - - /** - * Sets the footer background color. Calls to this method override any - * previous calls to setFooterBackgroundProvider(...). - * - * @param footerBackground - * the new background color. If null, the body background color - * will be used. - */ - public void setFooterBackground(RGB footerBackground) { - defaultFooterBackgroundProvider.setBackground(footerBackground); - this.footerBackgroundProvider = defaultFooterBackgroundProvider; - } - - /** - * Returns the footer background color provider. - * - * @return the footer background color provider. - */ - public CellBackgroundProvider getFooterBackgroundProvider() { - return footerBackgroundProvider; - } - - /** - * Sets the footer background color provider. Calls to this method override - * any previous calls to setFooterBackground(RGB). Setting this property to - * null restores the default background provider. - * - * @param footerBackgroundProvider - * the new background color provider. - */ - public void setFooterBackgroundProvider( - CellBackgroundProvider footerBackgroundProvider) { - this.footerBackgroundProvider = footerBackgroundProvider == null ? defaultFooterBackgroundProvider - : footerBackgroundProvider; - } - - public GridLookPainter getPainter(Device device, GC gc) { - return new DefaultGridLookPainter(this, device, gc); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import org.eclipse.nebula.paperclips.core.border.Border; +import org.eclipse.nebula.paperclips.core.border.GapBorder; +import org.eclipse.nebula.paperclips.core.grid.internal.DefaultGridLookPainter; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; + +/** + * A GridLook which draws a border around grid cells, with configurable + * background colors for body, header, and footer cells. + * + * @author Matthew Hall + */ +public class DefaultGridLook implements GridLook { + /** + * Constant cell spacing value indicating that the borders of adjacent cells + * should overlap so the appear continuous. + */ + public static final int BORDER_OVERLAP = -1; + + Point cellSpacing = new Point(BORDER_OVERLAP, BORDER_OVERLAP); + Rectangle cellPadding = new Rectangle(0, 0, 0, 0); + int headerGap = BORDER_OVERLAP; + int footerGap = BORDER_OVERLAP; + + Border cellBorder = new GapBorder(); + + DefaultCellBackgroundProvider defaultBodyBackgroundProvider; + DefaultCellBackgroundProvider defaultHeaderBackgroundProvider; + DefaultCellBackgroundProvider defaultFooterBackgroundProvider; + + CellBackgroundProvider bodyBackgroundProvider; + CellBackgroundProvider headerBackgroundProvider; + CellBackgroundProvider footerBackgroundProvider; + + /** + * Constructs a DefaultGridLook with no border, no cell spacing, and no + * background colors. + */ + public DefaultGridLook() { + this.bodyBackgroundProvider = defaultBodyBackgroundProvider = new DefaultCellBackgroundProvider(); + this.headerBackgroundProvider = defaultHeaderBackgroundProvider = new DefaultCellBackgroundProvider( + bodyBackgroundProvider); + this.footerBackgroundProvider = defaultFooterBackgroundProvider = new DefaultCellBackgroundProvider( + bodyBackgroundProvider); + } + + /** + * Constructs a DefaultGridLook with the given cell spacing, and no border + * or background colors. + * + * @param horizontalSpacing + * the horizontal cell spacing. + * @param verticalSpacing + * the vertical cell spacing. + */ + public DefaultGridLook(int horizontalSpacing, int verticalSpacing) { + this(); + setCellSpacing(horizontalSpacing, verticalSpacing); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime + * result + + ((bodyBackgroundProvider == null) ? 0 + : bodyBackgroundProvider.hashCode()); + result = prime * result + + ((cellBorder == null) ? 0 : cellBorder.hashCode()); + result = prime * result + + ((cellPadding == null) ? 0 : cellPadding.hashCode()); + result = prime * result + + ((cellSpacing == null) ? 0 : cellSpacing.hashCode()); + result = prime + * result + + ((footerBackgroundProvider == null) ? 0 + : footerBackgroundProvider.hashCode()); + result = prime * result + footerGap; + result = prime + * result + + ((headerBackgroundProvider == null) ? 0 + : headerBackgroundProvider.hashCode()); + result = prime * result + headerGap; + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DefaultGridLook other = (DefaultGridLook) obj; + if (bodyBackgroundProvider == null) { + if (other.bodyBackgroundProvider != null) + return false; + } else if (!bodyBackgroundProvider.equals(other.bodyBackgroundProvider)) + return false; + if (cellBorder == null) { + if (other.cellBorder != null) + return false; + } else if (!cellBorder.equals(other.cellBorder)) + return false; + if (cellPadding == null) { + if (other.cellPadding != null) + return false; + } else if (!cellPadding.equals(other.cellPadding)) + return false; + if (cellSpacing == null) { + if (other.cellSpacing != null) + return false; + } else if (!cellSpacing.equals(other.cellSpacing)) + return false; + if (footerBackgroundProvider == null) { + if (other.footerBackgroundProvider != null) + return false; + } else if (!footerBackgroundProvider + .equals(other.footerBackgroundProvider)) + return false; + if (footerGap != other.footerGap) + return false; + if (headerBackgroundProvider == null) { + if (other.headerBackgroundProvider != null) + return false; + } else if (!headerBackgroundProvider + .equals(other.headerBackgroundProvider)) + return false; + if (headerGap != other.headerGap) + return false; + return true; + } + + /** + * Returns the cell border. Default is an empty border with no margins. + * + * @return the cell border. + */ + public Border getCellBorder() { + return cellBorder; + } + + /** + * Sets the cell border. + * + * @param border + * the cell border. + */ + public void setCellBorder(Border border) { + this.cellBorder = border; + } + + /** + * Returns the border spacing, in points, between adjacent grid cells. + * Default is (x=BORDER_OVERLAP, y=BORDER_OVERLAP). + * + * @return the border spacing, in points, between adjacent grid cells. + */ + public Point getCellSpacing() { + return new Point(cellSpacing.x, cellSpacing.y); + } + + /** + * Sets the border spacing, in points, between adjacent grid cells. A value + * of {@link #BORDER_OVERLAP} causes the borders to overlap, making the + * border appear continuous throughout the grid. A value of 0 or more causes + * the cell borders to be spaced that many points apart. 72 points = 1". + * + * @param cellSpacing + * a point whose x and y elements indicate the horizontal and + * vertical spacing between grid cells. + */ + public void setCellSpacing(Point cellSpacing) { + setCellSpacing(cellSpacing.x, cellSpacing.y); + } + + /** + * Sets the border spacing, in points, between adjacent grid cells. A value + * of {@link #BORDER_OVERLAP} causes the borders to overlap, making the + * border appear continuous throughout the grid. A value of 0 or more causes + * the cell borders to be spaced that many points apart. 72 points = 1". + * + * @param horizontal + * the horizontal cell spacing. + * @param vertical + * the vertical cell spacing. + */ + public void setCellSpacing(int horizontal, int vertical) { + if (horizontal == BORDER_OVERLAP || horizontal >= 0) + this.cellSpacing.x = horizontal; + if (vertical == BORDER_OVERLAP || vertical >= 0) + this.cellSpacing.y = vertical; + } + + /** + * Returns a rectangle whose public fields denote the left (x), top (y), + * right (width) and bottom (height) cell padding, expressed in points. 72 + * points = 1" = 2.54cm. + * + * @return a rectangle whose public fields denote the cell padding at each + * edge. + */ + public Rectangle getCellPadding() { + return new Rectangle(cellPadding.x, cellPadding.y, cellPadding.width, + cellPadding.height); + } + + /** + * Sets the cell padding to the values in the public fields of the argument. + * + * @param cellPadding + * the new cell padding. + */ + public void setCellPadding(Rectangle cellPadding) { + setCellPadding(cellPadding.x, cellPadding.y, cellPadding.width, + cellPadding.height); + } + + /** + * Sets the cell padding to the given horizontal and vertical values. This + * is equivalent to calling setCellPadding(horizontalPadding, + * verticalPadding, horizontalPadding, verticalPadding). + * + * @param horizontalPadding + * the amount of padding to add to the left and right of each + * cell, in points. + * @param verticalPadding + * the amount padding to add to the top and bottom each cell, in + * points. + */ + public void setCellPadding(int horizontalPadding, int verticalPadding) { + setCellPadding(horizontalPadding, verticalPadding, horizontalPadding, + verticalPadding); + } + + /** + * Sets the cell padding to the specified values. + * + * @param left + * the left cell padding, in points. + * @param top + * the top cell padding, in points. + * @param right + * the right cell padding, in points. + * @param bottom + * the bottom cell padding, in points. + */ + public void setCellPadding(int left, int top, int right, int bottom) { + cellPadding.x = left; + cellPadding.y = top; + cellPadding.width = right; + cellPadding.height = bottom; + } + + /** + * Returns the header background color. If null, the body background color + * is used. Default is null. + * + * @return the header background color. + */ + public RGB getHeaderBackground() { + return defaultHeaderBackgroundProvider.getBackground(); + } + + /** + * Sets the header background color. Calls to this method override any + * previous calls to setHeaderBackgroundProvider(...). + * + * @param headerBackground + * the new background color. If null, the body background color + * will be used. + */ + public void setHeaderBackground(RGB headerBackground) { + defaultHeaderBackgroundProvider.setBackground(headerBackground); + this.headerBackgroundProvider = defaultHeaderBackgroundProvider; + } + + /** + * Returns the header background color provider. + * + * @return the header background color provider. + */ + public CellBackgroundProvider getHeaderBackgroundProvider() { + return headerBackgroundProvider; + } + + /** + * Sets the header background color provider. Calls to this method override + * any previous calls to setHeaderBackground(RGB). Setting this property to + * null restores the default background provider. + * + * @param headerBackgroundProvider + * the new background color provider. + */ + public void setHeaderBackgroundProvider( + CellBackgroundProvider headerBackgroundProvider) { + this.headerBackgroundProvider = headerBackgroundProvider == null ? defaultHeaderBackgroundProvider + : headerBackgroundProvider; + } + + /** + * Returns the vertical gap between the header and body cells. Default is + * BORDER_OVERLAP. + * + * @return the vertical gap between the header and body cells. + */ + public int getHeaderGap() { + return headerGap; + } + + /** + * Sets the vertical gap between the header and body cells. A value of + * {@link #BORDER_OVERLAP} causes the borders to overlap, making the border + * appear continuous in the transition from the header cells to the body + * cells. + * + * @param headerGap + * the new header gap. + */ + public void setHeaderGap(int headerGap) { + this.headerGap = headerGap; + } + + /** + * Returns the body background color. Default is null (no background color). + * + * @return the body background color. + */ + public RGB getBodyBackground() { + return defaultBodyBackgroundProvider.getBackground(); + } + + /** + * Sets the body background color. Calls to this method override any + * previous calls to setBodyBackgroundProvider(...). + * + * @param bodyBackground + * the new background color. + */ + public void setBodyBackground(RGB bodyBackground) { + defaultBodyBackgroundProvider.setBackground(bodyBackground); + this.bodyBackgroundProvider = defaultBodyBackgroundProvider; + } + + /** + * Returns the body background color provider. + * + * @return the body background color provider. + */ + public CellBackgroundProvider getBodyBackgroundProvider() { + return bodyBackgroundProvider; + } + + /** + * Sets the body background color provider. Calls to this method override + * any previous calls to setBodyBackground(RGB). Setting this property to + * null restores the default background provider. + * + * @param bodyBackgroundProvider + * the new background color provider. + */ + public void setBodyBackgroundProvider( + CellBackgroundProvider bodyBackgroundProvider) { + this.bodyBackgroundProvider = bodyBackgroundProvider == null ? defaultBodyBackgroundProvider + : bodyBackgroundProvider; + } + + /** + * Returns the vertical gap between the body and footer cells. Default is + * BORDER_OVERLAP. + * + * @return the vertical gap between the header and body cells. + */ + public int getFooterGap() { + return footerGap; + } + + /** + * Sets the vertical gap between the header and body cells. A value of + * {@link #BORDER_OVERLAP} causes the borders to overlap, making the border + * appear continuous in the transition from the body cells to the footer + * cells. + * + * @param footerGap + */ + public void setFooterGap(int footerGap) { + this.footerGap = footerGap; + } + + /** + * Returns the footer background color. If null, the body background color + * is used. Default is null. + * + * @return the footer background color. + */ + public RGB getFooterBackground() { + return defaultFooterBackgroundProvider.getBackground(); + } + + /** + * Sets the footer background color. Calls to this method override any + * previous calls to setFooterBackgroundProvider(...). + * + * @param footerBackground + * the new background color. If null, the body background color + * will be used. + */ + public void setFooterBackground(RGB footerBackground) { + defaultFooterBackgroundProvider.setBackground(footerBackground); + this.footerBackgroundProvider = defaultFooterBackgroundProvider; + } + + /** + * Returns the footer background color provider. + * + * @return the footer background color provider. + */ + public CellBackgroundProvider getFooterBackgroundProvider() { + return footerBackgroundProvider; + } + + /** + * Sets the footer background color provider. Calls to this method override + * any previous calls to setFooterBackground(RGB). Setting this property to + * null restores the default background provider. + * + * @param footerBackgroundProvider + * the new background color provider. + */ + public void setFooterBackgroundProvider( + CellBackgroundProvider footerBackgroundProvider) { + this.footerBackgroundProvider = footerBackgroundProvider == null ? defaultFooterBackgroundProvider + : footerBackgroundProvider; + } + + public GridLookPainter getPainter(Device device, GC gc) { + return new DefaultGridLookPainter(this, device, gc); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridColumn.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridColumn.java index 7ff273451..153d2fd2f 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridColumn.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridColumn.java @@ -1,334 +1,334 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; - -/** - * Describes the properties of a column in a GridPrint. - * - * @author Matthew Hall - */ -public class GridColumn { - /** - * The default alignment used when alignment is not specified. Value is - * SWT.LEFT. - */ - public static final int DEFAULT_ALIGN = SWT.LEFT; - - /** - * The default size used when size is not specified. Value is SWT.DEFAULT. - */ - public static final int DEFAULT_SIZE = SWT.DEFAULT; - - /** - * The default weight used when weight is not specified. Value is 0. - */ - public static final int DEFAULT_WEIGHT = 0; - - /** - * The size property for this GridColumn. Possible values: - *
    - *
  • GridPrint.PREFERRED - indicates that the column should be as wide as - * the preferred width of its widest element. - *
  • SWT.DEFAULT - Similar to GridPrint.PREFERRED, except that the column - * may shrink down to its minimum width if space is scarce. - *
  • A value > 0 indicates that the column should be size - * points wide (72pts = 1"). - *
- */ - public final int size; - - /** - * The default alignment for Prints in this column. Possible values are - * SWT.LEFT, SWT.CENTER, SWT.RIGHT, or SWT.DEFAULT. Note that alignment - * affects the placement of PrintPieces within the grid's cell--the - * alignment elements of the PrintPiece themselves are not affected. Thus, - * in order to achieve the desired effect, a Print having an alignment - * property should be set to the same alignment as the grid cell it is added - * to. For example, a TextPrint in a right-aligned grid cell should be set - * to right alignment as well. - *

- * Cells that span multiple columns use the alignment of the left-most cell - * in the cell span. - */ - public final int align; - - /** - * The weight of this column. If the available print space is wider than the - * grid's preferred width, this field determines how much of that extra - * space should be given to this column. A larger weight causes the column - * to receive more of the extra width. A value of 0 indicates that the - * column should not be given any excess width. - */ - public final int weight; - - /** - * Constructs a GridColumn. - * - * @param align - * The default alignment for Prints in this column. - * @param size - * The size this column should be given. - * @param weight - * The weight this column should be given. - */ - public GridColumn(int align, int size, int weight) { - this.align = checkAlign(align); - this.size = checkSize(size); - this.weight = checkWeight(weight); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + align; - result = prime * result + size; - result = prime * result + weight; - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - GridColumn other = (GridColumn) obj; - if (align != other.align) - return false; - if (size != other.size) - return false; - if (weight != other.weight) - return false; - return true; - } - - private static int checkAlign(int align) { - align = PaperClipsUtil.firstMatch(align, new int[] { SWT.LEFT, - SWT.CENTER, SWT.RIGHT, SWT.DEFAULT }, 0); - if (align == 0) - PaperClips - .error( - SWT.ERROR_INVALID_ARGUMENT, - "Alignment argument must be one of SWT.LEFT, SWT.CENTER, SWT.RIGHT, or SWT.DEFAULT"); //$NON-NLS-1$ - if (align == SWT.DEFAULT) - return DEFAULT_ALIGN; - return align; - } - - private static int checkSize(int size) { - if (size != SWT.DEFAULT && size != GridPrint.PREFERRED && size <= 0) - PaperClips - .error(SWT.ERROR_INVALID_ARGUMENT, - "Size argument must be SWT.DEFAULT, GridPrint.PREFERRED, or > 0"); //$NON-NLS-1$ - return size; - } - - private static int checkWeight(int grow) { - if (grow < 0) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Weight argument must be >= 0"); //$NON-NLS-1$ - return grow; - } - - /** - * Parses the given column spec and returns a GridColumn matching that spec. - *

- * Format: - * - *

-	 *  [align:]size[:grow]
-	 *  
-	 *  align  = L | LEFT |
-	 *           C | CENTER |
-	 *           R | RIGHT
-	 *  size   = P | PREF | PREFERRED |
-	 *           D | DEF | DEFAULT |
-	 *           (Positive number)[PT|IN|INCH|CM|MM]
-	 *  weight = N | NONE |
-	 *           G | GROW | G(#) | GROW(#)
-	 * 
- * - * The default alignment is LEFT. The - * - * weight argument expresses the weight property: NONE - * indicates a weight of 0; GROW indicates a weight of 1; and GROW(3) - * indicates a weight of 3. The default weight (if weight is - * omitted) is 0. - *

- * Examples: - * - *

-	 * LEFT:DEFAULT:GROW // left-aligned, default size, weight=1
-	 *  R:72PT:N          // light-aligned, 72 points (1") wide, weight=0
-	 *  right:72          // identical to previous line
-	 *  c:pref:none       // center-aligned, preferred size, weight=0
-	 *  p                 // left-aligned (default), preferred size, weight=0
-	 *  r:2inch           // right-aligned, 2 inches (50.8mm)
-	 *  r:50.8mm          // right-aligned, 50.8 mm (2")
-	 * 
- * - * @param spec - * the column spec that will be parsed. - * @return a GridColumn matching the column spec. - * @see #align - * @see #size - * @see #weight - */ - public static GridColumn parse(String spec) { - Util.notNull(spec); - - String[] matches = spec.split("\\s*:\\s*"); //$NON-NLS-1$ - if (matches.length == 0) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Missing column spec"); //$NON-NLS-1$ - - int align = DEFAULT_ALIGN; - int size = DEFAULT_SIZE; - int grow = DEFAULT_WEIGHT; - - if (matches.length == 1) { - // One option: must be size - size = parseSize(matches[0]); - } else if (matches.length == 2) { - // Two possible scenarios: - // 1. align:size - // 2. size:weight - if (isAlign(matches[0])) { - align = parseAlign(matches[0]); - size = parseSize(matches[1]); - } else { - size = parseSize(matches[0]); - grow = parseWeight(matches[1]); - } - } else if (matches.length == 3) { - align = parseAlign(matches[0]); - size = parseSize(matches[1]); - grow = parseWeight(matches[2]); - } - - return new GridColumn(align, size, grow); - } - - // Alignment patterns - private static final Pattern LEFT_ALIGN_PATTERN = Pattern.compile( - "^l(eft)?$", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private static final Pattern CENTER_ALIGN_PATTERN = Pattern.compile( - "^c(enter)?$", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private static final Pattern RIGHT_ALIGN_PATTERN = Pattern.compile( - "^r(ight)?$", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private static final Pattern ANY_ALIGN_PATTERN = Pattern.compile( - "^l(eft)?|c(enter)?|r(ight)?$", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private static boolean isAlign(String alignmentString) { - return ANY_ALIGN_PATTERN.matcher(alignmentString).matches(); - } - - private static int parseAlign(String alignmentString) { - if (LEFT_ALIGN_PATTERN.matcher(alignmentString).matches()) - return SWT.LEFT; - else if (CENTER_ALIGN_PATTERN.matcher(alignmentString).matches()) - return SWT.CENTER; - else if (RIGHT_ALIGN_PATTERN.matcher(alignmentString).matches()) - return SWT.RIGHT; - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Unknown alignment \"" + alignmentString + "\""); //$NON-NLS-1$//$NON-NLS-2$ - return 0; // unreachable - } - - // Size patterns. - private static final Pattern DEFAULT_SIZE_PATTERN = Pattern.compile( - "^d(ef(ault)?)?$", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private static final Pattern PREFERRED_SIZE_PATTERN = Pattern.compile( - "^p(ref(erred)?)?", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private static final Pattern EXPLICIT_SIZE_PATTERN = Pattern.compile( - "^(\\d+(\\.\\d+)?)\\s*(pt|in(ch)?|mm|cm)?$", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private static int parseSize(String sizeString) { - Matcher matcher; - if (DEFAULT_SIZE_PATTERN.matcher(sizeString).matches()) - return SWT.DEFAULT; - else if (PREFERRED_SIZE_PATTERN.matcher(sizeString).matches()) - return GridPrint.PREFERRED; - else if ((matcher = EXPLICIT_SIZE_PATTERN.matcher(sizeString)) - .matches()) { - return (int) Math.ceil(convertToPoints(Double.parseDouble(matcher - .group(1)), matcher.group(3))); - } else { - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Unknown size pattern: \"" + sizeString + "\""); //$NON-NLS-1$ //$NON-NLS-2$ - return 0; // unreachable - } - } - - private static double convertToPoints(double value, String unit) { - if (unit == null || unit.length() == 0 || unit.equalsIgnoreCase("pt")) //$NON-NLS-1$ - return value; - else if (unit.equalsIgnoreCase("in") || unit.equalsIgnoreCase("inch")) //$NON-NLS-1$ //$NON-NLS-2$ - return 72 * value; - else if (unit.equalsIgnoreCase("cm")) //$NON-NLS-1$ - return 72 * value / 2.54; - else if (unit.equalsIgnoreCase("mm")) //$NON-NLS-1$ - return 72 * value / 25.4; - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Unknown unit \"" + unit + "\"."); //$NON-NLS-1$ //$NON-NLS-2$ - return 0; - } - - private static final Pattern WEIGHTLESS_PATTERN = Pattern.compile( - "n(one)?", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private static final Pattern WEIGHTED_PATTERN = Pattern.compile( - "(g(row)?)(\\((\\d+)\\))?", // yikes //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private static int parseWeight(String weightString) { - Matcher matcher; - if (WEIGHTLESS_PATTERN.matcher(weightString).matches()) - return 0; - else if ((matcher = WEIGHTED_PATTERN.matcher(weightString)).matches()) { - String weight = matcher.group(4); - return (weight == null) ? 1 : Integer.parseInt(weight); - } else { - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Illegal grow pattern: \"" + weightString //$NON-NLS-1$ - + "\""); //$NON-NLS-1$ - return 0; // unreachable - } - } - - GridColumn copy() { - return new GridColumn(align, size, weight); - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; + +/** + * Describes the properties of a column in a GridPrint. + * + * @author Matthew Hall + */ +public class GridColumn { + /** + * The default alignment used when alignment is not specified. Value is + * SWT.LEFT. + */ + public static final int DEFAULT_ALIGN = SWT.LEFT; + + /** + * The default size used when size is not specified. Value is SWT.DEFAULT. + */ + public static final int DEFAULT_SIZE = SWT.DEFAULT; + + /** + * The default weight used when weight is not specified. Value is 0. + */ + public static final int DEFAULT_WEIGHT = 0; + + /** + * The size property for this GridColumn. Possible values: + *
    + *
  • GridPrint.PREFERRED - indicates that the column should be as wide as + * the preferred width of its widest element. + *
  • SWT.DEFAULT - Similar to GridPrint.PREFERRED, except that the column + * may shrink down to its minimum width if space is scarce. + *
  • A value > 0 indicates that the column should be size + * points wide (72pts = 1"). + *
+ */ + public final int size; + + /** + * The default alignment for Prints in this column. Possible values are + * SWT.LEFT, SWT.CENTER, SWT.RIGHT, or SWT.DEFAULT. Note that alignment + * affects the placement of PrintPieces within the grid's cell--the + * alignment elements of the PrintPiece themselves are not affected. Thus, + * in order to achieve the desired effect, a Print having an alignment + * property should be set to the same alignment as the grid cell it is added + * to. For example, a TextPrint in a right-aligned grid cell should be set + * to right alignment as well. + *

+ * Cells that span multiple columns use the alignment of the left-most cell + * in the cell span. + */ + public final int align; + + /** + * The weight of this column. If the available print space is wider than the + * grid's preferred width, this field determines how much of that extra + * space should be given to this column. A larger weight causes the column + * to receive more of the extra width. A value of 0 indicates that the + * column should not be given any excess width. + */ + public final int weight; + + /** + * Constructs a GridColumn. + * + * @param align + * The default alignment for Prints in this column. + * @param size + * The size this column should be given. + * @param weight + * The weight this column should be given. + */ + public GridColumn(int align, int size, int weight) { + this.align = checkAlign(align); + this.size = checkSize(size); + this.weight = checkWeight(weight); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + align; + result = prime * result + size; + result = prime * result + weight; + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + GridColumn other = (GridColumn) obj; + if (align != other.align) + return false; + if (size != other.size) + return false; + if (weight != other.weight) + return false; + return true; + } + + private static int checkAlign(int align) { + align = PaperClipsUtil.firstMatch(align, new int[] { SWT.LEFT, + SWT.CENTER, SWT.RIGHT, SWT.DEFAULT }, 0); + if (align == 0) + PaperClips + .error( + SWT.ERROR_INVALID_ARGUMENT, + "Alignment argument must be one of SWT.LEFT, SWT.CENTER, SWT.RIGHT, or SWT.DEFAULT"); //$NON-NLS-1$ + if (align == SWT.DEFAULT) + return DEFAULT_ALIGN; + return align; + } + + private static int checkSize(int size) { + if (size != SWT.DEFAULT && size != GridPrint.PREFERRED && size <= 0) + PaperClips + .error(SWT.ERROR_INVALID_ARGUMENT, + "Size argument must be SWT.DEFAULT, GridPrint.PREFERRED, or > 0"); //$NON-NLS-1$ + return size; + } + + private static int checkWeight(int grow) { + if (grow < 0) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Weight argument must be >= 0"); //$NON-NLS-1$ + return grow; + } + + /** + * Parses the given column spec and returns a GridColumn matching that spec. + *

+ * Format: + * + *

+	 *  [align:]size[:grow]
+	 *  
+	 *  align  = L | LEFT |
+	 *           C | CENTER |
+	 *           R | RIGHT
+	 *  size   = P | PREF | PREFERRED |
+	 *           D | DEF | DEFAULT |
+	 *           (Positive number)[PT|IN|INCH|CM|MM]
+	 *  weight = N | NONE |
+	 *           G | GROW | G(#) | GROW(#)
+	 * 
+ * + * The default alignment is LEFT. The + * + * weight argument expresses the weight property: NONE + * indicates a weight of 0; GROW indicates a weight of 1; and GROW(3) + * indicates a weight of 3. The default weight (if weight is + * omitted) is 0. + *

+ * Examples: + * + *

+	 * LEFT:DEFAULT:GROW // left-aligned, default size, weight=1
+	 *  R:72PT:N          // light-aligned, 72 points (1") wide, weight=0
+	 *  right:72          // identical to previous line
+	 *  c:pref:none       // center-aligned, preferred size, weight=0
+	 *  p                 // left-aligned (default), preferred size, weight=0
+	 *  r:2inch           // right-aligned, 2 inches (50.8mm)
+	 *  r:50.8mm          // right-aligned, 50.8 mm (2")
+	 * 
+ * + * @param spec + * the column spec that will be parsed. + * @return a GridColumn matching the column spec. + * @see #align + * @see #size + * @see #weight + */ + public static GridColumn parse(String spec) { + Util.notNull(spec); + + String[] matches = spec.split("\\s*:\\s*"); //$NON-NLS-1$ + if (matches.length == 0) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Missing column spec"); //$NON-NLS-1$ + + int align = DEFAULT_ALIGN; + int size = DEFAULT_SIZE; + int grow = DEFAULT_WEIGHT; + + if (matches.length == 1) { + // One option: must be size + size = parseSize(matches[0]); + } else if (matches.length == 2) { + // Two possible scenarios: + // 1. align:size + // 2. size:weight + if (isAlign(matches[0])) { + align = parseAlign(matches[0]); + size = parseSize(matches[1]); + } else { + size = parseSize(matches[0]); + grow = parseWeight(matches[1]); + } + } else if (matches.length == 3) { + align = parseAlign(matches[0]); + size = parseSize(matches[1]); + grow = parseWeight(matches[2]); + } + + return new GridColumn(align, size, grow); + } + + // Alignment patterns + private static final Pattern LEFT_ALIGN_PATTERN = Pattern.compile( + "^l(eft)?$", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + + private static final Pattern CENTER_ALIGN_PATTERN = Pattern.compile( + "^c(enter)?$", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + + private static final Pattern RIGHT_ALIGN_PATTERN = Pattern.compile( + "^r(ight)?$", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + + private static final Pattern ANY_ALIGN_PATTERN = Pattern.compile( + "^l(eft)?|c(enter)?|r(ight)?$", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + + private static boolean isAlign(String alignmentString) { + return ANY_ALIGN_PATTERN.matcher(alignmentString).matches(); + } + + private static int parseAlign(String alignmentString) { + if (LEFT_ALIGN_PATTERN.matcher(alignmentString).matches()) + return SWT.LEFT; + else if (CENTER_ALIGN_PATTERN.matcher(alignmentString).matches()) + return SWT.CENTER; + else if (RIGHT_ALIGN_PATTERN.matcher(alignmentString).matches()) + return SWT.RIGHT; + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Unknown alignment \"" + alignmentString + "\""); //$NON-NLS-1$//$NON-NLS-2$ + return 0; // unreachable + } + + // Size patterns. + private static final Pattern DEFAULT_SIZE_PATTERN = Pattern.compile( + "^d(ef(ault)?)?$", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + + private static final Pattern PREFERRED_SIZE_PATTERN = Pattern.compile( + "^p(ref(erred)?)?", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + + private static final Pattern EXPLICIT_SIZE_PATTERN = Pattern.compile( + "^(\\d+(\\.\\d+)?)\\s*(pt|in(ch)?|mm|cm)?$", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + + private static int parseSize(String sizeString) { + Matcher matcher; + if (DEFAULT_SIZE_PATTERN.matcher(sizeString).matches()) + return SWT.DEFAULT; + else if (PREFERRED_SIZE_PATTERN.matcher(sizeString).matches()) + return GridPrint.PREFERRED; + else if ((matcher = EXPLICIT_SIZE_PATTERN.matcher(sizeString)) + .matches()) { + return (int) Math.ceil(convertToPoints(Double.parseDouble(matcher + .group(1)), matcher.group(3))); + } else { + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Unknown size pattern: \"" + sizeString + "\""); //$NON-NLS-1$ //$NON-NLS-2$ + return 0; // unreachable + } + } + + private static double convertToPoints(double value, String unit) { + if (unit == null || unit.length() == 0 || unit.equalsIgnoreCase("pt")) //$NON-NLS-1$ + return value; + else if (unit.equalsIgnoreCase("in") || unit.equalsIgnoreCase("inch")) //$NON-NLS-1$ //$NON-NLS-2$ + return 72 * value; + else if (unit.equalsIgnoreCase("cm")) //$NON-NLS-1$ + return 72 * value / 2.54; + else if (unit.equalsIgnoreCase("mm")) //$NON-NLS-1$ + return 72 * value / 25.4; + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Unknown unit \"" + unit + "\"."); //$NON-NLS-1$ //$NON-NLS-2$ + return 0; + } + + private static final Pattern WEIGHTLESS_PATTERN = Pattern.compile( + "n(one)?", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + + private static final Pattern WEIGHTED_PATTERN = Pattern.compile( + "(g(row)?)(\\((\\d+)\\))?", // yikes //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + + private static int parseWeight(String weightString) { + Matcher matcher; + if (WEIGHTLESS_PATTERN.matcher(weightString).matches()) + return 0; + else if ((matcher = WEIGHTED_PATTERN.matcher(weightString)).matches()) { + String weight = matcher.group(4); + return (weight == null) ? 1 : Integer.parseInt(weight); + } else { + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Illegal grow pattern: \"" + weightString //$NON-NLS-1$ + + "\""); //$NON-NLS-1$ + return 0; // unreachable + } + } + + GridColumn copy() { + return new GridColumn(align, size, weight); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridLook.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridLook.java index 2e794ee15..b8e2943c2 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridLook.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridLook.java @@ -1,35 +1,35 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -/** - * A pluggable "look" for a GridPrint. - * - * @author Matthew Hall - */ -public interface GridLook { - /** - * Returns a GridLookPainter for painting the GridLook. - * - * @param device - * the device to paint on. - * @param gc - * the graphics context for painting. - * @return a GridLookPainter for painting the GridLook. - */ - public GridLookPainter getPainter(Device device, GC gc); +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +/** + * A pluggable "look" for a GridPrint. + * + * @author Matthew Hall + */ +public interface GridLook { + /** + * Returns a GridLookPainter for painting the GridLook. + * + * @param device + * the device to paint on. + * @param gc + * the graphics context for painting. + * @return a GridLookPainter for painting the GridLook. + */ + public GridLookPainter getPainter(Device device, GC gc); } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridLookPainter.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridLookPainter.java index 8f86c3da3..ef84e86cc 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridLookPainter.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridLookPainter.java @@ -1,92 +1,92 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import org.eclipse.swt.graphics.GC; - -/** - * Interface for drawing a GridLook. - * - * @author Matthew Hall - */ -public interface GridLookPainter { - /** - * Returns the grid margins used for the GridLook. - * - * @return the grid margins used for the GridLook. - * @see GridMargins - */ - public GridMargins getMargins(); - - /** - * Paints the grid look onto the GC. - * - * @param gc - * the graphics context to paint on. - * @param x - * the x coordinate of the top-left of the grid. - * @param y - * the y coordinate of the top-left of the grid. - * @param columns - * the column widths. The left and right margins of each cell are - * included in the column widths. - * @param headerRows - * the header row heights. - * @param headerColSpans - * a two-dimensional array of cell spans in the header. Each - * element in the outer array is a header row. Each element of an - * inner array is a cell, where the element value indicates how - * many columns the cell spans. - * @param firstRowIndex - * the zero-based index of the first row displayed on the page. - * @param topOpen - * whether the top body row should be drawn with the top edge of - * the cell border "open." An open top border is a visual - * indication that the top row is being continued from the - * previous page. - * @param bodyRows - * the body row heights. - * @param bodyColSpans - * a two-dimensional array of cell spans in the body. Each - * element in the outer array is a body row. Each element of an - * inner array is a cell, where the element value indicates how - * many columns the cell spans. - * @param bottomOpen - * whether the bottom body row should be drawn with the bottom - * edge of the cell border "open." An open bottom border is a - * visual indication that the bottom row will be continued on the - * next page. - * @param footerRows - * the footer row heights. - * @param footerColSpans - * a two-dimensional array of cell spans in the footer. Each - * element in the outer array is a footer row. Each element of an - * inner array is a cell, where the element value indicates how - * many columns the cell spans. - */ - public void paint(final GC gc, final int x, final int y, - final int[] columns, final int[] headerRows, - final int[][] headerColSpans, final int firstRowIndex, - final boolean topOpen, final int[] bodyRows, - final int[][] bodyColSpans, final boolean bottomOpen, - final int[] footerRows, final int[][] footerColSpans); - - /** - * Disposes the system resources allocated by this GridLookPainter. The - * dispose method is not a permanent disposal of a GridLookPainter. - * It is intended to reclaim system resources, however future calls to - * paint(GC,int,int) may require that the resources be allocated again. - */ - public void dispose(); -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import org.eclipse.swt.graphics.GC; + +/** + * Interface for drawing a GridLook. + * + * @author Matthew Hall + */ +public interface GridLookPainter { + /** + * Returns the grid margins used for the GridLook. + * + * @return the grid margins used for the GridLook. + * @see GridMargins + */ + public GridMargins getMargins(); + + /** + * Paints the grid look onto the GC. + * + * @param gc + * the graphics context to paint on. + * @param x + * the x coordinate of the top-left of the grid. + * @param y + * the y coordinate of the top-left of the grid. + * @param columns + * the column widths. The left and right margins of each cell are + * included in the column widths. + * @param headerRows + * the header row heights. + * @param headerColSpans + * a two-dimensional array of cell spans in the header. Each + * element in the outer array is a header row. Each element of an + * inner array is a cell, where the element value indicates how + * many columns the cell spans. + * @param firstRowIndex + * the zero-based index of the first row displayed on the page. + * @param topOpen + * whether the top body row should be drawn with the top edge of + * the cell border "open." An open top border is a visual + * indication that the top row is being continued from the + * previous page. + * @param bodyRows + * the body row heights. + * @param bodyColSpans + * a two-dimensional array of cell spans in the body. Each + * element in the outer array is a body row. Each element of an + * inner array is a cell, where the element value indicates how + * many columns the cell spans. + * @param bottomOpen + * whether the bottom body row should be drawn with the bottom + * edge of the cell border "open." An open bottom border is a + * visual indication that the bottom row will be continued on the + * next page. + * @param footerRows + * the footer row heights. + * @param footerColSpans + * a two-dimensional array of cell spans in the footer. Each + * element in the outer array is a footer row. Each element of an + * inner array is a cell, where the element value indicates how + * many columns the cell spans. + */ + public void paint(final GC gc, final int x, final int y, + final int[] columns, final int[] headerRows, + final int[][] headerColSpans, final int firstRowIndex, + final boolean topOpen, final int[] bodyRows, + final int[][] bodyColSpans, final boolean bottomOpen, + final int[] footerRows, final int[][] footerColSpans); + + /** + * Disposes the system resources allocated by this GridLookPainter. The + * dispose method is not a permanent disposal of a GridLookPainter. + * It is intended to reclaim system resources, however future calls to + * paint(GC,int,int) may require that the resources be allocated again. + */ + public void dispose(); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridMargins.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridMargins.java index 12730d294..c9f998e7d 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridMargins.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridMargins.java @@ -1,115 +1,115 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -/** - * An interface for informing a GridPrint what cell margins to use for the - * GridLook. - * - * @author Matthew Hall - */ -public interface GridMargins { - /** - * Returns the margin, in pixels, at the left side of the grid. - * - * @return the margin, in pixels, at the left side of the grid. - */ - public int getLeft(); - - /** - * Returns the horizontal spacing, in pixels, between grid cells. - * - * @return the horizontal spacing, in pixels, between grid cells. - */ - public int getHorizontalSpacing(); - - /** - * Returns the margin, in pixels, at the right side of the grid. - * - * @return the margin, in pixels, at the right side of the grid. - */ - public int getRight(); - - /** - * Returns the margin, in pixels, at the top of the header cells. If a grid - * has no header cells, this value is ignored. - * - * @return the margin, in pixels, at the top of the header cells. - */ - public int getHeaderTop(); - - /** - * Returns the vertical spacing, in pixels, between rows in the header. - * - * @return the vertical spacing, in pixels, between rows in the header. - */ - public int getHeaderVerticalSpacing(); - - /** - * Returns the margin, in pixels, at the top of the body cells. If a header - * is present, this is the spacing, in pixels, between the last header row - * and the first body row. If a header is not present, this is the margin, - * in pixels, at the top of the grid. - * - * @param headerPresent - * whether a header is present. - * @param open - * whether the top row of body cells are "open." That is, whether - * the top row was started on a previous page and is continuing - * on this page. A GridLook may choose to show a visual - * indication for cells that were "opened" on previous pages. - * @return the margin, in pixels, at the top of the body cells. - */ - public int getBodyTop(boolean headerPresent, boolean open); - - /** - * Returns the vertical spacing, in pixels, between rows in the body. - * - * @return the vertical spacing, in pixels, between rows in the body. - */ - public int getBodyVerticalSpacing(); - - /** - * Returns the margin, in pixels, at the bottom of the body cells. If a - * footer is present, this is the spacing, in pixels, between the last body - * row and the first footer row. If a header is not present, this is the - * margin, in pixels, at the bottom of the grid. - * - * @param footerPresent - * whether a footer is present. - * @param open - * whether the bottom row of body cells are "open." That is, - * whether the bottom row still has more content to display on - * the next page. A GridLook may choose to show a visual - * indication for cells that will be "continued" on the next - * page. - * @return the margin, in pixels, at the bottom of the body cells. - */ - public int getBodyBottom(boolean footerPresent, boolean open); - - /** - * Returns the vertical spacing, in pixels, between rows in the footer. - * - * @return the vertical spacing, in pixels, between rows in the footer. - */ - public int getFooterVerticalSpacing(); - - /** - * Returns the margin, in pixels, at the bottom of the footer cells. If a - * grid has no footer cells, this value is ignored. - * - * @return the margin, in pixels, at the bottom of the footer cells. - */ - public int getFooterBottom(); -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +/** + * An interface for informing a GridPrint what cell margins to use for the + * GridLook. + * + * @author Matthew Hall + */ +public interface GridMargins { + /** + * Returns the margin, in pixels, at the left side of the grid. + * + * @return the margin, in pixels, at the left side of the grid. + */ + public int getLeft(); + + /** + * Returns the horizontal spacing, in pixels, between grid cells. + * + * @return the horizontal spacing, in pixels, between grid cells. + */ + public int getHorizontalSpacing(); + + /** + * Returns the margin, in pixels, at the right side of the grid. + * + * @return the margin, in pixels, at the right side of the grid. + */ + public int getRight(); + + /** + * Returns the margin, in pixels, at the top of the header cells. If a grid + * has no header cells, this value is ignored. + * + * @return the margin, in pixels, at the top of the header cells. + */ + public int getHeaderTop(); + + /** + * Returns the vertical spacing, in pixels, between rows in the header. + * + * @return the vertical spacing, in pixels, between rows in the header. + */ + public int getHeaderVerticalSpacing(); + + /** + * Returns the margin, in pixels, at the top of the body cells. If a header + * is present, this is the spacing, in pixels, between the last header row + * and the first body row. If a header is not present, this is the margin, + * in pixels, at the top of the grid. + * + * @param headerPresent + * whether a header is present. + * @param open + * whether the top row of body cells are "open." That is, whether + * the top row was started on a previous page and is continuing + * on this page. A GridLook may choose to show a visual + * indication for cells that were "opened" on previous pages. + * @return the margin, in pixels, at the top of the body cells. + */ + public int getBodyTop(boolean headerPresent, boolean open); + + /** + * Returns the vertical spacing, in pixels, between rows in the body. + * + * @return the vertical spacing, in pixels, between rows in the body. + */ + public int getBodyVerticalSpacing(); + + /** + * Returns the margin, in pixels, at the bottom of the body cells. If a + * footer is present, this is the spacing, in pixels, between the last body + * row and the first footer row. If a header is not present, this is the + * margin, in pixels, at the bottom of the grid. + * + * @param footerPresent + * whether a footer is present. + * @param open + * whether the bottom row of body cells are "open." That is, + * whether the bottom row still has more content to display on + * the next page. A GridLook may choose to show a visual + * indication for cells that will be "continued" on the next + * page. + * @return the margin, in pixels, at the bottom of the body cells. + */ + public int getBodyBottom(boolean footerPresent, boolean open); + + /** + * Returns the vertical spacing, in pixels, between rows in the footer. + * + * @return the vertical spacing, in pixels, between rows in the footer. + */ + public int getFooterVerticalSpacing(); + + /** + * Returns the margin, in pixels, at the bottom of the footer cells. If a + * grid has no footer cells, this value is ignored. + * + * @return the margin, in pixels, at the bottom of the footer cells. + */ + public int getFooterBottom(); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridPrint.java index 7df8635b6..240ff54b6 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/GridPrint.java @@ -1,1043 +1,1043 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.grid.internal.GridCellImpl; -import org.eclipse.nebula.paperclips.core.grid.internal.GridIterator; -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -/** - * A Print which arranges child prints into a grid. A grid is initialized with a - * series of GridColumns, and child prints are laid out into those columns by - * invoking the add(...) methods. - *

- * GridPrint uses a column sizing algorithm based on the W3C - * recommendation for automatic layout of tables. GridPrint deviates from - * the recommendation on one important point: if there is less width available - * on the print device than the calculated "minimum" size of the grid, the - * columns will be scaled down to less than their calculated minimum - * widths. Only when one of the columns goes below its "absolute minimum" will - * the grid fail to print ( {@link PrintIterator#next(int, int)} returns null). - *

- * GridPrint offers three basic methods of specifying column size. - *

    - *
  1. Default size. The column will be somewhere between it's minimum and - * preferred width. GridPrint will determine the optimum widths for all default - * size columns, using the modified W3C recommendation described above. This is - * the recommended option for most cases. - *
  2. Preferred size. The column will be sized to it's preferred width. This - * option is sometimes appropriate, for example when certain portions of text - * should not be allowed to line-wrap. In cases where only a few cells in a - * column need to be prevented from line wrapping, consider wrapping them in a - * NoBreakPrint instead. - *
  3. Explicit size. The column will be the size you specify, expressed in - * points. 72 points = 1". - *
- * Example: GridPrint grid = new GridPrint("d, p, 72pts"); - *

- * In addition, any column can be given a grow attribute. In the event a grid is - * not as wide as the page, those columns with the grow attribute set will be - * widened to fill the extra space. - *

- * Because GridPrint scales columns according to their minimum sizes in the - * worst-case scenario, the absolute minimum size of a GridPrint is dependant on - * its child prints and is not clearly defined. - *

- * If a grid has one of more columns with the grow attribute set, the grid is - * horizontally greedy. Greedy prints take up all the available space on the - * page. - * - * @author Matthew Hall - * @see GridColumn - * @see PrintIterator#minimumSize() - * @see PrintIterator#preferredSize() - */ -public final class GridPrint implements Print { - /** - * Constant colspan value indicating that all remaining columns in the row - * should be used. - */ - public static final int REMAINDER = -1; - - /** - * Constant column size value indicating that the column should be given its - * preferred size. (In the context of W3C's autolayout recommendation, this - * has the effect of setting the columns minimum width to its preferred - * width. This value is used in the GridColumn constructor. - */ - public static final int PREFERRED = 0; - - /** - * Constant cell spacing value indicating that the borders of adjacent cells - * should overlap. - */ - public static final int BORDER_OVERLAP = -1; - - private GridLook look; - - /** The columns for this grid. */ - final List columns; - - /** Array of column groups. */ - int[][] columnGroups = new int[0][]; - - /** - * Two-dimension list of all header cells. Each element of this list - * represents a row in the header. Each element of a row represents a - * cellspan in that row. - */ - final List> header = new ArrayList<>(); - - /** - * Column cursor - the column that the next added header cell will go into. - */ - private int headerCol = 0; - - /** - * Two-dimensional list of all body cells. Each element of this list - * represents a row in the body. Each element of a row represents a cellspan - * in that row. - */ - - final List> body = new ArrayList<>(); - - /** Column cursor - the column that the next added print will go into. */ - private int bodyCol = 0; - - boolean cellClippingEnabled = true; - - /** - * Two-dimension list of all footer cells. Each element of this list - * represents a row in the footer. Each element of a row represents a - * cellspan in that row. - */ - final List> footer = new ArrayList<>(); - - /** - * Column cursor - the column that the next added footer cell will go into. - */ - private int footerCol = 0; - - /** - * Constructs a GridPrint with no columns and a default look. - */ - public GridPrint() { - this(new GridColumn[0]); - } - - /** - * Constructs a GridPrint with no columns and the given look. - * - * @param look - * the look to apply to the constructed grid. - */ - public GridPrint(GridLook look) { - this(new GridColumn[0], look); - } - - /** - * Constructs a GridPrint with the given columns and a default look. - * - * @param columns - * a comma-separated list of parseable column specs. - * @see GridColumn#parse(String) - */ - public GridPrint(String columns) { - this(parseColumns(columns)); - } - - /** - * Constructs a GridPrint with the given columns and look. - * - * @param columns - * a comma-separated list of parseable column specs. - * @param look - * the look to apply to the constructed grid. - * @see GridColumn#parse(String) - */ - public GridPrint(String columns, GridLook look) { - this(parseColumns(columns), look); - } - - /** - * Constructs a GridPrint with the given columns and a default look. - * - * @param columns - * the columns for the new grid. - */ - public GridPrint(GridColumn[] columns) { - Util.noNulls(columns); - - this.columns = new ArrayList<>(); - for (int i = 0; i < columns.length; i++) - this.columns.add(columns[i]); - this.look = new DefaultGridLook(); - } - - /** - * Constructs a GridPrint with the given columns and look. - * - * @param columns - * the columns for the new grid. - * @param look - * the look to apply to the constructed grid. - */ - public GridPrint(GridColumn[] columns, GridLook look) { - this(columns); - setLook(look); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + bodyCol; - result = prime * result + (cellClippingEnabled ? 1231 : 1237); - result = prime * result + GridPrint.hashCode(columnGroups); - result = prime * result + ((columns == null) ? 0 : columns.hashCode()); - result = prime * result + ((footer == null) ? 0 : footer.hashCode()); - result = prime * result + footerCol; - result = prime * result + ((header == null) ? 0 : header.hashCode()); - result = prime * result + headerCol; - result = prime * result + ((look == null) ? 0 : look.hashCode()); - return result; - } - - private static int hashCode(int[][] array) { - int prime = 31; - if (array == null) - return 0; - int result = 1; - for (int index = 0; index < array.length; index++) { - result = prime * result - + (array[index] == null ? 0 : hashCode(array[index])); - } - return result; - } - - private static int hashCode(int[] array) { - int prime = 31; - if (array == null) - return 0; - int result = 1; - for (int index = 0; index < array.length; index++) { - result = prime * result + array[index]; - } - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - GridPrint other = (GridPrint) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (bodyCol != other.bodyCol) - return false; - if (cellClippingEnabled != other.cellClippingEnabled) - return false; - if (!Util.equal(columnGroups, other.columnGroups)) - return false; - if (columns == null) { - if (other.columns != null) - return false; - } else if (!columns.equals(other.columns)) - return false; - if (footer == null) { - if (other.footer != null) - return false; - } else if (!footer.equals(other.footer)) - return false; - if (footerCol != other.footerCol) - return false; - if (header == null) { - if (other.header != null) - return false; - } else if (!header.equals(other.header)) - return false; - if (headerCol != other.headerCol) - return false; - if (look == null) { - if (other.look != null) - return false; - } else if (!look.equals(other.look)) - return false; - return true; - } - - /** - * Adds the column on the right edge of the grid. Any cells which have been - * added to the grid prior to adding the column will be adjusted as follows: - * the right-hand cell of each completed row will have it's colspan expanded - * to fill the added column. - * - * @param column - * the column to add to the grid. - * @see GridColumn#parse(String) - */ - public void addColumn(String column) { - addColumn(columns.size(), GridColumn.parse(column)); - } - - /** - * Adds the column on the right edge of the grid. Any cells which have been - * added to the grid prior to adding the column will be adjusted as follows: - * the right-hand cell of each completed row will have it's colspan expanded - * to fill the added column. - * - * @param column - * the column to add to the grid. - */ - public void addColumn(GridColumn column) { - addColumn(columns.size(), column); - } - - /** - * Inserts the column at the specified position in the grid. Any cells which - * have been added to the grid prior to adding the column will be adjusted - * as follows: on each row, the cell which overlaps or whose right edge - * touches the insert position will be expanded to fill the added column. - * - * @param index - * the insert position. - * @param column - * the column to be inserted. - * @see GridColumn#parse(String) - */ - public void addColumn(int index, String column) { - addColumn(index, GridColumn.parse(column)); - } - - /** - * Inserts the column at the specified position in the grid. Any cells which - * have been added to the grid prior to adding the column will be adjusted - * as follows: on each row, the cell which overlaps or whose right edge - * touches the insert position will be expanded to fill the added column. - * - * @param index - * the insert position. - * @param column - * the column to be inserted. - */ - public void addColumn(int index, GridColumn column) { - checkColumnInsert(index); - Util.notNull(column); - - this.columns.add(index, column); - adjustForColumnInsert(index, 1); - } - - /** - * Adds the columns on the right edge of the grid. Any cells which have been - * added to the grid prior to adding the columns will be adjusted as - * follows: the right-hand cell of each completed row will have it's colspan - * expanded to fill the added columns. - * - * @param columns - * the columns to add to the grid. - * @see GridColumn#parse(String) - */ - public void addColumns(String columns) { - addColumns(this.columns.size(), parseColumns(columns)); - } - - /** - * Adds the columns on the right edge of the grid. Any cells which have been - * added to the grid prior to adding the columns will be adjusted as - * follows: the right-hand cell of each completed row will have it's colspan - * expanded to fill the added columns. - * - * @param columns - * the columns to add to the grid. - */ - public void addColumns(GridColumn[] columns) { - addColumns(this.columns.size(), columns); - } - - /** - * Inserts the columns at the specified position in the grid. Any cells - * which have been added to the grid prior to adding the columns will be - * adjusted as follows: on each row, the cell which overlaps or whose right - * edge touches the insert position will be expanded to fill the added - * columns. - * - * @param index - * the insert position. - * @param columns - * the columns to be inserted. - * @see GridColumn#parse(String) - */ - public void addColumns(int index, String columns) { - addColumns(index, parseColumns(columns)); - } - - /** - * Inserts the columns at the specified position in the grid. Any cells - * which have been added to the grid prior to adding the columns will be - * adjusted as follows: on each row, the cell which overlaps or whose right - * edge touches the insert position will be expanded to fill the added - * columns. - * - * @param index - * the insert position. - * @param columns - * the columns to be inserted. - * @see GridColumn#parse(String) - */ - public void addColumns(int index, GridColumn[] columns) { - checkColumnInsert(index); - Util.noNulls(columns); - - this.columns.addAll(index, Arrays.asList(columns)); - - adjustForColumnInsert(index, columns.length); - } - - private void checkColumnInsert(int index) { - if (index < 0 || index > this.columns.size()) - PaperClips.error(SWT.ERROR_INVALID_RANGE, - "index = " + index + ", size = " + this.columns.size()); //$NON-NLS-1$ //$NON-NLS-2$ - } - - private void adjustForColumnInsert(int index, int count) { - adjustCellsForColumnInsert(header, index, count); - adjustCellsForColumnInsert(body, index, count); - adjustCellsForColumnInsert(footer, index, count); - - adjustColumnGroupsForColumnInsert(index, count); - - if (bodyCol > index) - bodyCol += count; - if (headerCol > index) - headerCol += count; - if (footerCol > index) - footerCol += count; - } - - private void adjustCellsForColumnInsert(List> rows, - int index, int count) { - for (int rowI = 0; rowI < rows.size(); rowI++) { - List row = rows.get(rowI); - int col = 0; - for (int cellI = 0; cellI < row.size(); cellI++) { - GridCell cell = row.get(cellI); - col += cell.getColSpan(); - - // Adjust the cell which extends through the insert point, or - // whose right side touches the insert - // point. Except on the last row, don't adjust the final cell if - // it only touches the insert point - // (the user may be adding columns right before s/he adds column - // headers). - if ( // cell overlaps insert point, or - (col > index) || - // right side touches insert point but is not the final cell. - (col == index && (rowI + 1 < rows.size() - || cellI + 1 < row.size()))) { - row.set(cellI, - new GridCellImpl(cell.getHorizontalAlignment(), - cell.getVerticalAlignment(), - cell.getContent(), - cell.getColSpan() + count)); - break; - } - } - } - } - - private void adjustColumnGroupsForColumnInsert(int index, int count) { - for (int groupI = 0; groupI < columnGroups.length; groupI++) { - int[] group = columnGroups[groupI]; - for (int i = 0; i < group.length; i++) - if (group[i] >= index) - group[i] += count; - } - } - - /** - * Separates the comma-separated argument and parses each piece to obtain an - * array of GridColumns. - * - * @param columns - * the comma-separated list of column specs. - * @return GridColumn array with the requested columns. - */ - private static GridColumn[] parseColumns(String columns) { - Util.notNull(columns); - String[] cols = columns.split("\\s*,\\s*"); //$NON-NLS-1$ - - GridColumn[] result = new GridColumn[cols.length]; - for (int i = 0; i < cols.length; i++) - result[i] = GridColumn.parse(cols[i]); - - return result; - } - - /** - * Returns an array of GridColumns which are the columns in the - * receiver. - * - * @return an array of GridColumns which are the columns in the - * receiver. - */ - public GridColumn[] getColumns() { - return columns.toArray(new GridColumn[columns.size()]); - } - - /** - * Adds the Print to the grid header, with default alignment and a colspan - * of 1. - * - * @param cell - * the print to add. - */ - public void addHeader(Print cell) { - headerCol = add(header, headerCol, SWT.DEFAULT, SWT.DEFAULT, cell, 1); - } - - /** - * Adds the Print to the grid header, using the given alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param cell - * the print to add. - */ - public void addHeader(int hAlignment, Print cell) { - headerCol = add(header, headerCol, hAlignment, SWT.DEFAULT, cell, 1); - } - - /** - * Adds the Print to the grid header, using the given alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param vAlignment - * the vertical alignment of the print within the grid cell. One - * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, - * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL - * indicates that the cell is vertically greedy, so GridPrint - * will limit the cell's height to the tallest non-FILL cell in - * the row. - * @param cell - * the print to add. - */ - public void addHeader(int hAlignment, int vAlignment, Print cell) { - headerCol = add(header, headerCol, hAlignment, vAlignment, cell, 1); - } - - /** - * Adds the Print to the grid header, with the given colspan and the default - * alignment. - * - * @param cell - * the print to add. - * @param colspan - * the number of columns to span, or {@link GridPrint#REMAINDER} - * to span the rest of the row. - */ - public void addHeader(Print cell, int colspan) { - headerCol = add(header, headerCol, SWT.DEFAULT, SWT.DEFAULT, cell, - colspan); - } - - /** - * Adds the Print to the grid header, using the given colspan and alignment. - * - * @param cell - * the print to add. - * @param colspan - * the number of columns to span, or {@link GridPrint#REMAINDER} - * to span the rest of the row. - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - */ - public void addHeader(int hAlignment, Print cell, int colspan) { - headerCol = add(header, headerCol, hAlignment, SWT.DEFAULT, cell, - colspan); - } - - /** - * Adds the Print to the grid header, using the given colspan and alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param vAlignment - * the vertical alignment of the print within the grid cell. One - * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, - * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL - * indicates that the cell is vertically greedy, so GridPrint - * will limit the cell's height to the tallest non-FILL cell in - * the row. - * @param cell - * the print to add. - * @param colspan - * the number of columns to span, or {@link GridPrint#REMAINDER} - * to span the rest of the row. - */ - public void addHeader(int hAlignment, int vAlignment, Print cell, - int colspan) { - headerCol = add(header, headerCol, hAlignment, vAlignment, cell, - colspan); - } - - /** - * Returns an array containing the header cells in this grid. Each inner - * array represents one row in the header. - * - * @return an array containing the header cells in this grid. - */ - public GridCell[][] getHeaderCells() { - return getGridCellArray(header); - } - - /** - * Returns an array containing the body cells in the grid. Each inner array - * represents one row in the body. - * - * @return an array containing the body cells in the grid. - */ - public GridCell[][] getBodyCells() { - return getGridCellArray(body); - } - - /** - * Returns an array containing the footer cells in the grid. Each inner - * array represents one row in the footer. - * - * @return an array containing the footer cells in the grid. - */ - public GridCell[][] getFooterCells() { - return getGridCellArray(footer); - } - - private static GridCell[][] getGridCellArray(List> list) { - GridCell[][] cells = new GridCell[list.size()][]; - for (int rowIndex = 0; rowIndex < cells.length; rowIndex++) { - List row = list.get(rowIndex); - GridCell[] rowCells = new GridCell[row.size()]; - for (int cellIndex = 0; cellIndex < rowCells.length; cellIndex++) - rowCells[cellIndex] = row.get(cellIndex); - cells[rowIndex] = rowCells; - } - return cells; - } - - /** - * Adds the Print to the grid body, with the default alignment and a colspan - * of 1. - * - * @param cell - * the print to add. - */ - public void add(Print cell) { - bodyCol = add(body, bodyCol, SWT.DEFAULT, SWT.DEFAULT, cell, 1); - } - - /** - * Adds the Print to the grid body, using the given colspan and alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param cell - * the print to add. - */ - public void add(int hAlignment, Print cell) { - bodyCol = add(body, bodyCol, hAlignment, SWT.DEFAULT, cell, 1); - } - - /** - * Adds the Print to the grid body, using the given colspan and alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param vAlignment - * the vertical alignment of the print within the grid cell. One - * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, - * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL - * indicates that the cell is vertically greedy, so GridPrint - * will limit the cell's height to the tallest non-FILL cell in - * the row. - * @param cell - * the print to add. - */ - public void add(int hAlignment, int vAlignment, Print cell) { - bodyCol = add(body, bodyCol, hAlignment, vAlignment, cell, 1); - } - - /** - * Adds the Print to the grid body, with the given colspan and the default - * alignment. - * - * @param cell - * the print to add. - * @param colspan - * the number of columns to span, or {@link GridPrint#REMAINDER} - * to span the rest of the row. - */ - public void add(Print cell, int colspan) { - bodyCol = add(body, bodyCol, SWT.DEFAULT, SWT.DEFAULT, cell, colspan); - } - - /** - * Adds the Print to the grid body, using the given colspan and alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param cell - * the print to add. - * @param colspan - * the number of columns to span, or {@link GridPrint#REMAINDER} - * to span the rest of the row. - */ - public void add(int hAlignment, Print cell, int colspan) { - bodyCol = add(body, bodyCol, hAlignment, SWT.DEFAULT, cell, colspan); - } - - /** - * Adds the Print to the grid body, using the given colspan and alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param vAlignment - * the vertical alignment of the print within the grid cell. One - * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, - * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL - * indicates that the cell is vertically greedy, so GridPrint - * will limit the cell's height to the tallest non-FILL cell in - * the row. - * @param cell - * the print to add. - * @param colspan - * the number of columns to span, or {@link GridPrint#REMAINDER} - * to span the rest of the row. - */ - public void add(int hAlignment, int vAlignment, Print cell, int colspan) { - bodyCol = add(body, bodyCol, hAlignment, vAlignment, cell, colspan); - } - - /** - * Returns whether individual body cells in the grid may be broken across - * pages. Defaults to true. - * - * @return whether individual body cells in the grid may be broken across - * pages. - */ - public boolean isCellClippingEnabled() { - return cellClippingEnabled; - } - - /** - * Sets whether individual body cells in the grid may be broken across - * pages. - * - * @param cellClippingEnabled - * whether to enabled cell clipping. - */ - public void setCellClippingEnabled(boolean cellClippingEnabled) { - this.cellClippingEnabled = cellClippingEnabled; - } - - /** - * Adds the Print to the grid footer, with the default alignment and a - * colspan of 1. - * - * @param cell - * the print to add. - */ - public void addFooter(Print cell) { - footerCol = add(footer, footerCol, SWT.DEFAULT, SWT.DEFAULT, cell, 1); - } - - /** - * Adds the Print to the grid footer, using the given colspan and alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param cell - * the print to add. - */ - public void addFooter(int hAlignment, Print cell) { - footerCol = add(footer, footerCol, hAlignment, SWT.DEFAULT, cell, 1); - } - - /** - * Adds the Print to the grid footer, using the given colspan and alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param vAlignment - * the vertical alignment of the print within the grid cell. One - * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, - * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL - * indicates that the cell is vertically greedy, so GridPrint - * will limit the cell's height to the tallest non-FILL cell in - * the row. - * @param cell - * the print to add. - */ - public void addFooter(int hAlignment, int vAlignment, Print cell) { - footerCol = add(footer, footerCol, hAlignment, vAlignment, cell, 1); - } - - /** - * Adds the Print to the grid footer, with the given colspan and the default - * alignment. - * - * @param cell - * the print to add. - * @param colspan - * the number of columns to span, or {@link GridPrint#REMAINDER} - * to span the rest of the row. - */ - public void addFooter(Print cell, int colspan) { - footerCol = add(footer, footerCol, SWT.DEFAULT, SWT.DEFAULT, cell, - colspan); - } - - /** - * Adds the Print to the grid footer, using the given colspan and alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param cell - * the print to add. - * @param colspan - * the number of columns to span, or {@link GridPrint#REMAINDER} - * to span the rest of the row. - */ - public void addFooter(int hAlignment, Print cell, int colspan) { - footerCol = add(footer, footerCol, hAlignment, SWT.DEFAULT, cell, - colspan); - } - - /** - * Adds the Print to the grid footer, using the given colspan and alignment. - * - * @param hAlignment - * the horizontal alignment of the print within the grid cell. - * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, - * {@link SWT#CENTER} or {@link SWT#RIGHT}. - * @param vAlignment - * the vertical alignment of the print within the grid cell. One - * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, - * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL - * indicates that the cell is vertically greedy, so GridPrint - * will limit the cell's height to the tallest non-FILL cell in - * the row. - * @param cell - * the print to add. - * @param colspan - * the number of columns to span, or {@link GridPrint#REMAINDER} - * to span the rest of the row. - */ - public void addFooter(int hAlignment, int vAlignment, Print cell, - int colspan) { - footerCol = add(footer, footerCol, hAlignment, vAlignment, cell, - colspan); - } - - /* - * Returns the column number that we've advanced to, after adding the new - * cell. - */ - private int add(List> rows, // List of List of GridCell - int startColumn, int hAlignment, int vAlignment, Print cellContents, - int colspan) { - startColumn = startNewRowIfCurrentRowFull(startColumn); - checkColumnSpan(startColumn, colspan); - List row = getOpenRow(rows, startColumn); - colspan = convertRemainderToExplicitColSpan(startColumn, colspan); - - GridCell cell = new GridCellImpl(hAlignment, vAlignment, cellContents, - colspan); - row.add(cell); - startColumn += colspan; - - // Make sure column number is valid. - if (startColumn > columns.size()) { - // THIS SHOULD NOT HAPPEN--ABOVE LOGIC SHOULD PREVENT THIS CASE - // ..but just in case. - - row.remove(row.size() - 1); - if (row.size() == 0) - rows.remove(row); - - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Colspan " + colspan //$NON-NLS-1$ - + " too wide at column " + startColumn + " (" //$NON-NLS-1$ //$NON-NLS-2$ - + columns.size() + " columns total)"); //$NON-NLS-1$ - } - - return startColumn; - } - - private int convertRemainderToExplicitColSpan(int startColumn, - int colspan) { - if (colspan == REMAINDER) - colspan = columns.size() - startColumn; - return colspan; - } - - private int startNewRowIfCurrentRowFull(int startColumn) { - // If we're at the end of a row, start a new row. - if (startColumn == columns.size()) - startColumn = 0; - return startColumn; - } - - private void checkColumnSpan(int startColumn, int colspan) { - if (startColumn + colspan > columns.size()) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Colspan " + colspan //$NON-NLS-1$ - + " too wide at column " + startColumn + " (" //$NON-NLS-1$ //$NON-NLS-2$ - + columns.size() + " columns total)"); //$NON-NLS-1$ - } - - private List getOpenRow(List> rows, - int startColumn) { - List row; // the row we will add the cell to. - if (startColumn == 0) - // Start a new row if back at column 0. - rows.add(row = new ArrayList<>(columns.size())); - else - // Get the incomplete row. - row = rows.get(rows.size() - 1); // List of GridCell - return row; - } - - /** - * Returns current column groups. The returned array may be modified without - * affecting this GridPrint. - * - * @return the column groups. - */ - public int[][] getColumnGroups() { - return PaperClipsUtil.copy(columnGroups); - } - - /** - * Sets the column groups to the given two-dimension array. Each int[] array - * is a group. Columns in a group will be the same size when laid out on the - * print device. - *

- * The following statement causes columns 0 and 2 to be the same size, and - * columns 1 and 3 to be the same size. - * - *

-	 * grid.setColumnGroups(new int[][] { { 0, 2 }, { 1, 3 } });
-	 * 
- * - *

- * The behavior of this property is undefined when a column belongs to more - * than one group. - *

- * Note: Column grouping is enforced before column weights. - * Therefore, columns in the same group should be given the same weight to - * ensure they are laid out at the same width. - * - * @param columnGroups - * the new column groups. - */ - public void setColumnGroups(int[][] columnGroups) { - checkColumnGroups(columnGroups); - this.columnGroups = PaperClipsUtil.copy(columnGroups); - } - - private void checkColumnGroups(int[][] columnGroups) { - Util.notNull(columnGroups); - for (int groupIndex = 0; groupIndex < columnGroups.length; groupIndex++) - checkColumnGroup(columnGroups[groupIndex]); - } - - private void checkColumnGroup(int[] columnGroup) { - Util.notNull(columnGroup); - for (int columnInGroupIndex = 0; columnInGroupIndex < columnGroup.length; columnInGroupIndex++) - checkColumnIndex(columnGroup[columnInGroupIndex]); - } - - private void checkColumnIndex(int columnIndex) { - if (columnIndex < 0 || columnIndex >= columns.size()) - PaperClips.error(SWT.ERROR_INVALID_RANGE, - "Column index in column group must be " + "0 <= " //$NON-NLS-1$ //$NON-NLS-2$ - + columnIndex + " < " + columns.size()); //$NON-NLS-1$ - } - - /** - * Returns the grid's look. A GridLook determines what decorations will - * appear around the grid's contents. Default is a DefaultGridLook with no - * cell spacing, no cell borders, and no background colors. - * - * @return the look of this grid. - */ - public GridLook getLook() { - return look; - } - - /** - * Sets the grid's look. - * - * @param look - * the new look. - */ - public void setLook(GridLook look) { - Util.notNull(look); - this.look = look; - } - - public PrintIterator iterator(Device device, GC gc) { - return new GridIterator(this, device, gc); - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.grid.internal.GridCellImpl; +import org.eclipse.nebula.paperclips.core.grid.internal.GridIterator; +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +/** + * A Print which arranges child prints into a grid. A grid is initialized with a + * series of GridColumns, and child prints are laid out into those columns by + * invoking the add(...) methods. + *

+ * GridPrint uses a column sizing algorithm based on the W3C + * recommendation for automatic layout of tables. GridPrint deviates from + * the recommendation on one important point: if there is less width available + * on the print device than the calculated "minimum" size of the grid, the + * columns will be scaled down to less than their calculated minimum + * widths. Only when one of the columns goes below its "absolute minimum" will + * the grid fail to print ( {@link PrintIterator#next(int, int)} returns null). + *

+ * GridPrint offers three basic methods of specifying column size. + *

    + *
  1. Default size. The column will be somewhere between it's minimum and + * preferred width. GridPrint will determine the optimum widths for all default + * size columns, using the modified W3C recommendation described above. This is + * the recommended option for most cases. + *
  2. Preferred size. The column will be sized to it's preferred width. This + * option is sometimes appropriate, for example when certain portions of text + * should not be allowed to line-wrap. In cases where only a few cells in a + * column need to be prevented from line wrapping, consider wrapping them in a + * NoBreakPrint instead. + *
  3. Explicit size. The column will be the size you specify, expressed in + * points. 72 points = 1". + *
+ * Example: GridPrint grid = new GridPrint("d, p, 72pts"); + *

+ * In addition, any column can be given a grow attribute. In the event a grid is + * not as wide as the page, those columns with the grow attribute set will be + * widened to fill the extra space. + *

+ * Because GridPrint scales columns according to their minimum sizes in the + * worst-case scenario, the absolute minimum size of a GridPrint is dependant on + * its child prints and is not clearly defined. + *

+ * If a grid has one of more columns with the grow attribute set, the grid is + * horizontally greedy. Greedy prints take up all the available space on the + * page. + * + * @author Matthew Hall + * @see GridColumn + * @see PrintIterator#minimumSize() + * @see PrintIterator#preferredSize() + */ +public final class GridPrint implements Print { + /** + * Constant colspan value indicating that all remaining columns in the row + * should be used. + */ + public static final int REMAINDER = -1; + + /** + * Constant column size value indicating that the column should be given its + * preferred size. (In the context of W3C's autolayout recommendation, this + * has the effect of setting the columns minimum width to its preferred + * width. This value is used in the GridColumn constructor. + */ + public static final int PREFERRED = 0; + + /** + * Constant cell spacing value indicating that the borders of adjacent cells + * should overlap. + */ + public static final int BORDER_OVERLAP = -1; + + private GridLook look; + + /** The columns for this grid. */ + final List columns; + + /** Array of column groups. */ + int[][] columnGroups = new int[0][]; + + /** + * Two-dimension list of all header cells. Each element of this list + * represents a row in the header. Each element of a row represents a + * cellspan in that row. + */ + final List> header = new ArrayList<>(); + + /** + * Column cursor - the column that the next added header cell will go into. + */ + private int headerCol = 0; + + /** + * Two-dimensional list of all body cells. Each element of this list + * represents a row in the body. Each element of a row represents a cellspan + * in that row. + */ + + final List> body = new ArrayList<>(); + + /** Column cursor - the column that the next added print will go into. */ + private int bodyCol = 0; + + boolean cellClippingEnabled = true; + + /** + * Two-dimension list of all footer cells. Each element of this list + * represents a row in the footer. Each element of a row represents a + * cellspan in that row. + */ + final List> footer = new ArrayList<>(); + + /** + * Column cursor - the column that the next added footer cell will go into. + */ + private int footerCol = 0; + + /** + * Constructs a GridPrint with no columns and a default look. + */ + public GridPrint() { + this(new GridColumn[0]); + } + + /** + * Constructs a GridPrint with no columns and the given look. + * + * @param look + * the look to apply to the constructed grid. + */ + public GridPrint(GridLook look) { + this(new GridColumn[0], look); + } + + /** + * Constructs a GridPrint with the given columns and a default look. + * + * @param columns + * a comma-separated list of parseable column specs. + * @see GridColumn#parse(String) + */ + public GridPrint(String columns) { + this(parseColumns(columns)); + } + + /** + * Constructs a GridPrint with the given columns and look. + * + * @param columns + * a comma-separated list of parseable column specs. + * @param look + * the look to apply to the constructed grid. + * @see GridColumn#parse(String) + */ + public GridPrint(String columns, GridLook look) { + this(parseColumns(columns), look); + } + + /** + * Constructs a GridPrint with the given columns and a default look. + * + * @param columns + * the columns for the new grid. + */ + public GridPrint(GridColumn[] columns) { + Util.noNulls(columns); + + this.columns = new ArrayList<>(); + for (int i = 0; i < columns.length; i++) + this.columns.add(columns[i]); + this.look = new DefaultGridLook(); + } + + /** + * Constructs a GridPrint with the given columns and look. + * + * @param columns + * the columns for the new grid. + * @param look + * the look to apply to the constructed grid. + */ + public GridPrint(GridColumn[] columns, GridLook look) { + this(columns); + setLook(look); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((body == null) ? 0 : body.hashCode()); + result = prime * result + bodyCol; + result = prime * result + (cellClippingEnabled ? 1231 : 1237); + result = prime * result + GridPrint.hashCode(columnGroups); + result = prime * result + ((columns == null) ? 0 : columns.hashCode()); + result = prime * result + ((footer == null) ? 0 : footer.hashCode()); + result = prime * result + footerCol; + result = prime * result + ((header == null) ? 0 : header.hashCode()); + result = prime * result + headerCol; + result = prime * result + ((look == null) ? 0 : look.hashCode()); + return result; + } + + private static int hashCode(int[][] array) { + int prime = 31; + if (array == null) + return 0; + int result = 1; + for (int index = 0; index < array.length; index++) { + result = prime * result + + (array[index] == null ? 0 : hashCode(array[index])); + } + return result; + } + + private static int hashCode(int[] array) { + int prime = 31; + if (array == null) + return 0; + int result = 1; + for (int index = 0; index < array.length; index++) { + result = prime * result + array[index]; + } + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + GridPrint other = (GridPrint) obj; + if (body == null) { + if (other.body != null) + return false; + } else if (!body.equals(other.body)) + return false; + if (bodyCol != other.bodyCol) + return false; + if (cellClippingEnabled != other.cellClippingEnabled) + return false; + if (!Util.equal(columnGroups, other.columnGroups)) + return false; + if (columns == null) { + if (other.columns != null) + return false; + } else if (!columns.equals(other.columns)) + return false; + if (footer == null) { + if (other.footer != null) + return false; + } else if (!footer.equals(other.footer)) + return false; + if (footerCol != other.footerCol) + return false; + if (header == null) { + if (other.header != null) + return false; + } else if (!header.equals(other.header)) + return false; + if (headerCol != other.headerCol) + return false; + if (look == null) { + if (other.look != null) + return false; + } else if (!look.equals(other.look)) + return false; + return true; + } + + /** + * Adds the column on the right edge of the grid. Any cells which have been + * added to the grid prior to adding the column will be adjusted as follows: + * the right-hand cell of each completed row will have it's colspan expanded + * to fill the added column. + * + * @param column + * the column to add to the grid. + * @see GridColumn#parse(String) + */ + public void addColumn(String column) { + addColumn(columns.size(), GridColumn.parse(column)); + } + + /** + * Adds the column on the right edge of the grid. Any cells which have been + * added to the grid prior to adding the column will be adjusted as follows: + * the right-hand cell of each completed row will have it's colspan expanded + * to fill the added column. + * + * @param column + * the column to add to the grid. + */ + public void addColumn(GridColumn column) { + addColumn(columns.size(), column); + } + + /** + * Inserts the column at the specified position in the grid. Any cells which + * have been added to the grid prior to adding the column will be adjusted + * as follows: on each row, the cell which overlaps or whose right edge + * touches the insert position will be expanded to fill the added column. + * + * @param index + * the insert position. + * @param column + * the column to be inserted. + * @see GridColumn#parse(String) + */ + public void addColumn(int index, String column) { + addColumn(index, GridColumn.parse(column)); + } + + /** + * Inserts the column at the specified position in the grid. Any cells which + * have been added to the grid prior to adding the column will be adjusted + * as follows: on each row, the cell which overlaps or whose right edge + * touches the insert position will be expanded to fill the added column. + * + * @param index + * the insert position. + * @param column + * the column to be inserted. + */ + public void addColumn(int index, GridColumn column) { + checkColumnInsert(index); + Util.notNull(column); + + this.columns.add(index, column); + adjustForColumnInsert(index, 1); + } + + /** + * Adds the columns on the right edge of the grid. Any cells which have been + * added to the grid prior to adding the columns will be adjusted as + * follows: the right-hand cell of each completed row will have it's colspan + * expanded to fill the added columns. + * + * @param columns + * the columns to add to the grid. + * @see GridColumn#parse(String) + */ + public void addColumns(String columns) { + addColumns(this.columns.size(), parseColumns(columns)); + } + + /** + * Adds the columns on the right edge of the grid. Any cells which have been + * added to the grid prior to adding the columns will be adjusted as + * follows: the right-hand cell of each completed row will have it's colspan + * expanded to fill the added columns. + * + * @param columns + * the columns to add to the grid. + */ + public void addColumns(GridColumn[] columns) { + addColumns(this.columns.size(), columns); + } + + /** + * Inserts the columns at the specified position in the grid. Any cells + * which have been added to the grid prior to adding the columns will be + * adjusted as follows: on each row, the cell which overlaps or whose right + * edge touches the insert position will be expanded to fill the added + * columns. + * + * @param index + * the insert position. + * @param columns + * the columns to be inserted. + * @see GridColumn#parse(String) + */ + public void addColumns(int index, String columns) { + addColumns(index, parseColumns(columns)); + } + + /** + * Inserts the columns at the specified position in the grid. Any cells + * which have been added to the grid prior to adding the columns will be + * adjusted as follows: on each row, the cell which overlaps or whose right + * edge touches the insert position will be expanded to fill the added + * columns. + * + * @param index + * the insert position. + * @param columns + * the columns to be inserted. + * @see GridColumn#parse(String) + */ + public void addColumns(int index, GridColumn[] columns) { + checkColumnInsert(index); + Util.noNulls(columns); + + this.columns.addAll(index, Arrays.asList(columns)); + + adjustForColumnInsert(index, columns.length); + } + + private void checkColumnInsert(int index) { + if (index < 0 || index > this.columns.size()) + PaperClips.error(SWT.ERROR_INVALID_RANGE, + "index = " + index + ", size = " + this.columns.size()); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private void adjustForColumnInsert(int index, int count) { + adjustCellsForColumnInsert(header, index, count); + adjustCellsForColumnInsert(body, index, count); + adjustCellsForColumnInsert(footer, index, count); + + adjustColumnGroupsForColumnInsert(index, count); + + if (bodyCol > index) + bodyCol += count; + if (headerCol > index) + headerCol += count; + if (footerCol > index) + footerCol += count; + } + + private void adjustCellsForColumnInsert(List> rows, + int index, int count) { + for (int rowI = 0; rowI < rows.size(); rowI++) { + List row = rows.get(rowI); + int col = 0; + for (int cellI = 0; cellI < row.size(); cellI++) { + GridCell cell = row.get(cellI); + col += cell.getColSpan(); + + // Adjust the cell which extends through the insert point, or + // whose right side touches the insert + // point. Except on the last row, don't adjust the final cell if + // it only touches the insert point + // (the user may be adding columns right before s/he adds column + // headers). + if ( // cell overlaps insert point, or + (col > index) || + // right side touches insert point but is not the final cell. + (col == index && (rowI + 1 < rows.size() + || cellI + 1 < row.size()))) { + row.set(cellI, + new GridCellImpl(cell.getHorizontalAlignment(), + cell.getVerticalAlignment(), + cell.getContent(), + cell.getColSpan() + count)); + break; + } + } + } + } + + private void adjustColumnGroupsForColumnInsert(int index, int count) { + for (int groupI = 0; groupI < columnGroups.length; groupI++) { + int[] group = columnGroups[groupI]; + for (int i = 0; i < group.length; i++) + if (group[i] >= index) + group[i] += count; + } + } + + /** + * Separates the comma-separated argument and parses each piece to obtain an + * array of GridColumns. + * + * @param columns + * the comma-separated list of column specs. + * @return GridColumn array with the requested columns. + */ + private static GridColumn[] parseColumns(String columns) { + Util.notNull(columns); + String[] cols = columns.split("\\s*,\\s*"); //$NON-NLS-1$ + + GridColumn[] result = new GridColumn[cols.length]; + for (int i = 0; i < cols.length; i++) + result[i] = GridColumn.parse(cols[i]); + + return result; + } + + /** + * Returns an array of GridColumns which are the columns in the + * receiver. + * + * @return an array of GridColumns which are the columns in the + * receiver. + */ + public GridColumn[] getColumns() { + return columns.toArray(new GridColumn[columns.size()]); + } + + /** + * Adds the Print to the grid header, with default alignment and a colspan + * of 1. + * + * @param cell + * the print to add. + */ + public void addHeader(Print cell) { + headerCol = add(header, headerCol, SWT.DEFAULT, SWT.DEFAULT, cell, 1); + } + + /** + * Adds the Print to the grid header, using the given alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param cell + * the print to add. + */ + public void addHeader(int hAlignment, Print cell) { + headerCol = add(header, headerCol, hAlignment, SWT.DEFAULT, cell, 1); + } + + /** + * Adds the Print to the grid header, using the given alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param vAlignment + * the vertical alignment of the print within the grid cell. One + * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, + * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL + * indicates that the cell is vertically greedy, so GridPrint + * will limit the cell's height to the tallest non-FILL cell in + * the row. + * @param cell + * the print to add. + */ + public void addHeader(int hAlignment, int vAlignment, Print cell) { + headerCol = add(header, headerCol, hAlignment, vAlignment, cell, 1); + } + + /** + * Adds the Print to the grid header, with the given colspan and the default + * alignment. + * + * @param cell + * the print to add. + * @param colspan + * the number of columns to span, or {@link GridPrint#REMAINDER} + * to span the rest of the row. + */ + public void addHeader(Print cell, int colspan) { + headerCol = add(header, headerCol, SWT.DEFAULT, SWT.DEFAULT, cell, + colspan); + } + + /** + * Adds the Print to the grid header, using the given colspan and alignment. + * + * @param cell + * the print to add. + * @param colspan + * the number of columns to span, or {@link GridPrint#REMAINDER} + * to span the rest of the row. + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + */ + public void addHeader(int hAlignment, Print cell, int colspan) { + headerCol = add(header, headerCol, hAlignment, SWT.DEFAULT, cell, + colspan); + } + + /** + * Adds the Print to the grid header, using the given colspan and alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param vAlignment + * the vertical alignment of the print within the grid cell. One + * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, + * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL + * indicates that the cell is vertically greedy, so GridPrint + * will limit the cell's height to the tallest non-FILL cell in + * the row. + * @param cell + * the print to add. + * @param colspan + * the number of columns to span, or {@link GridPrint#REMAINDER} + * to span the rest of the row. + */ + public void addHeader(int hAlignment, int vAlignment, Print cell, + int colspan) { + headerCol = add(header, headerCol, hAlignment, vAlignment, cell, + colspan); + } + + /** + * Returns an array containing the header cells in this grid. Each inner + * array represents one row in the header. + * + * @return an array containing the header cells in this grid. + */ + public GridCell[][] getHeaderCells() { + return getGridCellArray(header); + } + + /** + * Returns an array containing the body cells in the grid. Each inner array + * represents one row in the body. + * + * @return an array containing the body cells in the grid. + */ + public GridCell[][] getBodyCells() { + return getGridCellArray(body); + } + + /** + * Returns an array containing the footer cells in the grid. Each inner + * array represents one row in the footer. + * + * @return an array containing the footer cells in the grid. + */ + public GridCell[][] getFooterCells() { + return getGridCellArray(footer); + } + + private static GridCell[][] getGridCellArray(List> list) { + GridCell[][] cells = new GridCell[list.size()][]; + for (int rowIndex = 0; rowIndex < cells.length; rowIndex++) { + List row = list.get(rowIndex); + GridCell[] rowCells = new GridCell[row.size()]; + for (int cellIndex = 0; cellIndex < rowCells.length; cellIndex++) + rowCells[cellIndex] = row.get(cellIndex); + cells[rowIndex] = rowCells; + } + return cells; + } + + /** + * Adds the Print to the grid body, with the default alignment and a colspan + * of 1. + * + * @param cell + * the print to add. + */ + public void add(Print cell) { + bodyCol = add(body, bodyCol, SWT.DEFAULT, SWT.DEFAULT, cell, 1); + } + + /** + * Adds the Print to the grid body, using the given colspan and alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param cell + * the print to add. + */ + public void add(int hAlignment, Print cell) { + bodyCol = add(body, bodyCol, hAlignment, SWT.DEFAULT, cell, 1); + } + + /** + * Adds the Print to the grid body, using the given colspan and alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param vAlignment + * the vertical alignment of the print within the grid cell. One + * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, + * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL + * indicates that the cell is vertically greedy, so GridPrint + * will limit the cell's height to the tallest non-FILL cell in + * the row. + * @param cell + * the print to add. + */ + public void add(int hAlignment, int vAlignment, Print cell) { + bodyCol = add(body, bodyCol, hAlignment, vAlignment, cell, 1); + } + + /** + * Adds the Print to the grid body, with the given colspan and the default + * alignment. + * + * @param cell + * the print to add. + * @param colspan + * the number of columns to span, or {@link GridPrint#REMAINDER} + * to span the rest of the row. + */ + public void add(Print cell, int colspan) { + bodyCol = add(body, bodyCol, SWT.DEFAULT, SWT.DEFAULT, cell, colspan); + } + + /** + * Adds the Print to the grid body, using the given colspan and alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param cell + * the print to add. + * @param colspan + * the number of columns to span, or {@link GridPrint#REMAINDER} + * to span the rest of the row. + */ + public void add(int hAlignment, Print cell, int colspan) { + bodyCol = add(body, bodyCol, hAlignment, SWT.DEFAULT, cell, colspan); + } + + /** + * Adds the Print to the grid body, using the given colspan and alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param vAlignment + * the vertical alignment of the print within the grid cell. One + * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, + * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL + * indicates that the cell is vertically greedy, so GridPrint + * will limit the cell's height to the tallest non-FILL cell in + * the row. + * @param cell + * the print to add. + * @param colspan + * the number of columns to span, or {@link GridPrint#REMAINDER} + * to span the rest of the row. + */ + public void add(int hAlignment, int vAlignment, Print cell, int colspan) { + bodyCol = add(body, bodyCol, hAlignment, vAlignment, cell, colspan); + } + + /** + * Returns whether individual body cells in the grid may be broken across + * pages. Defaults to true. + * + * @return whether individual body cells in the grid may be broken across + * pages. + */ + public boolean isCellClippingEnabled() { + return cellClippingEnabled; + } + + /** + * Sets whether individual body cells in the grid may be broken across + * pages. + * + * @param cellClippingEnabled + * whether to enabled cell clipping. + */ + public void setCellClippingEnabled(boolean cellClippingEnabled) { + this.cellClippingEnabled = cellClippingEnabled; + } + + /** + * Adds the Print to the grid footer, with the default alignment and a + * colspan of 1. + * + * @param cell + * the print to add. + */ + public void addFooter(Print cell) { + footerCol = add(footer, footerCol, SWT.DEFAULT, SWT.DEFAULT, cell, 1); + } + + /** + * Adds the Print to the grid footer, using the given colspan and alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param cell + * the print to add. + */ + public void addFooter(int hAlignment, Print cell) { + footerCol = add(footer, footerCol, hAlignment, SWT.DEFAULT, cell, 1); + } + + /** + * Adds the Print to the grid footer, using the given colspan and alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param vAlignment + * the vertical alignment of the print within the grid cell. One + * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, + * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL + * indicates that the cell is vertically greedy, so GridPrint + * will limit the cell's height to the tallest non-FILL cell in + * the row. + * @param cell + * the print to add. + */ + public void addFooter(int hAlignment, int vAlignment, Print cell) { + footerCol = add(footer, footerCol, hAlignment, vAlignment, cell, 1); + } + + /** + * Adds the Print to the grid footer, with the given colspan and the default + * alignment. + * + * @param cell + * the print to add. + * @param colspan + * the number of columns to span, or {@link GridPrint#REMAINDER} + * to span the rest of the row. + */ + public void addFooter(Print cell, int colspan) { + footerCol = add(footer, footerCol, SWT.DEFAULT, SWT.DEFAULT, cell, + colspan); + } + + /** + * Adds the Print to the grid footer, using the given colspan and alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param cell + * the print to add. + * @param colspan + * the number of columns to span, or {@link GridPrint#REMAINDER} + * to span the rest of the row. + */ + public void addFooter(int hAlignment, Print cell, int colspan) { + footerCol = add(footer, footerCol, hAlignment, SWT.DEFAULT, cell, + colspan); + } + + /** + * Adds the Print to the grid footer, using the given colspan and alignment. + * + * @param hAlignment + * the horizontal alignment of the print within the grid cell. + * One of {@link SWT#DEFAULT} , {@link SWT#LEFT}, + * {@link SWT#CENTER} or {@link SWT#RIGHT}. + * @param vAlignment + * the vertical alignment of the print within the grid cell. One + * of {@link SWT#DEFAULT}, {@link SWT#TOP}, {@link SWT#CENTER}, + * {@link SWT#BOTTOM}, or {@link SWT#FILL}. A value of FILL + * indicates that the cell is vertically greedy, so GridPrint + * will limit the cell's height to the tallest non-FILL cell in + * the row. + * @param cell + * the print to add. + * @param colspan + * the number of columns to span, or {@link GridPrint#REMAINDER} + * to span the rest of the row. + */ + public void addFooter(int hAlignment, int vAlignment, Print cell, + int colspan) { + footerCol = add(footer, footerCol, hAlignment, vAlignment, cell, + colspan); + } + + /* + * Returns the column number that we've advanced to, after adding the new + * cell. + */ + private int add(List> rows, // List of List of GridCell + int startColumn, int hAlignment, int vAlignment, Print cellContents, + int colspan) { + startColumn = startNewRowIfCurrentRowFull(startColumn); + checkColumnSpan(startColumn, colspan); + List row = getOpenRow(rows, startColumn); + colspan = convertRemainderToExplicitColSpan(startColumn, colspan); + + GridCell cell = new GridCellImpl(hAlignment, vAlignment, cellContents, + colspan); + row.add(cell); + startColumn += colspan; + + // Make sure column number is valid. + if (startColumn > columns.size()) { + // THIS SHOULD NOT HAPPEN--ABOVE LOGIC SHOULD PREVENT THIS CASE + // ..but just in case. + + row.remove(row.size() - 1); + if (row.size() == 0) + rows.remove(row); + + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Colspan " + colspan //$NON-NLS-1$ + + " too wide at column " + startColumn + " (" //$NON-NLS-1$ //$NON-NLS-2$ + + columns.size() + " columns total)"); //$NON-NLS-1$ + } + + return startColumn; + } + + private int convertRemainderToExplicitColSpan(int startColumn, + int colspan) { + if (colspan == REMAINDER) + colspan = columns.size() - startColumn; + return colspan; + } + + private int startNewRowIfCurrentRowFull(int startColumn) { + // If we're at the end of a row, start a new row. + if (startColumn == columns.size()) + startColumn = 0; + return startColumn; + } + + private void checkColumnSpan(int startColumn, int colspan) { + if (startColumn + colspan > columns.size()) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Colspan " + colspan //$NON-NLS-1$ + + " too wide at column " + startColumn + " (" //$NON-NLS-1$ //$NON-NLS-2$ + + columns.size() + " columns total)"); //$NON-NLS-1$ + } + + private List getOpenRow(List> rows, + int startColumn) { + List row; // the row we will add the cell to. + if (startColumn == 0) + // Start a new row if back at column 0. + rows.add(row = new ArrayList<>(columns.size())); + else + // Get the incomplete row. + row = rows.get(rows.size() - 1); // List of GridCell + return row; + } + + /** + * Returns current column groups. The returned array may be modified without + * affecting this GridPrint. + * + * @return the column groups. + */ + public int[][] getColumnGroups() { + return PaperClipsUtil.copy(columnGroups); + } + + /** + * Sets the column groups to the given two-dimension array. Each int[] array + * is a group. Columns in a group will be the same size when laid out on the + * print device. + *

+ * The following statement causes columns 0 and 2 to be the same size, and + * columns 1 and 3 to be the same size. + * + *

+	 * grid.setColumnGroups(new int[][] { { 0, 2 }, { 1, 3 } });
+	 * 
+ * + *

+ * The behavior of this property is undefined when a column belongs to more + * than one group. + *

+ * Note: Column grouping is enforced before column weights. + * Therefore, columns in the same group should be given the same weight to + * ensure they are laid out at the same width. + * + * @param columnGroups + * the new column groups. + */ + public void setColumnGroups(int[][] columnGroups) { + checkColumnGroups(columnGroups); + this.columnGroups = PaperClipsUtil.copy(columnGroups); + } + + private void checkColumnGroups(int[][] columnGroups) { + Util.notNull(columnGroups); + for (int groupIndex = 0; groupIndex < columnGroups.length; groupIndex++) + checkColumnGroup(columnGroups[groupIndex]); + } + + private void checkColumnGroup(int[] columnGroup) { + Util.notNull(columnGroup); + for (int columnInGroupIndex = 0; columnInGroupIndex < columnGroup.length; columnInGroupIndex++) + checkColumnIndex(columnGroup[columnInGroupIndex]); + } + + private void checkColumnIndex(int columnIndex) { + if (columnIndex < 0 || columnIndex >= columns.size()) + PaperClips.error(SWT.ERROR_INVALID_RANGE, + "Column index in column group must be " + "0 <= " //$NON-NLS-1$ //$NON-NLS-2$ + + columnIndex + " < " + columns.size()); //$NON-NLS-1$ + } + + /** + * Returns the grid's look. A GridLook determines what decorations will + * appear around the grid's contents. Default is a DefaultGridLook with no + * cell spacing, no cell borders, and no background colors. + * + * @return the look of this grid. + */ + public GridLook getLook() { + return look; + } + + /** + * Sets the grid's look. + * + * @param look + * the new look. + */ + public void setLook(GridLook look) { + Util.notNull(look); + this.look = look; + } + + public PrintIterator iterator(Device device, GC gc) { + return new GridIterator(this, device, gc); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/DefaultGridLookPainter.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/DefaultGridLookPainter.java index a98c42621..545f66a12 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/DefaultGridLookPainter.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/DefaultGridLookPainter.java @@ -1,144 +1,144 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ - -package org.eclipse.nebula.paperclips.core.grid.internal; - -import org.eclipse.nebula.paperclips.core.border.BorderPainter; -import org.eclipse.nebula.paperclips.core.grid.BasicGridLookPainter; -import org.eclipse.nebula.paperclips.core.grid.CellBackgroundProvider; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridMargins; -import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; - -public class DefaultGridLookPainter extends BasicGridLookPainter { - private final Rectangle cellPadding; - - private final BorderPainter border; - - private final CellBackgroundProvider headerBackground; - private final CellBackgroundProvider bodyBackground; - private final CellBackgroundProvider footerBackground; - - private final GridMargins margins; - - private final ResourcePool resources; - - public DefaultGridLookPainter(DefaultGridLook look, Device device, GC gc) { - super(device); - - Point dpi = device.getDPI(); - - this.border = look.getCellBorder().createPainter(device, gc); - this.cellPadding = calculateCellPadding(look, dpi); - this.margins = calculateGridMargins(look, dpi); - - this.bodyBackground = look.getBodyBackgroundProvider(); - this.headerBackground = look.getHeaderBackgroundProvider(); - this.footerBackground = look.getFooterBackgroundProvider(); - - this.resources = ResourcePool.forDevice(device); - } - - private Rectangle calculateCellPadding(DefaultGridLook look, Point dpi) { - Rectangle cellPadding = new Rectangle(look.getCellPadding().x * dpi.x - / 72, look.getCellPadding().y * dpi.y / 72, - look.getCellPadding().width * dpi.x / 72, - look.getCellPadding().height * dpi.y / 72); - return cellPadding; - } - - private GridMargins calculateGridMargins(DefaultGridLook look, Point dpi) { - final Point cellSpacing = new Point( - border.getWidth() - + (look.getCellSpacing().x == DefaultGridLook.BORDER_OVERLAP ? -border.getOverlap().x - : dpi.x * look.getCellSpacing().x / 72), - border.getHeight(false, false) - + (look.getCellSpacing().y == DefaultGridLook.BORDER_OVERLAP ? -border - .getOverlap().y : dpi.y - * look.getCellSpacing().y / 72)); - - final int headerClosedSpacing = border.getHeight(false, false) - + (look.getHeaderGap() == DefaultGridLook.BORDER_OVERLAP ? -border - .getOverlap().y : dpi.y * look.getHeaderGap() / 72); - final int headerOpenSpacing = border.getHeight(true, false) - + (look.getHeaderGap() == DefaultGridLook.BORDER_OVERLAP ? dpi.y / 72 - : dpi.y * look.getHeaderGap() / 72); - final int footerClosedSpacing = border.getHeight(false, false) - + (look.getFooterGap() == DefaultGridLook.BORDER_OVERLAP ? -border - .getOverlap().y : dpi.y * look.getFooterGap() / 72); - final int footerOpenSpacing = border.getHeight(false, true) - + (look.getFooterGap() == DefaultGridLook.BORDER_OVERLAP ? dpi.y / 72 - : dpi.y * look.getFooterGap() / 72); - - return new DefaultGridMargins(border, cellSpacing, cellPadding, - headerClosedSpacing, headerOpenSpacing, footerClosedSpacing, - footerOpenSpacing); - } - - public GridMargins getMargins() { - return margins; - } - - protected void paintHeaderCell(GC gc, Rectangle bounds, int row, int col, - int colspan) { - RGB background = headerBackground.getCellBackground(row, col, colspan); - paintCell(gc, background, bounds, false, false); - } - - protected void paintBodyCell(GC gc, Rectangle bounds, int row, int col, - int colspan, boolean topOpen, boolean bottomOpen) { - RGB background = bodyBackground.getCellBackground(row, col, colspan); - paintCell(gc, background, bounds, topOpen, bottomOpen); - } - - protected void paintFooterCell(GC gc, Rectangle bounds, int row, int col, - int colspan) { - RGB background = footerBackground.getCellBackground(row, col, colspan); - paintCell(gc, background, bounds, false, false); - } - - private void paintCell(GC gc, RGB background, Rectangle bounds, - boolean topOpen, boolean bottomOpen) { - // Compute effective cell rectangle - int x = bounds.x - border.getLeft() - cellPadding.x; - int y = bounds.y - border.getTop(topOpen) - - (topOpen ? 0 : cellPadding.y); - int width = bounds.width + border.getWidth() + cellPadding.x - + cellPadding.width; - int height = bounds.height + border.getHeight(topOpen, bottomOpen) - + (bottomOpen ? 0 : cellPadding.y + cellPadding.height); - - // Paint background - Color backgroundColor = resources.getColor(background); - if (backgroundColor != null) { - Color oldBackground = gc.getBackground(); - gc.setBackground(backgroundColor); - gc.fillRectangle(x, y, width, height); - gc.setBackground(oldBackground); - } - - // Paint border - border.paint(gc, x, y, width, height, topOpen, bottomOpen); - } - - public void dispose() { - border.dispose(); - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ + +package org.eclipse.nebula.paperclips.core.grid.internal; + +import org.eclipse.nebula.paperclips.core.border.BorderPainter; +import org.eclipse.nebula.paperclips.core.grid.BasicGridLookPainter; +import org.eclipse.nebula.paperclips.core.grid.CellBackgroundProvider; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridMargins; +import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; + +public class DefaultGridLookPainter extends BasicGridLookPainter { + private final Rectangle cellPadding; + + private final BorderPainter border; + + private final CellBackgroundProvider headerBackground; + private final CellBackgroundProvider bodyBackground; + private final CellBackgroundProvider footerBackground; + + private final GridMargins margins; + + private final ResourcePool resources; + + public DefaultGridLookPainter(DefaultGridLook look, Device device, GC gc) { + super(device); + + Point dpi = device.getDPI(); + + this.border = look.getCellBorder().createPainter(device, gc); + this.cellPadding = calculateCellPadding(look, dpi); + this.margins = calculateGridMargins(look, dpi); + + this.bodyBackground = look.getBodyBackgroundProvider(); + this.headerBackground = look.getHeaderBackgroundProvider(); + this.footerBackground = look.getFooterBackgroundProvider(); + + this.resources = ResourcePool.forDevice(device); + } + + private Rectangle calculateCellPadding(DefaultGridLook look, Point dpi) { + Rectangle cellPadding = new Rectangle(look.getCellPadding().x * dpi.x + / 72, look.getCellPadding().y * dpi.y / 72, + look.getCellPadding().width * dpi.x / 72, + look.getCellPadding().height * dpi.y / 72); + return cellPadding; + } + + private GridMargins calculateGridMargins(DefaultGridLook look, Point dpi) { + final Point cellSpacing = new Point( + border.getWidth() + + (look.getCellSpacing().x == DefaultGridLook.BORDER_OVERLAP ? -border.getOverlap().x + : dpi.x * look.getCellSpacing().x / 72), + border.getHeight(false, false) + + (look.getCellSpacing().y == DefaultGridLook.BORDER_OVERLAP ? -border + .getOverlap().y : dpi.y + * look.getCellSpacing().y / 72)); + + final int headerClosedSpacing = border.getHeight(false, false) + + (look.getHeaderGap() == DefaultGridLook.BORDER_OVERLAP ? -border + .getOverlap().y : dpi.y * look.getHeaderGap() / 72); + final int headerOpenSpacing = border.getHeight(true, false) + + (look.getHeaderGap() == DefaultGridLook.BORDER_OVERLAP ? dpi.y / 72 + : dpi.y * look.getHeaderGap() / 72); + final int footerClosedSpacing = border.getHeight(false, false) + + (look.getFooterGap() == DefaultGridLook.BORDER_OVERLAP ? -border + .getOverlap().y : dpi.y * look.getFooterGap() / 72); + final int footerOpenSpacing = border.getHeight(false, true) + + (look.getFooterGap() == DefaultGridLook.BORDER_OVERLAP ? dpi.y / 72 + : dpi.y * look.getFooterGap() / 72); + + return new DefaultGridMargins(border, cellSpacing, cellPadding, + headerClosedSpacing, headerOpenSpacing, footerClosedSpacing, + footerOpenSpacing); + } + + public GridMargins getMargins() { + return margins; + } + + protected void paintHeaderCell(GC gc, Rectangle bounds, int row, int col, + int colspan) { + RGB background = headerBackground.getCellBackground(row, col, colspan); + paintCell(gc, background, bounds, false, false); + } + + protected void paintBodyCell(GC gc, Rectangle bounds, int row, int col, + int colspan, boolean topOpen, boolean bottomOpen) { + RGB background = bodyBackground.getCellBackground(row, col, colspan); + paintCell(gc, background, bounds, topOpen, bottomOpen); + } + + protected void paintFooterCell(GC gc, Rectangle bounds, int row, int col, + int colspan) { + RGB background = footerBackground.getCellBackground(row, col, colspan); + paintCell(gc, background, bounds, false, false); + } + + private void paintCell(GC gc, RGB background, Rectangle bounds, + boolean topOpen, boolean bottomOpen) { + // Compute effective cell rectangle + int x = bounds.x - border.getLeft() - cellPadding.x; + int y = bounds.y - border.getTop(topOpen) + - (topOpen ? 0 : cellPadding.y); + int width = bounds.width + border.getWidth() + cellPadding.x + + cellPadding.width; + int height = bounds.height + border.getHeight(topOpen, bottomOpen) + + (bottomOpen ? 0 : cellPadding.y + cellPadding.height); + + // Paint background + Color backgroundColor = resources.getColor(background); + if (backgroundColor != null) { + Color oldBackground = gc.getBackground(); + gc.setBackground(backgroundColor); + gc.fillRectangle(x, y, width, height); + gc.setBackground(oldBackground); + } + + // Paint border + border.paint(gc, x, y, width, height, topOpen, bottomOpen); + } + + public void dispose() { + border.dispose(); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/DefaultGridMargins.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/DefaultGridMargins.java index 9d18057c2..2215ee620 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/DefaultGridMargins.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/DefaultGridMargins.java @@ -1,89 +1,89 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ - -package org.eclipse.nebula.paperclips.core.grid.internal; - -import org.eclipse.nebula.paperclips.core.border.BorderPainter; -import org.eclipse.nebula.paperclips.core.grid.GridMargins; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; - -class DefaultGridMargins implements GridMargins { - private final BorderPainter border; - private final Point cellSpacing; - private final Rectangle cellPadding; - private final int headerClosedSpacing; - private final int headerOpenSpacing; - private final int footerClosedSpacing; - private final int footerOpenSpacing; - - DefaultGridMargins(BorderPainter border, Point cellSpacing, - Rectangle cellPadding, int headerClosedSpacing, - int headerOpenSpacing, int footerClosedSpacing, - int footerOpenSpacing) { - this.border = border; - this.cellSpacing = cellSpacing; - this.cellPadding = cellPadding; - this.headerClosedSpacing = headerClosedSpacing; - this.headerOpenSpacing = headerOpenSpacing; - this.footerClosedSpacing = footerClosedSpacing; - this.footerOpenSpacing = footerOpenSpacing; - } - - public int getLeft() { - return border.getLeft() + cellPadding.x; - } - - public int getHorizontalSpacing() { - return cellSpacing.x + cellPadding.x + cellPadding.width; - } - - public int getRight() { - return border.getRight() + cellPadding.width; - } - - public int getHeaderTop() { - return border.getTop(false) + cellPadding.y; - } - - public int getHeaderVerticalSpacing() { - return cellSpacing.y + cellPadding.y + cellPadding.height; - } - - public int getBodyTop(boolean headerPresent, boolean open) { - return headerPresent ? open ? headerOpenSpacing : headerClosedSpacing - + cellPadding.y : open ? border.getTop(true) : border - .getTop(false) - + cellPadding.y; - } - - public int getBodyVerticalSpacing() { - return cellSpacing.y + cellPadding.y + cellPadding.height; - } - - public int getBodyBottom(boolean footerPresent, boolean open) { - return footerPresent ? open ? footerOpenSpacing : footerClosedSpacing - + cellPadding.height : open ? border.getBottom(true) : border - .getBottom(false) - + cellPadding.height; - } - - public int getFooterVerticalSpacing() { - return cellSpacing.y + cellPadding.y + cellPadding.height; - } - - public int getFooterBottom() { - return border.getBottom(false) + cellPadding.height; - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ + +package org.eclipse.nebula.paperclips.core.grid.internal; + +import org.eclipse.nebula.paperclips.core.border.BorderPainter; +import org.eclipse.nebula.paperclips.core.grid.GridMargins; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; + +class DefaultGridMargins implements GridMargins { + private final BorderPainter border; + private final Point cellSpacing; + private final Rectangle cellPadding; + private final int headerClosedSpacing; + private final int headerOpenSpacing; + private final int footerClosedSpacing; + private final int footerOpenSpacing; + + DefaultGridMargins(BorderPainter border, Point cellSpacing, + Rectangle cellPadding, int headerClosedSpacing, + int headerOpenSpacing, int footerClosedSpacing, + int footerOpenSpacing) { + this.border = border; + this.cellSpacing = cellSpacing; + this.cellPadding = cellPadding; + this.headerClosedSpacing = headerClosedSpacing; + this.headerOpenSpacing = headerOpenSpacing; + this.footerClosedSpacing = footerClosedSpacing; + this.footerOpenSpacing = footerOpenSpacing; + } + + public int getLeft() { + return border.getLeft() + cellPadding.x; + } + + public int getHorizontalSpacing() { + return cellSpacing.x + cellPadding.x + cellPadding.width; + } + + public int getRight() { + return border.getRight() + cellPadding.width; + } + + public int getHeaderTop() { + return border.getTop(false) + cellPadding.y; + } + + public int getHeaderVerticalSpacing() { + return cellSpacing.y + cellPadding.y + cellPadding.height; + } + + public int getBodyTop(boolean headerPresent, boolean open) { + return headerPresent ? open ? headerOpenSpacing : headerClosedSpacing + + cellPadding.y : open ? border.getTop(true) : border + .getTop(false) + + cellPadding.y; + } + + public int getBodyVerticalSpacing() { + return cellSpacing.y + cellPadding.y + cellPadding.height; + } + + public int getBodyBottom(boolean footerPresent, boolean open) { + return footerPresent ? open ? footerOpenSpacing : footerClosedSpacing + + cellPadding.height : open ? border.getBottom(true) : border + .getBottom(false) + + cellPadding.height; + } + + public int getFooterVerticalSpacing() { + return cellSpacing.y + cellPadding.y + cellPadding.height; + } + + public int getFooterBottom() { + return border.getBottom(false) + cellPadding.height; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridCellIterator.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridCellIterator.java index e342386b9..b0a7ef422 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridCellIterator.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridCellIterator.java @@ -1,60 +1,60 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid.internal; - -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.grid.GridCell; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -public class GridCellIterator { - final int hAlignment; - final int vAlignment; - final PrintIterator target; - final int colspan; - - public GridCellIterator(GridCell cell, Device device, GC gc) { - this.hAlignment = cell.getHorizontalAlignment(); - this.vAlignment = cell.getVerticalAlignment(); - this.target = cell.getContent().iterator(device, gc); - this.colspan = cell.getColSpan(); - } - - private GridCellIterator(GridCellIterator that) { - this.hAlignment = that.hAlignment; - this.vAlignment = that.vAlignment; - this.target = that.target.copy(); - this.colspan = that.colspan; - } - - public int getHorizontalAlignment() { - return hAlignment; - } - - public int getVerticalAlignment() { - return vAlignment; - } - - public PrintIterator getTarget() { - return target; - } - - public int getColspan() { - return colspan; - } - - public GridCellIterator copy() { - return new GridCellIterator(this); - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid.internal; + +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.grid.GridCell; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +public class GridCellIterator { + final int hAlignment; + final int vAlignment; + final PrintIterator target; + final int colspan; + + public GridCellIterator(GridCell cell, Device device, GC gc) { + this.hAlignment = cell.getHorizontalAlignment(); + this.vAlignment = cell.getVerticalAlignment(); + this.target = cell.getContent().iterator(device, gc); + this.colspan = cell.getColSpan(); + } + + private GridCellIterator(GridCellIterator that) { + this.hAlignment = that.hAlignment; + this.vAlignment = that.vAlignment; + this.target = that.target.copy(); + this.colspan = that.colspan; + } + + public int getHorizontalAlignment() { + return hAlignment; + } + + public int getVerticalAlignment() { + return vAlignment; + } + + public PrintIterator getTarget() { + return target; + } + + public int getColspan() { + return colspan; + } + + public GridCellIterator copy() { + return new GridCellIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridIterator.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridIterator.java index 2f2ec5952..5457c0094 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridIterator.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridIterator.java @@ -1,1059 +1,1059 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid.internal; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.CompositeEntry; -import org.eclipse.nebula.paperclips.core.CompositePiece; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.grid.GridCell; -import org.eclipse.nebula.paperclips.core.grid.GridColumn; -import org.eclipse.nebula.paperclips.core.grid.GridLookPainter; -import org.eclipse.nebula.paperclips.core.grid.GridMargins; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * Iterator for Grid - */ -public class GridIterator implements PrintIterator { - final Device device; - final Point dpi; - - final GridColumn[] columns; - final int[][] columnGroups; - - final GridLookPainter look; - - final GridCellIterator[][] header; - final GridCellIterator[][] body; - final GridCellIterator[][] footer; - - final boolean cellClippingEnabled; - - final int[] minimumColSizes; // PIXELS - final int[] preferredColSizes; // PIXELS - - final Point minimumSize; // PIXELS - final Point preferredSize; // PIXELS - - // This is the cursor! - private int row; - - // Determines whether top edge of cell border is drawn open or closed for - // current row. - private boolean rowStarted; - - /** - * @param grid - * @param device - * @param gc - */ - public GridIterator(GridPrint grid, Device device, GC gc) { - this.device = device; - this.dpi = device.getDPI(); - this.columns = new GridColumn[grid.getColumns().length]; - System.arraycopy(grid.getColumns(), 0, this.columns, 0, - grid.getColumns().length); - this.columnGroups = grid.getColumnGroups(); - - this.header = createGridCellIterators(grid.getHeaderCells(), device, - gc); - this.body = createGridCellIterators(grid.getBodyCells(), device, gc); - this.footer = createGridCellIterators(grid.getFooterCells(), device, - gc); - - this.cellClippingEnabled = grid.isCellClippingEnabled(); - - this.look = grid.getLook().getPainter(device, gc); - - this.minimumColSizes = computeColumnSizes(PrintSizeStrategy.MINIMUM); - this.preferredColSizes = computeColumnSizes( - PrintSizeStrategy.PREFERRED); - - this.minimumSize = computeSize(PrintSizeStrategy.MINIMUM, - minimumColSizes); - this.preferredSize = computeSize(PrintSizeStrategy.PREFERRED, - preferredColSizes); - - row = 0; - rowStarted = false; - } - - private static GridCellIterator[][] createGridCellIterators( - GridCell[][] gridCells, Device device, GC gc) { - GridCellIterator[][] result = new GridCellIterator[gridCells.length][]; - for (int rowIndex = 0; rowIndex < result.length; rowIndex++) - result[rowIndex] = createRowCellIterators(gridCells[rowIndex], - device, gc); - return result; - } - - private static GridCellIterator[] createRowCellIterators( - GridCell[] rowCells, Device device, GC gc) { - GridCellIterator[] result = new GridCellIterator[rowCells.length]; - for (int cellIndex = 0; cellIndex < rowCells.length; cellIndex++) - result[cellIndex] = ((GridCellImpl) rowCells[cellIndex]) - .iterator(device, gc); - return result; - } - - /** Copy constructor (used by copy() only) */ - private GridIterator(GridIterator that) { - this.device = that.device; - this.dpi = that.dpi; - - this.columns = that.columns; - this.columnGroups = that.columnGroups; - - this.header = that.header; // never directly modified, clone not - // necessary - this.body = cloneRows(that.body, that.row); // Only need to deep copy - // the unconsumed rows. - this.footer = that.footer; // never directly modified, clone not - // necessary - - this.cellClippingEnabled = that.cellClippingEnabled; - - this.look = that.look; - - this.minimumColSizes = that.minimumColSizes; - this.preferredColSizes = that.preferredColSizes; - - this.minimumSize = that.minimumSize; - this.preferredSize = that.preferredSize; - - this.row = that.row; - this.rowStarted = that.rowStarted; - } - - private static GridCellIterator[][] cloneRows(GridCellIterator[][] rows, - int firstRow) { - GridCellIterator[][] result = rows.clone(); - // Cloning the outer array is all that's necessary. The inner arrays - // (rows) are cloned every time a row - // is laid out, so all we have to do is make sure different - // GridIterators have distinct outer arrays. - // for ( int i = firstRow; i < result.length; i++ ) - // result[i] = cloneRow( result[i] ); - return result; - } - - /** - * Compute the size of a column, respecting the constraints of the - * GridColumn. - */ - private int computeCellWidth(GridCellIterator entry, GridColumn col, - PrintSizeStrategy strategy) { - if (col.size == SWT.DEFAULT) - return strategy.computeSize(entry.getTarget()).x; - if (col.size == GridPrint.PREFERRED) - return entry.getTarget().preferredSize().x; - return Math.round(col.size * device.getDPI().x / 72f); - } - - private static boolean isExplicitSize(GridColumn col) { - return col.size > 0; - } - - private void applyColumnGrouping(int[] columnSizes) { - for (int groupIndex = 0; groupIndex < columnGroups.length; groupIndex++) { - int[] group = columnGroups[groupIndex]; - - // find max column width in group - int maxSize = 0; - for (int columnInGroupIndex = 0; columnInGroupIndex < group.length; columnInGroupIndex++) { - int col = group[columnInGroupIndex]; - maxSize = Math.max(maxSize, columnSizes[col]); - } - - // grow all columns to max column width - for (int columnInGroupIndex = 0; columnInGroupIndex < group.length; columnInGroupIndex++) { - int col = group[columnInGroupIndex]; - columnSizes[col] = maxSize; - } - } - } - - private boolean isColumnGrouped(int col) { - for (int groupIndex = 0; groupIndex < columnGroups.length; groupIndex++) { - int[] group = columnGroups[groupIndex]; - for (int columnInGroupIndex = 0; columnInGroupIndex < group.length; columnInGroupIndex++) { - int groupedColumn = group[columnInGroupIndex]; - if (groupedColumn == col) - return true; - } - } - - return false; - } - - private int[] computeColumnSizes(PrintSizeStrategy strategy) { - final int[] result = new int[columns.length]; - final GridCellIterator[][] rows = aggregateHeaderBodyAndFooterCells(); - - calculateExplicitlySizedColumnWidths(result); - - calculateColumnWidthsForCellsSpanningOneColumn(result, rows, strategy); - - applyColumnGrouping(result); - - calculateColumnWidthsForCellsSpanningMultipleColumns(result, rows, - strategy); - - applyColumnGrouping(result); - - return result; - } - - private GridCellIterator[][] aggregateHeaderBodyAndFooterCells() { - GridCellIterator[][] rows = new GridCellIterator[body.length - + header.length + footer.length][]; - - int offset = 0; - - System.arraycopy(body, 0, rows, offset, body.length); - offset += body.length; - - System.arraycopy(header, 0, rows, offset, header.length); - offset += header.length; - - System.arraycopy(footer, 0, rows, offset, footer.length); - - return rows; - } - - private void calculateColumnWidthsForCellsSpanningMultipleColumns( - final int[] colSizes, final GridCellIterator[][] rows, - final PrintSizeStrategy strategy) { - int horizontalSpacing = look.getMargins().getHorizontalSpacing(); - - for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) { - GridCellIterator[] row = rows[rowIndex]; - int columnIndex = 0; - for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { - GridCellIterator entry = row[cellIndex]; - int colspan = entry.getColspan(); - if (colspan > 1) { - int currentWidth = PaperClipsUtil.sum(colSizes, columnIndex, - colspan); - - // Subtract column spacing so the weighted distribution of - // extra width stays proportional. - int minimumWidth = strategy.computeSize(entry.getTarget()).x - - horizontalSpacing * (colspan - 1); - - if (currentWidth < minimumWidth) { - int extraWidth = minimumWidth - currentWidth; - - int[] indices = getExpandableColumnIndices(columnIndex, - colspan); - int totalWidth = PaperClipsUtil.sumByIndex(colSizes, - indices); - - if (totalWidth == 0) - resizeColumnsEqually(colSizes, extraWidth, indices); - else - resizeColumnsProportionateToCurrentSizes(colSizes, - indices, extraWidth, totalWidth); - } - } - columnIndex += colspan; - } - } - } - - private void resizeColumnsProportionateToCurrentSizes(final int[] colSizes, - final int[] columnIndices, int adjustment, int totalWidth) { - for (int i = 0; i < columnIndices.length && totalWidth != 0 - && adjustment != 0; i++) { - int columnIndex = columnIndices[i]; - - int addedWidth = (int) ((long) adjustment * colSizes[columnIndex] - / totalWidth); - - // Adjust extraWidth and totalCurrentWidth for future iterations. - totalWidth -= colSizes[columnIndex]; - adjustment -= addedWidth; - - // NOW we can add the added width. - colSizes[columnIndex] += addedWidth; - } - } - - private void resizeColumnsEqually(final int[] colSizes, int adjustment, - int[] expandableColumns) { - int expandableCols = expandableColumns.length; - for (int expandableColIndex = 0; expandableColIndex < expandableCols; expandableColIndex++) { - int expandableColumn = expandableColumns[expandableColIndex]; - - int addedWidth = adjustment / expandableCols; - - colSizes[expandableColumn] = addedWidth; - adjustment -= addedWidth; - expandableCols--; - } - } - - private void calculateColumnWidthsForCellsSpanningOneColumn(int[] colSizes, - GridCellIterator[][] rows, PrintSizeStrategy strategy) { - for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) { - GridCellIterator[] row = rows[rowIndex]; - int col = 0; - for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { - GridCellIterator entry = row[cellIndex]; - - // ignore explicitly sized cols - if (entry.getColspan() == 1 && !isExplicitSize(columns[col])) { - colSizes[col] = Math.max(colSizes[col], - computeCellWidth(entry, columns[col], strategy)); - } - col += entry.getColspan(); - } - } - } - - private void calculateExplicitlySizedColumnWidths(int[] colSizes) { - for (int col = 0; col < columns.length; col++) - if (isExplicitSize(columns[col])) - colSizes[col] = Math.round(columns[col].size * dpi.x / 72f); - } - - private int[] getExpandableColumnIndices(int firstColumn, int colspan) { - Condition[] conditions = getExpandableColumnConditions(); - for (int i = 0; i < conditions.length; i++) { - int[] columns = findColumns(firstColumn, colspan, conditions[i]); - if (columns != null && columns.length > 0) - return columns; - } - - return new int[0]; - } - - private interface Condition { - /** - * Returns whether the column at the specified index satisfies the - * condition. - * - * @param col - * the index of the column to test. - * @return whether the column at the specified index satisfies the - * condition. - */ - boolean satisfiedBy(int col); - } - - private Condition[] getExpandableColumnConditions() { - return new Condition[] { new Condition() { - public boolean satisfiedBy(int col) { - // Ungrouped columns with nonzero weight are first choice for - // expansion. - return !isColumnGrouped(col) && columns[col].weight > 0; - } - }, - - new Condition() { - public boolean satisfiedBy(int col) { - // Grouped columns with nonzero weight are next choice - return isColumnGrouped(col) && columns[col].weight > 0; - } - }, - - new Condition() { - public boolean satisfiedBy(int col) { - // Ungrouped columns with GridPrint.PREFERRED size are - // next - // choice. - return !isColumnGrouped(col) - && columns[col].size == GridPrint.PREFERRED; - } - }, - - new Condition() { - public boolean satisfiedBy(int col) { - // Grouped columns with GridPrint.PREFERRED size are - // next - // choice. - return isColumnGrouped(col) - && columns[col].size == GridPrint.PREFERRED; - } - }, - - new Condition() { - public boolean satisfiedBy(int col) { - // Ungrouped columns with SWT.DEFAULT size are next - // choice. - return !isColumnGrouped(col) - && columns[col].size == SWT.DEFAULT; - } - }, - - new Condition() { - public boolean satisfiedBy(int col) { - // Grouped columns with SWT.DEFAULT size are last - // choice. - return isColumnGrouped(col) - && columns[col].size == SWT.DEFAULT; - } - } }; - } - - private int[] findColumns(Condition condition) { - return findColumns(0, columns.length, condition); - } - - private int[] findColumns(int start, int count, Condition condition) { - int[] resultTemp = null; - int matches = 0; - - final int end = start + count; - for (int index = start; index < end; index++) - if (condition.satisfiedBy(index)) { - if (resultTemp == null) - resultTemp = new int[count]; - resultTemp[matches++] = index; - } - - if (matches == 0) - return new int[0]; - - int[] result = new int[matches]; - System.arraycopy(resultTemp, 0, result, 0, matches); - return result; - } - - private Point computeSize(PrintSizeStrategy strategy, int[] colSizes) { - final GridMargins margins = look.getMargins(); - - int width = computeMarginWidth() + PaperClipsUtil.sum(colSizes); - int height = 0; - - // This algorithm is not strictly accurate but probably good enough. The - // header and footer row heights - // are being calculated using getMinimumSize() and getPreferredSize(), - // which do not necessarily return - // the total content height. - - if (header.length > 0) - height += computeHeaderHeight(margins, strategy); - else - height += Math.max(margins.getBodyTop(false, true), - margins.getBodyTop(false, false)); - - height += computeMaxBodyRowHeight(strategy); - - if (footer.length > 0) - height += computeFooterHeight(strategy, margins); - else - height += Math.max(margins.getBodyBottom(false, false), - margins.getBodyBottom(false, true)); - - return new Point(width, height); - } - - private int computeHeaderHeight(final GridMargins margins, - PrintSizeStrategy strategy) { - int headerHeight = margins.getHeaderTop() - + margins.getHeaderVerticalSpacing() * (header.length - 1) - + Math.max(margins.getBodyTop(true, true), - margins.getBodyTop(true, false)); - for (int rowIndex = 0; rowIndex < header.length; rowIndex++) { - GridCellIterator[] row = header[rowIndex]; - int rowHeight = 0; - for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { - GridCellIterator entry = row[cellIndex]; - // Find tallest cell in row. - rowHeight = Math.max(rowHeight, - strategy.computeSize(entry.getTarget()).y); - } - headerHeight += rowHeight; - } - return headerHeight; - } - - private int computeMaxBodyRowHeight(PrintSizeStrategy strategy) { - int maxBodyRowHeight = 0; - for (int rowIndex = 0; rowIndex < body.length; rowIndex++) { - GridCellIterator[] row = body[rowIndex]; - for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { - GridCellIterator entry = row[cellIndex]; - // Find the greatest height of all cells' calculated sizes. - maxBodyRowHeight = Math.max(maxBodyRowHeight, - strategy.computeSize(entry.getTarget()).y); - } - } - return maxBodyRowHeight; - } - - private int computeFooterHeight(PrintSizeStrategy strategy, - final GridMargins margins) { - int footerHeight = Math.max(margins.getBodyBottom(true, false), - margins.getBodyBottom(true, true)) - + margins.getFooterVerticalSpacing() * (footer.length - 1) - + margins.getFooterBottom(); - for (int rowIndex = 0; rowIndex < footer.length; rowIndex++) { - GridCellIterator[] row = footer[rowIndex]; - int rowHeight = 0; - for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { - GridCellIterator entry = row[cellIndex]; - // Find tallest cell in row. - rowHeight = Math.max(rowHeight, - strategy.computeSize(entry.getTarget()).y); - } - footerHeight += rowHeight; - } - return footerHeight; - } - - public Point minimumSize() { - return new Point(minimumSize.x, minimumSize.y); - } - - public Point preferredSize() { - return new Point(preferredSize.x, preferredSize.y); - } - - private Condition[] getShrinkableColumnConditions() { - /* - * Disabled: new Condition() { public boolean satisfiedBy( int col ) { - * // Search first for columns with DEFAULT size. return - * columns[col].size == SWT.DEFAULT; } }, - */ - return new Condition[] { new Condition() { - public boolean satisfiedBy(int col) { - // Search next for columns with DEFAULT or PREFERRED size. - int size = columns[col].size; - return size == SWT.DEFAULT || size == GridPrint.PREFERRED; - } - } }; - } - - private int[] findShrinkableColumns(int extraWidth) { - Condition[] conditions = getShrinkableColumnConditions(); - for (int i = 0; i < conditions.length; i++) { - int[] indices = findColumns(conditions[i]); - if (PaperClipsUtil.sumByIndex(minimumColSizes, - indices) >= extraWidth) - return indices; - } - - return findAllColumns(); - } - - private int[] findAllColumns() { - int[] result = new int[columns.length]; - for (int i = 0; i < result.length; i++) - result[i] = i; - return result; - } - - private int[] computeColumnWidths(int width) { - int minimumWidth = PaperClipsUtil.sum(minimumColSizes); - int preferredWidth = PaperClipsUtil.sum(preferredColSizes); - - if (width < minimumWidth) - return reduceMinimumColumnWidths(minimumWidth - width); - else if (width == minimumWidth) - return minimumColSizes; - else if (width < preferredWidth) - return expandMinimumColumnWidths(width - minimumWidth); - else if (preferredWidth == width) - return preferredColSizes; - else - // ( preferredWidth < width ) - return expandPreferredColumnWidthsByWeight(width - preferredWidth); - } - - private int[] expandPreferredColumnWidthsByWeight(int extraWidth) { - int[] weightedCols = findColumns(new Condition() { - public boolean satisfiedBy(int col) { - return columns[col].weight > 0; - } - }); - int totalWeight = 0; - for (int i = 0; i < weightedCols.length; i++) - totalWeight += columns[weightedCols[i]].weight; - - int[] colSizes = PaperClipsUtil.copy(preferredColSizes); - for (int weightedColIndex = 0; weightedColIndex < weightedCols.length; weightedColIndex++) { - int columnIndex = weightedCols[weightedColIndex]; - - int columnWeight = columns[columnIndex].weight; - int addWidth = (int) ((long) extraWidth * columnWeight - / totalWeight); - - colSizes[columnIndex] += addWidth; - - // adjust extraWidth and totalWeight - eliminates round-off error - extraWidth -= addWidth; - totalWeight -= columnWeight; - } - - return colSizes; - } - - private int[] expandMinimumColumnWidths(int expansion) { - int difference = PaperClipsUtil.sum(preferredColSizes) - - PaperClipsUtil.sum(minimumColSizes); - int[] colSizes = PaperClipsUtil.copy(minimumColSizes); - for (int i = 0; i < columns.length && difference != 0 - && expansion != 0; i++) { - int columnDifference = preferredColSizes[i] - minimumColSizes[i]; - - int change = (int) ((long) expansion * columnDifference - / difference); - - colSizes[i] += change; - - // adjust extraWidth and difference - eliminates round-off error - expansion -= change; - difference -= columnDifference; - } - - return colSizes; - } - - private int computeMarginWidth() { - GridMargins margins = look.getMargins(); - return margins.getLeft() + margins.getRight() - + margins.getHorizontalSpacing() * (columns.length - 1); - } - - private int[] reduceMinimumColumnWidths(int reduction) { - int[] colSizes = PaperClipsUtil.copy(minimumColSizes); - - int[] shrinkableCols = findShrinkableColumns(reduction); - int shrinkableWidth = PaperClipsUtil.sumByIndex(colSizes, - shrinkableCols); - - for (int i = 0; i < shrinkableCols.length && shrinkableWidth != 0 - && reduction != 0; i++) { - int col = shrinkableCols[i]; - - int columnReduction = (int) ((long) colSizes[col] * reduction - / shrinkableWidth); - - shrinkableWidth -= colSizes[col]; - colSizes[col] -= columnReduction; - reduction -= columnReduction; - } - - return colSizes; - } - - public boolean hasNext() { - return row < body.length; - } - - private PrintPiece nextRow(final GridCellIterator[] cells, - final int[] columnWidths, final int height, - final boolean bottomOpen) { - if (bottomOpen && rowContainsNonDefaultVertAlignment(cells)) - return null; - if (height < 0) - return null; - - final int[] cellWidths = calculateCellWidths(cells, columnWidths); - - PrintPiece[] pieces = layoutCellsWithNonFillVertAlignment(cells, height, - bottomOpen, cellWidths); - if (pieces == null) - return null; - - final int rowHeight = calculateRowHeight(pieces, cells); - - pieces = layoutCellsWithFillVertAlignment(cells, rowHeight, cellWidths, - pieces); - if (pieces == null) - return null; - - final int[] xOffsets = new int[cells.length]; - final int[] yOffsets = new int[cells.length]; - applyCellAlignment(cells, cellWidths, pieces, rowHeight, xOffsets, - yOffsets); - - return createRowResult(pieces, xOffsets, yOffsets); - } - - private static boolean rowContainsNonDefaultVertAlignment( - final GridCellIterator[] cells) { - for (int i = 0; i < cells.length; i++) - if (!isDefaultVerticalAlignment(cells[i].getVerticalAlignment())) - return true; - return false; - } - - private static boolean isDefaultVerticalAlignment(int vAlignment) { - return vAlignment == SWT.DEFAULT || vAlignment == SWT.TOP; - } - - private int[] calculateCellWidths(final GridCellIterator[] cells, - final int[] columnWidths) { - final int[] result = new int[cells.length]; - final int horzSpacing = look.getMargins().getHorizontalSpacing(); - int col = 0; - for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { - int colspan = cells[cellIndex].getColspan(); - result[cellIndex] = (colspan - 1) * horzSpacing - + PaperClipsUtil.sum(columnWidths, col, colspan); - col += colspan; - } - return result; - } - - private static PrintPiece[] layoutCellsWithNonFillVertAlignment( - final GridCellIterator[] cells, final int height, - final boolean bottomOpen, final int[] cellWidths) { - final PrintPiece[] pieces = new PrintPiece[cells.length]; - for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { - final GridCellIterator cell = cells[cellIndex]; - final PrintIterator iter = cell.getTarget(); - - final int cellWidth = cellWidths[cellIndex]; - - if (iter.hasNext() && cell.getVerticalAlignment() != SWT.FILL) { - PrintPiece piece = pieces[cellIndex] = PaperClips.next(iter, - cellWidth, height); - if ((piece == null) || (iter.hasNext() && !bottomOpen)) { - PaperClipsUtil.dispose(piece, pieces); - return null; - } - } - } - return pieces; - } - - private static int calculateRowHeight(final PrintPiece[] cellPieces, - final GridCellIterator[] cells) { - int maxHeight = 0; - for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { - GridCellIterator cell = cells[cellIndex]; - if (cell.getVerticalAlignment() == SWT.FILL) - maxHeight = Math.max(maxHeight, - cell.getTarget().minimumSize().y); - else if (cellPieces[cellIndex] != null) - maxHeight = Math.max(maxHeight, - cellPieces[cellIndex].getSize().y); - } - return maxHeight; - } - - private static PrintPiece[] layoutCellsWithFillVertAlignment( - final GridCellIterator[] cells, final int height, - final int[] cellWidths, final PrintPiece[] cellPieces) { - for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { - GridCellIterator cell = cells[cellIndex]; - PrintIterator iter = cell.getTarget(); - - if (cell.getVerticalAlignment() == SWT.FILL) { - PrintPiece piece = cellPieces[cellIndex] = PaperClips.next(iter, - cellWidths[cellIndex], height); - if (piece == null || iter.hasNext()) { - PaperClipsUtil.dispose(piece, cellPieces); - return null; - } - } - } - return cellPieces; - } - - private void applyCellAlignment(final GridCellIterator[] cells, - final int[] cellWidths, final PrintPiece[] pieces, - final int rowHeight, final int[] xOffsets, final int[] yOffsets) { - final int horzSpacing = look.getMargins().getHorizontalSpacing(); - int x = 0; - int col = 0; - - for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { - xOffsets[cellIndex] = x; - yOffsets[cellIndex] = 0; - - GridCellIterator cell = cells[cellIndex]; - PrintPiece piece = pieces[cellIndex]; - if (piece != null) { - Point size = piece.getSize(); - int hAlignment = resolveHorzAlignment( - cell.getHorizontalAlignment(), columns[col].align); - xOffsets[cellIndex] += getHorzAlignmentOffset(hAlignment, - size.x, cellWidths[cellIndex]); - yOffsets[cellIndex] += getVertAlignmentOffset( - cell.getVerticalAlignment(), size.y, rowHeight); - } - - x += cellWidths[cellIndex] + horzSpacing; - col += cell.getColspan(); - } - } - - private static int resolveHorzAlignment(int cellAlignment, - int columnAlignment) { - return cellAlignment == SWT.DEFAULT ? columnAlignment : cellAlignment; - } - - private static int getHorzAlignmentOffset(int alignment, int pieceWidth, - int totalWidth) { - if (alignment == SWT.CENTER) - return (totalWidth - pieceWidth) / 2; - else if (alignment == SWT.RIGHT) - return totalWidth - pieceWidth; - return 0; - } - - private static int getVertAlignmentOffset(final int alignment, - final int pieceHeight, final int cellHeight) { - int offset = 0; - if (alignment == SWT.CENTER) { - offset = (cellHeight - pieceHeight) / 2; - } else if (alignment == SWT.BOTTOM) { - offset = cellHeight - pieceHeight; - } - return offset; - } - - private static PrintPiece createRowResult(final PrintPiece[] pieces, - final int[] xOffsets, final int[] yOffsets) { - List result = new ArrayList<>(); - for (int cellIndex = 0; cellIndex < pieces.length; cellIndex++) - if (pieces[cellIndex] != null) - result.add(new CompositeEntry(pieces[cellIndex], - new Point(xOffsets[cellIndex], yOffsets[cellIndex]))); - return new CompositePiece(result); - } - - private static boolean hasNext(GridCellIterator[] cells) { - for (int i = 0; i < cells.length; i++) - if (cells[i].getTarget().hasNext()) - return true; - return false; - } - - public PrintPiece next(final int width, int height) { - if (!hasNext()) - PaperClips.error(SWT.ERROR_UNSPECIFIED, "No more content"); //$NON-NLS-1$ - - GridMargins margins = look.getMargins(); - int[] colSizes = computeColumnWidths(width - computeMarginWidth()); - - final boolean headerPresent = header.length > 0; - final int[] headerHeights = new int[header.length]; - final int[][] headerColSpans = new int[header.length][]; - PrintPiece headerPiece = null; - if (headerPresent) { - height -= margins.getHeaderTop(); - headerPiece = nextHeaderPiece(colSizes, height, headerHeights, - headerColSpans); - if (headerPiece == null) - return null; - height -= headerPiece.getSize().y; - } - - final boolean footerPresent = footer.length > 0; - final int[] footerHeights = new int[footer.length]; - final int[][] footerColSpans = new int[footer.length][]; - PrintPiece footerPiece = null; - - if (footerPresent) { - height -= margins.getFooterBottom(); - footerPiece = nextFooterPiece(colSizes, height, footerHeights, - footerColSpans); - if (footerPiece == null) { - PaperClipsUtil.dispose(headerPiece); - return null; - } - height -= footerPiece.getSize().y; - } - - final int firstRow = row; - final boolean topOpen = rowStarted; - final List bodyRows = new ArrayList<>(); - final List bodyColSpans = new ArrayList<>(); - - height -= margins.getBodyTop(headerPresent, topOpen); - final PrintPiece bodyPiece = nextBodyPiece(colSizes, height, bodyRows, - bodyColSpans, footerPresent); - if (bodyPiece == null) - return null; - final boolean bottomOpen = rowStarted; - - return createResult(colSizes, headerPiece, headerHeights, - headerColSpans, firstRow, topOpen, bodyPiece, - PaperClipsUtil.toIntArray(bodyRows), - PaperClipsUtil.toIntIntArray(bodyColSpans), bottomOpen, - footerPiece, footerHeights, footerColSpans); - } - - private PrintPiece nextHeaderPiece(final int[] colSizes, final int height, - final int[] rowHeights, final int[][] colSpans) { - return nextHeaderOrFooterPiece(colSizes, height, rowHeights, colSpans, - look.getMargins().getHeaderVerticalSpacing(), header); - } - - private PrintPiece nextFooterPiece(final int[] colSizes, final int height, - final int[] rowHeights, final int[][] colSpans) { - return nextHeaderOrFooterPiece(colSizes, height, rowHeights, colSpans, - look.getMargins().getFooterVerticalSpacing(), footer); - } - - private PrintPiece nextHeaderOrFooterPiece(final int[] colSizes, - final int height, final int[] rowHeights, final int[][] colSpans, - final int rowSpacing, GridCellIterator[][] headerOrFooter) { - int y = 0; - List entries = new ArrayList<>(); - for (int rowIndex = 0; rowIndex < headerOrFooter.length; rowIndex++) { - GridCellIterator[] row = cloneRow(headerOrFooter[rowIndex]); - - colSpans[rowIndex] = new int[row.length]; - for (int cellIndex = 0; cellIndex < row.length; cellIndex++) - colSpans[rowIndex][cellIndex] = row[cellIndex].getColspan(); - - PrintPiece rowPiece = nextRow(row, colSizes, height - y, false); - boolean hasNext = hasNext(row); - - if (rowPiece == null || hasNext) { - PaperClipsUtil.dispose(rowPiece); - for (Iterator iter = entries.iterator(); iter - .hasNext();) { - CompositeEntry entry = iter.next(); - entry.dispose(); - } - return null; - } - - int rowHeight = rowHeights[rowIndex] = rowPiece.getSize().y; - entries.add(new CompositeEntry(rowPiece, new Point(0, y))); - - y += rowHeight + rowSpacing; - } - - return new CompositePiece(entries); - } - - private PrintPiece nextBodyPiece(int[] colSizes, final int height, - final List rowHeights, final List colSpans, - final boolean footerPresent) { - final GridMargins margins = look.getMargins(); - final int rowSpacing = margins.getBodyVerticalSpacing(); - final int bodyBottomSpacingOpen = margins.getBodyBottom(footerPresent, - true); - final int bodyBottomSpacingClosed = margins.getBodyBottom(footerPresent, - false); - - int y = 0; - List entries = new ArrayList<>(); - while (hasNext()) { - GridCellIterator[] thisRow = cloneRow(body[row]); - PrintPiece rowPiece = nextRow(thisRow, colSizes, - height - y - bodyBottomSpacingClosed, rowStarted); - boolean hasNext = hasNext(thisRow); - - if ((cellClippingEnabled || entries.isEmpty()) - && (rowPiece == null || hasNext)) { - thisRow = cloneRow(body[row]); - rowPiece = nextRow(thisRow, colSizes, - height - y - bodyBottomSpacingOpen, true); - hasNext = true; - } - - if (rowPiece == null) - break; - - entries.add(new CompositeEntry(rowPiece, new Point(0, y))); - body[row] = thisRow; - - final int[] rowColSpans = new int[thisRow.length]; - for (int cellIndex = 0; cellIndex < rowColSpans.length; cellIndex++) - rowColSpans[cellIndex] = thisRow[cellIndex].getColspan(); - colSpans.add(rowColSpans); - - final int rowHeight = rowPiece.getSize().y; - rowHeights.add(new Integer(rowHeight)); - - rowStarted = hasNext; - if (hasNext) - break; - - y += rowHeight + rowSpacing; - row++; - } - - if (entries.isEmpty()) - return null; - - return new CompositePiece(entries); - } - - private static GridCellIterator[] cloneRow(GridCellIterator[] row) { - GridCellIterator[] result = row.clone(); - for (int i = 0; i < result.length; i++) - result[i] = result[i].copy(); - return result; - } - - private PrintPiece createResult(final int[] colSizes, - final PrintPiece headerPiece, final int[] headerRows, - final int[][] headerColSpans, final int firstRow, - final boolean topOpen, final PrintPiece bodyPiece, - final int[] bodyRows, final int[][] bodyColSpans, - final boolean bottomOpen, final PrintPiece footerPiece, - final int[] footerRows, final int[][] footerColSpans) { - if (bodyPiece == null) { - if (headerPiece != null) - headerPiece.dispose(); - if (footerPiece != null) - footerPiece.dispose(); - return null; - } - - List sections = new ArrayList<>(); - - PrintPiece lookPiece = new GridLookPainterPiece(look, colSizes, - headerRows, headerColSpans, firstRow, topOpen, bodyRows, - bodyColSpans, bottomOpen, footerRows, footerColSpans); - sections.add(new CompositeEntry(lookPiece, new Point(0, 0))); - - GridMargins margins = look.getMargins(); - final int x = margins.getLeft(); - - int y = 0; - if (headerPiece != null) { - y = margins.getHeaderTop(); - sections.add(new CompositeEntry(headerPiece, new Point(x, y))); - y += headerPiece.getSize().y; - } - - y += margins.getBodyTop(headerPiece != null, topOpen); - sections.add(new CompositeEntry(bodyPiece, new Point(x, y))); - y += bodyPiece.getSize().y - + margins.getBodyBottom(footerPiece != null, bottomOpen); - - if (footerPiece != null) - sections.add(new CompositeEntry(footerPiece, new Point(x, y))); - - return new CompositePiece(sections); - } - - public PrintIterator copy() { - return new GridIterator(this); - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid.internal; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.CompositeEntry; +import org.eclipse.nebula.paperclips.core.CompositePiece; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.grid.GridCell; +import org.eclipse.nebula.paperclips.core.grid.GridColumn; +import org.eclipse.nebula.paperclips.core.grid.GridLookPainter; +import org.eclipse.nebula.paperclips.core.grid.GridMargins; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * Iterator for Grid + */ +public class GridIterator implements PrintIterator { + final Device device; + final Point dpi; + + final GridColumn[] columns; + final int[][] columnGroups; + + final GridLookPainter look; + + final GridCellIterator[][] header; + final GridCellIterator[][] body; + final GridCellIterator[][] footer; + + final boolean cellClippingEnabled; + + final int[] minimumColSizes; // PIXELS + final int[] preferredColSizes; // PIXELS + + final Point minimumSize; // PIXELS + final Point preferredSize; // PIXELS + + // This is the cursor! + private int row; + + // Determines whether top edge of cell border is drawn open or closed for + // current row. + private boolean rowStarted; + + /** + * @param grid + * @param device + * @param gc + */ + public GridIterator(GridPrint grid, Device device, GC gc) { + this.device = device; + this.dpi = device.getDPI(); + this.columns = new GridColumn[grid.getColumns().length]; + System.arraycopy(grid.getColumns(), 0, this.columns, 0, + grid.getColumns().length); + this.columnGroups = grid.getColumnGroups(); + + this.header = createGridCellIterators(grid.getHeaderCells(), device, + gc); + this.body = createGridCellIterators(grid.getBodyCells(), device, gc); + this.footer = createGridCellIterators(grid.getFooterCells(), device, + gc); + + this.cellClippingEnabled = grid.isCellClippingEnabled(); + + this.look = grid.getLook().getPainter(device, gc); + + this.minimumColSizes = computeColumnSizes(PrintSizeStrategy.MINIMUM); + this.preferredColSizes = computeColumnSizes( + PrintSizeStrategy.PREFERRED); + + this.minimumSize = computeSize(PrintSizeStrategy.MINIMUM, + minimumColSizes); + this.preferredSize = computeSize(PrintSizeStrategy.PREFERRED, + preferredColSizes); + + row = 0; + rowStarted = false; + } + + private static GridCellIterator[][] createGridCellIterators( + GridCell[][] gridCells, Device device, GC gc) { + GridCellIterator[][] result = new GridCellIterator[gridCells.length][]; + for (int rowIndex = 0; rowIndex < result.length; rowIndex++) + result[rowIndex] = createRowCellIterators(gridCells[rowIndex], + device, gc); + return result; + } + + private static GridCellIterator[] createRowCellIterators( + GridCell[] rowCells, Device device, GC gc) { + GridCellIterator[] result = new GridCellIterator[rowCells.length]; + for (int cellIndex = 0; cellIndex < rowCells.length; cellIndex++) + result[cellIndex] = ((GridCellImpl) rowCells[cellIndex]) + .iterator(device, gc); + return result; + } + + /** Copy constructor (used by copy() only) */ + private GridIterator(GridIterator that) { + this.device = that.device; + this.dpi = that.dpi; + + this.columns = that.columns; + this.columnGroups = that.columnGroups; + + this.header = that.header; // never directly modified, clone not + // necessary + this.body = cloneRows(that.body, that.row); // Only need to deep copy + // the unconsumed rows. + this.footer = that.footer; // never directly modified, clone not + // necessary + + this.cellClippingEnabled = that.cellClippingEnabled; + + this.look = that.look; + + this.minimumColSizes = that.minimumColSizes; + this.preferredColSizes = that.preferredColSizes; + + this.minimumSize = that.minimumSize; + this.preferredSize = that.preferredSize; + + this.row = that.row; + this.rowStarted = that.rowStarted; + } + + private static GridCellIterator[][] cloneRows(GridCellIterator[][] rows, + int firstRow) { + GridCellIterator[][] result = rows.clone(); + // Cloning the outer array is all that's necessary. The inner arrays + // (rows) are cloned every time a row + // is laid out, so all we have to do is make sure different + // GridIterators have distinct outer arrays. + // for ( int i = firstRow; i < result.length; i++ ) + // result[i] = cloneRow( result[i] ); + return result; + } + + /** + * Compute the size of a column, respecting the constraints of the + * GridColumn. + */ + private int computeCellWidth(GridCellIterator entry, GridColumn col, + PrintSizeStrategy strategy) { + if (col.size == SWT.DEFAULT) + return strategy.computeSize(entry.getTarget()).x; + if (col.size == GridPrint.PREFERRED) + return entry.getTarget().preferredSize().x; + return Math.round(col.size * device.getDPI().x / 72f); + } + + private static boolean isExplicitSize(GridColumn col) { + return col.size > 0; + } + + private void applyColumnGrouping(int[] columnSizes) { + for (int groupIndex = 0; groupIndex < columnGroups.length; groupIndex++) { + int[] group = columnGroups[groupIndex]; + + // find max column width in group + int maxSize = 0; + for (int columnInGroupIndex = 0; columnInGroupIndex < group.length; columnInGroupIndex++) { + int col = group[columnInGroupIndex]; + maxSize = Math.max(maxSize, columnSizes[col]); + } + + // grow all columns to max column width + for (int columnInGroupIndex = 0; columnInGroupIndex < group.length; columnInGroupIndex++) { + int col = group[columnInGroupIndex]; + columnSizes[col] = maxSize; + } + } + } + + private boolean isColumnGrouped(int col) { + for (int groupIndex = 0; groupIndex < columnGroups.length; groupIndex++) { + int[] group = columnGroups[groupIndex]; + for (int columnInGroupIndex = 0; columnInGroupIndex < group.length; columnInGroupIndex++) { + int groupedColumn = group[columnInGroupIndex]; + if (groupedColumn == col) + return true; + } + } + + return false; + } + + private int[] computeColumnSizes(PrintSizeStrategy strategy) { + final int[] result = new int[columns.length]; + final GridCellIterator[][] rows = aggregateHeaderBodyAndFooterCells(); + + calculateExplicitlySizedColumnWidths(result); + + calculateColumnWidthsForCellsSpanningOneColumn(result, rows, strategy); + + applyColumnGrouping(result); + + calculateColumnWidthsForCellsSpanningMultipleColumns(result, rows, + strategy); + + applyColumnGrouping(result); + + return result; + } + + private GridCellIterator[][] aggregateHeaderBodyAndFooterCells() { + GridCellIterator[][] rows = new GridCellIterator[body.length + + header.length + footer.length][]; + + int offset = 0; + + System.arraycopy(body, 0, rows, offset, body.length); + offset += body.length; + + System.arraycopy(header, 0, rows, offset, header.length); + offset += header.length; + + System.arraycopy(footer, 0, rows, offset, footer.length); + + return rows; + } + + private void calculateColumnWidthsForCellsSpanningMultipleColumns( + final int[] colSizes, final GridCellIterator[][] rows, + final PrintSizeStrategy strategy) { + int horizontalSpacing = look.getMargins().getHorizontalSpacing(); + + for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) { + GridCellIterator[] row = rows[rowIndex]; + int columnIndex = 0; + for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { + GridCellIterator entry = row[cellIndex]; + int colspan = entry.getColspan(); + if (colspan > 1) { + int currentWidth = PaperClipsUtil.sum(colSizes, columnIndex, + colspan); + + // Subtract column spacing so the weighted distribution of + // extra width stays proportional. + int minimumWidth = strategy.computeSize(entry.getTarget()).x + - horizontalSpacing * (colspan - 1); + + if (currentWidth < minimumWidth) { + int extraWidth = minimumWidth - currentWidth; + + int[] indices = getExpandableColumnIndices(columnIndex, + colspan); + int totalWidth = PaperClipsUtil.sumByIndex(colSizes, + indices); + + if (totalWidth == 0) + resizeColumnsEqually(colSizes, extraWidth, indices); + else + resizeColumnsProportionateToCurrentSizes(colSizes, + indices, extraWidth, totalWidth); + } + } + columnIndex += colspan; + } + } + } + + private void resizeColumnsProportionateToCurrentSizes(final int[] colSizes, + final int[] columnIndices, int adjustment, int totalWidth) { + for (int i = 0; i < columnIndices.length && totalWidth != 0 + && adjustment != 0; i++) { + int columnIndex = columnIndices[i]; + + int addedWidth = (int) ((long) adjustment * colSizes[columnIndex] + / totalWidth); + + // Adjust extraWidth and totalCurrentWidth for future iterations. + totalWidth -= colSizes[columnIndex]; + adjustment -= addedWidth; + + // NOW we can add the added width. + colSizes[columnIndex] += addedWidth; + } + } + + private void resizeColumnsEqually(final int[] colSizes, int adjustment, + int[] expandableColumns) { + int expandableCols = expandableColumns.length; + for (int expandableColIndex = 0; expandableColIndex < expandableCols; expandableColIndex++) { + int expandableColumn = expandableColumns[expandableColIndex]; + + int addedWidth = adjustment / expandableCols; + + colSizes[expandableColumn] = addedWidth; + adjustment -= addedWidth; + expandableCols--; + } + } + + private void calculateColumnWidthsForCellsSpanningOneColumn(int[] colSizes, + GridCellIterator[][] rows, PrintSizeStrategy strategy) { + for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) { + GridCellIterator[] row = rows[rowIndex]; + int col = 0; + for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { + GridCellIterator entry = row[cellIndex]; + + // ignore explicitly sized cols + if (entry.getColspan() == 1 && !isExplicitSize(columns[col])) { + colSizes[col] = Math.max(colSizes[col], + computeCellWidth(entry, columns[col], strategy)); + } + col += entry.getColspan(); + } + } + } + + private void calculateExplicitlySizedColumnWidths(int[] colSizes) { + for (int col = 0; col < columns.length; col++) + if (isExplicitSize(columns[col])) + colSizes[col] = Math.round(columns[col].size * dpi.x / 72f); + } + + private int[] getExpandableColumnIndices(int firstColumn, int colspan) { + Condition[] conditions = getExpandableColumnConditions(); + for (int i = 0; i < conditions.length; i++) { + int[] columns = findColumns(firstColumn, colspan, conditions[i]); + if (columns != null && columns.length > 0) + return columns; + } + + return new int[0]; + } + + private interface Condition { + /** + * Returns whether the column at the specified index satisfies the + * condition. + * + * @param col + * the index of the column to test. + * @return whether the column at the specified index satisfies the + * condition. + */ + boolean satisfiedBy(int col); + } + + private Condition[] getExpandableColumnConditions() { + return new Condition[] { new Condition() { + public boolean satisfiedBy(int col) { + // Ungrouped columns with nonzero weight are first choice for + // expansion. + return !isColumnGrouped(col) && columns[col].weight > 0; + } + }, + + new Condition() { + public boolean satisfiedBy(int col) { + // Grouped columns with nonzero weight are next choice + return isColumnGrouped(col) && columns[col].weight > 0; + } + }, + + new Condition() { + public boolean satisfiedBy(int col) { + // Ungrouped columns with GridPrint.PREFERRED size are + // next + // choice. + return !isColumnGrouped(col) + && columns[col].size == GridPrint.PREFERRED; + } + }, + + new Condition() { + public boolean satisfiedBy(int col) { + // Grouped columns with GridPrint.PREFERRED size are + // next + // choice. + return isColumnGrouped(col) + && columns[col].size == GridPrint.PREFERRED; + } + }, + + new Condition() { + public boolean satisfiedBy(int col) { + // Ungrouped columns with SWT.DEFAULT size are next + // choice. + return !isColumnGrouped(col) + && columns[col].size == SWT.DEFAULT; + } + }, + + new Condition() { + public boolean satisfiedBy(int col) { + // Grouped columns with SWT.DEFAULT size are last + // choice. + return isColumnGrouped(col) + && columns[col].size == SWT.DEFAULT; + } + } }; + } + + private int[] findColumns(Condition condition) { + return findColumns(0, columns.length, condition); + } + + private int[] findColumns(int start, int count, Condition condition) { + int[] resultTemp = null; + int matches = 0; + + final int end = start + count; + for (int index = start; index < end; index++) + if (condition.satisfiedBy(index)) { + if (resultTemp == null) + resultTemp = new int[count]; + resultTemp[matches++] = index; + } + + if (matches == 0) + return new int[0]; + + int[] result = new int[matches]; + System.arraycopy(resultTemp, 0, result, 0, matches); + return result; + } + + private Point computeSize(PrintSizeStrategy strategy, int[] colSizes) { + final GridMargins margins = look.getMargins(); + + int width = computeMarginWidth() + PaperClipsUtil.sum(colSizes); + int height = 0; + + // This algorithm is not strictly accurate but probably good enough. The + // header and footer row heights + // are being calculated using getMinimumSize() and getPreferredSize(), + // which do not necessarily return + // the total content height. + + if (header.length > 0) + height += computeHeaderHeight(margins, strategy); + else + height += Math.max(margins.getBodyTop(false, true), + margins.getBodyTop(false, false)); + + height += computeMaxBodyRowHeight(strategy); + + if (footer.length > 0) + height += computeFooterHeight(strategy, margins); + else + height += Math.max(margins.getBodyBottom(false, false), + margins.getBodyBottom(false, true)); + + return new Point(width, height); + } + + private int computeHeaderHeight(final GridMargins margins, + PrintSizeStrategy strategy) { + int headerHeight = margins.getHeaderTop() + + margins.getHeaderVerticalSpacing() * (header.length - 1) + + Math.max(margins.getBodyTop(true, true), + margins.getBodyTop(true, false)); + for (int rowIndex = 0; rowIndex < header.length; rowIndex++) { + GridCellIterator[] row = header[rowIndex]; + int rowHeight = 0; + for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { + GridCellIterator entry = row[cellIndex]; + // Find tallest cell in row. + rowHeight = Math.max(rowHeight, + strategy.computeSize(entry.getTarget()).y); + } + headerHeight += rowHeight; + } + return headerHeight; + } + + private int computeMaxBodyRowHeight(PrintSizeStrategy strategy) { + int maxBodyRowHeight = 0; + for (int rowIndex = 0; rowIndex < body.length; rowIndex++) { + GridCellIterator[] row = body[rowIndex]; + for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { + GridCellIterator entry = row[cellIndex]; + // Find the greatest height of all cells' calculated sizes. + maxBodyRowHeight = Math.max(maxBodyRowHeight, + strategy.computeSize(entry.getTarget()).y); + } + } + return maxBodyRowHeight; + } + + private int computeFooterHeight(PrintSizeStrategy strategy, + final GridMargins margins) { + int footerHeight = Math.max(margins.getBodyBottom(true, false), + margins.getBodyBottom(true, true)) + + margins.getFooterVerticalSpacing() * (footer.length - 1) + + margins.getFooterBottom(); + for (int rowIndex = 0; rowIndex < footer.length; rowIndex++) { + GridCellIterator[] row = footer[rowIndex]; + int rowHeight = 0; + for (int cellIndex = 0; cellIndex < row.length; cellIndex++) { + GridCellIterator entry = row[cellIndex]; + // Find tallest cell in row. + rowHeight = Math.max(rowHeight, + strategy.computeSize(entry.getTarget()).y); + } + footerHeight += rowHeight; + } + return footerHeight; + } + + public Point minimumSize() { + return new Point(minimumSize.x, minimumSize.y); + } + + public Point preferredSize() { + return new Point(preferredSize.x, preferredSize.y); + } + + private Condition[] getShrinkableColumnConditions() { + /* + * Disabled: new Condition() { public boolean satisfiedBy( int col ) { + * // Search first for columns with DEFAULT size. return + * columns[col].size == SWT.DEFAULT; } }, + */ + return new Condition[] { new Condition() { + public boolean satisfiedBy(int col) { + // Search next for columns with DEFAULT or PREFERRED size. + int size = columns[col].size; + return size == SWT.DEFAULT || size == GridPrint.PREFERRED; + } + } }; + } + + private int[] findShrinkableColumns(int extraWidth) { + Condition[] conditions = getShrinkableColumnConditions(); + for (int i = 0; i < conditions.length; i++) { + int[] indices = findColumns(conditions[i]); + if (PaperClipsUtil.sumByIndex(minimumColSizes, + indices) >= extraWidth) + return indices; + } + + return findAllColumns(); + } + + private int[] findAllColumns() { + int[] result = new int[columns.length]; + for (int i = 0; i < result.length; i++) + result[i] = i; + return result; + } + + private int[] computeColumnWidths(int width) { + int minimumWidth = PaperClipsUtil.sum(minimumColSizes); + int preferredWidth = PaperClipsUtil.sum(preferredColSizes); + + if (width < minimumWidth) + return reduceMinimumColumnWidths(minimumWidth - width); + else if (width == minimumWidth) + return minimumColSizes; + else if (width < preferredWidth) + return expandMinimumColumnWidths(width - minimumWidth); + else if (preferredWidth == width) + return preferredColSizes; + else + // ( preferredWidth < width ) + return expandPreferredColumnWidthsByWeight(width - preferredWidth); + } + + private int[] expandPreferredColumnWidthsByWeight(int extraWidth) { + int[] weightedCols = findColumns(new Condition() { + public boolean satisfiedBy(int col) { + return columns[col].weight > 0; + } + }); + int totalWeight = 0; + for (int i = 0; i < weightedCols.length; i++) + totalWeight += columns[weightedCols[i]].weight; + + int[] colSizes = PaperClipsUtil.copy(preferredColSizes); + for (int weightedColIndex = 0; weightedColIndex < weightedCols.length; weightedColIndex++) { + int columnIndex = weightedCols[weightedColIndex]; + + int columnWeight = columns[columnIndex].weight; + int addWidth = (int) ((long) extraWidth * columnWeight + / totalWeight); + + colSizes[columnIndex] += addWidth; + + // adjust extraWidth and totalWeight - eliminates round-off error + extraWidth -= addWidth; + totalWeight -= columnWeight; + } + + return colSizes; + } + + private int[] expandMinimumColumnWidths(int expansion) { + int difference = PaperClipsUtil.sum(preferredColSizes) + - PaperClipsUtil.sum(minimumColSizes); + int[] colSizes = PaperClipsUtil.copy(minimumColSizes); + for (int i = 0; i < columns.length && difference != 0 + && expansion != 0; i++) { + int columnDifference = preferredColSizes[i] - minimumColSizes[i]; + + int change = (int) ((long) expansion * columnDifference + / difference); + + colSizes[i] += change; + + // adjust extraWidth and difference - eliminates round-off error + expansion -= change; + difference -= columnDifference; + } + + return colSizes; + } + + private int computeMarginWidth() { + GridMargins margins = look.getMargins(); + return margins.getLeft() + margins.getRight() + + margins.getHorizontalSpacing() * (columns.length - 1); + } + + private int[] reduceMinimumColumnWidths(int reduction) { + int[] colSizes = PaperClipsUtil.copy(minimumColSizes); + + int[] shrinkableCols = findShrinkableColumns(reduction); + int shrinkableWidth = PaperClipsUtil.sumByIndex(colSizes, + shrinkableCols); + + for (int i = 0; i < shrinkableCols.length && shrinkableWidth != 0 + && reduction != 0; i++) { + int col = shrinkableCols[i]; + + int columnReduction = (int) ((long) colSizes[col] * reduction + / shrinkableWidth); + + shrinkableWidth -= colSizes[col]; + colSizes[col] -= columnReduction; + reduction -= columnReduction; + } + + return colSizes; + } + + public boolean hasNext() { + return row < body.length; + } + + private PrintPiece nextRow(final GridCellIterator[] cells, + final int[] columnWidths, final int height, + final boolean bottomOpen) { + if (bottomOpen && rowContainsNonDefaultVertAlignment(cells)) + return null; + if (height < 0) + return null; + + final int[] cellWidths = calculateCellWidths(cells, columnWidths); + + PrintPiece[] pieces = layoutCellsWithNonFillVertAlignment(cells, height, + bottomOpen, cellWidths); + if (pieces == null) + return null; + + final int rowHeight = calculateRowHeight(pieces, cells); + + pieces = layoutCellsWithFillVertAlignment(cells, rowHeight, cellWidths, + pieces); + if (pieces == null) + return null; + + final int[] xOffsets = new int[cells.length]; + final int[] yOffsets = new int[cells.length]; + applyCellAlignment(cells, cellWidths, pieces, rowHeight, xOffsets, + yOffsets); + + return createRowResult(pieces, xOffsets, yOffsets); + } + + private static boolean rowContainsNonDefaultVertAlignment( + final GridCellIterator[] cells) { + for (int i = 0; i < cells.length; i++) + if (!isDefaultVerticalAlignment(cells[i].getVerticalAlignment())) + return true; + return false; + } + + private static boolean isDefaultVerticalAlignment(int vAlignment) { + return vAlignment == SWT.DEFAULT || vAlignment == SWT.TOP; + } + + private int[] calculateCellWidths(final GridCellIterator[] cells, + final int[] columnWidths) { + final int[] result = new int[cells.length]; + final int horzSpacing = look.getMargins().getHorizontalSpacing(); + int col = 0; + for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { + int colspan = cells[cellIndex].getColspan(); + result[cellIndex] = (colspan - 1) * horzSpacing + + PaperClipsUtil.sum(columnWidths, col, colspan); + col += colspan; + } + return result; + } + + private static PrintPiece[] layoutCellsWithNonFillVertAlignment( + final GridCellIterator[] cells, final int height, + final boolean bottomOpen, final int[] cellWidths) { + final PrintPiece[] pieces = new PrintPiece[cells.length]; + for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { + final GridCellIterator cell = cells[cellIndex]; + final PrintIterator iter = cell.getTarget(); + + final int cellWidth = cellWidths[cellIndex]; + + if (iter.hasNext() && cell.getVerticalAlignment() != SWT.FILL) { + PrintPiece piece = pieces[cellIndex] = PaperClips.next(iter, + cellWidth, height); + if ((piece == null) || (iter.hasNext() && !bottomOpen)) { + PaperClipsUtil.dispose(piece, pieces); + return null; + } + } + } + return pieces; + } + + private static int calculateRowHeight(final PrintPiece[] cellPieces, + final GridCellIterator[] cells) { + int maxHeight = 0; + for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { + GridCellIterator cell = cells[cellIndex]; + if (cell.getVerticalAlignment() == SWT.FILL) + maxHeight = Math.max(maxHeight, + cell.getTarget().minimumSize().y); + else if (cellPieces[cellIndex] != null) + maxHeight = Math.max(maxHeight, + cellPieces[cellIndex].getSize().y); + } + return maxHeight; + } + + private static PrintPiece[] layoutCellsWithFillVertAlignment( + final GridCellIterator[] cells, final int height, + final int[] cellWidths, final PrintPiece[] cellPieces) { + for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { + GridCellIterator cell = cells[cellIndex]; + PrintIterator iter = cell.getTarget(); + + if (cell.getVerticalAlignment() == SWT.FILL) { + PrintPiece piece = cellPieces[cellIndex] = PaperClips.next(iter, + cellWidths[cellIndex], height); + if (piece == null || iter.hasNext()) { + PaperClipsUtil.dispose(piece, cellPieces); + return null; + } + } + } + return cellPieces; + } + + private void applyCellAlignment(final GridCellIterator[] cells, + final int[] cellWidths, final PrintPiece[] pieces, + final int rowHeight, final int[] xOffsets, final int[] yOffsets) { + final int horzSpacing = look.getMargins().getHorizontalSpacing(); + int x = 0; + int col = 0; + + for (int cellIndex = 0; cellIndex < cells.length; cellIndex++) { + xOffsets[cellIndex] = x; + yOffsets[cellIndex] = 0; + + GridCellIterator cell = cells[cellIndex]; + PrintPiece piece = pieces[cellIndex]; + if (piece != null) { + Point size = piece.getSize(); + int hAlignment = resolveHorzAlignment( + cell.getHorizontalAlignment(), columns[col].align); + xOffsets[cellIndex] += getHorzAlignmentOffset(hAlignment, + size.x, cellWidths[cellIndex]); + yOffsets[cellIndex] += getVertAlignmentOffset( + cell.getVerticalAlignment(), size.y, rowHeight); + } + + x += cellWidths[cellIndex] + horzSpacing; + col += cell.getColspan(); + } + } + + private static int resolveHorzAlignment(int cellAlignment, + int columnAlignment) { + return cellAlignment == SWT.DEFAULT ? columnAlignment : cellAlignment; + } + + private static int getHorzAlignmentOffset(int alignment, int pieceWidth, + int totalWidth) { + if (alignment == SWT.CENTER) + return (totalWidth - pieceWidth) / 2; + else if (alignment == SWT.RIGHT) + return totalWidth - pieceWidth; + return 0; + } + + private static int getVertAlignmentOffset(final int alignment, + final int pieceHeight, final int cellHeight) { + int offset = 0; + if (alignment == SWT.CENTER) { + offset = (cellHeight - pieceHeight) / 2; + } else if (alignment == SWT.BOTTOM) { + offset = cellHeight - pieceHeight; + } + return offset; + } + + private static PrintPiece createRowResult(final PrintPiece[] pieces, + final int[] xOffsets, final int[] yOffsets) { + List result = new ArrayList<>(); + for (int cellIndex = 0; cellIndex < pieces.length; cellIndex++) + if (pieces[cellIndex] != null) + result.add(new CompositeEntry(pieces[cellIndex], + new Point(xOffsets[cellIndex], yOffsets[cellIndex]))); + return new CompositePiece(result); + } + + private static boolean hasNext(GridCellIterator[] cells) { + for (int i = 0; i < cells.length; i++) + if (cells[i].getTarget().hasNext()) + return true; + return false; + } + + public PrintPiece next(final int width, int height) { + if (!hasNext()) + PaperClips.error(SWT.ERROR_UNSPECIFIED, "No more content"); //$NON-NLS-1$ + + GridMargins margins = look.getMargins(); + int[] colSizes = computeColumnWidths(width - computeMarginWidth()); + + final boolean headerPresent = header.length > 0; + final int[] headerHeights = new int[header.length]; + final int[][] headerColSpans = new int[header.length][]; + PrintPiece headerPiece = null; + if (headerPresent) { + height -= margins.getHeaderTop(); + headerPiece = nextHeaderPiece(colSizes, height, headerHeights, + headerColSpans); + if (headerPiece == null) + return null; + height -= headerPiece.getSize().y; + } + + final boolean footerPresent = footer.length > 0; + final int[] footerHeights = new int[footer.length]; + final int[][] footerColSpans = new int[footer.length][]; + PrintPiece footerPiece = null; + + if (footerPresent) { + height -= margins.getFooterBottom(); + footerPiece = nextFooterPiece(colSizes, height, footerHeights, + footerColSpans); + if (footerPiece == null) { + PaperClipsUtil.dispose(headerPiece); + return null; + } + height -= footerPiece.getSize().y; + } + + final int firstRow = row; + final boolean topOpen = rowStarted; + final List bodyRows = new ArrayList<>(); + final List bodyColSpans = new ArrayList<>(); + + height -= margins.getBodyTop(headerPresent, topOpen); + final PrintPiece bodyPiece = nextBodyPiece(colSizes, height, bodyRows, + bodyColSpans, footerPresent); + if (bodyPiece == null) + return null; + final boolean bottomOpen = rowStarted; + + return createResult(colSizes, headerPiece, headerHeights, + headerColSpans, firstRow, topOpen, bodyPiece, + PaperClipsUtil.toIntArray(bodyRows), + PaperClipsUtil.toIntIntArray(bodyColSpans), bottomOpen, + footerPiece, footerHeights, footerColSpans); + } + + private PrintPiece nextHeaderPiece(final int[] colSizes, final int height, + final int[] rowHeights, final int[][] colSpans) { + return nextHeaderOrFooterPiece(colSizes, height, rowHeights, colSpans, + look.getMargins().getHeaderVerticalSpacing(), header); + } + + private PrintPiece nextFooterPiece(final int[] colSizes, final int height, + final int[] rowHeights, final int[][] colSpans) { + return nextHeaderOrFooterPiece(colSizes, height, rowHeights, colSpans, + look.getMargins().getFooterVerticalSpacing(), footer); + } + + private PrintPiece nextHeaderOrFooterPiece(final int[] colSizes, + final int height, final int[] rowHeights, final int[][] colSpans, + final int rowSpacing, GridCellIterator[][] headerOrFooter) { + int y = 0; + List entries = new ArrayList<>(); + for (int rowIndex = 0; rowIndex < headerOrFooter.length; rowIndex++) { + GridCellIterator[] row = cloneRow(headerOrFooter[rowIndex]); + + colSpans[rowIndex] = new int[row.length]; + for (int cellIndex = 0; cellIndex < row.length; cellIndex++) + colSpans[rowIndex][cellIndex] = row[cellIndex].getColspan(); + + PrintPiece rowPiece = nextRow(row, colSizes, height - y, false); + boolean hasNext = hasNext(row); + + if (rowPiece == null || hasNext) { + PaperClipsUtil.dispose(rowPiece); + for (Iterator iter = entries.iterator(); iter + .hasNext();) { + CompositeEntry entry = iter.next(); + entry.dispose(); + } + return null; + } + + int rowHeight = rowHeights[rowIndex] = rowPiece.getSize().y; + entries.add(new CompositeEntry(rowPiece, new Point(0, y))); + + y += rowHeight + rowSpacing; + } + + return new CompositePiece(entries); + } + + private PrintPiece nextBodyPiece(int[] colSizes, final int height, + final List rowHeights, final List colSpans, + final boolean footerPresent) { + final GridMargins margins = look.getMargins(); + final int rowSpacing = margins.getBodyVerticalSpacing(); + final int bodyBottomSpacingOpen = margins.getBodyBottom(footerPresent, + true); + final int bodyBottomSpacingClosed = margins.getBodyBottom(footerPresent, + false); + + int y = 0; + List entries = new ArrayList<>(); + while (hasNext()) { + GridCellIterator[] thisRow = cloneRow(body[row]); + PrintPiece rowPiece = nextRow(thisRow, colSizes, + height - y - bodyBottomSpacingClosed, rowStarted); + boolean hasNext = hasNext(thisRow); + + if ((cellClippingEnabled || entries.isEmpty()) + && (rowPiece == null || hasNext)) { + thisRow = cloneRow(body[row]); + rowPiece = nextRow(thisRow, colSizes, + height - y - bodyBottomSpacingOpen, true); + hasNext = true; + } + + if (rowPiece == null) + break; + + entries.add(new CompositeEntry(rowPiece, new Point(0, y))); + body[row] = thisRow; + + final int[] rowColSpans = new int[thisRow.length]; + for (int cellIndex = 0; cellIndex < rowColSpans.length; cellIndex++) + rowColSpans[cellIndex] = thisRow[cellIndex].getColspan(); + colSpans.add(rowColSpans); + + final int rowHeight = rowPiece.getSize().y; + rowHeights.add(new Integer(rowHeight)); + + rowStarted = hasNext; + if (hasNext) + break; + + y += rowHeight + rowSpacing; + row++; + } + + if (entries.isEmpty()) + return null; + + return new CompositePiece(entries); + } + + private static GridCellIterator[] cloneRow(GridCellIterator[] row) { + GridCellIterator[] result = row.clone(); + for (int i = 0; i < result.length; i++) + result[i] = result[i].copy(); + return result; + } + + private PrintPiece createResult(final int[] colSizes, + final PrintPiece headerPiece, final int[] headerRows, + final int[][] headerColSpans, final int firstRow, + final boolean topOpen, final PrintPiece bodyPiece, + final int[] bodyRows, final int[][] bodyColSpans, + final boolean bottomOpen, final PrintPiece footerPiece, + final int[] footerRows, final int[][] footerColSpans) { + if (bodyPiece == null) { + if (headerPiece != null) + headerPiece.dispose(); + if (footerPiece != null) + footerPiece.dispose(); + return null; + } + + List sections = new ArrayList<>(); + + PrintPiece lookPiece = new GridLookPainterPiece(look, colSizes, + headerRows, headerColSpans, firstRow, topOpen, bodyRows, + bodyColSpans, bottomOpen, footerRows, footerColSpans); + sections.add(new CompositeEntry(lookPiece, new Point(0, 0))); + + GridMargins margins = look.getMargins(); + final int x = margins.getLeft(); + + int y = 0; + if (headerPiece != null) { + y = margins.getHeaderTop(); + sections.add(new CompositeEntry(headerPiece, new Point(x, y))); + y += headerPiece.getSize().y; + } + + y += margins.getBodyTop(headerPiece != null, topOpen); + sections.add(new CompositeEntry(bodyPiece, new Point(x, y))); + y += bodyPiece.getSize().y + + margins.getBodyBottom(footerPiece != null, bottomOpen); + + if (footerPiece != null) + sections.add(new CompositeEntry(footerPiece, new Point(x, y))); + + return new CompositePiece(sections); + } + + public PrintIterator copy() { + return new GridIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridLookPainterPiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridLookPainterPiece.java index 9d1e01be4..949965de5 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridLookPainterPiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/grid/internal/GridLookPainterPiece.java @@ -1,125 +1,125 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid.internal; - -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.grid.GridLookPainter; -import org.eclipse.nebula.paperclips.core.grid.GridMargins; -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -class GridLookPainterPiece implements PrintPiece { - final GridLookPainter look; - - final int[] columns; - final int[] headerRows; - final int[][] headerColSpans; - final int firstRowIndex; - final boolean topOpen; - final int[] bodyRows; - final int[][] bodyColSpans; - final boolean bottomOpen; - final int[] footerRows; - final int[][] footerColSpans; - - final Point size; - - GridLookPainterPiece(GridLookPainter look, int[] colSizes, - int[] headerRows, int[][] headerColSpans, int firstRowIndex, - boolean topOpen, int[] bodyRows, int[][] bodyColSpans, - boolean bottomOpen, int[] footerRows, int[][] footerColSpans) { - Util.notNull(look); - - this.look = look; - this.columns = PaperClipsUtil.copy(colSizes); - this.headerRows = PaperClipsUtil.copy(headerRows); - this.headerColSpans = PaperClipsUtil.copy(headerColSpans); - - this.firstRowIndex = firstRowIndex; - this.topOpen = topOpen; - this.bodyRows = PaperClipsUtil.copy(bodyRows); - this.bodyColSpans = PaperClipsUtil.copy(bodyColSpans); - this.bottomOpen = bottomOpen; - - this.footerRows = PaperClipsUtil.copy(footerRows); - this.footerColSpans = PaperClipsUtil.copy(footerColSpans); - - GridMargins margins = look.getMargins(); - - Point size = calculateSize(margins, colSizes, headerRows, topOpen, - bodyRows, bottomOpen, footerRows); - this.size = size; - } - - private static Point calculateSize(GridMargins margins, int[] columns, - int[] headerRows, boolean topOpen, int[] bodyRows, - boolean bottomOpen, int[] footerRows) { - final boolean headerPresent = headerRows.length > 0; - final boolean footerPresent = footerRows.length > 0; - - int width = calculateWidth(margins, columns); - - int height = calculateBodyHeight(margins, topOpen, bodyRows, - bottomOpen, headerPresent, footerPresent); - if (headerPresent) - height += calculateHeaderHeight(margins, headerRows); - if (footerPresent) - height += calculateFooterHeight(margins, footerRows); - - return new Point(width, height); - } - - private static int calculateWidth(GridMargins margins, int[] columns) { - return margins.getLeft() + margins.getHorizontalSpacing() - * (columns.length - 1) + margins.getRight() - + PaperClipsUtil.sum(columns); - } - - private static int calculateBodyHeight(GridMargins margins, - boolean topOpen, int[] bodyRows, boolean bottomOpen, - final boolean headerPresent, final boolean footerPresent) { - return margins.getBodyTop(headerPresent, topOpen) - + margins.getBodyVerticalSpacing() * (bodyRows.length - 1) - + margins.getBodyBottom(footerPresent, bottomOpen) - + PaperClipsUtil.sum(bodyRows); - } - - private static int calculateHeaderHeight(GridMargins margins, - int[] headerRows) { - return margins.getHeaderTop() + margins.getHeaderVerticalSpacing() - * (headerRows.length - 1) + PaperClipsUtil.sum(headerRows); - } - - private static int calculateFooterHeight(GridMargins margins, - int[] footerRows) { - return margins.getFooterVerticalSpacing() * (footerRows.length - 1) - + margins.getFooterBottom() + PaperClipsUtil.sum(footerRows); - } - - public void dispose() { - look.dispose(); - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - public void paint(GC gc, int x, int y) { - look.paint(gc, x, y, columns, headerRows, headerColSpans, - firstRowIndex, topOpen, bodyRows, bodyColSpans, bottomOpen, - footerRows, footerColSpans); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid.internal; + +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.grid.GridLookPainter; +import org.eclipse.nebula.paperclips.core.grid.GridMargins; +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +class GridLookPainterPiece implements PrintPiece { + final GridLookPainter look; + + final int[] columns; + final int[] headerRows; + final int[][] headerColSpans; + final int firstRowIndex; + final boolean topOpen; + final int[] bodyRows; + final int[][] bodyColSpans; + final boolean bottomOpen; + final int[] footerRows; + final int[][] footerColSpans; + + final Point size; + + GridLookPainterPiece(GridLookPainter look, int[] colSizes, + int[] headerRows, int[][] headerColSpans, int firstRowIndex, + boolean topOpen, int[] bodyRows, int[][] bodyColSpans, + boolean bottomOpen, int[] footerRows, int[][] footerColSpans) { + Util.notNull(look); + + this.look = look; + this.columns = PaperClipsUtil.copy(colSizes); + this.headerRows = PaperClipsUtil.copy(headerRows); + this.headerColSpans = PaperClipsUtil.copy(headerColSpans); + + this.firstRowIndex = firstRowIndex; + this.topOpen = topOpen; + this.bodyRows = PaperClipsUtil.copy(bodyRows); + this.bodyColSpans = PaperClipsUtil.copy(bodyColSpans); + this.bottomOpen = bottomOpen; + + this.footerRows = PaperClipsUtil.copy(footerRows); + this.footerColSpans = PaperClipsUtil.copy(footerColSpans); + + GridMargins margins = look.getMargins(); + + Point size = calculateSize(margins, colSizes, headerRows, topOpen, + bodyRows, bottomOpen, footerRows); + this.size = size; + } + + private static Point calculateSize(GridMargins margins, int[] columns, + int[] headerRows, boolean topOpen, int[] bodyRows, + boolean bottomOpen, int[] footerRows) { + final boolean headerPresent = headerRows.length > 0; + final boolean footerPresent = footerRows.length > 0; + + int width = calculateWidth(margins, columns); + + int height = calculateBodyHeight(margins, topOpen, bodyRows, + bottomOpen, headerPresent, footerPresent); + if (headerPresent) + height += calculateHeaderHeight(margins, headerRows); + if (footerPresent) + height += calculateFooterHeight(margins, footerRows); + + return new Point(width, height); + } + + private static int calculateWidth(GridMargins margins, int[] columns) { + return margins.getLeft() + margins.getHorizontalSpacing() + * (columns.length - 1) + margins.getRight() + + PaperClipsUtil.sum(columns); + } + + private static int calculateBodyHeight(GridMargins margins, + boolean topOpen, int[] bodyRows, boolean bottomOpen, + final boolean headerPresent, final boolean footerPresent) { + return margins.getBodyTop(headerPresent, topOpen) + + margins.getBodyVerticalSpacing() * (bodyRows.length - 1) + + margins.getBodyBottom(footerPresent, bottomOpen) + + PaperClipsUtil.sum(bodyRows); + } + + private static int calculateHeaderHeight(GridMargins margins, + int[] headerRows) { + return margins.getHeaderTop() + margins.getHeaderVerticalSpacing() + * (headerRows.length - 1) + PaperClipsUtil.sum(headerRows); + } + + private static int calculateFooterHeight(GridMargins margins, + int[] footerRows) { + return margins.getFooterVerticalSpacing() * (footerRows.length - 1) + + margins.getFooterBottom() + PaperClipsUtil.sum(footerRows); + } + + public void dispose() { + look.dispose(); + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + public void paint(GC gc, int x, int y) { + look.paint(gc, x, y, columns, headerRows, headerColSpans, + firstRowIndex, topOpen, bodyRows, bodyColSpans, bottomOpen, + footerRows, footerColSpans); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/LayerEntryImpl.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/LayerEntryImpl.java index e5156c70e..446dc05cf 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/LayerEntryImpl.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/LayerEntryImpl.java @@ -1,96 +1,96 @@ -package org.eclipse.nebula.paperclips.core.internal; - -import org.eclipse.nebula.paperclips.core.LayerEntry; -import org.eclipse.nebula.paperclips.core.LayerEntryIterator; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -/** - * Instances in this class represent an entry in a LayerPrint. - * - * @author Matthew Hall - */ -public class LayerEntryImpl implements LayerEntry { - - private final Print target; - private final int align; - - /** - * Create a new layer entry. - * - * @param target - * the target print of this entry. - * @param align - * the horizontal alignment applied to the target. - */ - public LayerEntryImpl(Print target, int align) { - Util.notNull(target); - this.target = target; - this.align = checkAlign(align); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + align; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LayerEntry other = (LayerEntry) obj; - if (align != other.getHorizontalAlignment()) - return false; - if (target == null) { - if (other.getTarget() != null) - return false; - } else if (!target.equals(other.getTarget())) - return false; - return true; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.nebula.paperclips.core.internal.LayerEntry#getTarget() - */ - public Print getTarget() { - return target; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.nebula.paperclips.core.internal.LayerEntry# - * getHorizontalAlignment () - */ - public int getHorizontalAlignment() { - return align; - } - - private static int checkAlign(int align) { - return PaperClipsUtil.firstMatch(align, - new int[] { SWT.LEFT, SWT.CENTER, SWT.RIGHT }, SWT.LEFT); - } - - /** - * @param device - * @param gc - * @return the iterator - */ - public LayerEntryIterator iterator(Device device, GC gc) { - return new LayerEntryIteratorImpl(this, device, gc); - } +package org.eclipse.nebula.paperclips.core.internal; + +import org.eclipse.nebula.paperclips.core.LayerEntry; +import org.eclipse.nebula.paperclips.core.LayerEntryIterator; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +/** + * Instances in this class represent an entry in a LayerPrint. + * + * @author Matthew Hall + */ +public class LayerEntryImpl implements LayerEntry { + + private final Print target; + private final int align; + + /** + * Create a new layer entry. + * + * @param target + * the target print of this entry. + * @param align + * the horizontal alignment applied to the target. + */ + public LayerEntryImpl(Print target, int align) { + Util.notNull(target); + this.target = target; + this.align = checkAlign(align); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + align; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LayerEntry other = (LayerEntry) obj; + if (align != other.getHorizontalAlignment()) + return false; + if (target == null) { + if (other.getTarget() != null) + return false; + } else if (!target.equals(other.getTarget())) + return false; + return true; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.nebula.paperclips.core.internal.LayerEntry#getTarget() + */ + public Print getTarget() { + return target; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.nebula.paperclips.core.internal.LayerEntry# + * getHorizontalAlignment () + */ + public int getHorizontalAlignment() { + return align; + } + + private static int checkAlign(int align) { + return PaperClipsUtil.firstMatch(align, + new int[] { SWT.LEFT, SWT.CENTER, SWT.RIGHT }, SWT.LEFT); + } + + /** + * @param device + * @param gc + * @return the iterator + */ + public LayerEntryIterator iterator(Device device, GC gc) { + return new LayerEntryIteratorImpl(this, device, gc); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/LayerIterator.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/LayerIterator.java index 66bda59b6..bce717995 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/LayerIterator.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/LayerIterator.java @@ -1,126 +1,126 @@ -package org.eclipse.nebula.paperclips.core.internal; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.CompositeEntry; -import org.eclipse.nebula.paperclips.core.CompositePiece; -import org.eclipse.nebula.paperclips.core.LayerEntry; -import org.eclipse.nebula.paperclips.core.LayerEntryIterator; -import org.eclipse.nebula.paperclips.core.LayerPrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -public class LayerIterator implements PrintIterator { - LayerEntryIterator[] entries; - - public LayerIterator(LayerPrint print, Device device, GC gc) { - entries = new LayerEntryIteratorImpl[print.getEntries().length]; - LayerEntry[] e = print.getEntries(); - for (int i = 0; i < entries.length; i++) { - entries[i] = e[i].iterator(device, gc); - } - } - - public LayerIterator(LayerIterator that) { - this.entries = that.entries.clone(); - for (int i = 0; i < entries.length; i++) - if (entries[i].getTarget().hasNext()) - entries[i] = entries[i].copy(); - } - - public boolean hasNext() { - for (int i = 0; i < entries.length; i++) - if (entries[i].getTarget().hasNext()) - return true; - return false; - } - - public PrintPiece next(int width, int height) { - if (!hasNext()) - PaperClips.error("No more content"); //$NON-NLS-1$ - - PrintPiece[] pieces = nextPieces(width, height); - if (pieces == null) - return null; - - CompositeEntry[] entries = new CompositeEntry[pieces.length]; - for (int i = 0; i < entries.length; i++) { - PrintPiece piece = pieces[i]; - int offset = getHorzAlignmentOffset(this.entries[i].getAlignment(), - piece.getSize().x, width); - entries[i] = new CompositeEntry(piece, new Point(offset, 0)); - } - return new CompositePiece(entries); - } - - private PrintPiece[] nextPieces(int width, int height) { - LayerEntryIteratorImpl[] entries = (LayerEntryIteratorImpl[]) this.entries - .clone(); - - List pieces = new ArrayList<>(); - for (int i = 0; i < entries.length; i++) { - LayerEntryIteratorImpl entry = entries[i]; - if (entry.target.hasNext()) { - PrintPiece piece = PaperClips.next(entry.target, width, height); - - if (piece == null) { - for (Iterator iter = pieces.iterator(); iter - .hasNext();) - iter.next().dispose(); - return null; - } - pieces.add(piece); - } - } - - // Replace instance entries with the entries that were just consumed. - this.entries = entries; - - return pieces.toArray(new PrintPiece[pieces.size()]); - } - - private int getHorzAlignmentOffset(int alignment, int pieceWidth, - int totalWidth) { - int offset = 0; - switch (alignment) { - case SWT.CENTER: - offset = (totalWidth - pieceWidth) / 2; - break; - case SWT.RIGHT: - offset = totalWidth - pieceWidth; - break; - } - return offset; - } - - Point computeSize(PrintSizeStrategy strategy) { - Point size = new Point(0, 0); - for (int i = 0; i < entries.length; i++) { - LayerEntryIterator entry = entries[i]; - Point entrySize = strategy.computeSize(entry.getTarget()); - size.x = Math.max(size.x, entrySize.x); - size.y = Math.max(size.y, entrySize.y); - } - return size; - } - - public Point minimumSize() { - return computeSize(PrintSizeStrategy.MINIMUM); - } - - public Point preferredSize() { - return computeSize(PrintSizeStrategy.PREFERRED); - } - - public PrintIterator copy() { - return new LayerIterator(this); - } +package org.eclipse.nebula.paperclips.core.internal; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.CompositeEntry; +import org.eclipse.nebula.paperclips.core.CompositePiece; +import org.eclipse.nebula.paperclips.core.LayerEntry; +import org.eclipse.nebula.paperclips.core.LayerEntryIterator; +import org.eclipse.nebula.paperclips.core.LayerPrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +public class LayerIterator implements PrintIterator { + LayerEntryIterator[] entries; + + public LayerIterator(LayerPrint print, Device device, GC gc) { + entries = new LayerEntryIteratorImpl[print.getEntries().length]; + LayerEntry[] e = print.getEntries(); + for (int i = 0; i < entries.length; i++) { + entries[i] = e[i].iterator(device, gc); + } + } + + public LayerIterator(LayerIterator that) { + this.entries = that.entries.clone(); + for (int i = 0; i < entries.length; i++) + if (entries[i].getTarget().hasNext()) + entries[i] = entries[i].copy(); + } + + public boolean hasNext() { + for (int i = 0; i < entries.length; i++) + if (entries[i].getTarget().hasNext()) + return true; + return false; + } + + public PrintPiece next(int width, int height) { + if (!hasNext()) + PaperClips.error("No more content"); //$NON-NLS-1$ + + PrintPiece[] pieces = nextPieces(width, height); + if (pieces == null) + return null; + + CompositeEntry[] entries = new CompositeEntry[pieces.length]; + for (int i = 0; i < entries.length; i++) { + PrintPiece piece = pieces[i]; + int offset = getHorzAlignmentOffset(this.entries[i].getAlignment(), + piece.getSize().x, width); + entries[i] = new CompositeEntry(piece, new Point(offset, 0)); + } + return new CompositePiece(entries); + } + + private PrintPiece[] nextPieces(int width, int height) { + LayerEntryIteratorImpl[] entries = (LayerEntryIteratorImpl[]) this.entries + .clone(); + + List pieces = new ArrayList<>(); + for (int i = 0; i < entries.length; i++) { + LayerEntryIteratorImpl entry = entries[i]; + if (entry.target.hasNext()) { + PrintPiece piece = PaperClips.next(entry.target, width, height); + + if (piece == null) { + for (Iterator iter = pieces.iterator(); iter + .hasNext();) + iter.next().dispose(); + return null; + } + pieces.add(piece); + } + } + + // Replace instance entries with the entries that were just consumed. + this.entries = entries; + + return pieces.toArray(new PrintPiece[pieces.size()]); + } + + private int getHorzAlignmentOffset(int alignment, int pieceWidth, + int totalWidth) { + int offset = 0; + switch (alignment) { + case SWT.CENTER: + offset = (totalWidth - pieceWidth) / 2; + break; + case SWT.RIGHT: + offset = totalWidth - pieceWidth; + break; + } + return offset; + } + + Point computeSize(PrintSizeStrategy strategy) { + Point size = new Point(0, 0); + for (int i = 0; i < entries.length; i++) { + LayerEntryIterator entry = entries[i]; + Point entrySize = strategy.computeSize(entry.getTarget()); + size.x = Math.max(size.x, entrySize.x); + size.y = Math.max(size.y, entrySize.y); + } + return size; + } + + public Point minimumSize() { + return computeSize(PrintSizeStrategy.MINIMUM); + } + + public Point preferredSize() { + return computeSize(PrintSizeStrategy.PREFERRED); + } + + public PrintIterator copy() { + return new LayerIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/RotatePiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/RotatePiece.java index 476519dea..7da3ac86b 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/RotatePiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/RotatePiece.java @@ -1,104 +1,104 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ - -package org.eclipse.nebula.paperclips.core.internal; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Transform; - -public final class RotatePiece implements PrintPiece { - private final Device device; - private final PrintPiece target; - private final int angle; - private final Point size; - - private Transform oldTransform; - private Transform transform; - - public RotatePiece(Device device, PrintPiece target, int angle, Point size) { - Util.notNull(device, target, size); - this.device = device; - this.target = target; - this.angle = angle; - this.size = size; - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - private Transform getOldTransform() { - if (oldTransform == null) - oldTransform = new Transform(device); - return oldTransform; - } - - private Transform getTransform() { - if (transform == null) - transform = new Transform(device); - return transform; - } - - public void paint(GC gc, int x, int y) { - Transform oldTransform = getOldTransform(); - gc.getTransform(oldTransform); - - Transform transform = getTransform(); - gc.getTransform(transform); - transform.translate(x, y); - rotateTransform(transform); - gc.setTransform(transform); - - target.paint(gc, 0, 0); - - gc.setTransform(oldTransform); - } - - private void rotateTransform(Transform transform) { - switch (angle) { - case 90: - transform.translate(0, size.y); - break; - case 180: - transform.translate(size.x, size.y); - break; - case 270: - transform.translate(size.x, 0); - break; - default: - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Rotation angle must be 90, 180 or 270."); //$NON-NLS-1$ - } - transform.rotate(-angle); // reverse the angle since Transform.rotate - // goes clockwise - } - - public void dispose() { - if (oldTransform != null) { - oldTransform.dispose(); - oldTransform = null; - } - if (transform != null) { - transform.dispose(); - transform = null; - } - target.dispose(); - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ + +package org.eclipse.nebula.paperclips.core.internal; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Transform; + +public final class RotatePiece implements PrintPiece { + private final Device device; + private final PrintPiece target; + private final int angle; + private final Point size; + + private Transform oldTransform; + private Transform transform; + + public RotatePiece(Device device, PrintPiece target, int angle, Point size) { + Util.notNull(device, target, size); + this.device = device; + this.target = target; + this.angle = angle; + this.size = size; + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + private Transform getOldTransform() { + if (oldTransform == null) + oldTransform = new Transform(device); + return oldTransform; + } + + private Transform getTransform() { + if (transform == null) + transform = new Transform(device); + return transform; + } + + public void paint(GC gc, int x, int y) { + Transform oldTransform = getOldTransform(); + gc.getTransform(oldTransform); + + Transform transform = getTransform(); + gc.getTransform(transform); + transform.translate(x, y); + rotateTransform(transform); + gc.setTransform(transform); + + target.paint(gc, 0, 0); + + gc.setTransform(oldTransform); + } + + private void rotateTransform(Transform transform) { + switch (angle) { + case 90: + transform.translate(0, size.y); + break; + case 180: + transform.translate(size.x, size.y); + break; + case 270: + transform.translate(size.x, 0); + break; + default: + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Rotation angle must be 90, 180 or 270."); //$NON-NLS-1$ + } + transform.rotate(-angle); // reverse the angle since Transform.rotate + // goes clockwise + } + + public void dispose() { + if (oldTransform != null) { + oldTransform.dispose(); + oldTransform = null; + } + if (transform != null) { + transform.dispose(); + transform = null; + } + target.dispose(); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/piece/EmptyPiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/piece/EmptyPiece.java index 39d53bfa4..4ebf6a9d8 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/piece/EmptyPiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/piece/EmptyPiece.java @@ -1,48 +1,48 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.internal.piece; - -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A blank PrintPiece of a predetermined size - * - * @author matt - */ -public class EmptyPiece implements PrintPiece { - private final Point size; - - /** - * @param size - */ - public EmptyPiece(Point size) { - Util.notNull(size); - this.size = size; - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - public void paint(GC gc, int x, int y) { - // Nothing to paint - } - - public void dispose() { - // Nothing to dispose - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.internal.piece; + +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A blank PrintPiece of a predetermined size + * + * @author matt + */ +public class EmptyPiece implements PrintPiece { + private final Point size; + + /** + * @param size + */ + public EmptyPiece(Point size) { + Util.notNull(size); + this.size = size; + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + public void paint(GC gc, int x, int y) { + // Nothing to paint + } + + public void dispose() { + // Nothing to dispose + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/PaperClipsUtil.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/PaperClipsUtil.java index c0977a6b9..37512c2b2 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/PaperClipsUtil.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/PaperClipsUtil.java @@ -1,234 +1,234 @@ -/* - * Copyright (c) 2007-2008 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ - -package org.eclipse.nebula.paperclips.core.internal.util; - -import java.util.Iterator; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.PrintPiece; - -/** - * Convenience methods specific to PaperClips - * - * @author Matthew Hall - */ -public class PaperClipsUtil { - private PaperClipsUtil() { - } // no instances - - /** - * Disposes the print piece if not null. - * - * @param piece - * the print piece to dispose. - */ - public static void dispose(final PrintPiece piece) { - if (piece != null) - piece.dispose(); - } - - /** - * Disposes the arguments that are not null. - * - * @param p1 - * print piece to dispose - * @param p2 - * print piece to dispose - */ - public static void dispose(PrintPiece p1, PrintPiece p2) { - dispose(p1); - dispose(p2); - } - - /** - * Disposes the print pieces that are not null. - * - * @param pieces - * array of print pieces to dispose. - */ - public static void dispose(final PrintPiece[] pieces) { - if (pieces != null) - for (int i = 0; i < pieces.length; i++) - dispose(pieces[i]); - } - - /** - * Disposes the print pieces in the array from start (inclusive) to end - * (exclusive). - * - * @param pages - * array of print pieces to dispose. - * @param start - * the start index. - * @param end - * the end index. - */ - public static void dispose(PrintPiece[] pages, int start, int end) { - for (int i = start; i < end; i++) - pages[i].dispose(); - } - - /** - * Disposes the print pieces in the list. - * - * @param pages - * list of print pieces to dispose. - */ - public static void dispose(List pages) { - for (Iterator it = pages.iterator(); it.hasNext();) - it.next().dispose(); - pages.clear(); - } - - /** - * Disposes the print pieces that are not null. - * - * @param piece - * a print piece to dispose - * @param pieces - * array of print pieces to dispose - */ - public static void dispose(PrintPiece piece, final PrintPiece[] pieces) { - dispose(piece); - dispose(pieces); - } - - /** - * Returns a copy of the array. - * - * @param array - * the array to copy - * @return a copy of the array. - */ - public static int[] copy(int[] array) { - Util.notNull(array); - return array.clone(); - } - - /** - * Returns a deep copy of the array. - * - * @param array - * the array to copy - * @return a copy of the array. - */ - public static int[][] copy(int[][] array) { - Util.notNull(array); - int[][] result = array.clone(); - for (int i = 0; i < result.length; i++) - result[i] = copy(result[i]); - return result; - } - - /** - * Returns the sum of all elements in the array. - * - * @param array - * the array - * @return the sum of all elements in the array. - */ - public static int sum(int[] array) { - return PaperClipsUtil.sum(array, 0, array.length); - } - - /** - * Returns the sum of all elements in the array in the range - * [start, start+count). - * - * @param array - * the array containing the elements to add up. - * @param start - * the index of the first element to add. - * @param count - * the number of elements to add. - * @return the sum of all elements in the array in the specified range. - */ - public static int sum(final int[] array, final int start, final int count) { - Util.notNull(array); - int result = 0; - final int end = start + count; - for (int i = start; i < end; i++) - result += array[i]; - return result; - } - - /** - * Returns the sum of all elements in the array at the given indices. - * - * @param array - * the array of elements to add up. - * @param indices - * the indices of the elements in the array to add up. - * @return the sum of all elements in the array at the given indices. - */ - public static int sumByIndex(final int[] array, final int[] indices) { - Util.notNull(array); - int result = 0; - for (int i = 0; i < indices.length; i++) - result += array[indices[i]]; - return result; - } - - /** - * Converts the argument to an int[] array. - * - * @param list - * a List of Integers. - * @return a primitive int[] array. - */ - public static int[] toIntArray(List list) { - final int[] array = new int[list.size()]; - for (int i = 0; i < array.length; i++) - array[i] = list.get(i).intValue(); - return array; - } - - /** - * Converts the argument to an int[][] array. - * - * @param list - * a List of int[] arrays. - * @return a primitive int[][] array. - */ - public static int[][] toIntIntArray(List list) { - final int[][] array = new int[list.size()][]; - for (int i = 0; i < array.length; i++) - array[i] = list.get(i); - return array; - } - - /** - * Returns the first element in masks where (value & mask[index]) == - * mask[index]. - * - * @param value - * the value to match - * @param masks - * the possible values. - * @param defaultMask - * the value to return if no match is found. - * @return the first value in possibleValues which is a bitwise match to - * value, or 0 if none is found. - */ - public static int firstMatch(int value, int[] masks, int defaultMask) { - Util.notNull(masks); - for (int i = 0; i < masks.length; i++) { - int mask = masks[i]; - if ((value & mask) == mask) - return mask; - } - return defaultMask; - } -} +/* + * Copyright (c) 2007-2008 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ + +package org.eclipse.nebula.paperclips.core.internal.util; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.PrintPiece; + +/** + * Convenience methods specific to PaperClips + * + * @author Matthew Hall + */ +public class PaperClipsUtil { + private PaperClipsUtil() { + } // no instances + + /** + * Disposes the print piece if not null. + * + * @param piece + * the print piece to dispose. + */ + public static void dispose(final PrintPiece piece) { + if (piece != null) + piece.dispose(); + } + + /** + * Disposes the arguments that are not null. + * + * @param p1 + * print piece to dispose + * @param p2 + * print piece to dispose + */ + public static void dispose(PrintPiece p1, PrintPiece p2) { + dispose(p1); + dispose(p2); + } + + /** + * Disposes the print pieces that are not null. + * + * @param pieces + * array of print pieces to dispose. + */ + public static void dispose(final PrintPiece[] pieces) { + if (pieces != null) + for (int i = 0; i < pieces.length; i++) + dispose(pieces[i]); + } + + /** + * Disposes the print pieces in the array from start (inclusive) to end + * (exclusive). + * + * @param pages + * array of print pieces to dispose. + * @param start + * the start index. + * @param end + * the end index. + */ + public static void dispose(PrintPiece[] pages, int start, int end) { + for (int i = start; i < end; i++) + pages[i].dispose(); + } + + /** + * Disposes the print pieces in the list. + * + * @param pages + * list of print pieces to dispose. + */ + public static void dispose(List pages) { + for (Iterator it = pages.iterator(); it.hasNext();) + it.next().dispose(); + pages.clear(); + } + + /** + * Disposes the print pieces that are not null. + * + * @param piece + * a print piece to dispose + * @param pieces + * array of print pieces to dispose + */ + public static void dispose(PrintPiece piece, final PrintPiece[] pieces) { + dispose(piece); + dispose(pieces); + } + + /** + * Returns a copy of the array. + * + * @param array + * the array to copy + * @return a copy of the array. + */ + public static int[] copy(int[] array) { + Util.notNull(array); + return array.clone(); + } + + /** + * Returns a deep copy of the array. + * + * @param array + * the array to copy + * @return a copy of the array. + */ + public static int[][] copy(int[][] array) { + Util.notNull(array); + int[][] result = array.clone(); + for (int i = 0; i < result.length; i++) + result[i] = copy(result[i]); + return result; + } + + /** + * Returns the sum of all elements in the array. + * + * @param array + * the array + * @return the sum of all elements in the array. + */ + public static int sum(int[] array) { + return PaperClipsUtil.sum(array, 0, array.length); + } + + /** + * Returns the sum of all elements in the array in the range + * [start, start+count). + * + * @param array + * the array containing the elements to add up. + * @param start + * the index of the first element to add. + * @param count + * the number of elements to add. + * @return the sum of all elements in the array in the specified range. + */ + public static int sum(final int[] array, final int start, final int count) { + Util.notNull(array); + int result = 0; + final int end = start + count; + for (int i = start; i < end; i++) + result += array[i]; + return result; + } + + /** + * Returns the sum of all elements in the array at the given indices. + * + * @param array + * the array of elements to add up. + * @param indices + * the indices of the elements in the array to add up. + * @return the sum of all elements in the array at the given indices. + */ + public static int sumByIndex(final int[] array, final int[] indices) { + Util.notNull(array); + int result = 0; + for (int i = 0; i < indices.length; i++) + result += array[indices[i]]; + return result; + } + + /** + * Converts the argument to an int[] array. + * + * @param list + * a List of Integers. + * @return a primitive int[] array. + */ + public static int[] toIntArray(List list) { + final int[] array = new int[list.size()]; + for (int i = 0; i < array.length; i++) + array[i] = list.get(i).intValue(); + return array; + } + + /** + * Converts the argument to an int[][] array. + * + * @param list + * a List of int[] arrays. + * @return a primitive int[][] array. + */ + public static int[][] toIntIntArray(List list) { + final int[][] array = new int[list.size()][]; + for (int i = 0; i < array.length; i++) + array[i] = list.get(i); + return array; + } + + /** + * Returns the first element in masks where (value & mask[index]) == + * mask[index]. + * + * @param value + * the value to match + * @param masks + * the possible values. + * @param defaultMask + * the value to return if no match is found. + * @return the first value in possibleValues which is a bitwise match to + * value, or 0 if none is found. + */ + public static int firstMatch(int value, int[] masks, int defaultMask) { + Util.notNull(masks); + for (int i = 0; i < masks.length; i++) { + int mask = masks[i]; + if ((value & mask) == mask) + return mask; + } + return defaultMask; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/PrintSizeStrategy.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/PrintSizeStrategy.java index d730e6cea..406487705 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/PrintSizeStrategy.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/PrintSizeStrategy.java @@ -1,52 +1,52 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.internal.util; - -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.swt.graphics.Point; - -/** - * The static instance members of this class aid in the calculation of prints - * and help abstract out the minimum/preferred size concepts to simplify - * algorithms. - * - * @author Matthew Hall - */ -public abstract class PrintSizeStrategy { - /** Compute the minimum size */ - public static final PrintSizeStrategy MINIMUM = new PrintSizeStrategy() { - public Point computeSize(PrintIterator iter) { - return iter.minimumSize(); - } - }; - - /** Compute the preferred size. */ - public static final PrintSizeStrategy PREFERRED = new PrintSizeStrategy() { - public Point computeSize(PrintIterator iter) { - return iter.preferredSize(); - } - }; - - private PrintSizeStrategy() { - } - - /** - * Computes the size of the PrintIterator. - * - * @param print - * the iterator - * @return the computed size of the PrintIterator. - */ - public abstract Point computeSize(PrintIterator print); +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.internal.util; + +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.swt.graphics.Point; + +/** + * The static instance members of this class aid in the calculation of prints + * and help abstract out the minimum/preferred size concepts to simplify + * algorithms. + * + * @author Matthew Hall + */ +public abstract class PrintSizeStrategy { + /** Compute the minimum size */ + public static final PrintSizeStrategy MINIMUM = new PrintSizeStrategy() { + public Point computeSize(PrintIterator iter) { + return iter.minimumSize(); + } + }; + + /** Compute the preferred size. */ + public static final PrintSizeStrategy PREFERRED = new PrintSizeStrategy() { + public Point computeSize(PrintIterator iter) { + return iter.preferredSize(); + } + }; + + private PrintSizeStrategy() { + } + + /** + * Computes the size of the PrintIterator. + * + * @param print + * the iterator + * @return the computed size of the PrintIterator. + */ + public abstract Point computeSize(PrintIterator print); } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/ResourcePool.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/ResourcePool.java index b4c974a91..237da48bf 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/ResourcePool.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/ResourcePool.java @@ -1,110 +1,110 @@ -/* - * Copyright (c) 2007-2008 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ - -package org.eclipse.nebula.paperclips.core.internal.util; - -import java.util.HashMap; -import java.util.Map; -import java.util.WeakHashMap; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; - -/** - * Manages a pool of graphics resources for a graphics device (fonts, colors). - * - * @author Matthew Hall - */ -public class ResourcePool { - private static Map devices = new WeakHashMap<>(); - - /** - * Returns a SharedGraphics which creates resources on the given device. - * - * @param device - * the device which resources will be created on. - * @return a SharedGraphics which creates resources on the given device. - */ - public synchronized static ResourcePool forDevice(Device device) { - Util.notNull(device); - notDisposed(device); - - ResourcePool sharedGraphics = devices.get(device); - if (sharedGraphics == null) { - sharedGraphics = new ResourcePool(device); - devices.put(device, sharedGraphics); - } - return sharedGraphics; - } - - private static void notDisposed(Device device) { - if (device.isDisposed()) - PaperClips.error(SWT.ERROR_DEVICE_DISPOSED); - } - - private final Device device; - private final Map fonts; - private final Map colors; - - private ResourcePool(Device device) { - this.device = device; - this.fonts = new HashMap<>(); - this.colors = new HashMap<>(); - } - - /** - * Returns a font for the passed in FontData. - * - * @param fontData - * FontData describing the required font. - * @return a font for the passed in FontData. - */ - public Font getFont(FontData fontData) { - if (fontData == null) - return null; - notDisposed(device); - - Font font = fonts.get(fontData); - if (font == null) { - font = new Font(device, fontData); - fonts.put(SWTUtil.copy(fontData), font); - } - return font; - } - - /** - * Returns a color for the passed in RGB. - * - * @param rgb - * RGB describing the required color. - * @return a color for the passed in RGB. - */ - public Color getColor(RGB rgb) { - if (rgb == null) - return null; - notDisposed(device); - - Color color = colors.get(rgb); - if (color == null) { - color = new Color(device, rgb); - colors.put(SWTUtil.copy(rgb), color); - } - return color; - } +/* + * Copyright (c) 2007-2008 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ + +package org.eclipse.nebula.paperclips.core.internal.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.WeakHashMap; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; + +/** + * Manages a pool of graphics resources for a graphics device (fonts, colors). + * + * @author Matthew Hall + */ +public class ResourcePool { + private static Map devices = new WeakHashMap<>(); + + /** + * Returns a SharedGraphics which creates resources on the given device. + * + * @param device + * the device which resources will be created on. + * @return a SharedGraphics which creates resources on the given device. + */ + public synchronized static ResourcePool forDevice(Device device) { + Util.notNull(device); + notDisposed(device); + + ResourcePool sharedGraphics = devices.get(device); + if (sharedGraphics == null) { + sharedGraphics = new ResourcePool(device); + devices.put(device, sharedGraphics); + } + return sharedGraphics; + } + + private static void notDisposed(Device device) { + if (device.isDisposed()) + PaperClips.error(SWT.ERROR_DEVICE_DISPOSED); + } + + private final Device device; + private final Map fonts; + private final Map colors; + + private ResourcePool(Device device) { + this.device = device; + this.fonts = new HashMap<>(); + this.colors = new HashMap<>(); + } + + /** + * Returns a font for the passed in FontData. + * + * @param fontData + * FontData describing the required font. + * @return a font for the passed in FontData. + */ + public Font getFont(FontData fontData) { + if (fontData == null) + return null; + notDisposed(device); + + Font font = fonts.get(fontData); + if (font == null) { + font = new Font(device, fontData); + fonts.put(SWTUtil.copy(fontData), font); + } + return font; + } + + /** + * Returns a color for the passed in RGB. + * + * @param rgb + * RGB describing the required color. + * @return a color for the passed in RGB. + */ + public Color getColor(RGB rgb) { + if (rgb == null) + return null; + notDisposed(device); + + Color color = colors.get(rgb); + if (color == null) { + color = new Color(device, rgb); + colors.put(SWTUtil.copy(rgb), color); + } + return color; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/SWTUtil.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/SWTUtil.java index 22bb5bb13..0da862aba 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/SWTUtil.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/SWTUtil.java @@ -1,190 +1,190 @@ -/* - * Copyright (c) 2008 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.internal.util; - -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.PaletteData; -import org.eclipse.swt.graphics.RGB; - -/** - * Utility methods for dealing with SWT objects - * - * @author Matthew Hall - */ -public class SWTUtil { - - /** - * Returns a defensive copy of the passed in FontData. - * - * @param fontData - * the FontData to copy. May be null. - * @return a copy of the passed in FontData, or null if the argument was - * null. - */ - public static FontData copy(FontData fontData) { - return fontData == null ? null : new FontData(fontData.getName(), - fontData.getHeight(), fontData.getStyle()); - } - - /** - * Returns a defensive copy of the passed in RGB. - * - * @param rgb - * the RGB to copy. May be null. - * @return a copy of the passed in RGB, or null if the argument was null. - */ - public static RGB copy(RGB rgb) { - return rgb == null ? null : new RGB(rgb.red, rgb.green, rgb.blue); - } - - /** - * Returns an RGB representing the color described by the argument. - *

- * Sample colors:
- * 0xFFFFFF: white
- * 0x000000: black
- * 0xFF0000: red
- * 0x00FF00: green
- * 0x0000FF: blue - * - * @param rgb - * an integer containing the red, green and blue components in - * the 0xFF0000, 0x00FF00, and 0x0000FF positions, respectively. - * @return an RGB representing the color described by the argument. - */ - public static RGB deriveRGB(final int rgb) { - int red = (rgb >> 16) & 0xFF; - int green = (rgb >> 8) & 0xFF; - int blue = rgb & 0xFF; - return new RGB(red, green, blue); - } - - /** - * Returns whether the PaletteData arguments are equivalent. - * - * @param left - * the left PaletteData - * @param right - * the right PaletteData - * @return whether the PaletteData arguments are equivalent. - */ - public static boolean equal(PaletteData left, PaletteData right) { - if (left == right) - return true; - if (left == null || right == null) - return false; - return left.isDirect == right.isDirect - && left.blueMask == right.blueMask - && left.blueShift == right.blueShift - && left.greenMask == right.greenMask - && left.greenShift == right.greenShift - && left.redMask == right.redMask - && left.redShift == right.redShift - && Util.equal(left.colors, right.colors); - } - - /** - * Returns a hash code for the PaletteData. - * - * @param data - * the PaletteData - * @return a hash code for the PaletteData. - */ - public static int hashCode(PaletteData data) { - final int prime = 31; - int result = 1; - result = prime * result + (data.isDirect ? 1231 : 1237); - result = prime * result + data.blueMask; - result = prime * result + data.blueShift; - result = prime * result + data.greenMask; - result = prime * result + data.greenShift; - result = prime * result + data.redMask; - result = prime * result + data.redShift; - result = prime * result + hashCode(data.colors); - return result; - } - - private static int hashCode(Object[] array) { - int prime = 31; - if (array == null) - return 0; - int result = 1; - for (int index = 0; index < array.length; index++) { - result = prime * result - + (array[index] == null ? 0 : array[index].hashCode()); - } - return result; - } - - /** - * Returns whether the ImageData arguments are equivalent. - * - * @param left - * the left ImageData - * @param right - * the right ImageData - * @return whether the ImageData arguments are equivalent. - */ - public static boolean equal(ImageData left, ImageData right) { - if (left == right) - return true; - if (left == null || right == null) - return false; - if (left.width != right.width || left.height != right.height) - return false; - if (!equal(left.palette, right.palette)) - return false; - - final int width = left.width; - int[] leftPixels = new int[width]; - int[] rightPixels = new int[width]; - byte[] leftAlphas = new byte[width]; - byte[] rightAlphas = new byte[width]; - for (int y = 0; y < left.height; y++) { - left.getAlphas(0, y, width, leftAlphas, 0); - right.getAlphas(0, y, width, rightAlphas, 0); - if (!Util.equal(leftAlphas, rightAlphas)) - return false; - - left.getPixels(0, y, width, leftPixels, 0); - right.getPixels(0, y, width, rightPixels, 0); - if (!Util.equal(leftPixels, rightPixels)) { - for (int x = 0; x < width; x++) { - if (leftAlphas[x] != 0 && leftPixels[x] != rightPixels[x]) - return false; - } - } - } - - return true; - } - - /** - * Returns a hash code for the ImageData - * - * @param data - * the ImageData - * @return a hash code for the ImageData - */ - public static int hashCode(ImageData data) { - final int prime = 31; - int result = 1; - result = prime * result + data.width; - result = prime * result + data.height; - result = prime * result + hashCode(data.palette); - // Neglect pixel data - return result; - } -} +/* + * Copyright (c) 2008 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.internal.util; + +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.RGB; + +/** + * Utility methods for dealing with SWT objects + * + * @author Matthew Hall + */ +public class SWTUtil { + + /** + * Returns a defensive copy of the passed in FontData. + * + * @param fontData + * the FontData to copy. May be null. + * @return a copy of the passed in FontData, or null if the argument was + * null. + */ + public static FontData copy(FontData fontData) { + return fontData == null ? null : new FontData(fontData.getName(), + fontData.getHeight(), fontData.getStyle()); + } + + /** + * Returns a defensive copy of the passed in RGB. + * + * @param rgb + * the RGB to copy. May be null. + * @return a copy of the passed in RGB, or null if the argument was null. + */ + public static RGB copy(RGB rgb) { + return rgb == null ? null : new RGB(rgb.red, rgb.green, rgb.blue); + } + + /** + * Returns an RGB representing the color described by the argument. + *

+ * Sample colors:
+ * 0xFFFFFF: white
+ * 0x000000: black
+ * 0xFF0000: red
+ * 0x00FF00: green
+ * 0x0000FF: blue + * + * @param rgb + * an integer containing the red, green and blue components in + * the 0xFF0000, 0x00FF00, and 0x0000FF positions, respectively. + * @return an RGB representing the color described by the argument. + */ + public static RGB deriveRGB(final int rgb) { + int red = (rgb >> 16) & 0xFF; + int green = (rgb >> 8) & 0xFF; + int blue = rgb & 0xFF; + return new RGB(red, green, blue); + } + + /** + * Returns whether the PaletteData arguments are equivalent. + * + * @param left + * the left PaletteData + * @param right + * the right PaletteData + * @return whether the PaletteData arguments are equivalent. + */ + public static boolean equal(PaletteData left, PaletteData right) { + if (left == right) + return true; + if (left == null || right == null) + return false; + return left.isDirect == right.isDirect + && left.blueMask == right.blueMask + && left.blueShift == right.blueShift + && left.greenMask == right.greenMask + && left.greenShift == right.greenShift + && left.redMask == right.redMask + && left.redShift == right.redShift + && Util.equal(left.colors, right.colors); + } + + /** + * Returns a hash code for the PaletteData. + * + * @param data + * the PaletteData + * @return a hash code for the PaletteData. + */ + public static int hashCode(PaletteData data) { + final int prime = 31; + int result = 1; + result = prime * result + (data.isDirect ? 1231 : 1237); + result = prime * result + data.blueMask; + result = prime * result + data.blueShift; + result = prime * result + data.greenMask; + result = prime * result + data.greenShift; + result = prime * result + data.redMask; + result = prime * result + data.redShift; + result = prime * result + hashCode(data.colors); + return result; + } + + private static int hashCode(Object[] array) { + int prime = 31; + if (array == null) + return 0; + int result = 1; + for (int index = 0; index < array.length; index++) { + result = prime * result + + (array[index] == null ? 0 : array[index].hashCode()); + } + return result; + } + + /** + * Returns whether the ImageData arguments are equivalent. + * + * @param left + * the left ImageData + * @param right + * the right ImageData + * @return whether the ImageData arguments are equivalent. + */ + public static boolean equal(ImageData left, ImageData right) { + if (left == right) + return true; + if (left == null || right == null) + return false; + if (left.width != right.width || left.height != right.height) + return false; + if (!equal(left.palette, right.palette)) + return false; + + final int width = left.width; + int[] leftPixels = new int[width]; + int[] rightPixels = new int[width]; + byte[] leftAlphas = new byte[width]; + byte[] rightAlphas = new byte[width]; + for (int y = 0; y < left.height; y++) { + left.getAlphas(0, y, width, leftAlphas, 0); + right.getAlphas(0, y, width, rightAlphas, 0); + if (!Util.equal(leftAlphas, rightAlphas)) + return false; + + left.getPixels(0, y, width, leftPixels, 0); + right.getPixels(0, y, width, rightPixels, 0); + if (!Util.equal(leftPixels, rightPixels)) { + for (int x = 0; x < width; x++) { + if (leftAlphas[x] != 0 && leftPixels[x] != rightPixels[x]) + return false; + } + } + } + + return true; + } + + /** + * Returns a hash code for the ImageData + * + * @param data + * the ImageData + * @return a hash code for the ImageData + */ + public static int hashCode(ImageData data) { + final int prime = 31; + int result = 1; + result = prime * result + data.width; + result = prime * result + data.height; + result = prime * result + hashCode(data.palette); + // Neglect pixel data + return result; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/Util.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/Util.java index c49033789..681986da6 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/Util.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/internal/util/Util.java @@ -1,173 +1,173 @@ -/* - * Copyright (c) 2007-2008 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.internal.util; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.swt.SWT; - -/** - * General use convenience methods: null checking, equality - * - * @author Matthew Hall - */ -public class Util { - /** - * Returns whether the objects are of the same class. - * - * @param left - * object to test - * @param right - * object to test - * @return whether the objects are of the same class. - */ - public static boolean sameClass(Object left, Object right) { - if (left == right) - return true; - if (left == null || right == null) - return false; - return left.getClass() == right.getClass(); - } - - /** - * Returns whether the arguments are equal. - * - * @param left - * object to test - * @param right - * object to test - * @return whether the arguments are equal. - */ - public static boolean equal(Object left, Object right) { - if (!sameClass(left, right)) - return false; - if (left == right) - return true; - Class clazz = left.getClass(); - if (clazz.isArray()) { - Class componentType = clazz.getComponentType(); - if (componentType.isPrimitive()) { - if (componentType == Byte.TYPE) - return Arrays.equals((byte[]) left, (byte[]) right); - if (componentType == Short.TYPE) - return Arrays.equals((short[]) left, (short[]) right); - if (componentType == Integer.TYPE) - return Arrays.equals((int[]) left, (int[]) right); - if (componentType == Long.TYPE) - return Arrays.equals((long[]) left, (long[]) right); - if (componentType == Character.TYPE) - return Arrays.equals((char[]) left, (char[]) right); - if (componentType == Float.TYPE) - return Arrays.equals((float[]) left, (float[]) right); - if (componentType == Double.TYPE) - return Arrays.equals((double[]) left, (double[]) right); - if (componentType == Boolean.TYPE) - return Arrays.equals((boolean[]) left, (boolean[]) right); - } - return equal((Object[]) left, (Object[]) right); - } - return left.equals(right); - } - - private static boolean equal(Object[] left, Object[] right) { - int length = left.length; - if (length != right.length) - return false; - for (int i = 0; i < length; i++) - if (!equal(left[i], right[i])) - return false; - return true; - } - - /** - * Returns whether the arguments are equal. - * - * @param left - * double value to test - * @param right - * double value to test - * @return whether the arguments are equal. - */ - public static boolean equal(double left, double right) { - return Double.doubleToLongBits(left) == Double.doubleToLongBits(right); - } - - /** - * Triggers a SWT.ERROR_NULL_ARGUMENT exception if the argument or any of - * its elements is null. - * - * @param list - * a list to test for null elements. - */ - public static void noNulls(List list) { - notNull(list); - if (list.contains(null)) - PaperClips.error(SWT.ERROR_NULL_ARGUMENT); - } - - /** - * Triggers a SWT.ERROR_NULL_ARGUMENT exception if the argument or any of - * its elements is null. - * - * @param objs - * an array to test for null elements. - */ - public static void noNulls(Object[] objs) { - notNull(objs); - for (int i = 0; i < objs.length; i++) - notNull(objs[i]); - } - - /** - * Triggers a SWT.ERROR_NULL_ARGUMENT exception if the argument is null. - * - * @param obj - * the object to test for null. - */ - public static void notNull(Object obj) { - if (obj == null) - PaperClips.error(SWT.ERROR_NULL_ARGUMENT); - } - - /** - * Triggers a SWT.ERROR_NULL_ARGUMENT exception if any argument is null. - * - * @param o1 - * an object to test for null. - * @param o2 - * an object to test for null. - */ - public static void notNull(Object o1, Object o2) { - notNull(o1); - notNull(o2); - } - - /** - * Triggers a SWT.ERROR_NULL_ARGUMENT exception if any argument is null. - * - * @param o1 - * an object to test for null. - * @param o2 - * an object to test for null. - * @param o3 - * an object to test for null. - */ - public static void notNull(Object o1, Object o2, Object o3) { - notNull(o1); - notNull(o2); - notNull(o3); - } -} +/* + * Copyright (c) 2007-2008 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.internal.util; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.swt.SWT; + +/** + * General use convenience methods: null checking, equality + * + * @author Matthew Hall + */ +public class Util { + /** + * Returns whether the objects are of the same class. + * + * @param left + * object to test + * @param right + * object to test + * @return whether the objects are of the same class. + */ + public static boolean sameClass(Object left, Object right) { + if (left == right) + return true; + if (left == null || right == null) + return false; + return left.getClass() == right.getClass(); + } + + /** + * Returns whether the arguments are equal. + * + * @param left + * object to test + * @param right + * object to test + * @return whether the arguments are equal. + */ + public static boolean equal(Object left, Object right) { + if (!sameClass(left, right)) + return false; + if (left == right) + return true; + Class clazz = left.getClass(); + if (clazz.isArray()) { + Class componentType = clazz.getComponentType(); + if (componentType.isPrimitive()) { + if (componentType == Byte.TYPE) + return Arrays.equals((byte[]) left, (byte[]) right); + if (componentType == Short.TYPE) + return Arrays.equals((short[]) left, (short[]) right); + if (componentType == Integer.TYPE) + return Arrays.equals((int[]) left, (int[]) right); + if (componentType == Long.TYPE) + return Arrays.equals((long[]) left, (long[]) right); + if (componentType == Character.TYPE) + return Arrays.equals((char[]) left, (char[]) right); + if (componentType == Float.TYPE) + return Arrays.equals((float[]) left, (float[]) right); + if (componentType == Double.TYPE) + return Arrays.equals((double[]) left, (double[]) right); + if (componentType == Boolean.TYPE) + return Arrays.equals((boolean[]) left, (boolean[]) right); + } + return equal((Object[]) left, (Object[]) right); + } + return left.equals(right); + } + + private static boolean equal(Object[] left, Object[] right) { + int length = left.length; + if (length != right.length) + return false; + for (int i = 0; i < length; i++) + if (!equal(left[i], right[i])) + return false; + return true; + } + + /** + * Returns whether the arguments are equal. + * + * @param left + * double value to test + * @param right + * double value to test + * @return whether the arguments are equal. + */ + public static boolean equal(double left, double right) { + return Double.doubleToLongBits(left) == Double.doubleToLongBits(right); + } + + /** + * Triggers a SWT.ERROR_NULL_ARGUMENT exception if the argument or any of + * its elements is null. + * + * @param list + * a list to test for null elements. + */ + public static void noNulls(List list) { + notNull(list); + if (list.contains(null)) + PaperClips.error(SWT.ERROR_NULL_ARGUMENT); + } + + /** + * Triggers a SWT.ERROR_NULL_ARGUMENT exception if the argument or any of + * its elements is null. + * + * @param objs + * an array to test for null elements. + */ + public static void noNulls(Object[] objs) { + notNull(objs); + for (int i = 0; i < objs.length; i++) + notNull(objs[i]); + } + + /** + * Triggers a SWT.ERROR_NULL_ARGUMENT exception if the argument is null. + * + * @param obj + * the object to test for null. + */ + public static void notNull(Object obj) { + if (obj == null) + PaperClips.error(SWT.ERROR_NULL_ARGUMENT); + } + + /** + * Triggers a SWT.ERROR_NULL_ARGUMENT exception if any argument is null. + * + * @param o1 + * an object to test for null. + * @param o2 + * an object to test for null. + */ + public static void notNull(Object o1, Object o2) { + notNull(o1); + notNull(o2); + } + + /** + * Triggers a SWT.ERROR_NULL_ARGUMENT exception if any argument is null. + * + * @param o1 + * an object to test for null. + * @param o2 + * an object to test for null. + * @param o3 + * an object to test for null. + */ + public static void notNull(Object o1, Object o2, Object o3) { + notNull(o1); + notNull(o2); + notNull(o3); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages.properties b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages.properties index d462d7ffe..2a7dda53f 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages.properties +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages.properties @@ -1 +1 @@ -PAGE_X_OF_Y=Page {0} of {1} +PAGE_X_OF_Y=Page {0} of {1} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_de.properties b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_de.properties index 7d2791c0d..4b88bc1e7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_de.properties +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_de.properties @@ -1 +1 @@ -PAGE_X_OF_Y=Seite {0} von {1} +PAGE_X_OF_Y=Seite {0} von {1} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_en.properties b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_en.properties index d462d7ffe..2a7dda53f 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_en.properties +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_en.properties @@ -1 +1 @@ -PAGE_X_OF_Y=Page {0} of {1} +PAGE_X_OF_Y=Page {0} of {1} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_fr.properties b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_fr.properties index e0f9b4f68..a9117f20e 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_fr.properties +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/messages_fr.properties @@ -1 +1 @@ -PAGE_X_OF_Y=Page {0} sur {1} +PAGE_X_OF_Y=Page {0} sur {1} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/package.html b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/package.html index 8b19ee7e0..ee45ddd2c 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/package.html +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/package.html @@ -1,6 +1,6 @@ - - - -Core classes for creating printable documents. - + + + +Core classes for creating printable documents. + \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/DefaultPageNumberFormat.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/DefaultPageNumberFormat.java index 6bb68c94f..1b00e96b7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/DefaultPageNumberFormat.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/DefaultPageNumberFormat.java @@ -1,45 +1,45 @@ -/* - * Copyright (c) 2006-2008 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.page; - -import java.text.MessageFormat; - -import org.eclipse.nebula.paperclips.core.Messages; -import org.eclipse.nebula.paperclips.core.internal.util.Util; - -/** - * The default PageNumberFormat used by PageNumberPrints. - *

- * This class formats page numbers as "Page x of y". - * - * @author Matthew Hall - */ -public final class DefaultPageNumberFormat implements PageNumberFormat { - private static MessageFormat messageFormat = new MessageFormat(Messages - .getString(Messages.PAGE_X_OF_Y)); - - public String format(PageNumber pageNumber) { - return messageFormat.format(new Object[] { - new Integer(pageNumber.getPageNumber() + 1), - new Integer(pageNumber.getPageCount()) }); - } - - public boolean equals(Object obj) { - return Util.sameClass(this, obj); - } - - public int hashCode() { - return 47 * 41; - } +/* + * Copyright (c) 2006-2008 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.page; + +import java.text.MessageFormat; + +import org.eclipse.nebula.paperclips.core.Messages; +import org.eclipse.nebula.paperclips.core.internal.util.Util; + +/** + * The default PageNumberFormat used by PageNumberPrints. + *

+ * This class formats page numbers as "Page x of y". + * + * @author Matthew Hall + */ +public final class DefaultPageNumberFormat implements PageNumberFormat { + private static MessageFormat messageFormat = new MessageFormat(Messages + .getString(Messages.PAGE_X_OF_Y)); + + public String format(PageNumber pageNumber) { + return messageFormat.format(new Object[] { + new Integer(pageNumber.getPageNumber() + 1), + new Integer(pageNumber.getPageCount()) }); + } + + public boolean equals(Object obj) { + return Util.sameClass(this, obj); + } + + public int hashCode() { + return 47 * 41; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageDecoration.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageDecoration.java index cd982ed0c..05d663be2 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageDecoration.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageDecoration.java @@ -1,38 +1,38 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.page; - -import org.eclipse.nebula.paperclips.core.Print; - -/** - * An interface for creating page decorations. Instances of this interface are - * used as headers and footers in conjunction with the PagePrint class. - * - * @see PagePrint - * @see SimplePageDecoration - * @see PageNumberPageDecoration - * @author Matthew Hall - */ -public interface PageDecoration { - /** - * Returns a decorator Print for the page with the given page number, or - * null if no decoration is provided for the given page. - * - * @param pageNumber - * the page number of the page being decorated. - * @return a decorator Print for the page with the given page number, or - * null if no decoration is provided for the given page. - */ - public Print createPrint(PageNumber pageNumber); -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.page; + +import org.eclipse.nebula.paperclips.core.Print; + +/** + * An interface for creating page decorations. Instances of this interface are + * used as headers and footers in conjunction with the PagePrint class. + * + * @see PagePrint + * @see SimplePageDecoration + * @see PageNumberPageDecoration + * @author Matthew Hall + */ +public interface PageDecoration { + /** + * Returns a decorator Print for the page with the given page number, or + * null if no decoration is provided for the given page. + * + * @param pageNumber + * the page number of the page being decorated. + * @return a decorator Print for the page with the given page number, or + * null if no decoration is provided for the given page. + */ + public Print createPrint(PageNumber pageNumber); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumber.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumber.java index beb6a9fa6..9cfac5eb8 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumber.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumber.java @@ -1,38 +1,38 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.page; - -/** - * Instances of this class represent a page index in the output of a PagePrint. - * - * @author Matthew Hall - */ -public interface PageNumber { - /** - * Returns the zero-based page index. - * - * @return the zero-based page index. - */ - public int getPageNumber(); - - /** - * Returns the total number of pages. Note that this method may not return - * an accurate value until all pages have been laid out. Therefore this - * method should not be used inside - * {@link PageDecoration#createPrint(PageNumber)}. - * - * @return the total number of pages. - */ - public int getPageCount(); -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.page; + +/** + * Instances of this class represent a page index in the output of a PagePrint. + * + * @author Matthew Hall + */ +public interface PageNumber { + /** + * Returns the zero-based page index. + * + * @return the zero-based page index. + */ + public int getPageNumber(); + + /** + * Returns the total number of pages. Note that this method may not return + * an accurate value until all pages have been laid out. Therefore this + * method should not be used inside + * {@link PageDecoration#createPrint(PageNumber)}. + * + * @return the total number of pages. + */ + public int getPageCount(); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberFormat.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberFormat.java index 00a9b10ca..3925b115c 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberFormat.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberFormat.java @@ -1,30 +1,30 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.page; - -/** - * Interface for formatting a PageNumber instance into a printable string. - * - * @author Matthew Hall - */ -public interface PageNumberFormat { - /** - * Returns a formatted String representing the pageNumber argument. - * - * @param pageNumber - * the page number to be formatted into a String. - * @return a formatted String representing the pageNumber argument. - */ - public String format(PageNumber pageNumber); -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.page; + +/** + * Interface for formatting a PageNumber instance into a printable string. + * + * @author Matthew Hall + */ +public interface PageNumberFormat { + /** + * Returns a formatted String representing the pageNumber argument. + * + * @param pageNumber + * the page number to be formatted into a String. + * @return a formatted String representing the pageNumber argument. + */ + public String format(PageNumber pageNumber); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberPageDecoration.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberPageDecoration.java index 798b44428..2abea36f5 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberPageDecoration.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberPageDecoration.java @@ -1,186 +1,186 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.page; - -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; - -/** - * A PageDecoration which displays the page number. This convenience class helps - * avoid the need for writing a new PageDecoration class if only a page number - * is needed. Getter and setter methods are provided for all the properties - * available in the PagePrint class itself. - * - * @author Matthew Hall - */ -public class PageNumberPageDecoration implements PageDecoration { - FontData fontData = new FontData(); - int align = SWT.LEFT; - RGB rgb = new RGB(0, 0, 0); // black - PageNumberFormat format = new DefaultPageNumberFormat(); - - /** - * Constructs a PageNumberPageDecoration with default font, alignment, and - * page number format. - */ - public PageNumberPageDecoration() { - } - - /** - * Constructs a PageNumberPageDecoration with the given alignment. - * - * @param align - * horizontal text alignment. - */ - public PageNumberPageDecoration(int align) { - setAlign(align); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + align; - result = prime * result - + ((fontData == null) ? 0 : fontData.hashCode()); - result = prime * result + ((format == null) ? 0 : format.hashCode()); - result = prime * result + ((rgb == null) ? 0 : rgb.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PageNumberPageDecoration other = (PageNumberPageDecoration) obj; - if (align != other.align) - return false; - if (fontData == null) { - if (other.fontData != null) - return false; - } else if (!fontData.equals(other.fontData)) - return false; - if (format == null) { - if (other.format != null) - return false; - } else if (!format.equals(other.format)) - return false; - if (rgb == null) { - if (other.rgb != null) - return false; - } else if (!rgb.equals(other.rgb)) - return false; - return true; - } - - /** - * Returns the font. - * - * @return the font. - */ - public FontData getFontData() { - return fontData; - } - - /** - * Sets the font. - * - * @param fontData - * the new font. - */ - public void setFontData(FontData fontData) { - Util.notNull(fontData); - this.fontData = fontData; - } - - /** - * Returns the horizontal text alignment. - * - * @return the horizontal text alignment. - */ - public int getAlign() { - return align; - } - - /** - * Sets the horizontal text alignment. - * - * @param align - * the horizontal text alignment. - */ - public void setAlign(int align) { - align = checkAlign(align); - this.align = align; - } - - private int checkAlign(int align) { - return PaperClipsUtil.firstMatch(align, new int[] { SWT.LEFT, - SWT.CENTER, SWT.RIGHT }, SWT.LEFT); - } - - /** - * Returns the text color. - * - * @return the text color. - */ - public RGB getRGB() { - return rgb; - } - - /** - * Sets the text color. - * - * @param rgb - * the new text color. - */ - public void setRGB(RGB rgb) { - Util.notNull(rgb); - this.rgb = rgb; - } - - /** - * Returns the page number format. - * - * @return the page number format. - */ - public PageNumberFormat getFormat() { - return format; - } - - /** - * Sets the page number format. - * - * @param format - * the page number format. - */ - public void setFormat(PageNumberFormat format) { - Util.notNull(format); - this.format = format; - } - - public Print createPrint(PageNumber pageNumber) { - PageNumberPrint result = new PageNumberPrint(pageNumber); - result.setFontData(fontData); - result.setAlign(align); - result.setPageNumberFormat(format); - result.setRGB(rgb); - return result; - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.page; + +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; + +/** + * A PageDecoration which displays the page number. This convenience class helps + * avoid the need for writing a new PageDecoration class if only a page number + * is needed. Getter and setter methods are provided for all the properties + * available in the PagePrint class itself. + * + * @author Matthew Hall + */ +public class PageNumberPageDecoration implements PageDecoration { + FontData fontData = new FontData(); + int align = SWT.LEFT; + RGB rgb = new RGB(0, 0, 0); // black + PageNumberFormat format = new DefaultPageNumberFormat(); + + /** + * Constructs a PageNumberPageDecoration with default font, alignment, and + * page number format. + */ + public PageNumberPageDecoration() { + } + + /** + * Constructs a PageNumberPageDecoration with the given alignment. + * + * @param align + * horizontal text alignment. + */ + public PageNumberPageDecoration(int align) { + setAlign(align); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + align; + result = prime * result + + ((fontData == null) ? 0 : fontData.hashCode()); + result = prime * result + ((format == null) ? 0 : format.hashCode()); + result = prime * result + ((rgb == null) ? 0 : rgb.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PageNumberPageDecoration other = (PageNumberPageDecoration) obj; + if (align != other.align) + return false; + if (fontData == null) { + if (other.fontData != null) + return false; + } else if (!fontData.equals(other.fontData)) + return false; + if (format == null) { + if (other.format != null) + return false; + } else if (!format.equals(other.format)) + return false; + if (rgb == null) { + if (other.rgb != null) + return false; + } else if (!rgb.equals(other.rgb)) + return false; + return true; + } + + /** + * Returns the font. + * + * @return the font. + */ + public FontData getFontData() { + return fontData; + } + + /** + * Sets the font. + * + * @param fontData + * the new font. + */ + public void setFontData(FontData fontData) { + Util.notNull(fontData); + this.fontData = fontData; + } + + /** + * Returns the horizontal text alignment. + * + * @return the horizontal text alignment. + */ + public int getAlign() { + return align; + } + + /** + * Sets the horizontal text alignment. + * + * @param align + * the horizontal text alignment. + */ + public void setAlign(int align) { + align = checkAlign(align); + this.align = align; + } + + private int checkAlign(int align) { + return PaperClipsUtil.firstMatch(align, new int[] { SWT.LEFT, + SWT.CENTER, SWT.RIGHT }, SWT.LEFT); + } + + /** + * Returns the text color. + * + * @return the text color. + */ + public RGB getRGB() { + return rgb; + } + + /** + * Sets the text color. + * + * @param rgb + * the new text color. + */ + public void setRGB(RGB rgb) { + Util.notNull(rgb); + this.rgb = rgb; + } + + /** + * Returns the page number format. + * + * @return the page number format. + */ + public PageNumberFormat getFormat() { + return format; + } + + /** + * Sets the page number format. + * + * @param format + * the page number format. + */ + public void setFormat(PageNumberFormat format) { + Util.notNull(format); + this.format = format; + } + + public Print createPrint(PageNumber pageNumber) { + PageNumberPrint result = new PageNumberPrint(pageNumber); + result.setFontData(fontData); + result.setAlign(align); + result.setPageNumberFormat(format); + result.setRGB(rgb); + return result; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberPrint.java index f356dd427..41a6a7f77 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PageNumberPrint.java @@ -1,446 +1,446 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.page; - -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.nebula.paperclips.core.text.TextStyle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; - -/** - * Displays the page number and page count within the context of a - * {@link PagePrint}. To properly display page numbers, instances of this class - * should be created using the {@link PageNumber} argument which is passed to - * the {@link PageDecoration#createPrint(PageNumber)} method by PagePrint. - *

- * PageNumberPrints are never greedy with layout space, even with center- or - * right-alignment. (Greedy prints take up all the available space on the page.) - * Therefore, when center- or right-alignment is required, it is necessary to - * wrap the page number in a Print which will enforce the same alignment. - * Usually this is a center:default:grow or right:default:grow column in a - * GridPrint. - * - * @author Matthew Hall - * @see PagePrint - * @see PageDecoration - * @see PageNumber - * @see PageNumberFormat - * @see DefaultPageNumberFormat - */ -public class PageNumberPrint implements Print { - /** The default font data for a PageNumberPrint. Value is device-dependent. */ - public static final FontData DEFAULT_FONT_DATA = new FontData(); - - /** The default alignment for a PageNumberPrint. Value is SWT.LEFT. */ - public static final int DEFAULT_ALIGN = SWT.LEFT; - - /** The default text style. Value is device-dependent. */ - public static final TextStyle DEFAULT_TEXT_STYLE = new TextStyle().font( - DEFAULT_FONT_DATA).align(DEFAULT_ALIGN); - - PageNumber pageNumber; - TextStyle textStyle; - PageNumberFormat format; - - /** - * Constructs a PageNumberPrint for the given page number. - * - * @param pageNumber - * the page number of the page this Print will appear on. - */ - public PageNumberPrint(PageNumber pageNumber) { - this(pageNumber, DEFAULT_TEXT_STYLE); - } - - /** - * Constructs a PageNumberPrint for the given page number and font. - * - * @param pageNumber - * the page number of the page this Print will appear on. - * @param fontData - * the font that this Print will appear in. - */ - public PageNumberPrint(PageNumber pageNumber, FontData fontData) { - this(pageNumber, DEFAULT_TEXT_STYLE.font(fontData)); - } - - /** - * Constructs a PageNumberPrint for the given page number and alignment. - * - * @param pageNumber - * the page number of the page this Print will appear on. - * @param align - * the horizontal alignment of the text. - */ - public PageNumberPrint(PageNumber pageNumber, int align) { - this(pageNumber, DEFAULT_TEXT_STYLE.align(align)); - } - - /** - * Constructs a PageNumberPrint for the given page number, font and - * alignment. - * - * @param pageNumber - * the page number of the page this Print will appear on. - * @param fontData - * the font that this Print will appear in. - * @param align - * the horizontal alignment of the text. - */ - public PageNumberPrint(PageNumber pageNumber, FontData fontData, int align) { - this(pageNumber, DEFAULT_TEXT_STYLE.font(fontData).align(align)); - } - - /** - * Constructs a PageNumberPrint for the given page number and text style. - * - * @param pageNumber - * the page number of the page this Print will appear on. - * @param textStyle - * the text style that this Print will appear in. - */ - public PageNumberPrint(PageNumber pageNumber, TextStyle textStyle) { - setPageNumber(pageNumber); - setTextStyle(textStyle); - setPageNumberFormat(new DefaultPageNumberFormat()); - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((pageNumber == null) ? 0 : pageNumber.hashCode()); - result = prime * result - + ((textStyle == null) ? 0 : textStyle.hashCode()); - result = prime * result + ((format == null) ? 0 : format.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PageNumberPrint other = (PageNumberPrint) obj; - - if (pageNumber == null) { - if (other.pageNumber != null) - return false; - } else if (!pageNumber.equals(other.pageNumber)) - return false; - - if (textStyle == null) { - if (other.textStyle != null) - return false; - } else if (!textStyle.equals(other.textStyle)) - return false; - - if (format == null) { - if (other.format != null) - return false; - } else if (!format.equals(other.format)) - return false; - - return true; - } - - /** - * Sets the page number to the argument. - * - * @param pageNumber - * the new page number. - */ - public void setPageNumber(PageNumber pageNumber) { - Util.notNull(pageNumber); - this.pageNumber = pageNumber; - } - - /** - * Returns the page number of this Print. - * - * @return the page number of this Print. - */ - public PageNumber getPageNumber() { - return pageNumber; - } - - /** - * Sets the text font to the argument. - * - * @param fontData - * the new text font. - */ - public void setFontData(FontData fontData) { - Util.notNull(fontData); - setTextStyle(textStyle.font(fontData)); - } - - /** - * Returns the text font. - * - * @return the text font. - */ - public FontData getFontData() { - return textStyle.getFontData(); - } - - /** - * Sets the horizontal text alignment to the argument. - * - * @param align - * the horizontal alignment. Must be one of {@link SWT#LEFT }, - * {@link SWT#CENTER } or {@link SWT#RIGHT }. - */ - public void setAlign(int align) { - setTextStyle(textStyle.align(checkAlign(align))); - } - - /** - * Returns the horizontal text alignment. - * - * @return the horizontal text alignment. - */ - public int getAlign() { - return textStyle.getAlignment(); - } - - private int checkAlign(int align) { - return PaperClipsUtil.firstMatch(align, new int[] { SWT.LEFT, - SWT.CENTER, SWT.RIGHT }, SWT.LEFT); - } - - /** - * Returns the text style that will be used to render the page number - * - * @return the text style that will be used to render the page number - */ - public TextStyle getTextStyle() { - return textStyle; - } - - /** - * Sets the text style that will be used to render the page number - * - * @param textStyle - * the text style - */ - public void setTextStyle(TextStyle textStyle) { - Util.notNull(textStyle); - this.textStyle = textStyle; - } - - /** - * Sets the format that will be used to convert the page number to a text - * string. - * - * @param format - * the new page number format. - */ - public void setPageNumberFormat(PageNumberFormat format) { - Util.notNull(format); - this.format = format; - } - - /** - * Returns the page number format. This property determines how the - * PageNumber will be converted into a String representing the page number. - * The default value of this property formats page numbers as follows:
- * - *

-	 * Page 1 of 5
-	 * 
- * - * @return the page number format. - */ - public PageNumberFormat getPageNumberFormat() { - return format; - } - - /** - * Sets the text color. - * - * @param foreground - * the new text color. - */ - public void setRGB(RGB foreground) { - Util.notNull(foreground); - setTextStyle(textStyle.foreground(foreground)); - } - - /** - * Returns the text color. - * - * @return the text color. - */ - public RGB getRGB() { - return textStyle.getForeground(); - } - - public PrintIterator iterator(Device device, GC gc) { - return new PageNumberIterator(this, device, gc); - } -} - -class PageNumberIterator implements PrintIterator { - private final Device device; - private final GC gc; - - final PageNumber pageNumber; - final TextStyle textStyle; - final PageNumberFormat format; - final Point size; - - boolean hasNext = true; - - PageNumberIterator(PageNumberPrint print, Device device, GC gc) { - this.device = device; - this.gc = gc; - - this.pageNumber = print.pageNumber; - this.textStyle = print.textStyle; - this.format = print.format; - - // Calculate the size for the largest possible page number string. - Font oldFont = gc.getFont(); - try { - gc.setFont(ResourcePool.forDevice(device).getFont( - textStyle.getFontData())); - - size = gc.textExtent(format.format(new PageNumber() { - public int getPageCount() { - return 9999; - } - - public int getPageNumber() { - return 9998; - } // (zero-based index) - })); - } finally { - gc.setFont(oldFont); - } - } - - PageNumberIterator(PageNumberIterator that) { - this.device = that.device; - this.gc = that.gc; - - this.pageNumber = that.pageNumber; - this.textStyle = that.textStyle; - this.format = that.format; - this.size = that.size; - this.hasNext = that.hasNext; - } - - public boolean hasNext() { - return hasNext; - } - - public Point minimumSize() { - return size; - } - - public Point preferredSize() { - return size; - } - - public PrintPiece next(int width, int height) { - if (width < size.x || height < size.y) - return null; - - Point size = new Point(this.size.x, this.size.y); - int align = textStyle.getAlignment(); - if (align == SWT.CENTER || align == SWT.RIGHT) - size.x = width; - - PageNumberPiece piece = new PageNumberPiece(this, device, size); - hasNext = false; - - return piece; - } - - public PrintIterator copy() { - return new PageNumberIterator(this); - } -} - -class PageNumberPiece implements PrintPiece { - private final Device device; - private final Point size; - - private final PageNumber pageNumber; - private final TextStyle textStyle; - private final PageNumberFormat format; - - PageNumberPiece(PageNumberIterator iter, Device device, Point size) { - this.device = device; - this.size = size; - this.pageNumber = iter.pageNumber; - this.textStyle = iter.textStyle; - this.format = iter.format; - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - public void paint(final GC gc, final int x, final int y) { - Font oldFont = gc.getFont(); - Color oldForeground = gc.getForeground(); - - Point size = getSize(); - - try { - ResourcePool resources = ResourcePool.forDevice(device); - gc.setFont(resources.getFont(textStyle.getFontData())); - gc.setForeground(resources.getColor(textStyle.getForeground())); - - String text = format.format(pageNumber); - gc.drawText(text, x - + getHorzAlignmentOffset(gc.textExtent(text).x, size.x), y, - true); - } finally { - gc.setFont(oldFont); - gc.setForeground(oldForeground); - } - } - - private int getHorzAlignmentOffset(int textWidth, int totalWidth) { - int offset = 0; - switch (textStyle.getAlignment()) { - case SWT.CENTER: - offset = (totalWidth - textWidth) / 2; - break; - case SWT.RIGHT: - offset = totalWidth - textWidth; - break; - } - return offset; - } - - public void dispose() { - } // Shared resources, nothing to dispose +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.page; + +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.nebula.paperclips.core.text.TextStyle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; + +/** + * Displays the page number and page count within the context of a + * {@link PagePrint}. To properly display page numbers, instances of this class + * should be created using the {@link PageNumber} argument which is passed to + * the {@link PageDecoration#createPrint(PageNumber)} method by PagePrint. + *

+ * PageNumberPrints are never greedy with layout space, even with center- or + * right-alignment. (Greedy prints take up all the available space on the page.) + * Therefore, when center- or right-alignment is required, it is necessary to + * wrap the page number in a Print which will enforce the same alignment. + * Usually this is a center:default:grow or right:default:grow column in a + * GridPrint. + * + * @author Matthew Hall + * @see PagePrint + * @see PageDecoration + * @see PageNumber + * @see PageNumberFormat + * @see DefaultPageNumberFormat + */ +public class PageNumberPrint implements Print { + /** The default font data for a PageNumberPrint. Value is device-dependent. */ + public static final FontData DEFAULT_FONT_DATA = new FontData(); + + /** The default alignment for a PageNumberPrint. Value is SWT.LEFT. */ + public static final int DEFAULT_ALIGN = SWT.LEFT; + + /** The default text style. Value is device-dependent. */ + public static final TextStyle DEFAULT_TEXT_STYLE = new TextStyle().font( + DEFAULT_FONT_DATA).align(DEFAULT_ALIGN); + + PageNumber pageNumber; + TextStyle textStyle; + PageNumberFormat format; + + /** + * Constructs a PageNumberPrint for the given page number. + * + * @param pageNumber + * the page number of the page this Print will appear on. + */ + public PageNumberPrint(PageNumber pageNumber) { + this(pageNumber, DEFAULT_TEXT_STYLE); + } + + /** + * Constructs a PageNumberPrint for the given page number and font. + * + * @param pageNumber + * the page number of the page this Print will appear on. + * @param fontData + * the font that this Print will appear in. + */ + public PageNumberPrint(PageNumber pageNumber, FontData fontData) { + this(pageNumber, DEFAULT_TEXT_STYLE.font(fontData)); + } + + /** + * Constructs a PageNumberPrint for the given page number and alignment. + * + * @param pageNumber + * the page number of the page this Print will appear on. + * @param align + * the horizontal alignment of the text. + */ + public PageNumberPrint(PageNumber pageNumber, int align) { + this(pageNumber, DEFAULT_TEXT_STYLE.align(align)); + } + + /** + * Constructs a PageNumberPrint for the given page number, font and + * alignment. + * + * @param pageNumber + * the page number of the page this Print will appear on. + * @param fontData + * the font that this Print will appear in. + * @param align + * the horizontal alignment of the text. + */ + public PageNumberPrint(PageNumber pageNumber, FontData fontData, int align) { + this(pageNumber, DEFAULT_TEXT_STYLE.font(fontData).align(align)); + } + + /** + * Constructs a PageNumberPrint for the given page number and text style. + * + * @param pageNumber + * the page number of the page this Print will appear on. + * @param textStyle + * the text style that this Print will appear in. + */ + public PageNumberPrint(PageNumber pageNumber, TextStyle textStyle) { + setPageNumber(pageNumber); + setTextStyle(textStyle); + setPageNumberFormat(new DefaultPageNumberFormat()); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((pageNumber == null) ? 0 : pageNumber.hashCode()); + result = prime * result + + ((textStyle == null) ? 0 : textStyle.hashCode()); + result = prime * result + ((format == null) ? 0 : format.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PageNumberPrint other = (PageNumberPrint) obj; + + if (pageNumber == null) { + if (other.pageNumber != null) + return false; + } else if (!pageNumber.equals(other.pageNumber)) + return false; + + if (textStyle == null) { + if (other.textStyle != null) + return false; + } else if (!textStyle.equals(other.textStyle)) + return false; + + if (format == null) { + if (other.format != null) + return false; + } else if (!format.equals(other.format)) + return false; + + return true; + } + + /** + * Sets the page number to the argument. + * + * @param pageNumber + * the new page number. + */ + public void setPageNumber(PageNumber pageNumber) { + Util.notNull(pageNumber); + this.pageNumber = pageNumber; + } + + /** + * Returns the page number of this Print. + * + * @return the page number of this Print. + */ + public PageNumber getPageNumber() { + return pageNumber; + } + + /** + * Sets the text font to the argument. + * + * @param fontData + * the new text font. + */ + public void setFontData(FontData fontData) { + Util.notNull(fontData); + setTextStyle(textStyle.font(fontData)); + } + + /** + * Returns the text font. + * + * @return the text font. + */ + public FontData getFontData() { + return textStyle.getFontData(); + } + + /** + * Sets the horizontal text alignment to the argument. + * + * @param align + * the horizontal alignment. Must be one of {@link SWT#LEFT }, + * {@link SWT#CENTER } or {@link SWT#RIGHT }. + */ + public void setAlign(int align) { + setTextStyle(textStyle.align(checkAlign(align))); + } + + /** + * Returns the horizontal text alignment. + * + * @return the horizontal text alignment. + */ + public int getAlign() { + return textStyle.getAlignment(); + } + + private int checkAlign(int align) { + return PaperClipsUtil.firstMatch(align, new int[] { SWT.LEFT, + SWT.CENTER, SWT.RIGHT }, SWT.LEFT); + } + + /** + * Returns the text style that will be used to render the page number + * + * @return the text style that will be used to render the page number + */ + public TextStyle getTextStyle() { + return textStyle; + } + + /** + * Sets the text style that will be used to render the page number + * + * @param textStyle + * the text style + */ + public void setTextStyle(TextStyle textStyle) { + Util.notNull(textStyle); + this.textStyle = textStyle; + } + + /** + * Sets the format that will be used to convert the page number to a text + * string. + * + * @param format + * the new page number format. + */ + public void setPageNumberFormat(PageNumberFormat format) { + Util.notNull(format); + this.format = format; + } + + /** + * Returns the page number format. This property determines how the + * PageNumber will be converted into a String representing the page number. + * The default value of this property formats page numbers as follows:
+ * + *

+	 * Page 1 of 5
+	 * 
+ * + * @return the page number format. + */ + public PageNumberFormat getPageNumberFormat() { + return format; + } + + /** + * Sets the text color. + * + * @param foreground + * the new text color. + */ + public void setRGB(RGB foreground) { + Util.notNull(foreground); + setTextStyle(textStyle.foreground(foreground)); + } + + /** + * Returns the text color. + * + * @return the text color. + */ + public RGB getRGB() { + return textStyle.getForeground(); + } + + public PrintIterator iterator(Device device, GC gc) { + return new PageNumberIterator(this, device, gc); + } +} + +class PageNumberIterator implements PrintIterator { + private final Device device; + private final GC gc; + + final PageNumber pageNumber; + final TextStyle textStyle; + final PageNumberFormat format; + final Point size; + + boolean hasNext = true; + + PageNumberIterator(PageNumberPrint print, Device device, GC gc) { + this.device = device; + this.gc = gc; + + this.pageNumber = print.pageNumber; + this.textStyle = print.textStyle; + this.format = print.format; + + // Calculate the size for the largest possible page number string. + Font oldFont = gc.getFont(); + try { + gc.setFont(ResourcePool.forDevice(device).getFont( + textStyle.getFontData())); + + size = gc.textExtent(format.format(new PageNumber() { + public int getPageCount() { + return 9999; + } + + public int getPageNumber() { + return 9998; + } // (zero-based index) + })); + } finally { + gc.setFont(oldFont); + } + } + + PageNumberIterator(PageNumberIterator that) { + this.device = that.device; + this.gc = that.gc; + + this.pageNumber = that.pageNumber; + this.textStyle = that.textStyle; + this.format = that.format; + this.size = that.size; + this.hasNext = that.hasNext; + } + + public boolean hasNext() { + return hasNext; + } + + public Point minimumSize() { + return size; + } + + public Point preferredSize() { + return size; + } + + public PrintPiece next(int width, int height) { + if (width < size.x || height < size.y) + return null; + + Point size = new Point(this.size.x, this.size.y); + int align = textStyle.getAlignment(); + if (align == SWT.CENTER || align == SWT.RIGHT) + size.x = width; + + PageNumberPiece piece = new PageNumberPiece(this, device, size); + hasNext = false; + + return piece; + } + + public PrintIterator copy() { + return new PageNumberIterator(this); + } +} + +class PageNumberPiece implements PrintPiece { + private final Device device; + private final Point size; + + private final PageNumber pageNumber; + private final TextStyle textStyle; + private final PageNumberFormat format; + + PageNumberPiece(PageNumberIterator iter, Device device, Point size) { + this.device = device; + this.size = size; + this.pageNumber = iter.pageNumber; + this.textStyle = iter.textStyle; + this.format = iter.format; + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + public void paint(final GC gc, final int x, final int y) { + Font oldFont = gc.getFont(); + Color oldForeground = gc.getForeground(); + + Point size = getSize(); + + try { + ResourcePool resources = ResourcePool.forDevice(device); + gc.setFont(resources.getFont(textStyle.getFontData())); + gc.setForeground(resources.getColor(textStyle.getForeground())); + + String text = format.format(pageNumber); + gc.drawText(text, x + + getHorzAlignmentOffset(gc.textExtent(text).x, size.x), y, + true); + } finally { + gc.setFont(oldFont); + gc.setForeground(oldForeground); + } + } + + private int getHorzAlignmentOffset(int textWidth, int totalWidth) { + int offset = 0; + switch (textStyle.getAlignment()) { + case SWT.CENTER: + offset = (totalWidth - textWidth) / 2; + break; + case SWT.RIGHT: + offset = totalWidth - textWidth; + break; + } + return offset; + } + + public void dispose() { + } // Shared resources, nothing to dispose } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PagePrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PagePrint.java index be0ddc6aa..827dcea26 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PagePrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/PagePrint.java @@ -1,556 +1,556 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.page; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.CompositeEntry; -import org.eclipse.nebula.paperclips.core.CompositePiece; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A decorator Print which displays page headers and footers around a document - * body, with page numbering capabilities. - *

- * PagePrint is horizontally and vertically greedy. Greedy prints take up all - * the available space on the page. - *

- * Note: Avoid wrapping PagePrint in prints with space-optimizing - * semantics (e.g. ColumnPrint equalizes columns on the last page), as this may - * cause the total page count to be incorrect on some pages. At this time there - * is no known fix. If wrapping a PagePrint is unavoidable, consider using a - * custom PageNumberFormat which does not display the total page count. - * - * @author Matthew Hall - */ -public class PagePrint implements Print { - private static final int DEFAULT_GAP = 1; - - PageDecoration header; - int headerGap = DEFAULT_GAP; // in points - Print body; - int footerGap = DEFAULT_GAP; // in points - PageDecoration footer; - - /** - * Constructs a PagePrint with the given header and body. - * - * @param header - * a PageDecoration for creating the header. May be null. - * @param headerGap - * the gap between the header and body, in points. - * @param body - * the Print being decorated. - */ - public PagePrint(PageDecoration header, int headerGap, Print body) { - this(header, headerGap, body, DEFAULT_GAP, null); - } - - /** - * Constructs a PagePrint with the given header and body. - * - * @param body - * the Print being decorated. - * @param header - * a PageDecoration for creating the header. May be null. - */ - public PagePrint(PageDecoration header, Print body) { - this(header, DEFAULT_GAP, body); - } - - /** - * Constructs a PagePrint with the given body. - * - * @param body - * the Print being decorated. - */ - public PagePrint(Print body) { - this(null, body, null); - } - - /** - * Constructs a PagePrint with the given body and footer. - * - * @param body - * the Print being decorated. - * @param footer - * a PageDecoration for creating the footer. may be null. - */ - public PagePrint(Print body, PageDecoration footer) { - this(body, DEFAULT_GAP, footer); - } - - /** - * Constructs a PagePrint with the given body, header and footer. - * - * @param body - * the Print being decorated. - * @param footerGap - * the gap between the body and footer, in points. - * @param footer - * a PageDecoration for creating the footer. May be null. - */ - public PagePrint(Print body, int footerGap, PageDecoration footer) { - this(null, DEFAULT_GAP, body, footerGap, footer); - } - - /** - * Constructs a PagePrint with the given body, header and footer. - * - * @param header - * a PageDecoration for creating the header. May be null. - * @param body - * the Print being decorated. - * @param footer - * a PageDecoration for creating the footer. may be null. - */ - public PagePrint(PageDecoration header, Print body, PageDecoration footer) { - this(header, DEFAULT_GAP, body, DEFAULT_GAP, footer); - } - - /** - * Constructs a PagePrint with the given body, header and footer. - * - * @param header - * a PageDecoration for creating the header. May be null. - * @param headerGap - * the gap between the header and body, in points. - * @param body - * the Print being decorated. - * @param footerGap - * the gap between the body and footer, in points. - * @param footer - * a PageDecoration for creating the footer. May be null. - */ - public PagePrint(PageDecoration header, int headerGap, Print body, - int footerGap, PageDecoration footer) { - setHeader(header); - setHeaderGap(headerGap); - setBody(body); - setFooterGap(footerGap); - setFooter(footer); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((body == null) ? 0 : body.hashCode()); - result = prime * result + ((footer == null) ? 0 : footer.hashCode()); - result = prime * result + footerGap; - result = prime * result + ((header == null) ? 0 : header.hashCode()); - result = prime * result + headerGap; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PagePrint other = (PagePrint) obj; - if (body == null) { - if (other.body != null) - return false; - } else if (!body.equals(other.body)) - return false; - if (footer == null) { - if (other.footer != null) - return false; - } else if (!footer.equals(other.footer)) - return false; - if (footerGap != other.footerGap) - return false; - if (header == null) { - if (other.header != null) - return false; - } else if (!header.equals(other.header)) - return false; - if (headerGap != other.headerGap) - return false; - return true; - } - - /** - * Returns the page header. - * - * @return the page header. - */ - public PageDecoration getHeader() { - return header; - } - - /** - * Sets the page header to the argument. - * - * @param header - * a PageDecoration which creates the header. May be null. - */ - public void setHeader(PageDecoration header) { - this.header = header; - } - - /** - * Returns the gap between the header and body, expressed in points. - * - * @return the gap between the header and body, expressed in points. - */ - public int getHeaderGap() { - return headerGap; - } - - /** - * Sets the gap between the header and body to the argument, expressed in - * points. - * - * @param points - * the new gap between the header and body, expressed in points. - * 72 points = 1". - */ - public void setHeaderGap(int points) { - this.headerGap = checkGap(points); - } - - /** - * Returns the page body. - * - * @return the page body. - */ - public Print getBody() { - return body; - } - - /** - * Sets the page body to the argument. - * - * @param body - * the new page body. - */ - public void setBody(Print body) { - Util.notNull(body); - this.body = body; - } - - /** - * Returns the page footer. - * - * @return the page footer. - */ - public PageDecoration getFooter() { - return footer; - } - - /** - * Sets the page footer to the argument. - * - * @param footer - * a PageDecoration which creates the footer. May be null. - */ - public void setFooter(PageDecoration footer) { - this.footer = footer; - } - - /** - * Returns the gap between the body and footer, expressed in points. - * - * @return the gap between the body and footer, expressed in points. - */ - public int getFooterGap() { - return footerGap; - } - - /** - * Sets the gap between the body and footer to the argument, expressed in - * points. - * - * @param points - * the new gap between the body and footer (if there is a - * footer). - */ - public void setFooterGap(int points) { - this.footerGap = checkGap(points); - } - - private static int checkGap(int gap) { - if (gap < 0) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, - "Gap must be >= 0 (value is " + gap + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - return gap; - } - - public PrintIterator iterator(Device device, GC gc) { - if (header == null && footer == null) - return body.iterator(device, gc); - - return new PageIterator(this, device, gc); - } -} - -class PageIterator implements PrintIterator { - class PageNumberer { - int pageCount = 0; - - synchronized PageNumber next() { - return new InnerPageNumber(); - } - - class InnerPageNumber implements PageNumber { - final int pageNumber = pageCount++; // POST-increment - - public int getPageCount() { - return pageCount; - } - - public int getPageNumber() { - return pageNumber; - } - } - - PageNumberer copy() { - PageNumberer result = new PageNumberer(); - result.pageCount = this.pageCount; - return result; - } - } - - final Device device; - final GC gc; - - final PageDecoration header; - final int headerGap; // pixels - final PrintIterator body; - final int footerGap; // pixels - final PageDecoration footer; - - final PageNumberer numberer; - - final Point minimumSize; - final Point preferredSize; - - PageIterator(PagePrint print, Device device, GC gc) { - this.device = device; - this.gc = gc; - - Point dpi = device.getDPI(); - - body = print.body.iterator(device, gc); - header = print.header; - headerGap = header == null ? 0 : print.headerGap * dpi.y / 72; - footer = print.footer; - footerGap = footer == null ? 0 : print.footerGap * dpi.y / 72; - - this.numberer = new PageNumberer(); - - this.minimumSize = computeSize(PrintSizeStrategy.MINIMUM); - this.preferredSize = computeSize(PrintSizeStrategy.PREFERRED); - } - - PageIterator(PageIterator that) { - this.device = that.device; - this.gc = that.gc; - - this.body = that.body.copy(); - this.header = that.header; - this.headerGap = that.headerGap; - this.footer = that.footer; - this.footerGap = that.footerGap; - - // FIXME: Wrapping PagePrint in a class with space-optimizing semantics - // (ColumnPrint) can fork the total - // page count. i.e. if the copied PageIterator is chosen as the optimal - // layout, then previous pages will - // have a page number spawned from a different page numberer. Thus the - // total page count for those - // previous pages will no longer be incremented with each new page. - this.numberer = that.numberer.copy(); - this.pageNumber = that.pageNumber; - - this.minimumSize = that.minimumSize; - this.preferredSize = that.preferredSize; - } - - private Point computeSize(PrintSizeStrategy strategy) { - Point size = strategy.computeSize(body); - - PageNumber samplePageNumber = new PageNumber() { - public int getPageCount() { - return 1; - } - - public int getPageNumber() { - return 0; - } - }; - - if (header != null) { - Print headerPrint = header.createPrint(samplePageNumber); - if (headerPrint != null) { - PrintIterator iter = headerPrint.iterator(device, gc); - - size.y += headerGap; - - Point headerSize = strategy.computeSize(iter); - size.x = Math.max(size.x, headerSize.x); - size.y += headerSize.y; - } - } - - if (footer != null) { - Print footerPrint = footer.createPrint(samplePageNumber); - if (footerPrint != null) { - PrintIterator iter = footerPrint.iterator(device, gc); - - size.y += footerGap; - - Point footerSize = strategy.computeSize(iter); - size.x = Math.max(size.x, footerSize.x); - size.y += footerSize.y; - } - } - - return size; - } - - public boolean hasNext() { - return body.hasNext(); - } - - public Point minimumSize() { - return new Point(minimumSize.x, minimumSize.y); - } - - public Point preferredSize() { - return new Point(preferredSize.x, preferredSize.y); - } - - public PrintPiece next(int width, final int height) { - PageNumber pageNumber = getCurrentPageNumber(); - - // HEADER - PrintPiece headerPiece = null; - int availableHeight = height; - if (header != null) { - Print headerPrint = header.createPrint(pageNumber); - if (headerPrint != null) { - headerPiece = getDecorationPrintPiece(headerPrint, width, - availableHeight); - if (headerPiece == null) - return null; - availableHeight -= (heightOf(headerPiece) + headerGap); - } - } - - // FOOTER - PrintPiece footerPiece = null; - if (footer != null) { - Print footerPrint = footer.createPrint(pageNumber); - if (footerPrint != null) { - footerPiece = getDecorationPrintPiece(footerPrint, width, - availableHeight); - if (footerPiece == null) { - PaperClipsUtil.dispose(headerPiece); - return null; - } - availableHeight -= (heightOf(footerPiece) + footerGap); - } - } - - // BODY - PrintPiece bodyPiece = PaperClips.next(body, width, availableHeight); - if (bodyPiece == null) { - PaperClipsUtil.dispose(headerPiece, footerPiece); - return null; - } - - PrintPiece result = createResult(height, headerPiece, bodyPiece, - footerPiece); - advancePageNumber(); - return result; - } - - private int heightOf(PrintPiece piece) { - return piece.getSize().y; - } - - PageNumber pageNumber; - - private void advancePageNumber() { - // Null the pageNumber field so the next iteration advances to the next - // page. - pageNumber = null; - } - - private PageNumber getCurrentPageNumber() { - if (pageNumber == null) - pageNumber = numberer.next(); - return pageNumber; - } - - private PrintPiece createResult(int height, PrintPiece headerPiece, - PrintPiece bodyPiece, PrintPiece footerPiece) { - if (headerPiece == null && footerPiece == null) - return bodyPiece; - - List entries = new ArrayList<>(); - - if (headerPiece != null) - entries.add(createEntry(headerPiece, 0)); - - int y = headerPiece == null ? 0 : heightOf(headerPiece) + headerGap; - entries.add(createEntry(bodyPiece, y)); - - if (footerPiece != null) { - y = height - heightOf(footerPiece); - entries.add(createEntry(footerPiece, y)); - } - - return new CompositePiece(entries); - } - - private CompositeEntry createEntry(PrintPiece piece, int y) { - return new CompositeEntry(piece, new Point(0, y)); - } - - private PrintPiece getDecorationPrintPiece(Print decoration, int width, - int height) { - PrintIterator iterator = decoration.iterator(device, gc); - PrintPiece piece = PaperClips.next(iterator, width, height); - - if (piece == null) - return null; - if (iterator.hasNext()) { - piece.dispose(); - return null; - } - return piece; - } - - public PrintIterator copy() { - return new PageIterator(this); - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.page; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.CompositeEntry; +import org.eclipse.nebula.paperclips.core.CompositePiece; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A decorator Print which displays page headers and footers around a document + * body, with page numbering capabilities. + *

+ * PagePrint is horizontally and vertically greedy. Greedy prints take up all + * the available space on the page. + *

+ * Note: Avoid wrapping PagePrint in prints with space-optimizing + * semantics (e.g. ColumnPrint equalizes columns on the last page), as this may + * cause the total page count to be incorrect on some pages. At this time there + * is no known fix. If wrapping a PagePrint is unavoidable, consider using a + * custom PageNumberFormat which does not display the total page count. + * + * @author Matthew Hall + */ +public class PagePrint implements Print { + private static final int DEFAULT_GAP = 1; + + PageDecoration header; + int headerGap = DEFAULT_GAP; // in points + Print body; + int footerGap = DEFAULT_GAP; // in points + PageDecoration footer; + + /** + * Constructs a PagePrint with the given header and body. + * + * @param header + * a PageDecoration for creating the header. May be null. + * @param headerGap + * the gap between the header and body, in points. + * @param body + * the Print being decorated. + */ + public PagePrint(PageDecoration header, int headerGap, Print body) { + this(header, headerGap, body, DEFAULT_GAP, null); + } + + /** + * Constructs a PagePrint with the given header and body. + * + * @param body + * the Print being decorated. + * @param header + * a PageDecoration for creating the header. May be null. + */ + public PagePrint(PageDecoration header, Print body) { + this(header, DEFAULT_GAP, body); + } + + /** + * Constructs a PagePrint with the given body. + * + * @param body + * the Print being decorated. + */ + public PagePrint(Print body) { + this(null, body, null); + } + + /** + * Constructs a PagePrint with the given body and footer. + * + * @param body + * the Print being decorated. + * @param footer + * a PageDecoration for creating the footer. may be null. + */ + public PagePrint(Print body, PageDecoration footer) { + this(body, DEFAULT_GAP, footer); + } + + /** + * Constructs a PagePrint with the given body, header and footer. + * + * @param body + * the Print being decorated. + * @param footerGap + * the gap between the body and footer, in points. + * @param footer + * a PageDecoration for creating the footer. May be null. + */ + public PagePrint(Print body, int footerGap, PageDecoration footer) { + this(null, DEFAULT_GAP, body, footerGap, footer); + } + + /** + * Constructs a PagePrint with the given body, header and footer. + * + * @param header + * a PageDecoration for creating the header. May be null. + * @param body + * the Print being decorated. + * @param footer + * a PageDecoration for creating the footer. may be null. + */ + public PagePrint(PageDecoration header, Print body, PageDecoration footer) { + this(header, DEFAULT_GAP, body, DEFAULT_GAP, footer); + } + + /** + * Constructs a PagePrint with the given body, header and footer. + * + * @param header + * a PageDecoration for creating the header. May be null. + * @param headerGap + * the gap between the header and body, in points. + * @param body + * the Print being decorated. + * @param footerGap + * the gap between the body and footer, in points. + * @param footer + * a PageDecoration for creating the footer. May be null. + */ + public PagePrint(PageDecoration header, int headerGap, Print body, + int footerGap, PageDecoration footer) { + setHeader(header); + setHeaderGap(headerGap); + setBody(body); + setFooterGap(footerGap); + setFooter(footer); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((body == null) ? 0 : body.hashCode()); + result = prime * result + ((footer == null) ? 0 : footer.hashCode()); + result = prime * result + footerGap; + result = prime * result + ((header == null) ? 0 : header.hashCode()); + result = prime * result + headerGap; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PagePrint other = (PagePrint) obj; + if (body == null) { + if (other.body != null) + return false; + } else if (!body.equals(other.body)) + return false; + if (footer == null) { + if (other.footer != null) + return false; + } else if (!footer.equals(other.footer)) + return false; + if (footerGap != other.footerGap) + return false; + if (header == null) { + if (other.header != null) + return false; + } else if (!header.equals(other.header)) + return false; + if (headerGap != other.headerGap) + return false; + return true; + } + + /** + * Returns the page header. + * + * @return the page header. + */ + public PageDecoration getHeader() { + return header; + } + + /** + * Sets the page header to the argument. + * + * @param header + * a PageDecoration which creates the header. May be null. + */ + public void setHeader(PageDecoration header) { + this.header = header; + } + + /** + * Returns the gap between the header and body, expressed in points. + * + * @return the gap between the header and body, expressed in points. + */ + public int getHeaderGap() { + return headerGap; + } + + /** + * Sets the gap between the header and body to the argument, expressed in + * points. + * + * @param points + * the new gap between the header and body, expressed in points. + * 72 points = 1". + */ + public void setHeaderGap(int points) { + this.headerGap = checkGap(points); + } + + /** + * Returns the page body. + * + * @return the page body. + */ + public Print getBody() { + return body; + } + + /** + * Sets the page body to the argument. + * + * @param body + * the new page body. + */ + public void setBody(Print body) { + Util.notNull(body); + this.body = body; + } + + /** + * Returns the page footer. + * + * @return the page footer. + */ + public PageDecoration getFooter() { + return footer; + } + + /** + * Sets the page footer to the argument. + * + * @param footer + * a PageDecoration which creates the footer. May be null. + */ + public void setFooter(PageDecoration footer) { + this.footer = footer; + } + + /** + * Returns the gap between the body and footer, expressed in points. + * + * @return the gap between the body and footer, expressed in points. + */ + public int getFooterGap() { + return footerGap; + } + + /** + * Sets the gap between the body and footer to the argument, expressed in + * points. + * + * @param points + * the new gap between the body and footer (if there is a + * footer). + */ + public void setFooterGap(int points) { + this.footerGap = checkGap(points); + } + + private static int checkGap(int gap) { + if (gap < 0) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, + "Gap must be >= 0 (value is " + gap + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + return gap; + } + + public PrintIterator iterator(Device device, GC gc) { + if (header == null && footer == null) + return body.iterator(device, gc); + + return new PageIterator(this, device, gc); + } +} + +class PageIterator implements PrintIterator { + class PageNumberer { + int pageCount = 0; + + synchronized PageNumber next() { + return new InnerPageNumber(); + } + + class InnerPageNumber implements PageNumber { + final int pageNumber = pageCount++; // POST-increment + + public int getPageCount() { + return pageCount; + } + + public int getPageNumber() { + return pageNumber; + } + } + + PageNumberer copy() { + PageNumberer result = new PageNumberer(); + result.pageCount = this.pageCount; + return result; + } + } + + final Device device; + final GC gc; + + final PageDecoration header; + final int headerGap; // pixels + final PrintIterator body; + final int footerGap; // pixels + final PageDecoration footer; + + final PageNumberer numberer; + + final Point minimumSize; + final Point preferredSize; + + PageIterator(PagePrint print, Device device, GC gc) { + this.device = device; + this.gc = gc; + + Point dpi = device.getDPI(); + + body = print.body.iterator(device, gc); + header = print.header; + headerGap = header == null ? 0 : print.headerGap * dpi.y / 72; + footer = print.footer; + footerGap = footer == null ? 0 : print.footerGap * dpi.y / 72; + + this.numberer = new PageNumberer(); + + this.minimumSize = computeSize(PrintSizeStrategy.MINIMUM); + this.preferredSize = computeSize(PrintSizeStrategy.PREFERRED); + } + + PageIterator(PageIterator that) { + this.device = that.device; + this.gc = that.gc; + + this.body = that.body.copy(); + this.header = that.header; + this.headerGap = that.headerGap; + this.footer = that.footer; + this.footerGap = that.footerGap; + + // FIXME: Wrapping PagePrint in a class with space-optimizing semantics + // (ColumnPrint) can fork the total + // page count. i.e. if the copied PageIterator is chosen as the optimal + // layout, then previous pages will + // have a page number spawned from a different page numberer. Thus the + // total page count for those + // previous pages will no longer be incremented with each new page. + this.numberer = that.numberer.copy(); + this.pageNumber = that.pageNumber; + + this.minimumSize = that.minimumSize; + this.preferredSize = that.preferredSize; + } + + private Point computeSize(PrintSizeStrategy strategy) { + Point size = strategy.computeSize(body); + + PageNumber samplePageNumber = new PageNumber() { + public int getPageCount() { + return 1; + } + + public int getPageNumber() { + return 0; + } + }; + + if (header != null) { + Print headerPrint = header.createPrint(samplePageNumber); + if (headerPrint != null) { + PrintIterator iter = headerPrint.iterator(device, gc); + + size.y += headerGap; + + Point headerSize = strategy.computeSize(iter); + size.x = Math.max(size.x, headerSize.x); + size.y += headerSize.y; + } + } + + if (footer != null) { + Print footerPrint = footer.createPrint(samplePageNumber); + if (footerPrint != null) { + PrintIterator iter = footerPrint.iterator(device, gc); + + size.y += footerGap; + + Point footerSize = strategy.computeSize(iter); + size.x = Math.max(size.x, footerSize.x); + size.y += footerSize.y; + } + } + + return size; + } + + public boolean hasNext() { + return body.hasNext(); + } + + public Point minimumSize() { + return new Point(minimumSize.x, minimumSize.y); + } + + public Point preferredSize() { + return new Point(preferredSize.x, preferredSize.y); + } + + public PrintPiece next(int width, final int height) { + PageNumber pageNumber = getCurrentPageNumber(); + + // HEADER + PrintPiece headerPiece = null; + int availableHeight = height; + if (header != null) { + Print headerPrint = header.createPrint(pageNumber); + if (headerPrint != null) { + headerPiece = getDecorationPrintPiece(headerPrint, width, + availableHeight); + if (headerPiece == null) + return null; + availableHeight -= (heightOf(headerPiece) + headerGap); + } + } + + // FOOTER + PrintPiece footerPiece = null; + if (footer != null) { + Print footerPrint = footer.createPrint(pageNumber); + if (footerPrint != null) { + footerPiece = getDecorationPrintPiece(footerPrint, width, + availableHeight); + if (footerPiece == null) { + PaperClipsUtil.dispose(headerPiece); + return null; + } + availableHeight -= (heightOf(footerPiece) + footerGap); + } + } + + // BODY + PrintPiece bodyPiece = PaperClips.next(body, width, availableHeight); + if (bodyPiece == null) { + PaperClipsUtil.dispose(headerPiece, footerPiece); + return null; + } + + PrintPiece result = createResult(height, headerPiece, bodyPiece, + footerPiece); + advancePageNumber(); + return result; + } + + private int heightOf(PrintPiece piece) { + return piece.getSize().y; + } + + PageNumber pageNumber; + + private void advancePageNumber() { + // Null the pageNumber field so the next iteration advances to the next + // page. + pageNumber = null; + } + + private PageNumber getCurrentPageNumber() { + if (pageNumber == null) + pageNumber = numberer.next(); + return pageNumber; + } + + private PrintPiece createResult(int height, PrintPiece headerPiece, + PrintPiece bodyPiece, PrintPiece footerPiece) { + if (headerPiece == null && footerPiece == null) + return bodyPiece; + + List entries = new ArrayList<>(); + + if (headerPiece != null) + entries.add(createEntry(headerPiece, 0)); + + int y = headerPiece == null ? 0 : heightOf(headerPiece) + headerGap; + entries.add(createEntry(bodyPiece, y)); + + if (footerPiece != null) { + y = height - heightOf(footerPiece); + entries.add(createEntry(footerPiece, y)); + } + + return new CompositePiece(entries); + } + + private CompositeEntry createEntry(PrintPiece piece, int y) { + return new CompositeEntry(piece, new Point(0, y)); + } + + private PrintPiece getDecorationPrintPiece(Print decoration, int width, + int height) { + PrintIterator iterator = decoration.iterator(device, gc); + PrintPiece piece = PaperClips.next(iterator, width, height); + + if (piece == null) + return null; + if (iterator.hasNext()) { + piece.dispose(); + return null; + } + return piece; + } + + public PrintIterator copy() { + return new PageIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/SimplePageDecoration.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/SimplePageDecoration.java index 8b0cd0749..5f2b352bc 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/SimplePageDecoration.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/page/SimplePageDecoration.java @@ -1,70 +1,70 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.page; - -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.internal.util.Util; - -/** - * A PageDecoration which displays the same decoration on every page (ignoring - * the page number). - *

- * Typically the page number will be in either the header or footer, but not in - * both. Often the page number is the only thing that changes from page to page - * in a header. Use this class for a header or footer which does not display the - * page number. - * - * @author Matthew Hall - */ -public class SimplePageDecoration implements PageDecoration { - private final Print print; - - /** - * Constructs a BasicPageDecoration. - * - * @param print - * the decoration which will appear on every page. - */ - public SimplePageDecoration(Print print) { - Util.notNull(print); - this.print = print; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((print == null) ? 0 : print.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SimplePageDecoration other = (SimplePageDecoration) obj; - if (print == null) { - if (other.print != null) - return false; - } else if (!print.equals(other.print)) - return false; - return true; - } - - public Print createPrint(PageNumber pageNumber) { - return print; - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.page; + +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.internal.util.Util; + +/** + * A PageDecoration which displays the same decoration on every page (ignoring + * the page number). + *

+ * Typically the page number will be in either the header or footer, but not in + * both. Often the page number is the only thing that changes from page to page + * in a header. Use this class for a header or footer which does not display the + * page number. + * + * @author Matthew Hall + */ +public class SimplePageDecoration implements PageDecoration { + private final Print print; + + /** + * Constructs a BasicPageDecoration. + * + * @param print + * the decoration which will appear on every page. + */ + public SimplePageDecoration(Print print) { + Util.notNull(print); + this.print = print; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((print == null) ? 0 : print.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SimplePageDecoration other = (SimplePageDecoration) obj; + if (print == null) { + if (other.print != null) + return false; + } else if (!print.equals(other.print)) + return false; + return true; + } + + public Print createPrint(PageNumber pageNumber) { + return print; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/LineBreakPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/LineBreakPrint.java index f48c47a82..15adc67b7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/LineBreakPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/LineBreakPrint.java @@ -1,127 +1,127 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.text; - -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.internal.piece.EmptyPiece; -import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A class for adding line breaks corresponding to a particular font size. - * Currently this class is used internally by StyledTextPrint to implement the - * newline() feature. - * - * @author Matthew Hall - */ -public class LineBreakPrint implements Print { - final FontData font; - - /** - * Constructs a new LineBreakPrint on the given font. - * - * @param font - * the font which determines the height of the line break. - */ - public LineBreakPrint(FontData font) { - Util.notNull(font); - this.font = font; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((font == null) ? 0 : font.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LineBreakPrint other = (LineBreakPrint) obj; - if (font == null) { - if (other.font != null) - return false; - } else if (!font.equals(other.font)) - return false; - return true; - } - - public PrintIterator iterator(Device device, GC gc) { - return new LineBreakIterator(this, device, gc); - } -} - -class LineBreakIterator implements PrintIterator { - private static final int MIN_HEIGHT = 0; - private static final int MIN_WIDTH = 1; - - private final int lineHeight; - private boolean hasNext = true; - - LineBreakIterator(LineBreakPrint print, Device device, GC gc) { - this(calculateLineHeight(print, device, gc)); - } - - private LineBreakIterator(int lineHeight) { - this.lineHeight = lineHeight; - } - - private static int calculateLineHeight(LineBreakPrint print, Device device, - GC gc) { - Font oldFont = gc.getFont(); - - gc.setFont(ResourcePool.forDevice(device).getFont(print.font)); - int result = gc.getFontMetrics().getHeight(); - - gc.setFont(oldFont); - - return result; - } - - public Point minimumSize() { - return new Point(MIN_WIDTH, MIN_HEIGHT); - } - - public Point preferredSize() { - return new Point(MIN_WIDTH, lineHeight); - } - - public boolean hasNext() { - return hasNext; - } - - public PrintPiece next(int width, int height) { - if (width < MIN_WIDTH || height < MIN_HEIGHT) - return null; - - hasNext = false; - return new EmptyPiece(new Point(width, Math.min(height, lineHeight))); - } - - public PrintIterator copy() { - return hasNext ? new LineBreakIterator(lineHeight) : this; - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.text; + +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.internal.piece.EmptyPiece; +import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A class for adding line breaks corresponding to a particular font size. + * Currently this class is used internally by StyledTextPrint to implement the + * newline() feature. + * + * @author Matthew Hall + */ +public class LineBreakPrint implements Print { + final FontData font; + + /** + * Constructs a new LineBreakPrint on the given font. + * + * @param font + * the font which determines the height of the line break. + */ + public LineBreakPrint(FontData font) { + Util.notNull(font); + this.font = font; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((font == null) ? 0 : font.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LineBreakPrint other = (LineBreakPrint) obj; + if (font == null) { + if (other.font != null) + return false; + } else if (!font.equals(other.font)) + return false; + return true; + } + + public PrintIterator iterator(Device device, GC gc) { + return new LineBreakIterator(this, device, gc); + } +} + +class LineBreakIterator implements PrintIterator { + private static final int MIN_HEIGHT = 0; + private static final int MIN_WIDTH = 1; + + private final int lineHeight; + private boolean hasNext = true; + + LineBreakIterator(LineBreakPrint print, Device device, GC gc) { + this(calculateLineHeight(print, device, gc)); + } + + private LineBreakIterator(int lineHeight) { + this.lineHeight = lineHeight; + } + + private static int calculateLineHeight(LineBreakPrint print, Device device, + GC gc) { + Font oldFont = gc.getFont(); + + gc.setFont(ResourcePool.forDevice(device).getFont(print.font)); + int result = gc.getFontMetrics().getHeight(); + + gc.setFont(oldFont); + + return result; + } + + public Point minimumSize() { + return new Point(MIN_WIDTH, MIN_HEIGHT); + } + + public Point preferredSize() { + return new Point(MIN_WIDTH, lineHeight); + } + + public boolean hasNext() { + return hasNext; + } + + public PrintPiece next(int width, int height) { + if (width < MIN_WIDTH || height < MIN_HEIGHT) + return null; + + hasNext = false; + return new EmptyPiece(new Point(width, Math.min(height, lineHeight))); + } + + public PrintIterator copy() { + return hasNext ? new LineBreakIterator(lineHeight) : this; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/StyledTextPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/StyledTextPrint.java index 8f0df1fd8..3d7264949 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/StyledTextPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/StyledTextPrint.java @@ -1,302 +1,302 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.text; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.CompositeEntry; -import org.eclipse.nebula.paperclips.core.CompositePiece; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.nebula.paperclips.core.text.internal.TextPrintPiece; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -/** - * A class for printing styled text. Text of varying size and style are aligned - * along the baseline. - * - * @author Matthew Hall - */ -public class StyledTextPrint implements Print { - private final List elements = new ArrayList<>(); - private TextStyle style = new TextStyle(); - - /** - * Constructs a new StyledTextPrint. - */ - public StyledTextPrint() { - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((elements == null) ? 0 : elements.hashCode()); - result = prime * result + ((style == null) ? 0 : style.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - StyledTextPrint other = (StyledTextPrint) obj; - if (elements == null) { - if (other.elements != null) - return false; - } else if (!elements.equals(other.elements)) - return false; - if (style == null) { - if (other.style != null) - return false; - } else if (!style.equals(other.style)) - return false; - return true; - } - - /** - * Sets the text style that will be applied to text added through the - * {@link #append(String)} - * - * @param style - * the new text style. - * @return this StyledTextPrint, for chaining method calls. - */ - public StyledTextPrint setStyle(TextStyle style) { - Util.notNull(style); - this.style = style; - return this; - } - - /** - * Appends the given text to the end of the document, using the default - * style. This method is equivalent to calling append(text, getStyle()). - * - * @param text - * the text to append. - * @return this StyledTextPrint, for chaining method calls. - */ - public StyledTextPrint append(String text) { - return append(text, style); - } - - /** - * Appends the given text to the end of the document, using the given style. - * - * @param text - * the text to append. - * @param style - * the text style. - * @return this StyledTextPrint, for chaining method calls. - */ - public StyledTextPrint append(String text, TextStyle style) { - TextPrint textPrint = new TextPrint(text, style); - textPrint.setWordSplitting(false); - return append(textPrint); - } - - /** - * Appends a line break to the document. If a line break produces a blank - * line, that line will take the height of the font in the default text - * style. - * - * @return this StyledTextPrint, for chaining method calls. - */ - public StyledTextPrint newline() { - return append(new LineBreakPrint(style.getFontData())); - } - - /** - * Appends the given element to the document. - * - * @param element - * the element to append. - * @return this StyledTextPrint, for chaining method calls. - */ - public StyledTextPrint append(Print element) { - elements.add(element); - return this; - } - - public PrintIterator iterator(Device device, GC gc) { - return new StyledTextIterator( - elements.toArray(new Print[elements.size()]), device, gc); - } -} - -class StyledTextIterator implements PrintIterator { - private final PrintIterator[] elements; - private final Point minimumSize; - private final Point preferredSize; - - private int cursor = 0; - - StyledTextIterator(Print[] elements, Device device, GC gc) { - this.elements = new PrintIterator[elements.length]; - for (int i = 0; i < elements.length; i++) - this.elements[i] = elements[i].iterator(device, gc); - minimumSize = computeSize(PrintSizeStrategy.MINIMUM); - preferredSize = computeSize(PrintSizeStrategy.PREFERRED); - } - - private StyledTextIterator(StyledTextIterator that) { - elements = new PrintIterator[that.elements.length - that.cursor]; - minimumSize = that.minimumSize; - preferredSize = that.preferredSize; - for (int i = 0; i < elements.length; i++) - elements[i] = that.elements[that.cursor + i].copy(); - } - - private Point computeSize(PrintSizeStrategy strategy) { - Point result = new Point(0, 0); - for (int i = 0; i < elements.length; i++) { - Point current = strategy.computeSize(elements[i]); - result.x = Math.max(result.x, current.x); - result.y = Math.max(result.y, current.y); - } - return result; - } - - public Point minimumSize() { - return new Point(minimumSize.x, minimumSize.y); - } - - public Point preferredSize() { - return new Point(preferredSize.x, preferredSize.y); - } - - public boolean hasNext() { - advanceCursor(); - return cursor < elements.length; - } - - public PrintPiece next(int width, int height) { - if (width < 0 || height < 0) - return null; - - int y = 0; - - List rows = new ArrayList<>(); - while (y < height) { - PrintPiece row = nextRow(width, height - y); - if (row == null) - break; - rows.add(new CompositeEntry(row, new Point(0, y))); - y += row.getSize().y; - } - - if (rows.size() == 0) - return null; - - return new CompositePiece(rows); - } - - private PrintPiece nextRow(int width, int height) { - int x = 0; - int maxAscent = 0; - int maxDescent = 0; - - final int backupCursor = cursor; - final List backup = new ArrayList<>(); - - List rowElements = new ArrayList<>(); - while (hasNext()) { // hasNext advances cursor internally - PrintIterator element = elements[cursor]; - Point preferredSize = element.preferredSize(); - if (preferredSize.y > height) - break; - - PrintIterator elementBackup = element.copy(); - PrintPiece piece = PaperClips.next(element, width - x, - preferredSize.y); - if (piece == null) - break; - - rowElements.add(piece); - backup.add(elementBackup); - - maxAscent = Math.max(maxAscent, getAscent(piece)); - maxDescent = Math.max(maxDescent, getDescent(piece)); - if (maxAscent + maxDescent > height) { - restoreBackup(backupCursor, backup); - return null; - } - - if (element.hasNext()) - break; - - x += piece.getSize().x; - } - - return createRowResult(maxAscent, rowElements); - } - - private PrintPiece createRowResult(int rowAscent, - List rowElements) { - if (rowElements.size() == 0) - return null; - - List entries = new ArrayList<>(); - int x = 0; - for (int i = 0; i < rowElements.size(); i++) { - PrintPiece piece = rowElements.get(i); - int ascent = getAscent(piece); - entries.add(new CompositeEntry(piece, - new Point(x, rowAscent - ascent))); - x += piece.getSize().x; - } - - return new CompositePiece(entries); - } - - private void restoreBackup(final int backupCursor, - final List backup) { - for (int i = 0; i < backup.size(); i++) - elements[backupCursor + i] = backup.get(i); - cursor = backupCursor; - } - - private int getAscent(PrintPiece piece) { - if (piece instanceof TextPrintPiece) - return ((TextPrintPiece) piece).getAscent(); - return piece.getSize().y; - } - - private int getDescent(PrintPiece piece) { - if (piece instanceof TextPrintPiece) - return piece.getSize().y - ((TextPrintPiece) piece).getAscent(); - return 0; - } - - private void advanceCursor() { - while (cursor < elements.length && !elements[cursor].hasNext()) - cursor++; - } - - public PrintIterator copy() { - return new StyledTextIterator(this); - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.text; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.CompositeEntry; +import org.eclipse.nebula.paperclips.core.CompositePiece; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.nebula.paperclips.core.text.internal.TextPrintPiece; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +/** + * A class for printing styled text. Text of varying size and style are aligned + * along the baseline. + * + * @author Matthew Hall + */ +public class StyledTextPrint implements Print { + private final List elements = new ArrayList<>(); + private TextStyle style = new TextStyle(); + + /** + * Constructs a new StyledTextPrint. + */ + public StyledTextPrint() { + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((elements == null) ? 0 : elements.hashCode()); + result = prime * result + ((style == null) ? 0 : style.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StyledTextPrint other = (StyledTextPrint) obj; + if (elements == null) { + if (other.elements != null) + return false; + } else if (!elements.equals(other.elements)) + return false; + if (style == null) { + if (other.style != null) + return false; + } else if (!style.equals(other.style)) + return false; + return true; + } + + /** + * Sets the text style that will be applied to text added through the + * {@link #append(String)} + * + * @param style + * the new text style. + * @return this StyledTextPrint, for chaining method calls. + */ + public StyledTextPrint setStyle(TextStyle style) { + Util.notNull(style); + this.style = style; + return this; + } + + /** + * Appends the given text to the end of the document, using the default + * style. This method is equivalent to calling append(text, getStyle()). + * + * @param text + * the text to append. + * @return this StyledTextPrint, for chaining method calls. + */ + public StyledTextPrint append(String text) { + return append(text, style); + } + + /** + * Appends the given text to the end of the document, using the given style. + * + * @param text + * the text to append. + * @param style + * the text style. + * @return this StyledTextPrint, for chaining method calls. + */ + public StyledTextPrint append(String text, TextStyle style) { + TextPrint textPrint = new TextPrint(text, style); + textPrint.setWordSplitting(false); + return append(textPrint); + } + + /** + * Appends a line break to the document. If a line break produces a blank + * line, that line will take the height of the font in the default text + * style. + * + * @return this StyledTextPrint, for chaining method calls. + */ + public StyledTextPrint newline() { + return append(new LineBreakPrint(style.getFontData())); + } + + /** + * Appends the given element to the document. + * + * @param element + * the element to append. + * @return this StyledTextPrint, for chaining method calls. + */ + public StyledTextPrint append(Print element) { + elements.add(element); + return this; + } + + public PrintIterator iterator(Device device, GC gc) { + return new StyledTextIterator( + elements.toArray(new Print[elements.size()]), device, gc); + } +} + +class StyledTextIterator implements PrintIterator { + private final PrintIterator[] elements; + private final Point minimumSize; + private final Point preferredSize; + + private int cursor = 0; + + StyledTextIterator(Print[] elements, Device device, GC gc) { + this.elements = new PrintIterator[elements.length]; + for (int i = 0; i < elements.length; i++) + this.elements[i] = elements[i].iterator(device, gc); + minimumSize = computeSize(PrintSizeStrategy.MINIMUM); + preferredSize = computeSize(PrintSizeStrategy.PREFERRED); + } + + private StyledTextIterator(StyledTextIterator that) { + elements = new PrintIterator[that.elements.length - that.cursor]; + minimumSize = that.minimumSize; + preferredSize = that.preferredSize; + for (int i = 0; i < elements.length; i++) + elements[i] = that.elements[that.cursor + i].copy(); + } + + private Point computeSize(PrintSizeStrategy strategy) { + Point result = new Point(0, 0); + for (int i = 0; i < elements.length; i++) { + Point current = strategy.computeSize(elements[i]); + result.x = Math.max(result.x, current.x); + result.y = Math.max(result.y, current.y); + } + return result; + } + + public Point minimumSize() { + return new Point(minimumSize.x, minimumSize.y); + } + + public Point preferredSize() { + return new Point(preferredSize.x, preferredSize.y); + } + + public boolean hasNext() { + advanceCursor(); + return cursor < elements.length; + } + + public PrintPiece next(int width, int height) { + if (width < 0 || height < 0) + return null; + + int y = 0; + + List rows = new ArrayList<>(); + while (y < height) { + PrintPiece row = nextRow(width, height - y); + if (row == null) + break; + rows.add(new CompositeEntry(row, new Point(0, y))); + y += row.getSize().y; + } + + if (rows.size() == 0) + return null; + + return new CompositePiece(rows); + } + + private PrintPiece nextRow(int width, int height) { + int x = 0; + int maxAscent = 0; + int maxDescent = 0; + + final int backupCursor = cursor; + final List backup = new ArrayList<>(); + + List rowElements = new ArrayList<>(); + while (hasNext()) { // hasNext advances cursor internally + PrintIterator element = elements[cursor]; + Point preferredSize = element.preferredSize(); + if (preferredSize.y > height) + break; + + PrintIterator elementBackup = element.copy(); + PrintPiece piece = PaperClips.next(element, width - x, + preferredSize.y); + if (piece == null) + break; + + rowElements.add(piece); + backup.add(elementBackup); + + maxAscent = Math.max(maxAscent, getAscent(piece)); + maxDescent = Math.max(maxDescent, getDescent(piece)); + if (maxAscent + maxDescent > height) { + restoreBackup(backupCursor, backup); + return null; + } + + if (element.hasNext()) + break; + + x += piece.getSize().x; + } + + return createRowResult(maxAscent, rowElements); + } + + private PrintPiece createRowResult(int rowAscent, + List rowElements) { + if (rowElements.size() == 0) + return null; + + List entries = new ArrayList<>(); + int x = 0; + for (int i = 0; i < rowElements.size(); i++) { + PrintPiece piece = rowElements.get(i); + int ascent = getAscent(piece); + entries.add(new CompositeEntry(piece, + new Point(x, rowAscent - ascent))); + x += piece.getSize().x; + } + + return new CompositePiece(entries); + } + + private void restoreBackup(final int backupCursor, + final List backup) { + for (int i = 0; i < backup.size(); i++) + elements[backupCursor + i] = backup.get(i); + cursor = backupCursor; + } + + private int getAscent(PrintPiece piece) { + if (piece instanceof TextPrintPiece) + return ((TextPrintPiece) piece).getAscent(); + return piece.getSize().y; + } + + private int getDescent(PrintPiece piece) { + if (piece instanceof TextPrintPiece) + return piece.getSize().y - ((TextPrintPiece) piece).getAscent(); + return 0; + } + + private void advanceCursor() { + while (cursor < elements.length && !elements[cursor].hasNext()) + cursor++; + } + + public PrintIterator copy() { + return new StyledTextIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/TextPrint.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/TextPrint.java index 44bea2dcb..151f8743d 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/TextPrint.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/TextPrint.java @@ -1,565 +1,565 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.text; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.nebula.paperclips.core.text.internal.TextPiece; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -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.Point; -import org.eclipse.swt.graphics.RGB; - -/** - * A Print for displaying text. - *

- * TextPrints are never greedy with layout space, even with center- or - * right-alignment. (Greedy prints take up all the available space on the page.) - * Therefore, when center- or right-alignment is required, it is necessary to - * wrap the text in a Print which will enforce the same alignment. Usually this - * is a center:default:grow or right:default:grow column in a GridPrint. - * - * @author Matthew Hall - */ -public class TextPrint implements Print { - /** The default text for a TextPrint. Value is "". */ - public static final String DEFAULT_TEXT = ""; //$NON-NLS-1$ - - /** The default font data for a TextPrint. Value is device-dependent. */ - public static final FontData DEFAULT_FONT_DATA = new FontData(); - - /** The default alignment for TextPrint. Value is SWT.LEFT. */ - public static final int DEFAULT_ALIGN = SWT.LEFT; - - private static final TextStyle DEFAULT_STYLE = new TextStyle(); - - String text; - TextStyle style; - boolean wordSplitting; - - /** - * Constructs a TextPrint with the default properties. - */ - public TextPrint() { - this(DEFAULT_TEXT); - } - - /** - * Constructs a TextPrint with the given text. - * - * @param text - * the text to print. - */ - public TextPrint(String text) { - this(text, DEFAULT_STYLE); - } - - /** - * Constructs a TextPrint with the given text and font data. - * - * @param text - * the text to print. - * @param fontData - * the font that will be used to print the text. - */ - public TextPrint(String text, FontData fontData) { - this(text, DEFAULT_STYLE.font(fontData)); - } - - /** - * Constructs a TextPrint with the give text and alignment. - * - * @param text - * the text to print. - * @param align - * the horizontal text alignment. Must be one of {@link SWT#LEFT} - * , {@link SWT#CENTER} or {@link SWT#RIGHT}. - */ - public TextPrint(String text, int align) { - this(text, DEFAULT_STYLE.align(align)); - } - - /** - * Constructs a TextPrint with the given text, font data, and alignment. - * - * @param text - * the text to print. - * @param fontData - * the font that will be used to print the text. - * @param align - * the horizontal text alignment. Must be one of {@link SWT#LEFT} - * , {@link SWT#CENTER} or {@link SWT#RIGHT}. - */ - public TextPrint(String text, FontData fontData, int align) { - this(text, DEFAULT_STYLE.font(fontData).align(align)); - } - - /** - * Constructs a TextPrint with the given text and style. - * - * @param text - * the text to print. - * @param style - * the style to apply to the text. - */ - public TextPrint(String text, TextStyle style) { - Util.notNull(text, style); - this.text = text; - this.style = style; - this.wordSplitting = true; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((style == null) ? 0 : style.hashCode()); - result = prime * result + ((text == null) ? 0 : text.hashCode()); - result = prime * result + (wordSplitting ? 1231 : 1237); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - TextPrint other = (TextPrint) obj; - if (style == null) { - if (other.style != null) - return false; - } else if (!style.equals(other.style)) - return false; - if (text == null) { - if (other.text != null) - return false; - } else if (!text.equals(other.text)) - return false; - if (wordSplitting != other.wordSplitting) - return false; - return true; - } - - /** - * Returns the text that will be printed. - * - * @return the text that will be printed. - */ - public String getText() { - return text; - } - - /** - * Sets the text that will be printed. - * - * @param text - * the text to print. - */ - public void setText(String text) { - Util.notNull(text); - this.text = text; - } - - /** - * Returns the text style. - * - * @return the text style. - */ - public TextStyle getStyle() { - return style; - } - - /** - * Sets the text style to the argument. - * - * @param style - * the new text style. - */ - public void setStyle(TextStyle style) { - Util.notNull(style); - this.style = style; - } - - /** - * Returns the font that will be used to print the text. - * - * @return the font that will be used to print the text. - */ - public FontData getFontData() { - return style.getFontData(); - } - - /** - * Sets the font that will be used to print the text. - * - * @param fontData - * the font that will be used to print the text. - */ - public void setFontData(FontData fontData) { - setStyle(style.font(fontData)); - } - - /** - * Returns the horizontal text alignment. Possible values include - * {@link SWT#LEFT}, {@link SWT#CENTER} or {@link SWT#RIGHT}. - * - * @return the horizontal text alignment. - */ - public int getAlignment() { - return style.getAlignment(); - } - - /** - * Sets the horizontal text alignment. - * - * @param alignment - * the horizontal text alignment. Must be one of {@link SWT#LEFT} - * , {@link SWT#CENTER} or {@link SWT#RIGHT}. - */ - public void setAlignment(int alignment) { - setStyle(style.align(alignment)); - } - - /** - * Returns the foreground color. A null value indicates that the foreground - * color is inherited. - * - * @return the foreground color. - */ - public RGB getForeground() { - return style.getForeground(); - } - - /** - * Sets the foreground color to the argument. - * - * @param foreground - * the new foreground color. A null value causes the foreground - * color to be inherited. - */ - public void setForeground(RGB foreground) { - setStyle(style.foreground(foreground)); - } - - /** - * Returns the background color. A null value indicates that the background - * is transparent. - * - * @return the background color. - */ - public RGB getBackground() { - return style.getBackground(); - } - - /** - * Sets the background color to the argument. - * - * @param background - * the new background color. A null value causes the background - * to be transparent. - */ - public void setBackground(RGB background) { - style = style.background(background); - } - - /** - * Returns the underline flag. - * - * @return the underline flag. - */ - public boolean getUnderline() { - return style.getUnderline(); - } - - /** - * Sets the underline flag to the argument. - * - * @param underline - * the underline flag. - */ - public void setUnderline(boolean underline) { - style = style.underline(underline); - } - - /** - * Returns the strikout flag. - * - * @return the strikout flag. - */ - public boolean getStrikeout() { - return style.getStrikeout(); - } - - /** - * Sets the strikeout flag to the argument. - * - * @param strikeout - * the strikeout flag. - */ - public void setStrikeout(boolean strikeout) { - style = style.strikeout(strikeout); - } - - /** - * Returns whether word splitting is enabled. Default is true. - * - * @return whether word splitting is enabled. - */ - public boolean getWordSplitting() { - return wordSplitting; - } - - /** - * Sets whether word splitting is enabled. - * - * @param wordBreaking - * whether to allow word splitting. - */ - public void setWordSplitting(boolean wordBreaking) { - this.wordSplitting = wordBreaking; - } - - public PrintIterator iterator(Device device, GC gc) { - return new TextIterator(this, device, gc); - } -} - -class TextIterator implements PrintIterator { - private final Device device; - private final GC gc; - - final String text; - final String[] lines; - final TextStyle style; - final boolean wordSplitting; - final Point minimumSize; - final Point preferredSize; - - int row; - int col; - - TextIterator(TextPrint print, Device device, GC gc) { - this.device = device; - this.gc = gc; - - this.text = print.text; - this.lines = print.text.split("(\r)?\n"); //$NON-NLS-1$ - this.style = print.style; - this.wordSplitting = print.wordSplitting; - this.minimumSize = maxExtent(text.split("\\s")); //$NON-NLS-1$ - this.preferredSize = maxExtent(lines); - - this.row = 0; - this.col = 0; - } - - TextIterator(TextIterator that) { - this.device = that.device; - this.gc = that.gc; - - this.text = that.text; - this.lines = that.lines; - this.style = that.style; - this.wordSplitting = that.wordSplitting; - this.minimumSize = that.minimumSize; - this.preferredSize = that.preferredSize; - - this.row = that.row; - this.col = that.col; - } - - public boolean hasNext() { - return row < lines.length; - } - - public PrintPiece next(int width, int height) { - if (!hasNext()) - PaperClips.error("No more content."); //$NON-NLS-1$ - - Font oldFont = initGC(); - PrintPiece result = internalNext(width, height); - restoreGC(oldFont); - - return result; - } - - private PrintPiece internalNext(int width, int height) { - FontMetrics fm = gc.getFontMetrics(); - - final int lineHeight = fm.getHeight(); - if (height < lineHeight) - return null; - - final int maxLines = height / lineHeight; - String[] nextLines = nextLines(width, maxLines); - if (nextLines.length == 0) - return null; - - int maxWidth = maxExtent(nextLines).x; - Point size = new Point(maxWidth, nextLines.length * lineHeight); - int ascent = fm.getAscent() + fm.getLeading(); - - return new TextPiece(device, style, nextLines, size, ascent); - } - - private Font initGC() { - Font oldFont = gc.getFont(); - FontData fontData = style.getFontData(); - if (fontData != null) - gc.setFont(ResourcePool.forDevice(device).getFont(fontData)); - return oldFont; - } - - private void restoreGC(Font oldFont) { - gc.setFont(oldFont); - } - - private String[] nextLines(final int width, final int maxLines) { - List nextLines = new ArrayList<>(Math.min(lines.length, maxLines)); - - while ((nextLines.size() < maxLines) && (row < lines.length)) { - String line = lines[row].substring(col); - - // Find out how much text will fit on one line. - int charCount = findLineBreak(gc, line, width); - - // If none of the text could fit in the current line, terminate this - // iteration. - if (line.length() > 0 && charCount == 0) - break; - - // Get the text that fits on this line. - String thisLine = line.substring(0, charCount); - nextLines.add(thisLine); - - // Move cursor past the text we just consumed. - col += charCount; - - skipWhitespace(); - - advanceToNextRowIfCurrentRowCompleted(); - } - - return (String[]) nextLines.toArray(new String[nextLines.size()]); - } - - private void skipWhitespace() { - while (col < lines[row].length() - && Character.isWhitespace(lines[row].charAt(col))) - col++; - } - - private void advanceToNextRowIfCurrentRowCompleted() { - if (col >= lines[row].length()) { - row++; - col = 0; - } - } - - public Point minimumSize() { - return new Point(minimumSize.x, minimumSize.y); - } - - public Point preferredSize() { - return new Point(preferredSize.x, preferredSize.y); - } - - private Point maxExtent(String[] text) { - Font oldFont = gc.getFont(); - try { - initGC(); - - FontMetrics fm = gc.getFontMetrics(); - int maxWidth = 0; - - for (int i = 0; i < text.length; i++) { - String textPiece = text[i]; - maxWidth = Math.max(maxWidth, gc.stringExtent(textPiece).x); - } - - return new Point(maxWidth, fm.getHeight()); - } finally { - restoreGC(oldFont); - } - } - - private int findLineBreak(GC gc, String text, int width) { - // Offsets within the string - int loIndex = 0; - int hiIndex = text.length(); - - // Pixel width of entire string - int pixelWidth = gc.stringExtent(text).x; - - // Does the whole string fit? - if (pixelWidth <= width) - // I'll take it - return hiIndex; - - // Do a binary search to find the maximum characters that will fit - // within the given width. - while (loIndex < hiIndex) { - int midIndex = (loIndex + hiIndex + 1) / 2; - int midWidth = gc.stringExtent(text.substring(0, midIndex)).x; - - if (midWidth < width) - // don't add 1, the next character could make it too big - loIndex = midIndex; - else if (midWidth > width) - // subtract 1, we already know midIndex makes it too big - hiIndex = midIndex - 1; - else { - // perfect fit - loIndex = hiIndex = midIndex; - } - } - - return findWordBreak(text, loIndex); - } - - int findWordBreak(String text, int maxLength) { - // If the max length is the string length, no break - // (we mainly check this to avoid an exception in for-loop) - if (maxLength == text.length()) - return maxLength; - - // Otherwise, break string at the last whitespace at or before - // maxLength. - for (int i = maxLength; i >= 0; i--) - if (Character.isWhitespace(text.charAt(i))) - return i; - - // No whitespace? Break at max length (if word breaking is allowed) - if (wordSplitting) - return maxLength; - - return 0; - } - - public PrintIterator copy() { - return new TextIterator(this); - } +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.text; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.nebula.paperclips.core.text.internal.TextPiece; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +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.Point; +import org.eclipse.swt.graphics.RGB; + +/** + * A Print for displaying text. + *

+ * TextPrints are never greedy with layout space, even with center- or + * right-alignment. (Greedy prints take up all the available space on the page.) + * Therefore, when center- or right-alignment is required, it is necessary to + * wrap the text in a Print which will enforce the same alignment. Usually this + * is a center:default:grow or right:default:grow column in a GridPrint. + * + * @author Matthew Hall + */ +public class TextPrint implements Print { + /** The default text for a TextPrint. Value is "". */ + public static final String DEFAULT_TEXT = ""; //$NON-NLS-1$ + + /** The default font data for a TextPrint. Value is device-dependent. */ + public static final FontData DEFAULT_FONT_DATA = new FontData(); + + /** The default alignment for TextPrint. Value is SWT.LEFT. */ + public static final int DEFAULT_ALIGN = SWT.LEFT; + + private static final TextStyle DEFAULT_STYLE = new TextStyle(); + + String text; + TextStyle style; + boolean wordSplitting; + + /** + * Constructs a TextPrint with the default properties. + */ + public TextPrint() { + this(DEFAULT_TEXT); + } + + /** + * Constructs a TextPrint with the given text. + * + * @param text + * the text to print. + */ + public TextPrint(String text) { + this(text, DEFAULT_STYLE); + } + + /** + * Constructs a TextPrint with the given text and font data. + * + * @param text + * the text to print. + * @param fontData + * the font that will be used to print the text. + */ + public TextPrint(String text, FontData fontData) { + this(text, DEFAULT_STYLE.font(fontData)); + } + + /** + * Constructs a TextPrint with the give text and alignment. + * + * @param text + * the text to print. + * @param align + * the horizontal text alignment. Must be one of {@link SWT#LEFT} + * , {@link SWT#CENTER} or {@link SWT#RIGHT}. + */ + public TextPrint(String text, int align) { + this(text, DEFAULT_STYLE.align(align)); + } + + /** + * Constructs a TextPrint with the given text, font data, and alignment. + * + * @param text + * the text to print. + * @param fontData + * the font that will be used to print the text. + * @param align + * the horizontal text alignment. Must be one of {@link SWT#LEFT} + * , {@link SWT#CENTER} or {@link SWT#RIGHT}. + */ + public TextPrint(String text, FontData fontData, int align) { + this(text, DEFAULT_STYLE.font(fontData).align(align)); + } + + /** + * Constructs a TextPrint with the given text and style. + * + * @param text + * the text to print. + * @param style + * the style to apply to the text. + */ + public TextPrint(String text, TextStyle style) { + Util.notNull(text, style); + this.text = text; + this.style = style; + this.wordSplitting = true; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((style == null) ? 0 : style.hashCode()); + result = prime * result + ((text == null) ? 0 : text.hashCode()); + result = prime * result + (wordSplitting ? 1231 : 1237); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TextPrint other = (TextPrint) obj; + if (style == null) { + if (other.style != null) + return false; + } else if (!style.equals(other.style)) + return false; + if (text == null) { + if (other.text != null) + return false; + } else if (!text.equals(other.text)) + return false; + if (wordSplitting != other.wordSplitting) + return false; + return true; + } + + /** + * Returns the text that will be printed. + * + * @return the text that will be printed. + */ + public String getText() { + return text; + } + + /** + * Sets the text that will be printed. + * + * @param text + * the text to print. + */ + public void setText(String text) { + Util.notNull(text); + this.text = text; + } + + /** + * Returns the text style. + * + * @return the text style. + */ + public TextStyle getStyle() { + return style; + } + + /** + * Sets the text style to the argument. + * + * @param style + * the new text style. + */ + public void setStyle(TextStyle style) { + Util.notNull(style); + this.style = style; + } + + /** + * Returns the font that will be used to print the text. + * + * @return the font that will be used to print the text. + */ + public FontData getFontData() { + return style.getFontData(); + } + + /** + * Sets the font that will be used to print the text. + * + * @param fontData + * the font that will be used to print the text. + */ + public void setFontData(FontData fontData) { + setStyle(style.font(fontData)); + } + + /** + * Returns the horizontal text alignment. Possible values include + * {@link SWT#LEFT}, {@link SWT#CENTER} or {@link SWT#RIGHT}. + * + * @return the horizontal text alignment. + */ + public int getAlignment() { + return style.getAlignment(); + } + + /** + * Sets the horizontal text alignment. + * + * @param alignment + * the horizontal text alignment. Must be one of {@link SWT#LEFT} + * , {@link SWT#CENTER} or {@link SWT#RIGHT}. + */ + public void setAlignment(int alignment) { + setStyle(style.align(alignment)); + } + + /** + * Returns the foreground color. A null value indicates that the foreground + * color is inherited. + * + * @return the foreground color. + */ + public RGB getForeground() { + return style.getForeground(); + } + + /** + * Sets the foreground color to the argument. + * + * @param foreground + * the new foreground color. A null value causes the foreground + * color to be inherited. + */ + public void setForeground(RGB foreground) { + setStyle(style.foreground(foreground)); + } + + /** + * Returns the background color. A null value indicates that the background + * is transparent. + * + * @return the background color. + */ + public RGB getBackground() { + return style.getBackground(); + } + + /** + * Sets the background color to the argument. + * + * @param background + * the new background color. A null value causes the background + * to be transparent. + */ + public void setBackground(RGB background) { + style = style.background(background); + } + + /** + * Returns the underline flag. + * + * @return the underline flag. + */ + public boolean getUnderline() { + return style.getUnderline(); + } + + /** + * Sets the underline flag to the argument. + * + * @param underline + * the underline flag. + */ + public void setUnderline(boolean underline) { + style = style.underline(underline); + } + + /** + * Returns the strikout flag. + * + * @return the strikout flag. + */ + public boolean getStrikeout() { + return style.getStrikeout(); + } + + /** + * Sets the strikeout flag to the argument. + * + * @param strikeout + * the strikeout flag. + */ + public void setStrikeout(boolean strikeout) { + style = style.strikeout(strikeout); + } + + /** + * Returns whether word splitting is enabled. Default is true. + * + * @return whether word splitting is enabled. + */ + public boolean getWordSplitting() { + return wordSplitting; + } + + /** + * Sets whether word splitting is enabled. + * + * @param wordBreaking + * whether to allow word splitting. + */ + public void setWordSplitting(boolean wordBreaking) { + this.wordSplitting = wordBreaking; + } + + public PrintIterator iterator(Device device, GC gc) { + return new TextIterator(this, device, gc); + } +} + +class TextIterator implements PrintIterator { + private final Device device; + private final GC gc; + + final String text; + final String[] lines; + final TextStyle style; + final boolean wordSplitting; + final Point minimumSize; + final Point preferredSize; + + int row; + int col; + + TextIterator(TextPrint print, Device device, GC gc) { + this.device = device; + this.gc = gc; + + this.text = print.text; + this.lines = print.text.split("(\r)?\n"); //$NON-NLS-1$ + this.style = print.style; + this.wordSplitting = print.wordSplitting; + this.minimumSize = maxExtent(text.split("\\s")); //$NON-NLS-1$ + this.preferredSize = maxExtent(lines); + + this.row = 0; + this.col = 0; + } + + TextIterator(TextIterator that) { + this.device = that.device; + this.gc = that.gc; + + this.text = that.text; + this.lines = that.lines; + this.style = that.style; + this.wordSplitting = that.wordSplitting; + this.minimumSize = that.minimumSize; + this.preferredSize = that.preferredSize; + + this.row = that.row; + this.col = that.col; + } + + public boolean hasNext() { + return row < lines.length; + } + + public PrintPiece next(int width, int height) { + if (!hasNext()) + PaperClips.error("No more content."); //$NON-NLS-1$ + + Font oldFont = initGC(); + PrintPiece result = internalNext(width, height); + restoreGC(oldFont); + + return result; + } + + private PrintPiece internalNext(int width, int height) { + FontMetrics fm = gc.getFontMetrics(); + + final int lineHeight = fm.getHeight(); + if (height < lineHeight) + return null; + + final int maxLines = height / lineHeight; + String[] nextLines = nextLines(width, maxLines); + if (nextLines.length == 0) + return null; + + int maxWidth = maxExtent(nextLines).x; + Point size = new Point(maxWidth, nextLines.length * lineHeight); + int ascent = fm.getAscent() + fm.getLeading(); + + return new TextPiece(device, style, nextLines, size, ascent); + } + + private Font initGC() { + Font oldFont = gc.getFont(); + FontData fontData = style.getFontData(); + if (fontData != null) + gc.setFont(ResourcePool.forDevice(device).getFont(fontData)); + return oldFont; + } + + private void restoreGC(Font oldFont) { + gc.setFont(oldFont); + } + + private String[] nextLines(final int width, final int maxLines) { + List nextLines = new ArrayList<>(Math.min(lines.length, maxLines)); + + while ((nextLines.size() < maxLines) && (row < lines.length)) { + String line = lines[row].substring(col); + + // Find out how much text will fit on one line. + int charCount = findLineBreak(gc, line, width); + + // If none of the text could fit in the current line, terminate this + // iteration. + if (line.length() > 0 && charCount == 0) + break; + + // Get the text that fits on this line. + String thisLine = line.substring(0, charCount); + nextLines.add(thisLine); + + // Move cursor past the text we just consumed. + col += charCount; + + skipWhitespace(); + + advanceToNextRowIfCurrentRowCompleted(); + } + + return (String[]) nextLines.toArray(new String[nextLines.size()]); + } + + private void skipWhitespace() { + while (col < lines[row].length() + && Character.isWhitespace(lines[row].charAt(col))) + col++; + } + + private void advanceToNextRowIfCurrentRowCompleted() { + if (col >= lines[row].length()) { + row++; + col = 0; + } + } + + public Point minimumSize() { + return new Point(minimumSize.x, minimumSize.y); + } + + public Point preferredSize() { + return new Point(preferredSize.x, preferredSize.y); + } + + private Point maxExtent(String[] text) { + Font oldFont = gc.getFont(); + try { + initGC(); + + FontMetrics fm = gc.getFontMetrics(); + int maxWidth = 0; + + for (int i = 0; i < text.length; i++) { + String textPiece = text[i]; + maxWidth = Math.max(maxWidth, gc.stringExtent(textPiece).x); + } + + return new Point(maxWidth, fm.getHeight()); + } finally { + restoreGC(oldFont); + } + } + + private int findLineBreak(GC gc, String text, int width) { + // Offsets within the string + int loIndex = 0; + int hiIndex = text.length(); + + // Pixel width of entire string + int pixelWidth = gc.stringExtent(text).x; + + // Does the whole string fit? + if (pixelWidth <= width) + // I'll take it + return hiIndex; + + // Do a binary search to find the maximum characters that will fit + // within the given width. + while (loIndex < hiIndex) { + int midIndex = (loIndex + hiIndex + 1) / 2; + int midWidth = gc.stringExtent(text.substring(0, midIndex)).x; + + if (midWidth < width) + // don't add 1, the next character could make it too big + loIndex = midIndex; + else if (midWidth > width) + // subtract 1, we already know midIndex makes it too big + hiIndex = midIndex - 1; + else { + // perfect fit + loIndex = hiIndex = midIndex; + } + } + + return findWordBreak(text, loIndex); + } + + int findWordBreak(String text, int maxLength) { + // If the max length is the string length, no break + // (we mainly check this to avoid an exception in for-loop) + if (maxLength == text.length()) + return maxLength; + + // Otherwise, break string at the last whitespace at or before + // maxLength. + for (int i = maxLength; i >= 0; i--) + if (Character.isWhitespace(text.charAt(i))) + return i; + + // No whitespace? Break at max length (if word breaking is allowed) + if (wordSplitting) + return maxLength; + + return 0; + } + + public PrintIterator copy() { + return new TextIterator(this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/TextStyle.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/TextStyle.java index 13a4ffdad..0c21af6ac 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/TextStyle.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/TextStyle.java @@ -1,419 +1,419 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.text; - -import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; -import org.eclipse.nebula.paperclips.core.internal.util.SWTUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; - -/** - * Defines a set of styles that can be applied to text. Instances of this class - * are immutable. - * - * @author Matthew Hall - */ -public class TextStyle { - private FontData fontData; - private RGB foreground; - private RGB background; - private int alignment; - private boolean underline; - private boolean strikeout; - - /** - * Constructs a new TextStyle with default font (device-dependent), black - * foreground, transparent background, default alignment, and the strikeout - * and underline flags set to false. - */ - public TextStyle() { - fontData = SWTUtil.copy(TextPrint.DEFAULT_FONT_DATA); - foreground = new RGB(0, 0, 0); - background = null; - alignment = TextPrint.DEFAULT_ALIGN; - underline = false; - strikeout = false; - } - - private TextStyle(TextStyle that) { - this.fontData = that.fontData; - this.foreground = that.foreground; - this.background = that.background; - this.alignment = that.alignment; - this.underline = that.underline; - this.strikeout = that.strikeout; - } - - private TextStyle internalFont(FontData fontData) { - TextStyle result = new TextStyle(this); - result.fontData = fontData; - return result; - } - - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + alignment; - result = prime * result - + ((background == null) ? 0 : background.hashCode()); - result = prime * result - + ((fontData == null) ? 0 : fontData.hashCode()); - result = prime * result - + ((foreground == null) ? 0 : foreground.hashCode()); - result = prime * result + (strikeout ? 1231 : 1237); - result = prime * result + (underline ? 1231 : 1237); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - TextStyle other = (TextStyle) obj; - if (alignment != other.alignment) - return false; - if (background == null) { - if (other.background != null) - return false; - } else if (!background.equals(other.background)) - return false; - if (fontData == null) { - if (other.fontData != null) - return false; - } else if (!fontData.equals(other.fontData)) - return false; - if (foreground == null) { - if (other.foreground != null) - return false; - } else if (!foreground.equals(other.foreground)) - return false; - if (strikeout != other.strikeout) - return false; - if (underline != other.underline) - return false; - return true; - } - - /** - * Returns a copy of this TextStyle, with the font changed to the font - * described by the arguments. This method is equivalent to calling font( - * new FontData( name, height, style ) ). - * - * @param name - * the name of the font (must not be null) - * @param height - * the font height in points - * @param style - * a bit or combination of NORMAL, BOLD, ITALIC - * @return a copy of this TextStyle, with the font changed to the font - * described by the arguments. - */ - public TextStyle font(String name, int height, int style) { - return internalFont(new FontData(name, height, style)); - } - - /** - * Returns a copy of this TextStyle, with the font changed to the argument. - * - * @param fontData - * the new font. A null value causes the font to be inherited - * from the enclosing elements of the document. - * @return a copy of this TextStyle, with the font changed to the argument. - */ - public TextStyle font(FontData fontData) { - return internalFont(SWTUtil.copy(fontData)); - } - - /** - * Returns a copy of this TextStyle, with the font name changed to the - * argument. - * - * @param name - * the new font name (must not be null) - * @return a copy of this TextStyle, with the font name changed to the - * argument. - */ - public TextStyle fontName(String name) { - return font(name, fontData.getHeight(), fontData.getStyle()); - } - - /** - * Returns a copy of this TextStyle, with the font height changed to the - * argument. - * - * @param height - * the new font height in points - * @return a copy of this TextStyle, with the font height changed to the - * argument. - */ - public TextStyle fontHeight(int height) { - return font(fontData.getName(), height, fontData.getStyle()); - } - - /** - * Returns a copy of this TextStyle, with the font style changed to the - * argument. - * - * @param style - * a bit or combination of NORMAL, BOLD, ITALIC - * @return a copy of this TextStyle, with the font style changed to the - * argument. - */ - public TextStyle fontStyle(int style) { - return font(fontData.getName(), fontData.getHeight(), style); - } - - private TextStyle internalForeground(RGB foreground) { - TextStyle result = new TextStyle(this); - result.foreground = foreground; - return result; - } - - /** - * Returns a copy of this TextStyle, with the foreground changed to the - * argument. - * - * @param foreground - * the new foreground. A null value causes the foreground to be - * inherited from the enclosing elements of the document. - * @return a copy of this TextStyle, with the foreground changed to the - * argument. - */ - public TextStyle foreground(RGB foreground) { - return internalForeground(SWTUtil.copy(foreground)); - } - - /** - * Returns a copy of this TextStyle, with the foreground changed to the - * color described by the arguments. This method is equivalent to calling - * foreground(new RGB(red, green, blue)). - * - * @param red - * the red component of the new foreground color - * @param green - * the green component of the new foreground color - * @param blue - * the blue component of the new foreground color - * @return a copy of this TextStyle, with the foreground changed to the - * color described by the arguments. - */ - public TextStyle foreground(int red, int green, int blue) { - return internalForeground(new RGB(red, green, blue)); - } - - /** - * Returns a copy of this TextStyle, with the foreground changed to the - * color described by the argument. - * - * @param rgb - * an integer containing the red, green and blue components in - * the 0xFF0000, 0x00FF00, and 0x0000FF positions, respectively. - * @return a copy of this TextStyle, with the foreground changed to the - * color described by the argument. - */ - public TextStyle foreground(int rgb) { - return internalForeground(SWTUtil.deriveRGB(rgb)); - } - - private TextStyle internalBackground(RGB background) { - TextStyle result = new TextStyle(this); - result.background = background; - return result; - } - - /** - * Returns a copy of this TextStyle, with the background changed to the - * argument. - * - * @param background - * the new background. A null value causes the text background to - * be transparent. - * @return a copy of this TextStyle, with the background changed to the - * argument. - */ - public TextStyle background(RGB background) { - return internalBackground(SWTUtil.copy(background)); - } - - /** - * Returns a copy of this TextStyle, with the background changed to the - * color described by the arguments. This method is equivalent to calling - * background(new RGB(red, green, blue) - * - * @param red - * the red component of the new background color - * @param green - * the green component of the new background color - * @param blue - * the blue component of the new background color - * @return a copy of this TextStyle, with the background changed to the - * color described by the arguments. - */ - public TextStyle background(int red, int green, int blue) { - return internalBackground(new RGB(red, green, blue)); - } - - /** - * Returns a copy of this TextStyle, with the background changed to the - * color described by the argument. - * - * @param rgb - * an integer containing the red, green and blue components in - * the 0xFF0000, 0x00FF00, and 0x0000FF positions, respectively. - * @return a copy of this TextStyle, with the background changed to the - * color described by the argument. - */ - public TextStyle background(int rgb) { - return internalBackground(SWTUtil.deriveRGB(rgb)); - } - - /** - * Returns a copy of this TextStyle, with the alignment changed to the - * argument. - * - * @param alignment - * the new alignment. Must be one of SWT.LEFT, SWT.CENTER, or - * SWT.RIGHT. Invalid values will be changed to SWT.LEFT. - * @return a copy of this TextStyle, with the alignment changed to the - * argument. - */ - public TextStyle align(int alignment) { - TextStyle result = new TextStyle(this); - result.alignment = PaperClipsUtil.firstMatch(alignment, new int[] { - SWT.LEFT, SWT.CENTER, SWT.RIGHT }, SWT.LEFT); - return result; - } - - /** - * Returns a copy of this TextStyle, with the underline flag set to true. - * - * @return a copy of this TextStyle, with the underline flag set to true. - */ - public TextStyle underline() { - return underline(true); - } - - /** - * Returns a copy of this TextStyle, with the underline flag set to the - * argument. - * - * @param underline - * the new underline flag. - * @return a copy of this TextStyle, with the underline flag set to the - * argument. - */ - public TextStyle underline(boolean underline) { - TextStyle result = new TextStyle(this); - result.underline = underline; - return result; - } - - /** - * Returns a copy of this TextStyle, with the strikeout flag set to true. - * - * @return a copy of this TextStyle, with the strikeout flag set to true. - */ - public TextStyle strikeout() { - return strikeout(true); - } - - /** - * Returns a copy of this TextStyle, with the strikeout flag set to the - * argument. - * - * @param strikeout - * the new strikeout flag. - * @return a copy of this TextStyle, with the strikeout flag set to the - * argument. - */ - public TextStyle strikeout(boolean strikeout) { - TextStyle result = new TextStyle(this); - result.strikeout = strikeout; - return result; - } - - /** - * Returns the font applied to the text. - * - * @return the font applied to the text. - */ - public FontData getFontData() { - return SWTUtil.copy(fontData); - } - - /** - * Returns the text foreground color. A null value indicates that the - * foreground color will be inherited from the enclosing elements of the - * document. - * - * @return the text foreground color. - */ - public RGB getForeground() { - return SWTUtil.copy(foreground); - } - - /** - * Returns the text background color. A null value indicates that the - * background will be transparent. - * - * @return the text background color. A null value indicates that the - * background will be transparent. - */ - public RGB getBackground() { - return SWTUtil.copy(background); - } - - /** - * Returns the text alignment. Possible values include SWT.LEFT, SWT.CENTER, - * or SWT.RIGHT. - * - * @return the text alignment. - */ - public int getAlignment() { - return alignment; - } - - /** - * Returns the underline flag. - * - * @return the underline flag. - */ - public boolean getUnderline() { - return underline; - } - - /** - * Returns the strikeout flag. - * - * @return the strikeout flag. - */ - public boolean getStrikeout() { - return strikeout; - } - - /** - * Returns a TextPrint of the given text in this text style - * - * @param text - * the text - * @return a TextPrint of the given text in this text style - */ - public TextPrint create(String text) { - return new TextPrint(text, this); - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.text; + +import org.eclipse.nebula.paperclips.core.internal.util.PaperClipsUtil; +import org.eclipse.nebula.paperclips.core.internal.util.SWTUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; + +/** + * Defines a set of styles that can be applied to text. Instances of this class + * are immutable. + * + * @author Matthew Hall + */ +public class TextStyle { + private FontData fontData; + private RGB foreground; + private RGB background; + private int alignment; + private boolean underline; + private boolean strikeout; + + /** + * Constructs a new TextStyle with default font (device-dependent), black + * foreground, transparent background, default alignment, and the strikeout + * and underline flags set to false. + */ + public TextStyle() { + fontData = SWTUtil.copy(TextPrint.DEFAULT_FONT_DATA); + foreground = new RGB(0, 0, 0); + background = null; + alignment = TextPrint.DEFAULT_ALIGN; + underline = false; + strikeout = false; + } + + private TextStyle(TextStyle that) { + this.fontData = that.fontData; + this.foreground = that.foreground; + this.background = that.background; + this.alignment = that.alignment; + this.underline = that.underline; + this.strikeout = that.strikeout; + } + + private TextStyle internalFont(FontData fontData) { + TextStyle result = new TextStyle(this); + result.fontData = fontData; + return result; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + alignment; + result = prime * result + + ((background == null) ? 0 : background.hashCode()); + result = prime * result + + ((fontData == null) ? 0 : fontData.hashCode()); + result = prime * result + + ((foreground == null) ? 0 : foreground.hashCode()); + result = prime * result + (strikeout ? 1231 : 1237); + result = prime * result + (underline ? 1231 : 1237); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TextStyle other = (TextStyle) obj; + if (alignment != other.alignment) + return false; + if (background == null) { + if (other.background != null) + return false; + } else if (!background.equals(other.background)) + return false; + if (fontData == null) { + if (other.fontData != null) + return false; + } else if (!fontData.equals(other.fontData)) + return false; + if (foreground == null) { + if (other.foreground != null) + return false; + } else if (!foreground.equals(other.foreground)) + return false; + if (strikeout != other.strikeout) + return false; + if (underline != other.underline) + return false; + return true; + } + + /** + * Returns a copy of this TextStyle, with the font changed to the font + * described by the arguments. This method is equivalent to calling font( + * new FontData( name, height, style ) ). + * + * @param name + * the name of the font (must not be null) + * @param height + * the font height in points + * @param style + * a bit or combination of NORMAL, BOLD, ITALIC + * @return a copy of this TextStyle, with the font changed to the font + * described by the arguments. + */ + public TextStyle font(String name, int height, int style) { + return internalFont(new FontData(name, height, style)); + } + + /** + * Returns a copy of this TextStyle, with the font changed to the argument. + * + * @param fontData + * the new font. A null value causes the font to be inherited + * from the enclosing elements of the document. + * @return a copy of this TextStyle, with the font changed to the argument. + */ + public TextStyle font(FontData fontData) { + return internalFont(SWTUtil.copy(fontData)); + } + + /** + * Returns a copy of this TextStyle, with the font name changed to the + * argument. + * + * @param name + * the new font name (must not be null) + * @return a copy of this TextStyle, with the font name changed to the + * argument. + */ + public TextStyle fontName(String name) { + return font(name, fontData.getHeight(), fontData.getStyle()); + } + + /** + * Returns a copy of this TextStyle, with the font height changed to the + * argument. + * + * @param height + * the new font height in points + * @return a copy of this TextStyle, with the font height changed to the + * argument. + */ + public TextStyle fontHeight(int height) { + return font(fontData.getName(), height, fontData.getStyle()); + } + + /** + * Returns a copy of this TextStyle, with the font style changed to the + * argument. + * + * @param style + * a bit or combination of NORMAL, BOLD, ITALIC + * @return a copy of this TextStyle, with the font style changed to the + * argument. + */ + public TextStyle fontStyle(int style) { + return font(fontData.getName(), fontData.getHeight(), style); + } + + private TextStyle internalForeground(RGB foreground) { + TextStyle result = new TextStyle(this); + result.foreground = foreground; + return result; + } + + /** + * Returns a copy of this TextStyle, with the foreground changed to the + * argument. + * + * @param foreground + * the new foreground. A null value causes the foreground to be + * inherited from the enclosing elements of the document. + * @return a copy of this TextStyle, with the foreground changed to the + * argument. + */ + public TextStyle foreground(RGB foreground) { + return internalForeground(SWTUtil.copy(foreground)); + } + + /** + * Returns a copy of this TextStyle, with the foreground changed to the + * color described by the arguments. This method is equivalent to calling + * foreground(new RGB(red, green, blue)). + * + * @param red + * the red component of the new foreground color + * @param green + * the green component of the new foreground color + * @param blue + * the blue component of the new foreground color + * @return a copy of this TextStyle, with the foreground changed to the + * color described by the arguments. + */ + public TextStyle foreground(int red, int green, int blue) { + return internalForeground(new RGB(red, green, blue)); + } + + /** + * Returns a copy of this TextStyle, with the foreground changed to the + * color described by the argument. + * + * @param rgb + * an integer containing the red, green and blue components in + * the 0xFF0000, 0x00FF00, and 0x0000FF positions, respectively. + * @return a copy of this TextStyle, with the foreground changed to the + * color described by the argument. + */ + public TextStyle foreground(int rgb) { + return internalForeground(SWTUtil.deriveRGB(rgb)); + } + + private TextStyle internalBackground(RGB background) { + TextStyle result = new TextStyle(this); + result.background = background; + return result; + } + + /** + * Returns a copy of this TextStyle, with the background changed to the + * argument. + * + * @param background + * the new background. A null value causes the text background to + * be transparent. + * @return a copy of this TextStyle, with the background changed to the + * argument. + */ + public TextStyle background(RGB background) { + return internalBackground(SWTUtil.copy(background)); + } + + /** + * Returns a copy of this TextStyle, with the background changed to the + * color described by the arguments. This method is equivalent to calling + * background(new RGB(red, green, blue) + * + * @param red + * the red component of the new background color + * @param green + * the green component of the new background color + * @param blue + * the blue component of the new background color + * @return a copy of this TextStyle, with the background changed to the + * color described by the arguments. + */ + public TextStyle background(int red, int green, int blue) { + return internalBackground(new RGB(red, green, blue)); + } + + /** + * Returns a copy of this TextStyle, with the background changed to the + * color described by the argument. + * + * @param rgb + * an integer containing the red, green and blue components in + * the 0xFF0000, 0x00FF00, and 0x0000FF positions, respectively. + * @return a copy of this TextStyle, with the background changed to the + * color described by the argument. + */ + public TextStyle background(int rgb) { + return internalBackground(SWTUtil.deriveRGB(rgb)); + } + + /** + * Returns a copy of this TextStyle, with the alignment changed to the + * argument. + * + * @param alignment + * the new alignment. Must be one of SWT.LEFT, SWT.CENTER, or + * SWT.RIGHT. Invalid values will be changed to SWT.LEFT. + * @return a copy of this TextStyle, with the alignment changed to the + * argument. + */ + public TextStyle align(int alignment) { + TextStyle result = new TextStyle(this); + result.alignment = PaperClipsUtil.firstMatch(alignment, new int[] { + SWT.LEFT, SWT.CENTER, SWT.RIGHT }, SWT.LEFT); + return result; + } + + /** + * Returns a copy of this TextStyle, with the underline flag set to true. + * + * @return a copy of this TextStyle, with the underline flag set to true. + */ + public TextStyle underline() { + return underline(true); + } + + /** + * Returns a copy of this TextStyle, with the underline flag set to the + * argument. + * + * @param underline + * the new underline flag. + * @return a copy of this TextStyle, with the underline flag set to the + * argument. + */ + public TextStyle underline(boolean underline) { + TextStyle result = new TextStyle(this); + result.underline = underline; + return result; + } + + /** + * Returns a copy of this TextStyle, with the strikeout flag set to true. + * + * @return a copy of this TextStyle, with the strikeout flag set to true. + */ + public TextStyle strikeout() { + return strikeout(true); + } + + /** + * Returns a copy of this TextStyle, with the strikeout flag set to the + * argument. + * + * @param strikeout + * the new strikeout flag. + * @return a copy of this TextStyle, with the strikeout flag set to the + * argument. + */ + public TextStyle strikeout(boolean strikeout) { + TextStyle result = new TextStyle(this); + result.strikeout = strikeout; + return result; + } + + /** + * Returns the font applied to the text. + * + * @return the font applied to the text. + */ + public FontData getFontData() { + return SWTUtil.copy(fontData); + } + + /** + * Returns the text foreground color. A null value indicates that the + * foreground color will be inherited from the enclosing elements of the + * document. + * + * @return the text foreground color. + */ + public RGB getForeground() { + return SWTUtil.copy(foreground); + } + + /** + * Returns the text background color. A null value indicates that the + * background will be transparent. + * + * @return the text background color. A null value indicates that the + * background will be transparent. + */ + public RGB getBackground() { + return SWTUtil.copy(background); + } + + /** + * Returns the text alignment. Possible values include SWT.LEFT, SWT.CENTER, + * or SWT.RIGHT. + * + * @return the text alignment. + */ + public int getAlignment() { + return alignment; + } + + /** + * Returns the underline flag. + * + * @return the underline flag. + */ + public boolean getUnderline() { + return underline; + } + + /** + * Returns the strikeout flag. + * + * @return the strikeout flag. + */ + public boolean getStrikeout() { + return strikeout; + } + + /** + * Returns a TextPrint of the given text in this text style + * + * @param text + * the text + * @return a TextPrint of the given text in this text style + */ + public TextPrint create(String text) { + return new TextPrint(text, this); + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/internal/TextPiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/internal/TextPiece.java index 3bcbea800..3c468d011 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/internal/TextPiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/internal/TextPiece.java @@ -1,143 +1,143 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.text.internal; - -import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.nebula.paperclips.core.text.TextStyle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; - -public class TextPiece implements TextPrintPiece { - private final Point size; - private final String[] lines; - private final TextStyle style; - private final int ascent; - - private final ResourcePool resources; - - public TextPiece(Device device, TextStyle style, String[] text, Point size, - int ascent) { - Util.notNull(device, size, style); - Util.noNulls(text); - this.size = size; - this.lines = text; - this.style = style; - this.ascent = ascent; - - this.resources = ResourcePool.forDevice(device); - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - public int getAscent() { - return ascent; - } - - public void paint(final GC gc, final int x, final int y) { - Font oldFont = gc.getFont(); - Color oldForeground = gc.getForeground(); - Color oldBackground = gc.getBackground(); - - final int width = getSize().x; - final int align = style.getAlignment(); - - try { - boolean transparent = initGC(gc); - - FontMetrics fm = gc.getFontMetrics(); - int lineHeight = fm.getHeight(); - - boolean strikeout = style.getStrikeout(); - boolean underline = style.getUnderline(); - int lineThickness = Math.max(1, fm.getDescent() / 3); - int strikeoutOffset = fm.getLeading() + fm.getAscent() / 2; - int underlineOffset = ascent + lineThickness; - - for (int i = 0; i < lines.length; i++) { - String line = lines[i]; - int lineWidth = gc.stringExtent(line).x; - int offset = getHorzAlignmentOffset(align, lineWidth, width); - - gc.drawString(lines[i], x + offset, y + lineHeight * i, - transparent); - if (strikeout || underline) { - Color saveBackground = gc.getBackground(); - gc.setBackground(gc.getForeground()); - if (strikeout) - gc.fillRectangle(x + offset, y + lineHeight * i - + strikeoutOffset, lineWidth, lineThickness); - if (underline) - gc.fillRectangle(x + offset, y + lineHeight * i - + underlineOffset, lineWidth, lineThickness); - gc.setBackground(saveBackground); - } - } - } finally { - restoreGC(gc, oldFont, oldForeground, oldBackground); - } - } - - private boolean initGC(final GC gc) { - initGCFont(gc); - initGCForeground(gc); - boolean transparent = initGCBackground(gc); - return transparent; - } - - private void restoreGC(final GC gc, Font font, Color foreground, - Color background) { - gc.setFont(font); - gc.setForeground(foreground); - gc.setBackground(background); - } - - private int getHorzAlignmentOffset(int align, int lineWidth, int totalWidth) { - if (align == SWT.CENTER) - return (totalWidth - lineWidth) / 2; - else if (align == SWT.RIGHT) - return totalWidth - lineWidth; - return 0; - } - - private boolean initGCBackground(GC gc) { - Color background = resources.getColor(style.getBackground()); - boolean transparent = (background == null); - if (!transparent) - gc.setBackground(background); - return transparent; - } - - private void initGCForeground(GC gc) { - Color foreground = resources.getColor(style.getForeground()); - if (foreground != null) - gc.setForeground(foreground); - } - - private void initGCFont(GC gc) { - Font font = resources.getFont(style.getFontData()); - if (font != null) - gc.setFont(font); - } - - public void dispose() { - } // Shared resources, nothing to dispose. +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.text.internal; + +import org.eclipse.nebula.paperclips.core.internal.util.ResourcePool; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.nebula.paperclips.core.text.TextStyle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +public class TextPiece implements TextPrintPiece { + private final Point size; + private final String[] lines; + private final TextStyle style; + private final int ascent; + + private final ResourcePool resources; + + public TextPiece(Device device, TextStyle style, String[] text, Point size, + int ascent) { + Util.notNull(device, size, style); + Util.noNulls(text); + this.size = size; + this.lines = text; + this.style = style; + this.ascent = ascent; + + this.resources = ResourcePool.forDevice(device); + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + public int getAscent() { + return ascent; + } + + public void paint(final GC gc, final int x, final int y) { + Font oldFont = gc.getFont(); + Color oldForeground = gc.getForeground(); + Color oldBackground = gc.getBackground(); + + final int width = getSize().x; + final int align = style.getAlignment(); + + try { + boolean transparent = initGC(gc); + + FontMetrics fm = gc.getFontMetrics(); + int lineHeight = fm.getHeight(); + + boolean strikeout = style.getStrikeout(); + boolean underline = style.getUnderline(); + int lineThickness = Math.max(1, fm.getDescent() / 3); + int strikeoutOffset = fm.getLeading() + fm.getAscent() / 2; + int underlineOffset = ascent + lineThickness; + + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + int lineWidth = gc.stringExtent(line).x; + int offset = getHorzAlignmentOffset(align, lineWidth, width); + + gc.drawString(lines[i], x + offset, y + lineHeight * i, + transparent); + if (strikeout || underline) { + Color saveBackground = gc.getBackground(); + gc.setBackground(gc.getForeground()); + if (strikeout) + gc.fillRectangle(x + offset, y + lineHeight * i + + strikeoutOffset, lineWidth, lineThickness); + if (underline) + gc.fillRectangle(x + offset, y + lineHeight * i + + underlineOffset, lineWidth, lineThickness); + gc.setBackground(saveBackground); + } + } + } finally { + restoreGC(gc, oldFont, oldForeground, oldBackground); + } + } + + private boolean initGC(final GC gc) { + initGCFont(gc); + initGCForeground(gc); + boolean transparent = initGCBackground(gc); + return transparent; + } + + private void restoreGC(final GC gc, Font font, Color foreground, + Color background) { + gc.setFont(font); + gc.setForeground(foreground); + gc.setBackground(background); + } + + private int getHorzAlignmentOffset(int align, int lineWidth, int totalWidth) { + if (align == SWT.CENTER) + return (totalWidth - lineWidth) / 2; + else if (align == SWT.RIGHT) + return totalWidth - lineWidth; + return 0; + } + + private boolean initGCBackground(GC gc) { + Color background = resources.getColor(style.getBackground()); + boolean transparent = (background == null); + if (!transparent) + gc.setBackground(background); + return transparent; + } + + private void initGCForeground(GC gc) { + Color foreground = resources.getColor(style.getForeground()); + if (foreground != null) + gc.setForeground(foreground); + } + + private void initGCFont(GC gc) { + Font font = resources.getFont(style.getFontData()); + if (font != null) + gc.setFont(font); + } + + public void dispose() { + } // Shared resources, nothing to dispose. } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/internal/TextPrintPiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/internal/TextPrintPiece.java index 151fda2cb..89804899f 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/internal/TextPrintPiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.core/src/org/eclipse/nebula/paperclips/core/text/internal/TextPrintPiece.java @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.text.internal; - -import org.eclipse.nebula.paperclips.core.PrintPiece; - -public interface TextPrintPiece extends PrintPiece { - /** - * Returns the ascent of the first line of text, in pixels. - * - * @return the ascent of the first line of text, in pixels. - */ - public int getAscent(); -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.text.internal; + +import org.eclipse.nebula.paperclips.core.PrintPiece; + +public interface TextPrintPiece extends PrintPiece { + /** + * Returns the ascent of the first line of text, in pixels. + * + * @return the ascent of the first line of text, in pixels. + */ + public int getAscent(); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.classpath b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.classpath index 540ee9402..7aa94b021 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.classpath +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.settings/org.eclipse.jdt.core.prefs index 544c00662..6cff52107 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,297 +1,297 @@ -eclipse.preferences.version=1 -instance/org.eclipse.core.net/org.eclipse.core.net.hasMigrated=true -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true -org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true -org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true -org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true -org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true +eclipse.preferences.version=1 +instance/org.eclipse.core.net/org.eclipse.core.net.hasMigrated=true +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true +org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true +org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true +org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true +org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.settings/org.eclipse.jdt.ui.prefs b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.settings/org.eclipse.jdt.ui.prefs index 55e363ee7..620ad47ec 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.settings/org.eclipse.jdt.ui.prefs +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/.settings/org.eclipse.jdt.ui.prefs @@ -1,53 +1,53 @@ -#Tue Aug 11 15:06:41 MDT 2009 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile -formatter_settings_version=11 -internal.default.compliance=default -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.format_source_code=true -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=true -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +#Tue Aug 11 15:06:41 MDT 2009 +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile +formatter_settings_version=11 +internal.default.compliance=default +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.format_source_code=true +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=true +sp_cleanup.remove_unused_imports=true +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/META-INF/MANIFEST.MF b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/META-INF/MANIFEST.MF index 04c1b96f6..03f4635c7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/META-INF/MANIFEST.MF +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/META-INF/MANIFEST.MF @@ -1,12 +1,12 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Paperclips Snippets -Bundle-SymbolicName: org.eclipse.nebula.paperclips.snippets -Bundle-Version: 2.1.0.qualifier -Bundle-Vendor: Eclipse Nebula -Require-Bundle: org.eclipse.nebula.paperclips.core;bundle-version="[2.1.0,3.0.0)", - org.eclipse.nebula.paperclips.widgets;bundle-version="[2.1.0,3.0.0)", - org.eclipse.swt;bundle-version="[3.2.0,4.0.0)" -Export-Package: org.eclipse.nebula.paperclips.snippets -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Automatic-Module-Name: org.eclipse.nebula.paperclips.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Paperclips Snippets +Bundle-SymbolicName: org.eclipse.nebula.paperclips.snippets +Bundle-Version: 2.1.0.qualifier +Bundle-Vendor: Eclipse Nebula +Require-Bundle: org.eclipse.nebula.paperclips.core;bundle-version="[2.1.0,3.0.0)", + org.eclipse.nebula.paperclips.widgets;bundle-version="[2.1.0,3.0.0)", + org.eclipse.swt;bundle-version="[3.2.0,4.0.0)" +Export-Package: org.eclipse.nebula.paperclips.snippets +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Automatic-Module-Name: org.eclipse.nebula.paperclips.snippets diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/build.properties b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/build.properties index 92277c3c8..cf98076b3 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/build.properties +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/build.properties @@ -1,5 +1,5 @@ -source.. = src/ -bin.includes = .,\ - META-INF/,\ - about.html,\ - icons/ +source.. = src/ +bin.includes = .,\ + META-INF/,\ + about.html,\ + icons/ diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/AlignPrintExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/AlignPrintExample.java index 769eb0b3e..4c063cfc7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/AlignPrintExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/AlignPrintExample.java @@ -1,55 +1,55 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.AlignPrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.swt.SWT; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Prints the contents of TutorialExample2, but centered horizontally and - * vertically on the page. - * - * @author Matthew - */ -public class AlignPrintExample { - public static Print createPrint() { - Print print = TutorialExample2.createPrint(); - return new AlignPrint(print, SWT.CENTER, SWT.CENTER); - } - - /** - * Prints the BreakPrintExample to the default printer. - * - * @param args - * command-line args - */ - public static void main(String[] args) { - Display display = new Display(); - Shell shell = new Shell(display, SWT.SHELL_TRIM); - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - shell.dispose(); - display.dispose(); - if (printerData != null) - PaperClips.print(new PrintJob("AlignPrintExample.java", - createPrint()), printerData); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.AlignPrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.swt.SWT; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Prints the contents of TutorialExample2, but centered horizontally and + * vertically on the page. + * + * @author Matthew + */ +public class AlignPrintExample { + public static Print createPrint() { + Print print = TutorialExample2.createPrint(); + return new AlignPrint(print, SWT.CENTER, SWT.CENTER); + } + + /** + * Prints the BreakPrintExample to the default printer. + * + * @param args + * command-line args + */ + public static void main(String[] args) { + Display display = new Display(); + Shell shell = new Shell(display, SWT.SHELL_TRIM); + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + shell.dispose(); + display.dispose(); + if (printerData != null) + PaperClips.print(new PrintJob("AlignPrintExample.java", + createPrint()), printerData); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/BreakPrintExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/BreakPrintExample.java index a38b4ac84..6ce821fe8 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/BreakPrintExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/BreakPrintExample.java @@ -1,68 +1,68 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.BreakPrint; -import org.eclipse.nebula.paperclips.core.ColumnPrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.BorderPrint; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; - -/** - * Prints "The quick brown fox jumps over the lazy dog." in increasingly large - * blocks, using a BreakPrint every 5 blocks to force printing to advance to the - * next column / page. - * - * @author Matthew - */ -public class BreakPrintExample { - public static Print createPrint() { - GridPrint grid = new GridPrint("d:g", new DefaultGridLook(10, 10)); - - String text = "The quick brown fox jumps over the lazy dog."; - String printText = text; - - LineBorder border = new LineBorder(); - for (int i = 0; i < 15; i++, printText += " " + text) { - if (i > 0 && i % 5 == 0) - grid.add(new BreakPrint()); - - grid.add(new BorderPrint(new TextPrint(printText), border)); - } - - return new ColumnPrint(grid, 2, 10); - } - - /** - * Prints the BreakPrintExample to the default printer. - * - * @param args - * command-line args - */ - public static void main(String[] args) { - // Workaround for SWT bug on GTK - force SWT to initialize so we don't - // crash. - Display.getDefault(); - - PaperClips.print(new PrintJob("BreakPrintExample.java", createPrint()), - new PrinterData()); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.BreakPrint; +import org.eclipse.nebula.paperclips.core.ColumnPrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.BorderPrint; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; + +/** + * Prints "The quick brown fox jumps over the lazy dog." in increasingly large + * blocks, using a BreakPrint every 5 blocks to force printing to advance to the + * next column / page. + * + * @author Matthew + */ +public class BreakPrintExample { + public static Print createPrint() { + GridPrint grid = new GridPrint("d:g", new DefaultGridLook(10, 10)); + + String text = "The quick brown fox jumps over the lazy dog."; + String printText = text; + + LineBorder border = new LineBorder(); + for (int i = 0; i < 15; i++, printText += " " + text) { + if (i > 0 && i % 5 == 0) + grid.add(new BreakPrint()); + + grid.add(new BorderPrint(new TextPrint(printText), border)); + } + + return new ColumnPrint(grid, 2, 10); + } + + /** + * Prints the BreakPrintExample to the default printer. + * + * @param args + * command-line args + */ + public static void main(String[] args) { + // Workaround for SWT bug on GTK - force SWT to initialize so we don't + // crash. + Display.getDefault(); + + PaperClips.print(new PrintJob("BreakPrintExample.java", createPrint()), + new PrinterData()); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/ColumnPrintExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/ColumnPrintExample.java index 90f7283cb..0bd26b2c9 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/ColumnPrintExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/ColumnPrintExample.java @@ -1,74 +1,74 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.ColumnPrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.BorderPrint; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Example for the ColumnPrint class. - * - * @author Matthew - */ -public class ColumnPrintExample { - /** - * Executes the ColumnPrint example. - * - * @param args - * the command line arguments. - */ - public static void main(String[] args) { - final Display display = new Display(); - - Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setLayout(new FillLayout()); - shell.setSize(600, 600); - - final PrintViewer preview = new PrintViewer(shell, SWT.BORDER); - preview.setPrint(createPrint()); - - shell.open(); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - PaperClips.print( - new PrintJob("ColumnPrintExample.java", createPrint()), - new PrinterData()); - } - - public static Print createPrint() { - StringBuffer buf = new StringBuffer(11000); - for (int i = 1; i <= 500; i++) { - buf.append("This is sentence #").append(i).append(". "); - if (i % 20 == 0) - buf.append("\n\n"); - } - - return new ColumnPrint(new BorderPrint(new TextPrint(buf.toString()), - new LineBorder()), 3, 18); - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.ColumnPrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.BorderPrint; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Example for the ColumnPrint class. + * + * @author Matthew + */ +public class ColumnPrintExample { + /** + * Executes the ColumnPrint example. + * + * @param args + * the command line arguments. + */ + public static void main(String[] args) { + final Display display = new Display(); + + Shell shell = new Shell(display, SWT.SHELL_TRIM); + shell.setLayout(new FillLayout()); + shell.setSize(600, 600); + + final PrintViewer preview = new PrintViewer(shell, SWT.BORDER); + preview.setPrint(createPrint()); + + shell.open(); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + PaperClips.print( + new PrintJob("ColumnPrintExample.java", createPrint()), + new PrinterData()); + } + + public static Print createPrint() { + StringBuffer buf = new StringBuffer(11000); + for (int i = 1; i <= 500; i++) { + buf.append("This is sentence #").append(i).append(". "); + if (i % 20 == 0) + buf.append("\n\n"); + } + + return new ColumnPrint(new BorderPrint(new TextPrint(buf.toString()), + new LineBorder()), 3, 18); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintCellClippingAllowClipFirstRow.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintCellClippingAllowClipFirstRow.java index 4717192a8..3d12ad1d4 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintCellClippingAllowClipFirstRow.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintCellClippingAllowClipFirstRow.java @@ -1,119 +1,119 @@ -/* - * Copyright (c) 2009 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; - -public class GridPrintCellClippingAllowClipFirstRow { - public static void main(String[] args) { - final Display display = new Display(); - - final Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setLayout(new GridLayout()); - shell.setSize(600, 600); - - final PrintJob job = new PrintJob( - "GridPrintCellClippingAllowClipFirstRow", createPrint()); - - Composite buttons = new Composite(shell, SWT.NONE); - buttons.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - buttons.setLayout(new RowLayout(SWT.HORIZONTAL)); - - final Button prev = new Button(buttons, SWT.PUSH); - prev.setText("<< Prev"); - prev.setEnabled(false); - - final Button next = new Button(buttons, SWT.PUSH); - next.setText("Next >>"); - - final Button print = new Button(buttons, SWT.PUSH); - print.setText("Print.."); - - final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); - preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - preview.setPrintJob(job); - next.setEnabled(preview.getPageCount() > 1); - - Listener listener = event -> { - int newIndex = preview.getPageIndex(); - if (event.widget == prev) - newIndex--; - else - newIndex++; - preview.setPageIndex(newIndex); - prev.setEnabled(newIndex > 0); - next.setEnabled(newIndex < preview.getPageCount() - 1); - }; - prev.addListener(SWT.Selection, listener); - next.addListener(SWT.Selection, listener); - - print.addListener(SWT.Selection, event -> { - PrinterData printerData = new PrintDialog(shell).open(); - if (printerData != null) { - PaperClips.print(job, printerData); - } - }); - - shell.open(); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - } - - public static Print createPrint() { - GridPrint doc = new GridPrint("d:g, d:g", new DefaultGridLook(5, 2)); - - doc.addHeader(new TextPrint("Cell clipping enabled")); - doc.add(createGrid(true)); - - doc.addHeader(new TextPrint("Cell clipping disabled")); - doc.add(createGrid(false)); - return doc; - } - - public static GridPrint createGrid(boolean cellClippingEnabled) { - DefaultGridLook look = new DefaultGridLook(); - look.setCellBorder(new LineBorder()); - GridPrint grid = new GridPrint("d", look); - grid.setCellClippingEnabled(cellClippingEnabled); - - String longText = "The quick brown fox jumps over the lazy dog."; - for (int i = 0; i < 5; i++) - // double 7 times -> repeated 128 times - longText += " " + longText; - - for (int i = 0; i < 5; i++) - grid.add(new TextPrint(longText)); - return grid; - } -} +/* + * Copyright (c) 2009 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; + +public class GridPrintCellClippingAllowClipFirstRow { + public static void main(String[] args) { + final Display display = new Display(); + + final Shell shell = new Shell(display, SWT.SHELL_TRIM); + shell.setLayout(new GridLayout()); + shell.setSize(600, 600); + + final PrintJob job = new PrintJob( + "GridPrintCellClippingAllowClipFirstRow", createPrint()); + + Composite buttons = new Composite(shell, SWT.NONE); + buttons.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + buttons.setLayout(new RowLayout(SWT.HORIZONTAL)); + + final Button prev = new Button(buttons, SWT.PUSH); + prev.setText("<< Prev"); + prev.setEnabled(false); + + final Button next = new Button(buttons, SWT.PUSH); + next.setText("Next >>"); + + final Button print = new Button(buttons, SWT.PUSH); + print.setText("Print.."); + + final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); + preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + preview.setPrintJob(job); + next.setEnabled(preview.getPageCount() > 1); + + Listener listener = event -> { + int newIndex = preview.getPageIndex(); + if (event.widget == prev) + newIndex--; + else + newIndex++; + preview.setPageIndex(newIndex); + prev.setEnabled(newIndex > 0); + next.setEnabled(newIndex < preview.getPageCount() - 1); + }; + prev.addListener(SWT.Selection, listener); + next.addListener(SWT.Selection, listener); + + print.addListener(SWT.Selection, event -> { + PrinterData printerData = new PrintDialog(shell).open(); + if (printerData != null) { + PaperClips.print(job, printerData); + } + }); + + shell.open(); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + } + + public static Print createPrint() { + GridPrint doc = new GridPrint("d:g, d:g", new DefaultGridLook(5, 2)); + + doc.addHeader(new TextPrint("Cell clipping enabled")); + doc.add(createGrid(true)); + + doc.addHeader(new TextPrint("Cell clipping disabled")); + doc.add(createGrid(false)); + return doc; + } + + public static GridPrint createGrid(boolean cellClippingEnabled) { + DefaultGridLook look = new DefaultGridLook(); + look.setCellBorder(new LineBorder()); + GridPrint grid = new GridPrint("d", look); + grid.setCellClippingEnabled(cellClippingEnabled); + + String longText = "The quick brown fox jumps over the lazy dog."; + for (int i = 0; i < 5; i++) + // double 7 times -> repeated 128 times + longText += " " + longText; + + for (int i = 0; i < 5; i++) + grid.add(new TextPrint(longText)); + return grid; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintCellClippingExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintCellClippingExample.java index 01034ada3..c27fae8c8 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintCellClippingExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintCellClippingExample.java @@ -1,82 +1,82 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Example for the GridPrint class using. - * - * @author Matthew - */ -public class GridPrintCellClippingExample { - /** - * Executes the GridPrintNoBreak example. - * - * @param args - * the command line arguments. - */ - public static void main(String[] args) { - final Display display = new Display(); - - Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setLayout(new GridLayout()); - shell.setSize(600, 600); - - PrintJob job = new PrintJob("GridPrintNoBreakExample", createPrint()); - - final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); - preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - preview.setPrintJob(job); - - shell.open(); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - PaperClips.print(job, new PrinterData()); - } - - public static Print createPrint() { - GridPrint doc = new GridPrint("d:g, d:g", new DefaultGridLook(5, 2)); - doc.add(createGrid(true)); - doc.add(createGrid(false)); - return doc; - } - - public static GridPrint createGrid(boolean cellClippingEnabled) { - DefaultGridLook look = new DefaultGridLook(); - look.setCellBorder(new LineBorder()); - GridPrint grid = new GridPrint("d, d, d, d", look); - grid.setCellClippingEnabled(cellClippingEnabled); - - for (int i = 0; i < 200; i++) - grid.add(new TextPrint("Text cell\n#" + i)); - return grid; - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Example for the GridPrint class using. + * + * @author Matthew + */ +public class GridPrintCellClippingExample { + /** + * Executes the GridPrintNoBreak example. + * + * @param args + * the command line arguments. + */ + public static void main(String[] args) { + final Display display = new Display(); + + Shell shell = new Shell(display, SWT.SHELL_TRIM); + shell.setLayout(new GridLayout()); + shell.setSize(600, 600); + + PrintJob job = new PrintJob("GridPrintNoBreakExample", createPrint()); + + final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); + preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + preview.setPrintJob(job); + + shell.open(); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + PaperClips.print(job, new PrinterData()); + } + + public static Print createPrint() { + GridPrint doc = new GridPrint("d:g, d:g", new DefaultGridLook(5, 2)); + doc.add(createGrid(true)); + doc.add(createGrid(false)); + return doc; + } + + public static GridPrint createGrid(boolean cellClippingEnabled) { + DefaultGridLook look = new DefaultGridLook(); + look.setCellBorder(new LineBorder()); + GridPrint grid = new GridPrint("d, d, d, d", look); + grid.setCellClippingEnabled(cellClippingEnabled); + + for (int i = 0; i < 200; i++) + grid.add(new TextPrint("Text cell\n#" + i)); + return grid; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintExample.java index bc98e6f93..176d24b4e 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintExample.java @@ -1,102 +1,102 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.ImagePrint; -import org.eclipse.nebula.paperclips.core.LinePrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Example for the GridPrint class. - * - * @author Matthew - */ -public class GridPrintExample { - /** - * Executes the GridPrint example. - * - * @param args - * the command line arguments. - */ - public static void main(String[] args) { - final Display display = new Display(); - - Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setLayout(new FillLayout()); - shell.setSize(600, 600); - - final PrintViewer preview = new PrintViewer(shell, SWT.BORDER); - preview.setPrint(createPrint()); - - shell.open(); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - PaperClips.print(new PrintJob("GridPrintExample", createPrint()), - new PrinterData()); - } - - public static Print createPrint() { - GridPrint grid = new GridPrint("r:72, p, d, r:d:g(3), r:d:g", - new DefaultGridLook(5, 5)); - - ImageData imageData = new ImageData(GridPrintExample.class - .getResourceAsStream("logo.png")); - ImagePrint image = new ImagePrint(imageData); - image.setDPI(300, 300); - - grid.add(SWT.CENTER, image, GridPrint.REMAINDER); - - FontData fontData = new FontData("Arial", 10, SWT.BOLD); - - grid.add(new TextPrint("This column is 72 pts wide no matter what", - fontData, SWT.RIGHT)); - grid.add(new TextPrint("Preferred size", fontData)); - grid.add(new TextPrint("Default width column", fontData)); - grid.add(new TextPrint("This is another default width column", - fontData, SWT.CENTER)); - grid.add(new TextPrint("Default width column", fontData, SWT.RIGHT), - GridPrint.REMAINDER); - grid.add(new LinePrint(), GridPrint.REMAINDER); - grid.add(SWT.CENTER, new TextPrint( - "LOTS AND LOTS AND LOTS AND LOTS AND LOTS OF TEXT", fontData, - SWT.CENTER), GridPrint.REMAINDER); - - GridPrint child = new GridPrint("d:g, d:g", new DefaultGridLook(10, 10)); - child.add(new TextPrint("This is a line with some text.", fontData)); - child - .add(new TextPrint( - "This is a line with lots of text. Where is all this text coming from??", - fontData)); - - grid.add(SWT.LEFT, child, GridPrint.REMAINDER); - - return grid; - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.ImagePrint; +import org.eclipse.nebula.paperclips.core.LinePrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Example for the GridPrint class. + * + * @author Matthew + */ +public class GridPrintExample { + /** + * Executes the GridPrint example. + * + * @param args + * the command line arguments. + */ + public static void main(String[] args) { + final Display display = new Display(); + + Shell shell = new Shell(display, SWT.SHELL_TRIM); + shell.setLayout(new FillLayout()); + shell.setSize(600, 600); + + final PrintViewer preview = new PrintViewer(shell, SWT.BORDER); + preview.setPrint(createPrint()); + + shell.open(); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + PaperClips.print(new PrintJob("GridPrintExample", createPrint()), + new PrinterData()); + } + + public static Print createPrint() { + GridPrint grid = new GridPrint("r:72, p, d, r:d:g(3), r:d:g", + new DefaultGridLook(5, 5)); + + ImageData imageData = new ImageData(GridPrintExample.class + .getResourceAsStream("logo.png")); + ImagePrint image = new ImagePrint(imageData); + image.setDPI(300, 300); + + grid.add(SWT.CENTER, image, GridPrint.REMAINDER); + + FontData fontData = new FontData("Arial", 10, SWT.BOLD); + + grid.add(new TextPrint("This column is 72 pts wide no matter what", + fontData, SWT.RIGHT)); + grid.add(new TextPrint("Preferred size", fontData)); + grid.add(new TextPrint("Default width column", fontData)); + grid.add(new TextPrint("This is another default width column", + fontData, SWT.CENTER)); + grid.add(new TextPrint("Default width column", fontData, SWT.RIGHT), + GridPrint.REMAINDER); + grid.add(new LinePrint(), GridPrint.REMAINDER); + grid.add(SWT.CENTER, new TextPrint( + "LOTS AND LOTS AND LOTS AND LOTS AND LOTS OF TEXT", fontData, + SWT.CENTER), GridPrint.REMAINDER); + + GridPrint child = new GridPrint("d:g, d:g", new DefaultGridLook(10, 10)); + child.add(new TextPrint("This is a line with some text.", fontData)); + child + .add(new TextPrint( + "This is a line with lots of text. Where is all this text coming from??", + fontData)); + + grid.add(SWT.LEFT, child, GridPrint.REMAINDER); + + return grid; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintVerticalAlignmentExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintVerticalAlignmentExample.java index 1d359a172..921531f6c 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintVerticalAlignmentExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/GridPrintVerticalAlignmentExample.java @@ -1,145 +1,145 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.ImagePrint; -import org.eclipse.nebula.paperclips.core.LinePrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Example for the GridPrint class. - * - * @author Matthew - */ -public class GridPrintVerticalAlignmentExample { - /** - * Executes the GridPrint example. - * - * @param args - * the command line arguments. - */ - public static void main(String[] args) { - final Display display = new Display(); - - Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setText("GridPrintVerticalAlignmentExample.java"); - shell.setLayout(new GridLayout()); - shell.setSize(600, 800); - - final PrintJob job = new PrintJob( - "GridPrintVerticalAlignmentExample.java", createPrint()); - - Composite buttonPanel = new Composite(shell, SWT.NONE); - buttonPanel - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - buttonPanel.setLayout(new RowLayout(SWT.HORIZONTAL)); - - final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); - - Button prev = new Button(buttonPanel, SWT.PUSH); - prev.setText("<< Prev"); - prev.addListener(SWT.Selection, event -> { - preview.setPageIndex(Math.max(preview.getPageIndex() - 1, 0)); - }); - - Button next = new Button(buttonPanel, SWT.PUSH); - next.setText("Next >>"); - next.addListener(SWT.Selection, event -> { - preview.setPageIndex(Math.min(preview.getPageIndex() + 1, - preview.getPageCount() - 1)); - }); - - Button print = new Button(buttonPanel, SWT.PUSH); - print.setText("Print"); - print.addListener(SWT.Selection, event -> { - PaperClips.print(job, new PrinterData()); - }); - - preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - preview.setFitHorizontal(true); - preview.setFitVertical(true); - preview.setPrintJob(job); - - shell.open(); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } - - public static Print createPrint() { - DefaultGridLook look = new DefaultGridLook(5, 5); - look.setHeaderGap(5); - GridPrint grid = new GridPrint("d:g, d, d:g, d, d:g, d, d:g", look); - - ImageData imageData = new ImageData( - GridPrintVerticalAlignmentExample.class - .getResourceAsStream("logo.png")); - ImagePrint image = new ImagePrint(imageData); - image.setDPI(300, 300); - - Print verticalRule = new LinePrint(SWT.VERTICAL); - - grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 1")); - grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 2")); - grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 3")); - grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 4")); - - grid.addHeader(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); - - grid.add(SWT.LEFT, SWT.CENTER, image); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.DEFAULT, SWT.DEFAULT, - new TextPrint("triple\nline\nleft\n")); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.CENTER, SWT.CENTER, - new TextPrint("double line\ncenter", SWT.CENTER)); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.RIGHT, SWT.BOTTOM, new TextPrint("single line right")); - - grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); - - grid.add(SWT.CENTER, SWT.CENTER, - new TextPrint("several\nlines\nof\ntext\nhere", SWT.CENTER)); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.LEFT, SWT.FILL, verticalRule); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.CENTER, SWT.FILL, verticalRule); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.RIGHT, SWT.FILL, verticalRule); - - return grid; - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.ImagePrint; +import org.eclipse.nebula.paperclips.core.LinePrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Example for the GridPrint class. + * + * @author Matthew + */ +public class GridPrintVerticalAlignmentExample { + /** + * Executes the GridPrint example. + * + * @param args + * the command line arguments. + */ + public static void main(String[] args) { + final Display display = new Display(); + + Shell shell = new Shell(display, SWT.SHELL_TRIM); + shell.setText("GridPrintVerticalAlignmentExample.java"); + shell.setLayout(new GridLayout()); + shell.setSize(600, 800); + + final PrintJob job = new PrintJob( + "GridPrintVerticalAlignmentExample.java", createPrint()); + + Composite buttonPanel = new Composite(shell, SWT.NONE); + buttonPanel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + buttonPanel.setLayout(new RowLayout(SWT.HORIZONTAL)); + + final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); + + Button prev = new Button(buttonPanel, SWT.PUSH); + prev.setText("<< Prev"); + prev.addListener(SWT.Selection, event -> { + preview.setPageIndex(Math.max(preview.getPageIndex() - 1, 0)); + }); + + Button next = new Button(buttonPanel, SWT.PUSH); + next.setText("Next >>"); + next.addListener(SWT.Selection, event -> { + preview.setPageIndex(Math.min(preview.getPageIndex() + 1, + preview.getPageCount() - 1)); + }); + + Button print = new Button(buttonPanel, SWT.PUSH); + print.setText("Print"); + print.addListener(SWT.Selection, event -> { + PaperClips.print(job, new PrinterData()); + }); + + preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + preview.setFitHorizontal(true); + preview.setFitVertical(true); + preview.setPrintJob(job); + + shell.open(); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } + + public static Print createPrint() { + DefaultGridLook look = new DefaultGridLook(5, 5); + look.setHeaderGap(5); + GridPrint grid = new GridPrint("d:g, d, d:g, d, d:g, d, d:g", look); + + ImageData imageData = new ImageData( + GridPrintVerticalAlignmentExample.class + .getResourceAsStream("logo.png")); + ImagePrint image = new ImagePrint(imageData); + image.setDPI(300, 300); + + Print verticalRule = new LinePrint(SWT.VERTICAL); + + grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 1")); + grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 2")); + grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 3")); + grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 4")); + + grid.addHeader(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); + + grid.add(SWT.LEFT, SWT.CENTER, image); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.DEFAULT, SWT.DEFAULT, + new TextPrint("triple\nline\nleft\n")); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.CENTER, SWT.CENTER, + new TextPrint("double line\ncenter", SWT.CENTER)); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.RIGHT, SWT.BOTTOM, new TextPrint("single line right")); + + grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); + + grid.add(SWT.CENTER, SWT.CENTER, + new TextPrint("several\nlines\nof\ntext\nhere", SWT.CENTER)); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.LEFT, SWT.FILL, verticalRule); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.CENTER, SWT.FILL, verticalRule); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.RIGHT, SWT.FILL, verticalRule); + + return grid; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/ImageCaptureExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/ImageCaptureExample.java index 08bec6c90..34aecc274 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/ImageCaptureExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/ImageCaptureExample.java @@ -1,154 +1,154 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.ImageLoader; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Transform; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; - -/** - * Demonstrate capturing the pages of a print job to in-memory images. - * - * @author Matthew Hall - */ -public class ImageCaptureExample { - /** - * Returns a sample print - * - * @return a sample print - */ - public static Print createPrint() { - GridPrint grid = new GridPrint(new DefaultGridLook()); - - int COLS = 5; - int ROWS = 50; - - for (int c = 0; c < COLS; c++) { - grid.addColumn("d"); - grid.addHeader(new TextPrint("Column " + (c + 1))); - grid.addFooter(new TextPrint("Column " + (c + 1))); - } - - for (int r = 0; r < ROWS; r++) - for (int c = 0; c < COLS; c++) - grid.add(new TextPrint("Row " + (r + 1) + " Col " + (c + 1))); - - return grid; - } - - /** - * Captures the page to an image and returns it. - * - * @param printer - * the printer device. - * @param page - * the page to capture. - * @param imageSize - * the size of the returned image - * @return an image of the captured page. - */ - public static ImageData captureImageData(Printer printer, PrintPiece page, - Point imageSize) { - Point pageSize = page.getSize(); - - Image image = null; - GC gc = null; - Transform transform = null; - - try { - image = new Image(printer, imageSize.x, imageSize.y); - gc = new GC(image); - gc.setAdvanced(true); - gc.setAntialias(SWT.ON); - gc.setTextAntialias(SWT.ON); - gc.setInterpolation(SWT.HIGH); - transform = new Transform(printer); - - // Scale from the page size to the image size - gc.getTransform(transform); - transform.scale((float) imageSize.x / (float) pageSize.x, - (float) imageSize.y / (float) pageSize.y); - gc.setTransform(transform); - - page.paint(gc, 0, 0); - - return image.getImageData(); - } finally { - if (transform != null) - transform.dispose(); - if (gc != null) - gc.dispose(); - if (image != null) - image.dispose(); - } - } - - private static String getImageName(int index) { - // Saving PNG is not supported until SWT version 3.3 or later. - return "capture_image_" + index + ".jpg"; - } - - /** - * Demonstrate capturing the pages of a print to in-memory images. - * - * @param args - * command-line arguments (ignored) - */ - public static void main(String[] args) { - Display display = new Display(); - Point displayDPI = display.getDPI(); - display.dispose(); - - Printer printer = new Printer(new PrinterData()); - Point printerDPI = printer.getDPI(); - - try { - PrintJob job = new PrintJob("ImageCapture.java", createPrint()); - - PrintPiece[] pages = PaperClips.getPages(job, printer); - - ImageLoader imageLoader = new ImageLoader(); - for (int i = 0; i < pages.length; i++) { - PrintPiece page = pages[i]; - Point pageSize = page.getSize(); - pageSize.x = pageSize.x * displayDPI.x / printerDPI.x; - pageSize.y = pageSize.y * displayDPI.y / printerDPI.y; - ImageData pageImage = captureImageData(printer, page, pageSize); - - // Do something with the image - pageImage.scanlinePad = 1; - - imageLoader.data = new ImageData[] { pageImage }; - imageLoader.save(getImageName(i), SWT.IMAGE_JPEG); - } - - } finally { - printer.dispose(); - } - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Transform; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; + +/** + * Demonstrate capturing the pages of a print job to in-memory images. + * + * @author Matthew Hall + */ +public class ImageCaptureExample { + /** + * Returns a sample print + * + * @return a sample print + */ + public static Print createPrint() { + GridPrint grid = new GridPrint(new DefaultGridLook()); + + int COLS = 5; + int ROWS = 50; + + for (int c = 0; c < COLS; c++) { + grid.addColumn("d"); + grid.addHeader(new TextPrint("Column " + (c + 1))); + grid.addFooter(new TextPrint("Column " + (c + 1))); + } + + for (int r = 0; r < ROWS; r++) + for (int c = 0; c < COLS; c++) + grid.add(new TextPrint("Row " + (r + 1) + " Col " + (c + 1))); + + return grid; + } + + /** + * Captures the page to an image and returns it. + * + * @param printer + * the printer device. + * @param page + * the page to capture. + * @param imageSize + * the size of the returned image + * @return an image of the captured page. + */ + public static ImageData captureImageData(Printer printer, PrintPiece page, + Point imageSize) { + Point pageSize = page.getSize(); + + Image image = null; + GC gc = null; + Transform transform = null; + + try { + image = new Image(printer, imageSize.x, imageSize.y); + gc = new GC(image); + gc.setAdvanced(true); + gc.setAntialias(SWT.ON); + gc.setTextAntialias(SWT.ON); + gc.setInterpolation(SWT.HIGH); + transform = new Transform(printer); + + // Scale from the page size to the image size + gc.getTransform(transform); + transform.scale((float) imageSize.x / (float) pageSize.x, + (float) imageSize.y / (float) pageSize.y); + gc.setTransform(transform); + + page.paint(gc, 0, 0); + + return image.getImageData(); + } finally { + if (transform != null) + transform.dispose(); + if (gc != null) + gc.dispose(); + if (image != null) + image.dispose(); + } + } + + private static String getImageName(int index) { + // Saving PNG is not supported until SWT version 3.3 or later. + return "capture_image_" + index + ".jpg"; + } + + /** + * Demonstrate capturing the pages of a print to in-memory images. + * + * @param args + * command-line arguments (ignored) + */ + public static void main(String[] args) { + Display display = new Display(); + Point displayDPI = display.getDPI(); + display.dispose(); + + Printer printer = new Printer(new PrinterData()); + Point printerDPI = printer.getDPI(); + + try { + PrintJob job = new PrintJob("ImageCapture.java", createPrint()); + + PrintPiece[] pages = PaperClips.getPages(job, printer); + + ImageLoader imageLoader = new ImageLoader(); + for (int i = 0; i < pages.length; i++) { + PrintPiece page = pages[i]; + Point pageSize = page.getSize(); + pageSize.x = pageSize.x * displayDPI.x / printerDPI.x; + pageSize.y = pageSize.y * displayDPI.y / printerDPI.y; + ImageData pageImage = captureImageData(printer, page, pageSize); + + // Do something with the image + pageImage.scanlinePad = 1; + + imageLoader.data = new ImageData[] { pageImage }; + imageLoader.save(getImageName(i), SWT.IMAGE_JPEG); + } + + } finally { + printer.dispose(); + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/NoBreakPrintExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/NoBreakPrintExample.java index 2a1575ae0..4acbab02f 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/NoBreakPrintExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/NoBreakPrintExample.java @@ -1,74 +1,74 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.ColumnPrint; -import org.eclipse.nebula.paperclips.core.NoBreakPrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; - -/** - * Prints "The quick brown fox jumps over the lazy dog." in increasingly large - * blocks, using a NoBreakPrint to prevent each block from being broken up - * across page or across columns. - * - * @author Matthew - */ -public class NoBreakPrintExample { - public static Print createPrint() { - DefaultGridLook look = new DefaultGridLook(10, 10); - look.setCellBorder(new LineBorder()); - GridPrint grid = new GridPrint("d:g", look); - - String text = "The quick brown fox jumps over the lazy dog."; - String printText = text; - - for (int i = 0; i < 20; i++, printText += " " + text) { - // the text - Print print = new TextPrint(printText); - - // Wrap the text in a NoBreakPrint so it stays together on the page. - print = new NoBreakPrint(print); - // Comment the above line and run the program again to see the - // difference. - - grid.add(print); - } - - return new ColumnPrint(grid, 2, 10); - } - - /** - * Prints the NoBreakPrintExample to the default printer. - * - * @param args - * command-line args - */ - public static void main(String[] args) { - // Workaround for SWT bug on GTK - force SWT to initialize so we don't - // crash. - Display.getDefault(); - - PaperClips.print( - new PrintJob("NoBreakPrintExample.java", createPrint()), - new PrinterData()); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.ColumnPrint; +import org.eclipse.nebula.paperclips.core.NoBreakPrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; + +/** + * Prints "The quick brown fox jumps over the lazy dog." in increasingly large + * blocks, using a NoBreakPrint to prevent each block from being broken up + * across page or across columns. + * + * @author Matthew + */ +public class NoBreakPrintExample { + public static Print createPrint() { + DefaultGridLook look = new DefaultGridLook(10, 10); + look.setCellBorder(new LineBorder()); + GridPrint grid = new GridPrint("d:g", look); + + String text = "The quick brown fox jumps over the lazy dog."; + String printText = text; + + for (int i = 0; i < 20; i++, printText += " " + text) { + // the text + Print print = new TextPrint(printText); + + // Wrap the text in a NoBreakPrint so it stays together on the page. + print = new NoBreakPrint(print); + // Comment the above line and run the program again to see the + // difference. + + grid.add(print); + } + + return new ColumnPrint(grid, 2, 10); + } + + /** + * Prints the NoBreakPrintExample to the default printer. + * + * @param args + * command-line args + */ + public static void main(String[] args) { + // Workaround for SWT bug on GTK - force SWT to initialize so we don't + // crash. + Display.getDefault(); + + PaperClips.print( + new PrintJob("NoBreakPrintExample.java", createPrint()), + new PrinterData()); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/PagePrintExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/PagePrintExample.java index 0dd6d8280..37474fe80 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/PagePrintExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/PagePrintExample.java @@ -1,161 +1,161 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.ImagePrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.page.PageDecoration; -import org.eclipse.nebula.paperclips.core.page.PageNumber; -import org.eclipse.nebula.paperclips.core.page.PageNumberPrint; -import org.eclipse.nebula.paperclips.core.page.PagePrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Demonstrate use of PagePrint and friends PageDecoration, PageNumberPrint, and - * PageNumber. - * - * @author Matthew - */ -public class PagePrintExample { - /** - * Executes the GridPrint example. - * - * @param args - * the command line arguments. - */ - public static void main(String[] args) { - final Display display = new Display(); - - Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setText("PagePrintExample.java"); - shell.setLayout(new GridLayout()); - shell.setSize(600, 800); - - final PrintJob job = new PrintJob("PagePrintExample.java", - createPrint()); - - Composite buttonPanel = new Composite(shell, SWT.NONE); - buttonPanel - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - buttonPanel.setLayout(new RowLayout(SWT.HORIZONTAL)); - - final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); - - Button prev = new Button(buttonPanel, SWT.PUSH); - prev.setText("<< Prev"); - prev.addListener(SWT.Selection, event -> { - preview.setPageIndex(Math.max(preview.getPageIndex() - 1, 0)); - }); - - Button next = new Button(buttonPanel, SWT.PUSH); - next.setText("Next >>"); - next.addListener(SWT.Selection, event -> { - preview.setPageIndex(Math.min(preview.getPageIndex() + 1, - preview.getPageCount() - 1)); - }); - - Button print = new Button(buttonPanel, SWT.PUSH); - print.setText("Print"); - print.addListener(SWT.Selection, event -> { - PaperClips.print(job, new PrinterData()); - }); - - preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - preview.setFitHorizontal(true); - preview.setFitVertical(true); - preview.setPrintJob(job); - - shell.open(); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } - - public static Print createPrint() { - PageDecoration header = createHeader(); - Print body = createBody(); - PageDecoration footer = createFooter(); - - PagePrint page = new PagePrint(header, body, footer); - page.setHeaderGap(72 / 4); - page.setFooterGap(72 / 8); - - return page; - } - - public static PageDecoration createHeader() { - PageDecoration header = new PageDecoration() { - public Print createPrint(PageNumber pageNumber) { - // Only show a header on the first page - if (pageNumber.getPageNumber() == 0) { - ImageData imageData = new ImageData(PagePrintExample.class - .getResourceAsStream("logo.png")); - ImagePrint image = new ImagePrint(imageData); - image.setDPI(300, 300); - return image; - } - - return null; - } - }; - return header; - } - - public static PageDecoration createFooter() { - PageDecoration footer = new PageDecoration() { - public Print createPrint(PageNumber pageNumber) { - GridPrint grid = new GridPrint("d:g, r:d"); - grid.add(new TextPrint( - "Copyright 2006 ABC Corp, All Rights Reserved")); - grid.add(new PageNumberPrint(pageNumber, SWT.RIGHT)); - return grid; - } - }; - return footer; - } - - public static Print createBody() { - GridPrint grid = new GridPrint(); - - final int ROWS = 200; - final int COLS = 4; - for (int c = 0; c < COLS; c++) { - grid.addColumn("d:g"); - grid.addHeader(new TextPrint("Column " + c)); - } - - for (int r = 0; r < ROWS; r++) - for (int c = 0; c < COLS; c++) - grid.add(new TextPrint("Cell (" + c + ", " + r + ")")); - - return grid; - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.ImagePrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.page.PageDecoration; +import org.eclipse.nebula.paperclips.core.page.PageNumber; +import org.eclipse.nebula.paperclips.core.page.PageNumberPrint; +import org.eclipse.nebula.paperclips.core.page.PagePrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Demonstrate use of PagePrint and friends PageDecoration, PageNumberPrint, and + * PageNumber. + * + * @author Matthew + */ +public class PagePrintExample { + /** + * Executes the GridPrint example. + * + * @param args + * the command line arguments. + */ + public static void main(String[] args) { + final Display display = new Display(); + + Shell shell = new Shell(display, SWT.SHELL_TRIM); + shell.setText("PagePrintExample.java"); + shell.setLayout(new GridLayout()); + shell.setSize(600, 800); + + final PrintJob job = new PrintJob("PagePrintExample.java", + createPrint()); + + Composite buttonPanel = new Composite(shell, SWT.NONE); + buttonPanel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + buttonPanel.setLayout(new RowLayout(SWT.HORIZONTAL)); + + final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); + + Button prev = new Button(buttonPanel, SWT.PUSH); + prev.setText("<< Prev"); + prev.addListener(SWT.Selection, event -> { + preview.setPageIndex(Math.max(preview.getPageIndex() - 1, 0)); + }); + + Button next = new Button(buttonPanel, SWT.PUSH); + next.setText("Next >>"); + next.addListener(SWT.Selection, event -> { + preview.setPageIndex(Math.min(preview.getPageIndex() + 1, + preview.getPageCount() - 1)); + }); + + Button print = new Button(buttonPanel, SWT.PUSH); + print.setText("Print"); + print.addListener(SWT.Selection, event -> { + PaperClips.print(job, new PrinterData()); + }); + + preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + preview.setFitHorizontal(true); + preview.setFitVertical(true); + preview.setPrintJob(job); + + shell.open(); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } + + public static Print createPrint() { + PageDecoration header = createHeader(); + Print body = createBody(); + PageDecoration footer = createFooter(); + + PagePrint page = new PagePrint(header, body, footer); + page.setHeaderGap(72 / 4); + page.setFooterGap(72 / 8); + + return page; + } + + public static PageDecoration createHeader() { + PageDecoration header = new PageDecoration() { + public Print createPrint(PageNumber pageNumber) { + // Only show a header on the first page + if (pageNumber.getPageNumber() == 0) { + ImageData imageData = new ImageData(PagePrintExample.class + .getResourceAsStream("logo.png")); + ImagePrint image = new ImagePrint(imageData); + image.setDPI(300, 300); + return image; + } + + return null; + } + }; + return header; + } + + public static PageDecoration createFooter() { + PageDecoration footer = new PageDecoration() { + public Print createPrint(PageNumber pageNumber) { + GridPrint grid = new GridPrint("d:g, r:d"); + grid.add(new TextPrint( + "Copyright 2006 ABC Corp, All Rights Reserved")); + grid.add(new PageNumberPrint(pageNumber, SWT.RIGHT)); + return grid; + } + }; + return footer; + } + + public static Print createBody() { + GridPrint grid = new GridPrint(); + + final int ROWS = 200; + final int COLS = 4; + for (int c = 0; c < COLS; c++) { + grid.addColumn("d:g"); + grid.addHeader(new TextPrint("Column " + c)); + } + + for (int r = 0; r < ROWS; r++) + for (int c = 0; c < COLS; c++) + grid.add(new TextPrint("Cell (" + c + ", " + r + ")")); + + return grid; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/PaperClipsExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/PaperClipsExample.java index da9f77976..35879d8fa 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/PaperClipsExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/PaperClipsExample.java @@ -1,79 +1,79 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.ImagePrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; - -/** - * Example for PaperClips. - * - * @author Matthew - */ -public class PaperClipsExample { - /** - * Executes the PaperClips example. - * - * @param args - * the command line arguments. - */ - public static void main(String[] args) { - GridPrint grid = new GridPrint("p, d, c:d:g, 72", new DefaultGridLook( - 5, 5)); - - // Now add some items to the grid - grid.add(new ImagePrint(new ImageData(PaperClipsExample.class - .getResourceAsStream("logo.png")), new Point(300, 300))); // (The - // point - // indicates - // DPI) - grid.add(new TextPrint("Column 2 will shrink if space is scarce.")); - grid - .add(new TextPrint( - "Column 3 will shrink too, and it also grows to fill excess page width.")); - grid.add(new TextPrint( - "Column 4 will be 1\" wide (72 points) wide no matter what.")); - grid.add(new TextPrint("This is in column 1 on the 2nd row")); - grid.add(new TextPrint("Often is it useful for a document element " - + "to span several cells in a grid."), 3); - grid.add(SWT.RIGHT, new TextPrint( - "And sometimes you may want to override the " - + "default alignment", SWT.RIGHT), 4); - grid - .add( - new TextPrint( - "A handy shorthand for 'the rest of the row' is " - + "to use GridPrint.REMAINDER as the colSpan argument."), - GridPrint.REMAINDER); - - // Workaround for SWT bug on GTK - force SWT to initialize so we don't - // crash. - Display.getDefault(); - - // When the document is ready to go, pass it to the - // PrintUtil.print(Print) - // method. - PaperClips.print(new PrintJob("PaperClipsExample.java", grid), - new PrinterData()); - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.ImagePrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; + +/** + * Example for PaperClips. + * + * @author Matthew + */ +public class PaperClipsExample { + /** + * Executes the PaperClips example. + * + * @param args + * the command line arguments. + */ + public static void main(String[] args) { + GridPrint grid = new GridPrint("p, d, c:d:g, 72", new DefaultGridLook( + 5, 5)); + + // Now add some items to the grid + grid.add(new ImagePrint(new ImageData(PaperClipsExample.class + .getResourceAsStream("logo.png")), new Point(300, 300))); // (The + // point + // indicates + // DPI) + grid.add(new TextPrint("Column 2 will shrink if space is scarce.")); + grid + .add(new TextPrint( + "Column 3 will shrink too, and it also grows to fill excess page width.")); + grid.add(new TextPrint( + "Column 4 will be 1\" wide (72 points) wide no matter what.")); + grid.add(new TextPrint("This is in column 1 on the 2nd row")); + grid.add(new TextPrint("Often is it useful for a document element " + + "to span several cells in a grid."), 3); + grid.add(SWT.RIGHT, new TextPrint( + "And sometimes you may want to override the " + + "default alignment", SWT.RIGHT), 4); + grid + .add( + new TextPrint( + "A handy shorthand for 'the rest of the row' is " + + "to use GridPrint.REMAINDER as the colSpan argument."), + GridPrint.REMAINDER); + + // Workaround for SWT bug on GTK - force SWT to initialize so we don't + // crash. + Display.getDefault(); + + // When the document is ready to go, pass it to the + // PrintUtil.print(Print) + // method. + PaperClips.print(new PrintJob("PaperClipsExample.java", grid), + new PrinterData()); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet1.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet1.java index 36877280b..f6e6ca8c9 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet1.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet1.java @@ -1,150 +1,150 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.ImagePrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridColumn; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; - -/** - * Demonstrates how to print the contents of a Table widget. This snippet uses - * the GridPrint, TextPrint, and ImagePrint classes. - * - * @author Matthew - */ -public class Snippet1 { - public static Print createPrint(Table table) { - // Create GridPrint with all columns at default size. - - DefaultGridLook look = new DefaultGridLook(); - look.setCellBorder(new LineBorder()); - RGB background = table.getDisplay() - .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB(); - look.setHeaderBackground(background); - look.setFooterBackground(background); - - GridPrint grid = new GridPrint(look); - - // Add header and footer to match table column names. - TableColumn[] columns = table.getColumns(); - for (int i = 0; i < columns.length; i++) { - TableColumn col = columns[i]; - - // Add the column to the grid with alignment applied, default width, - // no - // weight - grid.addColumn(new GridColumn(col.getAlignment(), SWT.DEFAULT, 0)); - - Print cell = createCell(col.getImage(), col.getText(), SWT.CENTER); - grid.addHeader(cell); - grid.addFooter(cell); - } - - // Add content rows - TableItem[] items = table.getItems(); - for (int i = 0; i < items.length; i++) { - TableItem item = items[i]; - for (int j = 0; j < columns.length; j++) - grid.add(createCell(item.getImage(j), item.getText(j), - columns[j].getAlignment())); - } - - return grid; - } - - public static Print createCell(Image image, String text, int align) { - if (image == null) - return new TextPrint(text, align); - - GridPrint grid = new GridPrint("p, d"); - grid.add(new ImagePrint(image.getImageData(), - image.getDevice().getDPI())); - grid.add(new TextPrint(text, align)); - return grid; - } - - /** - * Executes the snippet. - * - * @param args - * command-line args. - */ - public static void main(String[] args) { - Display display = Display.getDefault(); - final Shell shell = new Shell(display); - shell.setText("Snippet1.java"); - shell.setBounds(100, 100, 640, 480); - shell.setLayout(new GridLayout()); - - Button button = new Button(shell, SWT.PUSH); - button.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); - button.setText("Print the table"); - - final Table table = new Table(shell, SWT.BORDER); - table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - // Set up Table widget with dummy data. - for (int i = 0; i < 5; i++) - new TableColumn(table, SWT.LEFT).setText("Column " + i); - - for (int row = 0; row < 100; row++) { - TableItem item = new TableItem(table, SWT.NONE); - for (int col = 0; col < 5; col++) - item.setText(col, "Cell [" + col + ", " + row + "]"); - } - - table.setHeaderVisible(true); - TableColumn[] columns = table.getColumns(); - for (int i = 0; i < columns.length; i++) - columns[i].pack(); - - button.addListener(SWT.Selection, event -> { - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - if (printerData != null) { - Print print = createPrint(table); - PaperClips.print( - new PrintJob("Snippet1.java", print).setMargins(72), - printerData); - } - }); - - shell.setVisible(true); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.ImagePrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridColumn; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; + +/** + * Demonstrates how to print the contents of a Table widget. This snippet uses + * the GridPrint, TextPrint, and ImagePrint classes. + * + * @author Matthew + */ +public class Snippet1 { + public static Print createPrint(Table table) { + // Create GridPrint with all columns at default size. + + DefaultGridLook look = new DefaultGridLook(); + look.setCellBorder(new LineBorder()); + RGB background = table.getDisplay() + .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB(); + look.setHeaderBackground(background); + look.setFooterBackground(background); + + GridPrint grid = new GridPrint(look); + + // Add header and footer to match table column names. + TableColumn[] columns = table.getColumns(); + for (int i = 0; i < columns.length; i++) { + TableColumn col = columns[i]; + + // Add the column to the grid with alignment applied, default width, + // no + // weight + grid.addColumn(new GridColumn(col.getAlignment(), SWT.DEFAULT, 0)); + + Print cell = createCell(col.getImage(), col.getText(), SWT.CENTER); + grid.addHeader(cell); + grid.addFooter(cell); + } + + // Add content rows + TableItem[] items = table.getItems(); + for (int i = 0; i < items.length; i++) { + TableItem item = items[i]; + for (int j = 0; j < columns.length; j++) + grid.add(createCell(item.getImage(j), item.getText(j), + columns[j].getAlignment())); + } + + return grid; + } + + public static Print createCell(Image image, String text, int align) { + if (image == null) + return new TextPrint(text, align); + + GridPrint grid = new GridPrint("p, d"); + grid.add(new ImagePrint(image.getImageData(), + image.getDevice().getDPI())); + grid.add(new TextPrint(text, align)); + return grid; + } + + /** + * Executes the snippet. + * + * @param args + * command-line args. + */ + public static void main(String[] args) { + Display display = Display.getDefault(); + final Shell shell = new Shell(display); + shell.setText("Snippet1.java"); + shell.setBounds(100, 100, 640, 480); + shell.setLayout(new GridLayout()); + + Button button = new Button(shell, SWT.PUSH); + button.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); + button.setText("Print the table"); + + final Table table = new Table(shell, SWT.BORDER); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + // Set up Table widget with dummy data. + for (int i = 0; i < 5; i++) + new TableColumn(table, SWT.LEFT).setText("Column " + i); + + for (int row = 0; row < 100; row++) { + TableItem item = new TableItem(table, SWT.NONE); + for (int col = 0; col < 5; col++) + item.setText(col, "Cell [" + col + ", " + row + "]"); + } + + table.setHeaderVisible(true); + TableColumn[] columns = table.getColumns(); + for (int i = 0; i < columns.length; i++) + columns[i].pack(); + + button.addListener(SWT.Selection, event -> { + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + if (printerData != null) { + Print print = createPrint(table); + PaperClips.print( + new PrintJob("Snippet1.java", print).setMargins(72), + printerData); + } + }); + + shell.setVisible(true); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet2.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet2.java index 621e556ca..2387210cd 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet2.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet2.java @@ -1,104 +1,104 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.BackgroundPrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Demonstrate use of BackgroundColorPrint. - * - * @author Matthew - */ -public class Snippet2 { - public static Print createPrint() { - DefaultGridLook look = new DefaultGridLook(); - look.setCellBorder(new LineBorder()); - GridPrint grid = new GridPrint("d, d, d, d", look); - - // Light gray background on header - for (int i = 0; i < 4; i++) - grid.add(new BackgroundPrint(new TextPrint("Column " + i), - new RGB(200, 200, 200))); - - // Even rows light yellow, odd rows light blue - RGB evenRows = new RGB(255, 255, 200); - RGB oddRows = new RGB(200, 200, 255); - for (int r = 0; r < 20; r++) - for (int c = 0; c < 4; c++) - grid.add(new BackgroundPrint( - new TextPrint("Row " + r + " Col " + c), - (r % 2 == 0) ? evenRows : oddRows)); - - // Give entire grid a light green background. - return new BackgroundPrint(grid, new RGB(200, 255, 200)); - } - - /** - * Executes the snippet. - * - * @param args - * command-line args. - */ - public static void main(String[] args) { - Display display = Display.getDefault(); - final Shell shell = new Shell(display); - shell.setText("Snippet2.java"); - shell.setBounds(100, 100, 640, 480); - shell.setLayout(new GridLayout()); - - Button button = new Button(shell, SWT.PUSH); - button.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); - button.setText("Print"); - - PrintViewer viewer = new PrintViewer(shell, SWT.BORDER); - viewer.getControl() - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - final Print print = createPrint(); - viewer.setPrint(print); - - button.addListener(SWT.Selection, event -> { - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - if (printerData != null) - PaperClips.print( - new PrintJob("Snippet2.java", print).setMargins(72), - printerData); - }); - - shell.setVisible(true); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.BackgroundPrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Demonstrate use of BackgroundColorPrint. + * + * @author Matthew + */ +public class Snippet2 { + public static Print createPrint() { + DefaultGridLook look = new DefaultGridLook(); + look.setCellBorder(new LineBorder()); + GridPrint grid = new GridPrint("d, d, d, d", look); + + // Light gray background on header + for (int i = 0; i < 4; i++) + grid.add(new BackgroundPrint(new TextPrint("Column " + i), + new RGB(200, 200, 200))); + + // Even rows light yellow, odd rows light blue + RGB evenRows = new RGB(255, 255, 200); + RGB oddRows = new RGB(200, 200, 255); + for (int r = 0; r < 20; r++) + for (int c = 0; c < 4; c++) + grid.add(new BackgroundPrint( + new TextPrint("Row " + r + " Col " + c), + (r % 2 == 0) ? evenRows : oddRows)); + + // Give entire grid a light green background. + return new BackgroundPrint(grid, new RGB(200, 255, 200)); + } + + /** + * Executes the snippet. + * + * @param args + * command-line args. + */ + public static void main(String[] args) { + Display display = Display.getDefault(); + final Shell shell = new Shell(display); + shell.setText("Snippet2.java"); + shell.setBounds(100, 100, 640, 480); + shell.setLayout(new GridLayout()); + + Button button = new Button(shell, SWT.PUSH); + button.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); + button.setText("Print"); + + PrintViewer viewer = new PrintViewer(shell, SWT.BORDER); + viewer.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + final Print print = createPrint(); + viewer.setPrint(print); + + button.addListener(SWT.Selection, event -> { + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + if (printerData != null) + PaperClips.print( + new PrintJob("Snippet2.java", print).setMargins(72), + printerData); + }); + + shell.setVisible(true); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet3.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet3.java index 827e4db4a..b47c29a29 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet3.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet3.java @@ -1,130 +1,130 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.BigPrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Demonstrate use of BigPrint. - * - * @author Matthew - */ -public class Snippet3 { - public static Print createPrint() { - // Using "preferred" size columns, to force the document to be wider - // than - // the page. In most - // cases it is recommended to use "d" for "default" columns, which can - // shrink when needed. - DefaultGridLook look = new DefaultGridLook(); - look.setCellBorder(new LineBorder()); - GridPrint grid = new GridPrint(look); - - final int ROWS = 60; - final int COLS = 10; - - for (int i = 0; i < COLS; i++) - grid.addColumn("p"); - for (int r = 0; r < ROWS; r++) - for (int c = 0; c < COLS; c++) - grid.add(new TextPrint("Row " + r + " Col " + c)); - - // Give entire grid a light green background. - return new BigPrint(grid); - } - - /** - * Executes the snippet. - * - * @param args - * command-line args. - */ - public static void main(String[] args) { - Display display = Display.getDefault(); - final Shell shell = new Shell(display); - shell.setText("Snippet3.java"); - shell.setBounds(100, 100, 640, 480); - shell.setLayout(new GridLayout(3, false)); - - Button prevPage = new Button(shell, SWT.PUSH); - prevPage.setLayoutData( - new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); - prevPage.setText("Previous Page"); - - Button nextPage = new Button(shell, SWT.PUSH); - nextPage.setLayoutData( - new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); - nextPage.setText("Next Page"); - - Button printButton = new Button(shell, SWT.PUSH); - printButton.setLayoutData( - new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); - printButton.setText("Print"); - - final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); - preview.setFitHorizontal(true); - preview.setFitVertical(true); - preview.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); - final PrintJob job = new PrintJob("Snippet3.java", createPrint()); - job.setMargins(72); - preview.setPrintJob(job); - - prevPage.addListener(SWT.Selection, event -> { - int page = Math.max(preview.getPageIndex() - 1, 0); - preview.setPageIndex(page); - }); - - nextPage.addListener(SWT.Selection, event -> { - int page = Math.min(preview.getPageIndex() + 1, - preview.getPageCount() - 1); - preview.setPageIndex(page); - }); - - printButton.addListener(SWT.Selection, event -> { - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - if (printerData != null) { - PaperClips.print(job, printerData); - // Update the preview to display according to the selected - // printer. - preview.setPrinterData(printerData); - } - }); - - shell.setVisible(true); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.BigPrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Demonstrate use of BigPrint. + * + * @author Matthew + */ +public class Snippet3 { + public static Print createPrint() { + // Using "preferred" size columns, to force the document to be wider + // than + // the page. In most + // cases it is recommended to use "d" for "default" columns, which can + // shrink when needed. + DefaultGridLook look = new DefaultGridLook(); + look.setCellBorder(new LineBorder()); + GridPrint grid = new GridPrint(look); + + final int ROWS = 60; + final int COLS = 10; + + for (int i = 0; i < COLS; i++) + grid.addColumn("p"); + for (int r = 0; r < ROWS; r++) + for (int c = 0; c < COLS; c++) + grid.add(new TextPrint("Row " + r + " Col " + c)); + + // Give entire grid a light green background. + return new BigPrint(grid); + } + + /** + * Executes the snippet. + * + * @param args + * command-line args. + */ + public static void main(String[] args) { + Display display = Display.getDefault(); + final Shell shell = new Shell(display); + shell.setText("Snippet3.java"); + shell.setBounds(100, 100, 640, 480); + shell.setLayout(new GridLayout(3, false)); + + Button prevPage = new Button(shell, SWT.PUSH); + prevPage.setLayoutData( + new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); + prevPage.setText("Previous Page"); + + Button nextPage = new Button(shell, SWT.PUSH); + nextPage.setLayoutData( + new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); + nextPage.setText("Next Page"); + + Button printButton = new Button(shell, SWT.PUSH); + printButton.setLayoutData( + new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); + printButton.setText("Print"); + + final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); + preview.setFitHorizontal(true); + preview.setFitVertical(true); + preview.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); + final PrintJob job = new PrintJob("Snippet3.java", createPrint()); + job.setMargins(72); + preview.setPrintJob(job); + + prevPage.addListener(SWT.Selection, event -> { + int page = Math.max(preview.getPageIndex() - 1, 0); + preview.setPageIndex(page); + }); + + nextPage.addListener(SWT.Selection, event -> { + int page = Math.min(preview.getPageIndex() + 1, + preview.getPageCount() - 1); + preview.setPageIndex(page); + }); + + printButton.addListener(SWT.Selection, event -> { + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + if (printerData != null) { + PaperClips.print(job, printerData); + // Update the preview to display according to the selected + // printer. + preview.setPrinterData(printerData); + } + }); + + shell.setVisible(true); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet4.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet4.java index edb41a723..91b0a595e 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet4.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet4.java @@ -1,126 +1,126 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.ScalePrint; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Demonstrate use of ScalePrint. - * - * @author Matthew - */ -public class Snippet4 { - public static Print createPrint() { - // Using "preferred" size columns, to force the document to be wider - // than the page. In most cases it is - // recommended to use "d" for "default" columns, which can shrink when - // needed. - DefaultGridLook look = new DefaultGridLook(); - look.setCellBorder(new LineBorder()); - GridPrint grid = new GridPrint(look); - - final int ROWS = 60; - final int COLS = 10; - - for (int i = 0; i < COLS; i++) - grid.addColumn("p"); - - for (int r = 0; r < ROWS; r++) - for (int c = 0; c < COLS; c++) - grid.add(new TextPrint("Row " + r + " Col " + c)); - - return new ScalePrint(grid); - } - - /** - * Executes the snippet. - * - * @param args - * command-line args. - */ - public static void main(String[] args) { - Display display = Display.getDefault(); - final Shell shell = new Shell(display); - shell.setText("Snippet4.java"); - shell.setBounds(100, 100, 640, 480); - shell.setLayout(new GridLayout(3, false)); - - Button prevPage = new Button(shell, SWT.PUSH); - prevPage.setLayoutData( - new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); - prevPage.setText("Previous Page"); - - Button nextPage = new Button(shell, SWT.PUSH); - nextPage.setLayoutData( - new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); - nextPage.setText("Next Page"); - - Button printButton = new Button(shell, SWT.PUSH); - printButton.setLayoutData( - new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); - printButton.setText("Print"); - - final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); - preview.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); - final PrintJob job = new PrintJob("Snippet4.java", createPrint()); - preview.setPrintJob(job); - - prevPage.addListener(SWT.Selection, event -> { - int page = Math.max(preview.getPageIndex() - 1, 0); - preview.setPageIndex(page); - }); - - nextPage.addListener(SWT.Selection, event -> { - int page = Math.min(preview.getPageIndex() + 1, - preview.getPageCount() - 1); - preview.setPageIndex(page); - }); - - printButton.addListener(SWT.Selection, event -> { - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - if (printerData != null) { - PaperClips.print(job, printerData); - // Update the preview to display according to the selected - // printer. - preview.setPrinterData(printerData); - } - }); - - shell.setVisible(true); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.ScalePrint; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Demonstrate use of ScalePrint. + * + * @author Matthew + */ +public class Snippet4 { + public static Print createPrint() { + // Using "preferred" size columns, to force the document to be wider + // than the page. In most cases it is + // recommended to use "d" for "default" columns, which can shrink when + // needed. + DefaultGridLook look = new DefaultGridLook(); + look.setCellBorder(new LineBorder()); + GridPrint grid = new GridPrint(look); + + final int ROWS = 60; + final int COLS = 10; + + for (int i = 0; i < COLS; i++) + grid.addColumn("p"); + + for (int r = 0; r < ROWS; r++) + for (int c = 0; c < COLS; c++) + grid.add(new TextPrint("Row " + r + " Col " + c)); + + return new ScalePrint(grid); + } + + /** + * Executes the snippet. + * + * @param args + * command-line args. + */ + public static void main(String[] args) { + Display display = Display.getDefault(); + final Shell shell = new Shell(display); + shell.setText("Snippet4.java"); + shell.setBounds(100, 100, 640, 480); + shell.setLayout(new GridLayout(3, false)); + + Button prevPage = new Button(shell, SWT.PUSH); + prevPage.setLayoutData( + new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); + prevPage.setText("Previous Page"); + + Button nextPage = new Button(shell, SWT.PUSH); + nextPage.setLayoutData( + new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); + nextPage.setText("Next Page"); + + Button printButton = new Button(shell, SWT.PUSH); + printButton.setLayoutData( + new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); + printButton.setText("Print"); + + final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); + preview.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); + final PrintJob job = new PrintJob("Snippet4.java", createPrint()); + preview.setPrintJob(job); + + prevPage.addListener(SWT.Selection, event -> { + int page = Math.max(preview.getPageIndex() - 1, 0); + preview.setPageIndex(page); + }); + + nextPage.addListener(SWT.Selection, event -> { + int page = Math.min(preview.getPageIndex() + 1, + preview.getPageCount() - 1); + preview.setPageIndex(page); + }); + + printButton.addListener(SWT.Selection, event -> { + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + if (printerData != null) { + PaperClips.print(job, printerData); + // Update the preview to display according to the selected + // printer. + preview.setPrinterData(printerData); + } + }); + + shell.setVisible(true); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet5.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet5.java index 0fa346bf4..0673af929 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet5.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet5.java @@ -1,108 +1,108 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.CellBackgroundProvider; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Demonstrate use of CellBackgroundProvider. - * - * @author Matthew - */ -public class Snippet5 { - public static Print createPrint() { - DefaultGridLook look = new DefaultGridLook(); - look.setCellBorder(new LineBorder()); - look.setHeaderBackground(new RGB(200, 200, 200)); - - // Alternate between light yellow and light blue every 5 rows - look.setBodyBackgroundProvider(new CellBackgroundProvider() { - private final RGB evenRows = new RGB(255, 255, 200); - private final RGB oddRows = new RGB(200, 200, 255); - - public RGB getCellBackground(int row, int column, int colspan) { - return (row / 5) % 2 == 0 ? evenRows : oddRows; - } - }); - GridPrint grid = new GridPrint("d, d, d, d", look); - - // Light gray background on header - for (int i = 0; i < 4; i++) - grid.addHeader(new TextPrint("Column " + i)); - - for (int r = 0; r < 20; r++) - for (int c = 0; c < 4; c++) - grid.add(new TextPrint("Row " + r + " Col " + c)); - - return grid; - } - - /** - * Executes the snippet. - * - * @param args - * command-line args. - */ - public static void main(String[] args) { - Display display = Display.getDefault(); - final Shell shell = new Shell(display); - shell.setText("Snippet5.java"); - shell.setBounds(100, 100, 640, 480); - shell.setLayout(new GridLayout()); - - Button button = new Button(shell, SWT.PUSH); - button.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); - button.setText("Print"); - - PrintViewer viewer = new PrintViewer(shell, SWT.BORDER); - viewer.getControl() - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - final Print print = createPrint(); - viewer.setPrint(print); - - button.addListener(SWT.Selection, event -> { - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - if (printerData != null) - PaperClips.print( - new PrintJob("Snippet5.java", print).setMargins(72), - printerData); - }); - - shell.setVisible(true); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.CellBackgroundProvider; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Demonstrate use of CellBackgroundProvider. + * + * @author Matthew + */ +public class Snippet5 { + public static Print createPrint() { + DefaultGridLook look = new DefaultGridLook(); + look.setCellBorder(new LineBorder()); + look.setHeaderBackground(new RGB(200, 200, 200)); + + // Alternate between light yellow and light blue every 5 rows + look.setBodyBackgroundProvider(new CellBackgroundProvider() { + private final RGB evenRows = new RGB(255, 255, 200); + private final RGB oddRows = new RGB(200, 200, 255); + + public RGB getCellBackground(int row, int column, int colspan) { + return (row / 5) % 2 == 0 ? evenRows : oddRows; + } + }); + GridPrint grid = new GridPrint("d, d, d, d", look); + + // Light gray background on header + for (int i = 0; i < 4; i++) + grid.addHeader(new TextPrint("Column " + i)); + + for (int r = 0; r < 20; r++) + for (int c = 0; c < 4; c++) + grid.add(new TextPrint("Row " + r + " Col " + c)); + + return grid; + } + + /** + * Executes the snippet. + * + * @param args + * command-line args. + */ + public static void main(String[] args) { + Display display = Display.getDefault(); + final Shell shell = new Shell(display); + shell.setText("Snippet5.java"); + shell.setBounds(100, 100, 640, 480); + shell.setLayout(new GridLayout()); + + Button button = new Button(shell, SWT.PUSH); + button.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); + button.setText("Print"); + + PrintViewer viewer = new PrintViewer(shell, SWT.BORDER); + viewer.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + final Print print = createPrint(); + viewer.setPrint(print); + + button.addListener(SWT.Selection, event -> { + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + if (printerData != null) + PaperClips.print( + new PrintJob("Snippet5.java", print).setMargins(72), + printerData); + }); + + shell.setVisible(true); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet6.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet6.java index dc2864a2b..212e8e62b 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet6.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet6.java @@ -1,141 +1,141 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import java.util.Calendar; - -import org.eclipse.nebula.paperclips.core.LinePrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.CellBackgroundProvider; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.page.PageDecoration; -import org.eclipse.nebula.paperclips.core.page.PageNumber; -import org.eclipse.nebula.paperclips.core.page.PageNumberPrint; -import org.eclipse.nebula.paperclips.core.page.PagePrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Demonstrate use of PagePrint and PageNumberPrint. - * - * @author Matthew - */ -public class Snippet6 { - public static Print createPrint() { - DefaultGridLook look = new DefaultGridLook(); - look.setCellBorder(new LineBorder()); - look.setHeaderBackground(new RGB(200, 200, 200)); - look.setBodyBackgroundProvider(new CellBackgroundProvider() { - private final RGB evenRows = new RGB(255, 255, 200); - private final RGB oddRows = new RGB(200, 200, 255); - - public RGB getCellBackground(int row, int column, int colspan) { - // Alternate between light yellow and light blue every 5 rows - return (row / 5) % 2 == 0 ? evenRows : oddRows; - } - }); - - // create a grid 50 rows tall by 5 columns wide with dummy data. - GridPrint grid = new GridPrint("d, d, d, d, d", look); - for (int i = 0; i < 50; i++) - for (int j = 0; j < 5; j++) - grid.add(new TextPrint("row " + i + ", col " + j)); - - // Page footer showing a horizontal rule with a copyright statement and - // page - // number underneath. - PageDecoration footer = new PageDecoration() { - private final Print copyrightStatement; - private final GridLook footerLook; - { - int year = Calendar.getInstance().get(Calendar.YEAR); - String copyrightText = "Copyright (c) " + year - + " ABC Corp. All Rights Reserved."; - - copyrightStatement = new TextPrint(copyrightText); - - footerLook = new DefaultGridLook(5, 2); - } - - public Print createPrint(PageNumber pageNumber) { - GridPrint grid = new GridPrint("d:g, d", footerLook); - grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); - grid.add(copyrightStatement); - grid.add(new PageNumberPrint(pageNumber, SWT.RIGHT)); - return grid; - } - }; - - PagePrint page = new PagePrint(grid); - page.setFooter(footer); - page.setFooterGap(2); - - return page; - } - - /** - * Executes the snippet. - * - * @param args - * command-line args. - */ - public static void main(String[] args) { - Display display = Display.getDefault(); - final Shell shell = new Shell(display); - shell.setText("Snippet6.java"); - shell.setBounds(100, 100, 640, 480); - shell.setLayout(new GridLayout()); - - Button button = new Button(shell, SWT.PUSH); - button.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); - button.setText("Print"); - - PrintViewer viewer = new PrintViewer(shell, SWT.BORDER); - viewer.getControl() - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - final Print print = createPrint(); - viewer.setPrint(print); - - button.addListener(SWT.Selection, event -> { - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - if (printerData != null) - PaperClips.print( - new PrintJob("Snippet6.java", print).setMargins(72), - printerData); - }); - - shell.setVisible(true); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import java.util.Calendar; + +import org.eclipse.nebula.paperclips.core.LinePrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.CellBackgroundProvider; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.page.PageDecoration; +import org.eclipse.nebula.paperclips.core.page.PageNumber; +import org.eclipse.nebula.paperclips.core.page.PageNumberPrint; +import org.eclipse.nebula.paperclips.core.page.PagePrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Demonstrate use of PagePrint and PageNumberPrint. + * + * @author Matthew + */ +public class Snippet6 { + public static Print createPrint() { + DefaultGridLook look = new DefaultGridLook(); + look.setCellBorder(new LineBorder()); + look.setHeaderBackground(new RGB(200, 200, 200)); + look.setBodyBackgroundProvider(new CellBackgroundProvider() { + private final RGB evenRows = new RGB(255, 255, 200); + private final RGB oddRows = new RGB(200, 200, 255); + + public RGB getCellBackground(int row, int column, int colspan) { + // Alternate between light yellow and light blue every 5 rows + return (row / 5) % 2 == 0 ? evenRows : oddRows; + } + }); + + // create a grid 50 rows tall by 5 columns wide with dummy data. + GridPrint grid = new GridPrint("d, d, d, d, d", look); + for (int i = 0; i < 50; i++) + for (int j = 0; j < 5; j++) + grid.add(new TextPrint("row " + i + ", col " + j)); + + // Page footer showing a horizontal rule with a copyright statement and + // page + // number underneath. + PageDecoration footer = new PageDecoration() { + private final Print copyrightStatement; + private final GridLook footerLook; + { + int year = Calendar.getInstance().get(Calendar.YEAR); + String copyrightText = "Copyright (c) " + year + + " ABC Corp. All Rights Reserved."; + + copyrightStatement = new TextPrint(copyrightText); + + footerLook = new DefaultGridLook(5, 2); + } + + public Print createPrint(PageNumber pageNumber) { + GridPrint grid = new GridPrint("d:g, d", footerLook); + grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); + grid.add(copyrightStatement); + grid.add(new PageNumberPrint(pageNumber, SWT.RIGHT)); + return grid; + } + }; + + PagePrint page = new PagePrint(grid); + page.setFooter(footer); + page.setFooterGap(2); + + return page; + } + + /** + * Executes the snippet. + * + * @param args + * command-line args. + */ + public static void main(String[] args) { + Display display = Display.getDefault(); + final Shell shell = new Shell(display); + shell.setText("Snippet6.java"); + shell.setBounds(100, 100, 640, 480); + shell.setLayout(new GridLayout()); + + Button button = new Button(shell, SWT.PUSH); + button.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); + button.setText("Print"); + + PrintViewer viewer = new PrintViewer(shell, SWT.BORDER); + viewer.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + final Print print = createPrint(); + viewer.setPrint(print); + + button.addListener(SWT.Selection, event -> { + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + if (printerData != null) + PaperClips.print( + new PrintJob("Snippet6.java", print).setMargins(72), + printerData); + }); + + shell.setVisible(true); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet7.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet7.java index b12a52fea..4b4b157b7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet7.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet7.java @@ -1,503 +1,503 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.page.PageNumberPageDecoration; -import org.eclipse.nebula.paperclips.core.page.PagePrint; -import org.eclipse.nebula.paperclips.core.page.SimplePageDecoration; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Spinner; - -/** - * Demonstrate use of PrintPreview control. - * - * @author Matthew - */ -public class Snippet7 { - public static Print createPrint() { - DefaultGridLook look = new DefaultGridLook(); - look.setCellSpacing(5, 2); - GridPrint grid = new GridPrint("p:g, d:g", look); - - String text = "The quick brown fox jumps over the lazy dog."; - for (int i = 0; i < 500; i++) - grid.add(new TextPrint(text)); - - PagePrint page = new PagePrint(grid); - page.setHeader(new SimplePageDecoration( - new TextPrint("Snippet7.java", SWT.CENTER))); - page.setFooter(new PageNumberPageDecoration(SWT.CENTER)); - page.setHeaderGap(5); - page.setFooterGap(5); - - return page; - } - - public static class UI { - final Display display; - - PrintJob printJob; - - Shell shell; - Button previousPage; - Label pageNumber; - Button nextPage; - - ScrolledComposite scroll; - PrintPreview preview; - - double[] scrollingPosition; - - public UI(Display display) { - this.display = display; - } - - public Shell createShell() { - printJob = new PrintJob("Snippet7.java", createPrint()) - .setMargins(108); // 1.5" - - shell = new Shell(display); - shell.setText("Snippet7.java"); - shell.setBounds(100, 100, 800, 600); - shell.setLayout(new GridLayout(1, false)); - - createButtonPanel(shell).setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, false)); - createScrollingPreview(shell).setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - - preview.setPrintJob(printJob); - updatePreviewSize(); - updatePageNumber(); - - shell.setVisible(true); - - return shell; - } - - private Control createButtonPanel(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - - GridLayout layout = new GridLayout(16, false); - layout.marginWidth = layout.marginHeight = 0; - composite.setLayout(layout); - - previousPage = createIconButton(composite, "previous_page.gif", - "Previous Page", event -> { - setPreviewPageIndex(preview.getPageIndex() - - preview.getHorizontalPageCount() - * preview.getVerticalPageCount()); - }); - - pageNumber = new Label(composite, SWT.NONE); - - nextPage = createIconButton(composite, "next_page.gif", "Next Page", - event -> { - setPreviewPageIndex(preview.getPageIndex() - + preview.getHorizontalPageCount() - * preview.getVerticalPageCount()); - }); - - createIconButton(composite, "fit_horizontal.png", "Fit Width", - event -> { - preview.setFitHorizontal(true); - preview.setFitVertical(false); - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - }); - - createIconButton(composite, "fit_vertical.png", "Fit Height", - event -> { - preview.setFitVertical(true); - preview.setFitHorizontal(false); - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - }); - - createIconButton(composite, "fit_best.png", "Fit Window", event -> { - preview.setFitVertical(true); - preview.setFitHorizontal(true); - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - }); - - createIconButton(composite, "zoom_in.gif", "Zoom In", event -> { - setPreviewScale(preview.getAbsoluteScale() * 1.1f); - }); - - createIconButton(composite, "zoom_out.gif", "Zoom Out", event -> { - setPreviewScale(preview.getAbsoluteScale() / 1.1f); - }); - - createIconButton(composite, "zoom_scale.gif", "Zoom to Scale", - event -> { - setPreviewScale(1); - }); - - createTextButton(composite, "Port", "Portrait Orientation", - event -> { - printJob.setOrientation( - PaperClips.ORIENTATION_PORTRAIT); - preview.setPrintJob(printJob); - - forgetScrollingPosition(); - updatePreviewSize(); - updatePageNumber(); - }); - - createTextButton(composite, "Land", "Landscape Orientation", - event -> { - printJob.setOrientation( - PaperClips.ORIENTATION_LANDSCAPE); - preview.setPrintJob(printJob); - - forgetScrollingPosition(); - updatePreviewSize(); - updatePageNumber(); - }); - - createIconButton(composite, "print.gif", "Print", event -> { - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - if (printerData != null) { - PaperClips.print(printJob, printerData); - preview.setPrinterData(printerData); - } - }); - - createLabel(composite, "Horz Pages"); - createPageCountSpinner(composite, event -> { - preview.setHorizontalPageCount( - ((Spinner) event.widget).getSelection()); - forgetScrollingPosition(); - updatePreviewSize(); - updatePageNumber(); - }); - - createLabel(composite, "Vert Pages"); - createPageCountSpinner(composite, event -> { - preview.setVerticalPageCount( - ((Spinner) event.widget).getSelection()); - forgetScrollingPosition(); - updatePreviewSize(); - updatePageNumber(); - }); - - return composite; - } - - private Control createScrollingPreview(Composite parent) { - scroll = new ScrolledComposite(parent, - SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); - scroll.setExpandHorizontal(true); - scroll.setExpandVertical(true); - - preview = new PrintPreview(scroll, SWT.NONE); - scroll.setContent(preview); - - scroll.addListener(SWT.Resize, event -> { - Rectangle bounds = scroll.getClientArea(); - - scroll.getHorizontalBar() - .setPageIncrement(bounds.width * 2 / 3); - scroll.getVerticalBar().setPageIncrement(bounds.height * 2 / 3); - - if (preview.isFitHorizontal() ^ preview.isFitVertical()) { - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - } - }); - - preview.setFitVertical(true); - preview.setFitHorizontal(true); - - Listener dragListener = new Listener() { - private final Point dpi = display.getDPI(); - private boolean scrollable = false; - - private boolean dragging = false; - private Point dragStartScrollOrigin = null; - private Point dragStartMouseAnchor = null; - - public void handleEvent(Event event) { - switch (event.type) { - case SWT.Resize: - forgetScrollingPosition(); - Rectangle bounds = scroll.getClientArea(); - Point size = preview.getSize(); - scrollable = size.x > bounds.width - || size.y > bounds.height; - if (!scrollable && dragging) - endDragging(); - break; - case SWT.MouseDown: - forgetScrollingPosition(); - if (scrollable && event.button == 1) - beginDragging(event); - break; - case SWT.MouseMove: - if (dragging) { - forgetScrollingPosition(); - Point point = preview.toDisplay(event.x, event.y); - scroll.setOrigin( - dragStartScrollOrigin.x - + dragStartMouseAnchor.x - point.x, - dragStartScrollOrigin.y - + dragStartMouseAnchor.y - point.y); - } - break; - case SWT.MouseUp: - forgetScrollingPosition(); - if (dragging) - endDragging(); - break; - case SWT.MouseEnter: - display.addFilter(SWT.MouseWheel, this); - break; - case SWT.MouseWheel: - if (event.count != 0) { - if (scrollable && !dragging - && (event.stateMask == SWT.NONE - || event.stateMask == SWT.SHIFT)) { - forgetScrollingPosition(); - bounds = scroll.getClientArea(); - size = preview.getSize(); - Point origin = scroll.getOrigin(); - int direction = event.count > 0 ? -1 : 1; - // Prefer vertical scrolling unless user is - // pressing Shift - if (size.y > bounds.height - && event.stateMask == SWT.NONE) - origin.y += direction * Math.min(dpi.y, - bounds.height / 4); - else if (size.x > bounds.width) - origin.x += direction - * Math.min(dpi.x, bounds.width / 4); - scroll.setOrigin(origin); - event.doit = false; - } else if (event.stateMask == SWT.CTRL) { // Ctrl+MouseWheel - // -> - // zoom - float scale = preview.getAbsoluteScale(); - setPreviewScale(event.count > 0 ? scale / 1.1f - : scale * 1.1f); - } - } - break; - case SWT.MouseExit: - display.removeFilter(SWT.MouseWheel, this); - break; - } - } - - private void beginDragging(Event event) { - dragStartScrollOrigin = scroll.getOrigin(); - dragStartMouseAnchor = preview.toDisplay(event.x, event.y); - dragging = true; - } - - private void endDragging() { - dragging = false; - dragStartMouseAnchor = null; - dragStartScrollOrigin = null; - } - }; - - scroll.addListener(SWT.Resize, dragListener); - preview.addListener(SWT.MouseDown, dragListener); - preview.addListener(SWT.MouseMove, dragListener); - preview.addListener(SWT.MouseUp, dragListener); - - // These are for mouse wheel handling - preview.addListener(SWT.MouseEnter, dragListener); - preview.addListener(SWT.MouseExit, dragListener); - - return scroll; - } - - private Button createIconButton(Composite parent, String imageFilename, - String toolTipText, Listener selectionListener) { - Button button = createButton(parent, toolTipText, - selectionListener); - button.setImage(createImage(imageFilename)); - return button; - } - - private Button createTextButton(Composite parent, String text, - String toolTipText, Listener selectionListener) { - Button button = createButton(parent, toolTipText, - selectionListener); - button.setText(text); - return button; - } - - private Button createButton(Composite parent, String toolTipText, - Listener selectionListener) { - Button button = new Button(parent, SWT.PUSH); - button.setToolTipText(toolTipText); - button.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, false, false)); - button.addListener(SWT.Selection, selectionListener); - return button; - } - - private Spinner createPageCountSpinner(Composite parent, - Listener selectionListener) { - Spinner spinner = new Spinner(parent, SWT.BORDER); - spinner.setMinimum(1); - spinner.setMaximum(99); - spinner.addListener(SWT.Selection, selectionListener); - return spinner; - } - - private void createLabel(Composite parent, String text) { - new Label(parent, SWT.NONE).setText(text); - } - - private Image createImage(String filename) { - final Image image = new Image(display, - getClass().getResourceAsStream(filename)); - - shell.addListener(SWT.Dispose, new Listener() { - public void handleEvent(Event event) { - image.dispose(); - } - }); - - return image; - } - - private void updatePageNumber() { - int pageIndex = preview.getPageIndex(); - int pageCount = preview.getPageCount(); - int visiblePageCount = preview.getHorizontalPageCount() - * preview.getVerticalPageCount(); - String text = (visiblePageCount > 1 - ? "Pages " + (pageIndex + 1) + "-" - + Math.min(pageCount, pageIndex + visiblePageCount) - : "Page " + (pageIndex + 1)) + " of " + pageCount; - pageNumber.setText(text); - previousPage.setEnabled(pageIndex > 0); - nextPage.setEnabled(pageIndex < pageCount - visiblePageCount); - shell.layout(new Control[] { pageNumber }); - } - - private void rememberScrollingPosition() { - Point size = preview.getSize(); - if (size.x == 0 || size.y == 0) { - forgetScrollingPosition(); - } else if (scrollingPosition == null) { - Point origin = scroll.getOrigin(); - scrollingPosition = new double[] { - (double) origin.x / (double) size.x, - (double) origin.y / (double) size.y }; - } - } - - private void forgetScrollingPosition() { - scrollingPosition = null; - } - - private void restoreScrollingPosition() { - if (scrollingPosition != null) { - Point size = preview.getSize(); - scroll.setOrigin( - (int) Math.round(scrollingPosition[0] * size.x), - (int) Math.round(scrollingPosition[1] * size.y)); - } - } - - private void updatePreviewSize() { - Point minSize; - Rectangle bounds = scroll.getClientArea(); - if (preview.isFitHorizontal()) { - if (preview.isFitVertical()) - minSize = new Point(0, 0); // Best fit - else - minSize = new Point(0, - preview.computeSize(bounds.width, SWT.DEFAULT).y); // Fit - // to - // width - } else { - if (preview.isFitVertical()) - minSize = new Point( - preview.computeSize(SWT.DEFAULT, bounds.height).x, - 0); // Fit to height - else - minSize = preview.computeSize(SWT.DEFAULT, SWT.DEFAULT); // Custom - // scale - } - scroll.setMinSize(minSize); - } - - private void setPreviewScale(float scale) { - preview.setFitVertical(false); - preview.setFitHorizontal(false); - preview.setScale(scale); - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - } - - private void setPreviewPageIndex(int pageIndex) { - preview.setPageIndex(Math - .max(Math.min(pageIndex, preview.getPageCount() - 1), 0)); - updatePageNumber(); - } - } - - /** - * Executes the snippet. - * - * @param args - * command-line args. - */ - public static void main(String[] args) { - final Display display = Display.getDefault(); - - Shell shell = new UI(display).createShell(); - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.page.PageNumberPageDecoration; +import org.eclipse.nebula.paperclips.core.page.PagePrint; +import org.eclipse.nebula.paperclips.core.page.SimplePageDecoration; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Spinner; + +/** + * Demonstrate use of PrintPreview control. + * + * @author Matthew + */ +public class Snippet7 { + public static Print createPrint() { + DefaultGridLook look = new DefaultGridLook(); + look.setCellSpacing(5, 2); + GridPrint grid = new GridPrint("p:g, d:g", look); + + String text = "The quick brown fox jumps over the lazy dog."; + for (int i = 0; i < 500; i++) + grid.add(new TextPrint(text)); + + PagePrint page = new PagePrint(grid); + page.setHeader(new SimplePageDecoration( + new TextPrint("Snippet7.java", SWT.CENTER))); + page.setFooter(new PageNumberPageDecoration(SWT.CENTER)); + page.setHeaderGap(5); + page.setFooterGap(5); + + return page; + } + + public static class UI { + final Display display; + + PrintJob printJob; + + Shell shell; + Button previousPage; + Label pageNumber; + Button nextPage; + + ScrolledComposite scroll; + PrintPreview preview; + + double[] scrollingPosition; + + public UI(Display display) { + this.display = display; + } + + public Shell createShell() { + printJob = new PrintJob("Snippet7.java", createPrint()) + .setMargins(108); // 1.5" + + shell = new Shell(display); + shell.setText("Snippet7.java"); + shell.setBounds(100, 100, 800, 600); + shell.setLayout(new GridLayout(1, false)); + + createButtonPanel(shell).setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); + createScrollingPreview(shell).setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + preview.setPrintJob(printJob); + updatePreviewSize(); + updatePageNumber(); + + shell.setVisible(true); + + return shell; + } + + private Control createButtonPanel(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + + GridLayout layout = new GridLayout(16, false); + layout.marginWidth = layout.marginHeight = 0; + composite.setLayout(layout); + + previousPage = createIconButton(composite, "previous_page.gif", + "Previous Page", event -> { + setPreviewPageIndex(preview.getPageIndex() + - preview.getHorizontalPageCount() + * preview.getVerticalPageCount()); + }); + + pageNumber = new Label(composite, SWT.NONE); + + nextPage = createIconButton(composite, "next_page.gif", "Next Page", + event -> { + setPreviewPageIndex(preview.getPageIndex() + + preview.getHorizontalPageCount() + * preview.getVerticalPageCount()); + }); + + createIconButton(composite, "fit_horizontal.png", "Fit Width", + event -> { + preview.setFitHorizontal(true); + preview.setFitVertical(false); + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + }); + + createIconButton(composite, "fit_vertical.png", "Fit Height", + event -> { + preview.setFitVertical(true); + preview.setFitHorizontal(false); + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + }); + + createIconButton(composite, "fit_best.png", "Fit Window", event -> { + preview.setFitVertical(true); + preview.setFitHorizontal(true); + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + }); + + createIconButton(composite, "zoom_in.gif", "Zoom In", event -> { + setPreviewScale(preview.getAbsoluteScale() * 1.1f); + }); + + createIconButton(composite, "zoom_out.gif", "Zoom Out", event -> { + setPreviewScale(preview.getAbsoluteScale() / 1.1f); + }); + + createIconButton(composite, "zoom_scale.gif", "Zoom to Scale", + event -> { + setPreviewScale(1); + }); + + createTextButton(composite, "Port", "Portrait Orientation", + event -> { + printJob.setOrientation( + PaperClips.ORIENTATION_PORTRAIT); + preview.setPrintJob(printJob); + + forgetScrollingPosition(); + updatePreviewSize(); + updatePageNumber(); + }); + + createTextButton(composite, "Land", "Landscape Orientation", + event -> { + printJob.setOrientation( + PaperClips.ORIENTATION_LANDSCAPE); + preview.setPrintJob(printJob); + + forgetScrollingPosition(); + updatePreviewSize(); + updatePageNumber(); + }); + + createIconButton(composite, "print.gif", "Print", event -> { + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + if (printerData != null) { + PaperClips.print(printJob, printerData); + preview.setPrinterData(printerData); + } + }); + + createLabel(composite, "Horz Pages"); + createPageCountSpinner(composite, event -> { + preview.setHorizontalPageCount( + ((Spinner) event.widget).getSelection()); + forgetScrollingPosition(); + updatePreviewSize(); + updatePageNumber(); + }); + + createLabel(composite, "Vert Pages"); + createPageCountSpinner(composite, event -> { + preview.setVerticalPageCount( + ((Spinner) event.widget).getSelection()); + forgetScrollingPosition(); + updatePreviewSize(); + updatePageNumber(); + }); + + return composite; + } + + private Control createScrollingPreview(Composite parent) { + scroll = new ScrolledComposite(parent, + SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); + scroll.setExpandHorizontal(true); + scroll.setExpandVertical(true); + + preview = new PrintPreview(scroll, SWT.NONE); + scroll.setContent(preview); + + scroll.addListener(SWT.Resize, event -> { + Rectangle bounds = scroll.getClientArea(); + + scroll.getHorizontalBar() + .setPageIncrement(bounds.width * 2 / 3); + scroll.getVerticalBar().setPageIncrement(bounds.height * 2 / 3); + + if (preview.isFitHorizontal() ^ preview.isFitVertical()) { + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + } + }); + + preview.setFitVertical(true); + preview.setFitHorizontal(true); + + Listener dragListener = new Listener() { + private final Point dpi = display.getDPI(); + private boolean scrollable = false; + + private boolean dragging = false; + private Point dragStartScrollOrigin = null; + private Point dragStartMouseAnchor = null; + + public void handleEvent(Event event) { + switch (event.type) { + case SWT.Resize: + forgetScrollingPosition(); + Rectangle bounds = scroll.getClientArea(); + Point size = preview.getSize(); + scrollable = size.x > bounds.width + || size.y > bounds.height; + if (!scrollable && dragging) + endDragging(); + break; + case SWT.MouseDown: + forgetScrollingPosition(); + if (scrollable && event.button == 1) + beginDragging(event); + break; + case SWT.MouseMove: + if (dragging) { + forgetScrollingPosition(); + Point point = preview.toDisplay(event.x, event.y); + scroll.setOrigin( + dragStartScrollOrigin.x + + dragStartMouseAnchor.x - point.x, + dragStartScrollOrigin.y + + dragStartMouseAnchor.y - point.y); + } + break; + case SWT.MouseUp: + forgetScrollingPosition(); + if (dragging) + endDragging(); + break; + case SWT.MouseEnter: + display.addFilter(SWT.MouseWheel, this); + break; + case SWT.MouseWheel: + if (event.count != 0) { + if (scrollable && !dragging + && (event.stateMask == SWT.NONE + || event.stateMask == SWT.SHIFT)) { + forgetScrollingPosition(); + bounds = scroll.getClientArea(); + size = preview.getSize(); + Point origin = scroll.getOrigin(); + int direction = event.count > 0 ? -1 : 1; + // Prefer vertical scrolling unless user is + // pressing Shift + if (size.y > bounds.height + && event.stateMask == SWT.NONE) + origin.y += direction * Math.min(dpi.y, + bounds.height / 4); + else if (size.x > bounds.width) + origin.x += direction + * Math.min(dpi.x, bounds.width / 4); + scroll.setOrigin(origin); + event.doit = false; + } else if (event.stateMask == SWT.CTRL) { // Ctrl+MouseWheel + // -> + // zoom + float scale = preview.getAbsoluteScale(); + setPreviewScale(event.count > 0 ? scale / 1.1f + : scale * 1.1f); + } + } + break; + case SWT.MouseExit: + display.removeFilter(SWT.MouseWheel, this); + break; + } + } + + private void beginDragging(Event event) { + dragStartScrollOrigin = scroll.getOrigin(); + dragStartMouseAnchor = preview.toDisplay(event.x, event.y); + dragging = true; + } + + private void endDragging() { + dragging = false; + dragStartMouseAnchor = null; + dragStartScrollOrigin = null; + } + }; + + scroll.addListener(SWT.Resize, dragListener); + preview.addListener(SWT.MouseDown, dragListener); + preview.addListener(SWT.MouseMove, dragListener); + preview.addListener(SWT.MouseUp, dragListener); + + // These are for mouse wheel handling + preview.addListener(SWT.MouseEnter, dragListener); + preview.addListener(SWT.MouseExit, dragListener); + + return scroll; + } + + private Button createIconButton(Composite parent, String imageFilename, + String toolTipText, Listener selectionListener) { + Button button = createButton(parent, toolTipText, + selectionListener); + button.setImage(createImage(imageFilename)); + return button; + } + + private Button createTextButton(Composite parent, String text, + String toolTipText, Listener selectionListener) { + Button button = createButton(parent, toolTipText, + selectionListener); + button.setText(text); + return button; + } + + private Button createButton(Composite parent, String toolTipText, + Listener selectionListener) { + Button button = new Button(parent, SWT.PUSH); + button.setToolTipText(toolTipText); + button.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, false, false)); + button.addListener(SWT.Selection, selectionListener); + return button; + } + + private Spinner createPageCountSpinner(Composite parent, + Listener selectionListener) { + Spinner spinner = new Spinner(parent, SWT.BORDER); + spinner.setMinimum(1); + spinner.setMaximum(99); + spinner.addListener(SWT.Selection, selectionListener); + return spinner; + } + + private void createLabel(Composite parent, String text) { + new Label(parent, SWT.NONE).setText(text); + } + + private Image createImage(String filename) { + final Image image = new Image(display, + getClass().getResourceAsStream(filename)); + + shell.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + image.dispose(); + } + }); + + return image; + } + + private void updatePageNumber() { + int pageIndex = preview.getPageIndex(); + int pageCount = preview.getPageCount(); + int visiblePageCount = preview.getHorizontalPageCount() + * preview.getVerticalPageCount(); + String text = (visiblePageCount > 1 + ? "Pages " + (pageIndex + 1) + "-" + + Math.min(pageCount, pageIndex + visiblePageCount) + : "Page " + (pageIndex + 1)) + " of " + pageCount; + pageNumber.setText(text); + previousPage.setEnabled(pageIndex > 0); + nextPage.setEnabled(pageIndex < pageCount - visiblePageCount); + shell.layout(new Control[] { pageNumber }); + } + + private void rememberScrollingPosition() { + Point size = preview.getSize(); + if (size.x == 0 || size.y == 0) { + forgetScrollingPosition(); + } else if (scrollingPosition == null) { + Point origin = scroll.getOrigin(); + scrollingPosition = new double[] { + (double) origin.x / (double) size.x, + (double) origin.y / (double) size.y }; + } + } + + private void forgetScrollingPosition() { + scrollingPosition = null; + } + + private void restoreScrollingPosition() { + if (scrollingPosition != null) { + Point size = preview.getSize(); + scroll.setOrigin( + (int) Math.round(scrollingPosition[0] * size.x), + (int) Math.round(scrollingPosition[1] * size.y)); + } + } + + private void updatePreviewSize() { + Point minSize; + Rectangle bounds = scroll.getClientArea(); + if (preview.isFitHorizontal()) { + if (preview.isFitVertical()) + minSize = new Point(0, 0); // Best fit + else + minSize = new Point(0, + preview.computeSize(bounds.width, SWT.DEFAULT).y); // Fit + // to + // width + } else { + if (preview.isFitVertical()) + minSize = new Point( + preview.computeSize(SWT.DEFAULT, bounds.height).x, + 0); // Fit to height + else + minSize = preview.computeSize(SWT.DEFAULT, SWT.DEFAULT); // Custom + // scale + } + scroll.setMinSize(minSize); + } + + private void setPreviewScale(float scale) { + preview.setFitVertical(false); + preview.setFitHorizontal(false); + preview.setScale(scale); + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + } + + private void setPreviewPageIndex(int pageIndex) { + preview.setPageIndex(Math + .max(Math.min(pageIndex, preview.getPageCount() - 1), 0)); + updatePageNumber(); + } + } + + /** + * Executes the snippet. + * + * @param args + * command-line args. + */ + public static void main(String[] args) { + final Display display = Display.getDefault(); + + Shell shell = new UI(display).createShell(); + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet8.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet8.java index 1ac0d2720..03dc16e3c 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet8.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/Snippet8.java @@ -1,526 +1,526 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.page.PageNumber; -import org.eclipse.nebula.paperclips.core.page.PageNumberFormat; -import org.eclipse.nebula.paperclips.core.page.PageNumberPageDecoration; -import org.eclipse.nebula.paperclips.core.page.PagePrint; -import org.eclipse.nebula.paperclips.core.page.SimplePageDecoration; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Spinner; - -/** - * Demonstrate use of PrintPreview control. - * - * @author Matthew - */ -public class Snippet8 { - public static Print createPrint() { - DefaultGridLook look = new DefaultGridLook(); - look.setCellSpacing(5, 2); - GridPrint grid = new GridPrint("p:g, p:g, p:g, p:g, p:g", look); - - String text = "The quick brown fox jumps over the lazy dog."; - for (int i = 0; i < 20000; i++) - grid.add(new TextPrint(text)); - - PagePrint page = new PagePrint(grid); - page.setHeader(new SimplePageDecoration( - new TextPrint("Snippet8.java", SWT.CENTER))); - page.setHeaderGap(5); - page.setFooterGap(5); - PageNumberPageDecoration footer = new PageNumberPageDecoration( - SWT.CENTER); - footer.setFormat(new PageNumberFormat() { - public String format(PageNumber pageNumber) { - return "Page " + (pageNumber.getPageNumber() + 1); - } - }); - page.setFooter(footer); - - return page; - } - - private static class UI { - final Display display; - - PrintJob printJob; - - Shell shell; - Button previousPage; - Label pageNumber; - Button nextPage; - - ScrolledComposite scroll; - PrintPreview preview; - - double[] scrollingPosition; - - public UI(Display display) { - this.display = display; - } - - public Shell createShell() { - printJob = new PrintJob("Snippet8.java", createPrint()) - .setMargins(108); // 1.5" - - shell = new Shell(display); - shell.setText("Snippet8.java"); - shell.setBounds(100, 100, 800, 600); - shell.setLayout(new GridLayout(1, false)); - - createButtonPanel(shell).setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, false)); - createScrollingPreview(shell).setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, true)); - - preview.setLazyPageLayout(true); - preview.setPrintJob(printJob); - updatePreviewSize(); - updatePageNumber(); - preview.startBackgroundLayout(() -> { - updatePageNumber(); - }); - - shell.setVisible(true); - - return shell; - } - - private Control createButtonPanel(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - - GridLayout layout = new GridLayout(16, false); - layout.marginWidth = layout.marginHeight = 0; - composite.setLayout(layout); - - previousPage = createIconButton(composite, "previous_page.gif", - "Previous Page", event -> { - setPreviewPageIndex(preview.getPageIndex() - - preview.getHorizontalPageCount() - * preview.getVerticalPageCount()); - }); - - pageNumber = new Label(composite, SWT.NONE); - - nextPage = createIconButton(composite, "next_page.gif", "Next Page", - event -> { - setPreviewPageIndex(preview.getPageIndex() - + preview.getHorizontalPageCount() - * preview.getVerticalPageCount()); - }); - - createIconButton(composite, "fit_horizontal.png", "Fit Width", - event -> { - preview.setFitHorizontal(true); - preview.setFitVertical(false); - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - }); - - createIconButton(composite, "fit_vertical.png", "Fit Height", - event -> { - preview.setFitVertical(true); - preview.setFitHorizontal(false); - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - }); - - createIconButton(composite, "fit_best.png", "Fit Window", event -> { - preview.setFitVertical(true); - preview.setFitHorizontal(true); - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - }); - - createIconButton(composite, "zoom_in.gif", "Zoom In", event -> { - setPreviewScale(preview.getAbsoluteScale() * 1.1f); - }); - - createIconButton(composite, "zoom_out.gif", "Zoom Out", event -> { - setPreviewScale(preview.getAbsoluteScale() / 1.1f); - }); - - createIconButton(composite, "zoom_scale.gif", "Zoom to Scale", - event -> { - setPreviewScale(1); - }); - - createTextButton(composite, "Port", "Portrait Orientation", - event -> { - printJob.setOrientation( - PaperClips.ORIENTATION_PORTRAIT); - preview.setPrintJob(printJob); - - forgetScrollingPosition(); - updatePreviewSize(); - updatePageNumber(); - }); - - createTextButton(composite, "Land", "Landscape Orientation", - event -> { - printJob.setOrientation( - PaperClips.ORIENTATION_LANDSCAPE); - preview.setPrintJob(printJob); - - forgetScrollingPosition(); - updatePreviewSize(); - updatePageNumber(); - }); - - createIconButton(composite, "print.gif", "Print", event -> { - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - if (printerData != null) { - PaperClips.print(printJob, printerData); - preview.setPrinterData(printerData); - } - }); - - createLabel(composite, "Horz Pages"); - createPageCountSpinner(composite, event -> { - preview.setHorizontalPageCount( - ((Spinner) event.widget).getSelection()); - forgetScrollingPosition(); - updatePreviewSize(); - updatePageNumber(); - }); - - createLabel(composite, "Vert Pages"); - createPageCountSpinner(composite, event -> { - preview.setVerticalPageCount( - ((Spinner) event.widget).getSelection()); - forgetScrollingPosition(); - updatePreviewSize(); - updatePageNumber(); - }); - - return composite; - } - - private Control createScrollingPreview(Composite parent) { - scroll = new ScrolledComposite(parent, - SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); - scroll.setExpandHorizontal(true); - scroll.setExpandVertical(true); - - preview = new PrintPreview(scroll, SWT.NONE); - scroll.setContent(preview); - - scroll.addListener(SWT.Resize, event -> { - Rectangle bounds = scroll.getClientArea(); - - scroll.getHorizontalBar() - .setPageIncrement(bounds.width * 2 / 3); - scroll.getVerticalBar().setPageIncrement(bounds.height * 2 / 3); - - if (preview.isFitHorizontal() ^ preview.isFitVertical()) { - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - } - }); - - preview.setFitVertical(true); - preview.setFitHorizontal(true); - - Listener dragListener = new Listener() { - private final Point dpi = display.getDPI(); - private boolean scrollable = false; - - private boolean dragging = false; - private Point dragStartScrollOrigin = null; - private Point dragStartMouseAnchor = null; - - public void handleEvent(Event event) { - switch (event.type) { - case SWT.Resize: - forgetScrollingPosition(); - Rectangle bounds = scroll.getClientArea(); - Point size = preview.getSize(); - scrollable = size.x > bounds.width - || size.y > bounds.height; - if (!scrollable && dragging) - endDragging(); - break; - case SWT.MouseDown: - forgetScrollingPosition(); - if (scrollable && event.button == 1) - beginDragging(event); - break; - case SWT.MouseMove: - if (dragging) { - forgetScrollingPosition(); - Point point = preview.toDisplay(event.x, event.y); - scroll.setOrigin( - dragStartScrollOrigin.x - + dragStartMouseAnchor.x - point.x, - dragStartScrollOrigin.y - + dragStartMouseAnchor.y - point.y); - } - break; - case SWT.MouseUp: - forgetScrollingPosition(); - if (dragging) - endDragging(); - break; - case SWT.MouseEnter: - display.addFilter(SWT.MouseWheel, this); - break; - case SWT.MouseWheel: - if (event.count != 0) { - if (scrollable && !dragging - && (event.stateMask == SWT.NONE - || event.stateMask == SWT.SHIFT)) { - forgetScrollingPosition(); - bounds = scroll.getClientArea(); - size = preview.getSize(); - Point origin = scroll.getOrigin(); - int direction = event.count > 0 ? -1 : 1; - // Prefer vertical scrolling unless user is - // pressing Shift - if (size.y > bounds.height - && event.stateMask == SWT.NONE) - origin.y += direction * Math.min(dpi.y, - bounds.height / 4); - else if (size.x > bounds.width) - origin.x += direction - * Math.min(dpi.x, bounds.width / 4); - scroll.setOrigin(origin); - event.doit = false; - } else if (event.stateMask == SWT.CTRL) { // Ctrl+MouseWheel - // -> - // zoom - float scale = preview.getAbsoluteScale(); - setPreviewScale(event.count > 0 ? scale / 1.1f - : scale * 1.1f); - } - } - break; - case SWT.MouseExit: - display.removeFilter(SWT.MouseWheel, this); - break; - } - } - - private void beginDragging(Event event) { - dragStartScrollOrigin = scroll.getOrigin(); - dragStartMouseAnchor = preview.toDisplay(event.x, event.y); - dragging = true; - } - - private void endDragging() { - dragging = false; - dragStartMouseAnchor = null; - dragStartScrollOrigin = null; - } - }; - - scroll.addListener(SWT.Resize, dragListener); - preview.addListener(SWT.MouseDown, dragListener); - preview.addListener(SWT.MouseMove, dragListener); - preview.addListener(SWT.MouseUp, dragListener); - - // These are for mouse wheel handling - preview.addListener(SWT.MouseEnter, dragListener); - preview.addListener(SWT.MouseExit, dragListener); - - return scroll; - } - - private Button createIconButton(Composite parent, String imageFilename, - String toolTipText, Listener selectionListener) { - Button button = createButton(parent, toolTipText, - selectionListener); - button.setImage(createImage(imageFilename)); - return button; - } - - private Button createTextButton(Composite parent, String text, - String toolTipText, Listener selectionListener) { - Button button = createButton(parent, toolTipText, - selectionListener); - button.setText(text); - return button; - } - - private Button createButton(Composite parent, String toolTipText, - Listener selectionListener) { - Button button = new Button(parent, SWT.PUSH); - button.setToolTipText(toolTipText); - button.setLayoutData( - new GridData(SWT.FILL, SWT.FILL, false, false)); - button.addListener(SWT.Selection, selectionListener); - return button; - } - - private Spinner createPageCountSpinner(Composite parent, - Listener selectionListener) { - Spinner spinner = new Spinner(parent, SWT.BORDER); - spinner.setMinimum(1); - spinner.setMaximum(99); - spinner.addListener(SWT.Selection, selectionListener); - return spinner; - } - - private void createLabel(Composite parent, String text) { - new Label(parent, SWT.NONE).setText(text); - } - - private Image createImage(String filename) { - final Image image = new Image(display, - getClass().getResourceAsStream(filename)); - - shell.addListener(SWT.Dispose, new Listener() { - public void handleEvent(Event event) { - image.dispose(); - } - }); - - return image; - } - - private void updatePageNumber() { - int pageIndex = preview.getPageIndex(); - int pageCount = preview.getPageCount(); - int visiblePages = preview.getHorizontalPageCount() - * preview.getVerticalPageCount(); - boolean layoutComplete = preview.isPageLayoutComplete(); - String text = (visiblePages > 1 - ? "Pages " + (pageIndex + 1) + "-" - + Math.min(pageCount, pageIndex + visiblePages) - : "Page " + (pageIndex + 1)); - text += " of " + pageCount; - if (!layoutComplete) - text += ".."; - pageNumber.setText(text); - previousPage.setEnabled(pageIndex > 0); - nextPage.setEnabled( - pageIndex < pageCount - visiblePages || !layoutComplete); - shell.layout(new Control[] { pageNumber }); - } - - private void rememberScrollingPosition() { - Point size = preview.getSize(); - if (size.x == 0 || size.y == 0) { - forgetScrollingPosition(); - } else if (scrollingPosition == null) { - Point origin = scroll.getOrigin(); - scrollingPosition = new double[] { - (double) origin.x / (double) size.x, - (double) origin.y / (double) size.y }; - } - } - - private void forgetScrollingPosition() { - scrollingPosition = null; - } - - private void restoreScrollingPosition() { - if (scrollingPosition != null) { - Point size = preview.getSize(); - scroll.setOrigin( - (int) Math.round(scrollingPosition[0] * size.x), - (int) Math.round(scrollingPosition[1] * size.y)); - } - } - - private void updatePreviewSize() { - Point minSize; - Rectangle bounds = scroll.getClientArea(); - if (preview.isFitHorizontal()) { - if (preview.isFitVertical()) - minSize = new Point(0, 0); // Best fit - else - minSize = new Point(0, - preview.computeSize(bounds.width, SWT.DEFAULT).y); // Fit - // to - // width - } else { - if (preview.isFitVertical()) - minSize = new Point( - preview.computeSize(SWT.DEFAULT, bounds.height).x, - 0); // Fit to height - else - minSize = preview.computeSize(SWT.DEFAULT, SWT.DEFAULT); // Custom - // scale - } - scroll.setMinSize(minSize); - } - - private void setPreviewScale(float scale) { - preview.setFitVertical(false); - preview.setFitHorizontal(false); - preview.setScale(scale); - rememberScrollingPosition(); - updatePreviewSize(); - restoreScrollingPosition(); - } - - private void setPreviewPageIndex(int pageIndex) { - if (preview.isPageLayoutComplete()) - pageIndex = Math.min(pageIndex, - preview.getPageCount() - - preview.getHorizontalPageCount() - * preview.getVerticalPageCount()); - pageIndex = Math.max(pageIndex, 0); - preview.setPageIndex(pageIndex); - updatePageNumber(); - } - } - - /** - * Executes the snippet. - * - * @param args - * command-line args. - */ - public static void main(String[] args) { - final Display display = Display.getDefault(); - - Shell shell = new UI(display).createShell(); - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.page.PageNumber; +import org.eclipse.nebula.paperclips.core.page.PageNumberFormat; +import org.eclipse.nebula.paperclips.core.page.PageNumberPageDecoration; +import org.eclipse.nebula.paperclips.core.page.PagePrint; +import org.eclipse.nebula.paperclips.core.page.SimplePageDecoration; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Spinner; + +/** + * Demonstrate use of PrintPreview control. + * + * @author Matthew + */ +public class Snippet8 { + public static Print createPrint() { + DefaultGridLook look = new DefaultGridLook(); + look.setCellSpacing(5, 2); + GridPrint grid = new GridPrint("p:g, p:g, p:g, p:g, p:g", look); + + String text = "The quick brown fox jumps over the lazy dog."; + for (int i = 0; i < 20000; i++) + grid.add(new TextPrint(text)); + + PagePrint page = new PagePrint(grid); + page.setHeader(new SimplePageDecoration( + new TextPrint("Snippet8.java", SWT.CENTER))); + page.setHeaderGap(5); + page.setFooterGap(5); + PageNumberPageDecoration footer = new PageNumberPageDecoration( + SWT.CENTER); + footer.setFormat(new PageNumberFormat() { + public String format(PageNumber pageNumber) { + return "Page " + (pageNumber.getPageNumber() + 1); + } + }); + page.setFooter(footer); + + return page; + } + + private static class UI { + final Display display; + + PrintJob printJob; + + Shell shell; + Button previousPage; + Label pageNumber; + Button nextPage; + + ScrolledComposite scroll; + PrintPreview preview; + + double[] scrollingPosition; + + public UI(Display display) { + this.display = display; + } + + public Shell createShell() { + printJob = new PrintJob("Snippet8.java", createPrint()) + .setMargins(108); // 1.5" + + shell = new Shell(display); + shell.setText("Snippet8.java"); + shell.setBounds(100, 100, 800, 600); + shell.setLayout(new GridLayout(1, false)); + + createButtonPanel(shell).setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); + createScrollingPreview(shell).setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + preview.setLazyPageLayout(true); + preview.setPrintJob(printJob); + updatePreviewSize(); + updatePageNumber(); + preview.startBackgroundLayout(() -> { + updatePageNumber(); + }); + + shell.setVisible(true); + + return shell; + } + + private Control createButtonPanel(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + + GridLayout layout = new GridLayout(16, false); + layout.marginWidth = layout.marginHeight = 0; + composite.setLayout(layout); + + previousPage = createIconButton(composite, "previous_page.gif", + "Previous Page", event -> { + setPreviewPageIndex(preview.getPageIndex() + - preview.getHorizontalPageCount() + * preview.getVerticalPageCount()); + }); + + pageNumber = new Label(composite, SWT.NONE); + + nextPage = createIconButton(composite, "next_page.gif", "Next Page", + event -> { + setPreviewPageIndex(preview.getPageIndex() + + preview.getHorizontalPageCount() + * preview.getVerticalPageCount()); + }); + + createIconButton(composite, "fit_horizontal.png", "Fit Width", + event -> { + preview.setFitHorizontal(true); + preview.setFitVertical(false); + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + }); + + createIconButton(composite, "fit_vertical.png", "Fit Height", + event -> { + preview.setFitVertical(true); + preview.setFitHorizontal(false); + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + }); + + createIconButton(composite, "fit_best.png", "Fit Window", event -> { + preview.setFitVertical(true); + preview.setFitHorizontal(true); + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + }); + + createIconButton(composite, "zoom_in.gif", "Zoom In", event -> { + setPreviewScale(preview.getAbsoluteScale() * 1.1f); + }); + + createIconButton(composite, "zoom_out.gif", "Zoom Out", event -> { + setPreviewScale(preview.getAbsoluteScale() / 1.1f); + }); + + createIconButton(composite, "zoom_scale.gif", "Zoom to Scale", + event -> { + setPreviewScale(1); + }); + + createTextButton(composite, "Port", "Portrait Orientation", + event -> { + printJob.setOrientation( + PaperClips.ORIENTATION_PORTRAIT); + preview.setPrintJob(printJob); + + forgetScrollingPosition(); + updatePreviewSize(); + updatePageNumber(); + }); + + createTextButton(composite, "Land", "Landscape Orientation", + event -> { + printJob.setOrientation( + PaperClips.ORIENTATION_LANDSCAPE); + preview.setPrintJob(printJob); + + forgetScrollingPosition(); + updatePreviewSize(); + updatePageNumber(); + }); + + createIconButton(composite, "print.gif", "Print", event -> { + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + if (printerData != null) { + PaperClips.print(printJob, printerData); + preview.setPrinterData(printerData); + } + }); + + createLabel(composite, "Horz Pages"); + createPageCountSpinner(composite, event -> { + preview.setHorizontalPageCount( + ((Spinner) event.widget).getSelection()); + forgetScrollingPosition(); + updatePreviewSize(); + updatePageNumber(); + }); + + createLabel(composite, "Vert Pages"); + createPageCountSpinner(composite, event -> { + preview.setVerticalPageCount( + ((Spinner) event.widget).getSelection()); + forgetScrollingPosition(); + updatePreviewSize(); + updatePageNumber(); + }); + + return composite; + } + + private Control createScrollingPreview(Composite parent) { + scroll = new ScrolledComposite(parent, + SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); + scroll.setExpandHorizontal(true); + scroll.setExpandVertical(true); + + preview = new PrintPreview(scroll, SWT.NONE); + scroll.setContent(preview); + + scroll.addListener(SWT.Resize, event -> { + Rectangle bounds = scroll.getClientArea(); + + scroll.getHorizontalBar() + .setPageIncrement(bounds.width * 2 / 3); + scroll.getVerticalBar().setPageIncrement(bounds.height * 2 / 3); + + if (preview.isFitHorizontal() ^ preview.isFitVertical()) { + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + } + }); + + preview.setFitVertical(true); + preview.setFitHorizontal(true); + + Listener dragListener = new Listener() { + private final Point dpi = display.getDPI(); + private boolean scrollable = false; + + private boolean dragging = false; + private Point dragStartScrollOrigin = null; + private Point dragStartMouseAnchor = null; + + public void handleEvent(Event event) { + switch (event.type) { + case SWT.Resize: + forgetScrollingPosition(); + Rectangle bounds = scroll.getClientArea(); + Point size = preview.getSize(); + scrollable = size.x > bounds.width + || size.y > bounds.height; + if (!scrollable && dragging) + endDragging(); + break; + case SWT.MouseDown: + forgetScrollingPosition(); + if (scrollable && event.button == 1) + beginDragging(event); + break; + case SWT.MouseMove: + if (dragging) { + forgetScrollingPosition(); + Point point = preview.toDisplay(event.x, event.y); + scroll.setOrigin( + dragStartScrollOrigin.x + + dragStartMouseAnchor.x - point.x, + dragStartScrollOrigin.y + + dragStartMouseAnchor.y - point.y); + } + break; + case SWT.MouseUp: + forgetScrollingPosition(); + if (dragging) + endDragging(); + break; + case SWT.MouseEnter: + display.addFilter(SWT.MouseWheel, this); + break; + case SWT.MouseWheel: + if (event.count != 0) { + if (scrollable && !dragging + && (event.stateMask == SWT.NONE + || event.stateMask == SWT.SHIFT)) { + forgetScrollingPosition(); + bounds = scroll.getClientArea(); + size = preview.getSize(); + Point origin = scroll.getOrigin(); + int direction = event.count > 0 ? -1 : 1; + // Prefer vertical scrolling unless user is + // pressing Shift + if (size.y > bounds.height + && event.stateMask == SWT.NONE) + origin.y += direction * Math.min(dpi.y, + bounds.height / 4); + else if (size.x > bounds.width) + origin.x += direction + * Math.min(dpi.x, bounds.width / 4); + scroll.setOrigin(origin); + event.doit = false; + } else if (event.stateMask == SWT.CTRL) { // Ctrl+MouseWheel + // -> + // zoom + float scale = preview.getAbsoluteScale(); + setPreviewScale(event.count > 0 ? scale / 1.1f + : scale * 1.1f); + } + } + break; + case SWT.MouseExit: + display.removeFilter(SWT.MouseWheel, this); + break; + } + } + + private void beginDragging(Event event) { + dragStartScrollOrigin = scroll.getOrigin(); + dragStartMouseAnchor = preview.toDisplay(event.x, event.y); + dragging = true; + } + + private void endDragging() { + dragging = false; + dragStartMouseAnchor = null; + dragStartScrollOrigin = null; + } + }; + + scroll.addListener(SWT.Resize, dragListener); + preview.addListener(SWT.MouseDown, dragListener); + preview.addListener(SWT.MouseMove, dragListener); + preview.addListener(SWT.MouseUp, dragListener); + + // These are for mouse wheel handling + preview.addListener(SWT.MouseEnter, dragListener); + preview.addListener(SWT.MouseExit, dragListener); + + return scroll; + } + + private Button createIconButton(Composite parent, String imageFilename, + String toolTipText, Listener selectionListener) { + Button button = createButton(parent, toolTipText, + selectionListener); + button.setImage(createImage(imageFilename)); + return button; + } + + private Button createTextButton(Composite parent, String text, + String toolTipText, Listener selectionListener) { + Button button = createButton(parent, toolTipText, + selectionListener); + button.setText(text); + return button; + } + + private Button createButton(Composite parent, String toolTipText, + Listener selectionListener) { + Button button = new Button(parent, SWT.PUSH); + button.setToolTipText(toolTipText); + button.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, false, false)); + button.addListener(SWT.Selection, selectionListener); + return button; + } + + private Spinner createPageCountSpinner(Composite parent, + Listener selectionListener) { + Spinner spinner = new Spinner(parent, SWT.BORDER); + spinner.setMinimum(1); + spinner.setMaximum(99); + spinner.addListener(SWT.Selection, selectionListener); + return spinner; + } + + private void createLabel(Composite parent, String text) { + new Label(parent, SWT.NONE).setText(text); + } + + private Image createImage(String filename) { + final Image image = new Image(display, + getClass().getResourceAsStream(filename)); + + shell.addListener(SWT.Dispose, new Listener() { + public void handleEvent(Event event) { + image.dispose(); + } + }); + + return image; + } + + private void updatePageNumber() { + int pageIndex = preview.getPageIndex(); + int pageCount = preview.getPageCount(); + int visiblePages = preview.getHorizontalPageCount() + * preview.getVerticalPageCount(); + boolean layoutComplete = preview.isPageLayoutComplete(); + String text = (visiblePages > 1 + ? "Pages " + (pageIndex + 1) + "-" + + Math.min(pageCount, pageIndex + visiblePages) + : "Page " + (pageIndex + 1)); + text += " of " + pageCount; + if (!layoutComplete) + text += ".."; + pageNumber.setText(text); + previousPage.setEnabled(pageIndex > 0); + nextPage.setEnabled( + pageIndex < pageCount - visiblePages || !layoutComplete); + shell.layout(new Control[] { pageNumber }); + } + + private void rememberScrollingPosition() { + Point size = preview.getSize(); + if (size.x == 0 || size.y == 0) { + forgetScrollingPosition(); + } else if (scrollingPosition == null) { + Point origin = scroll.getOrigin(); + scrollingPosition = new double[] { + (double) origin.x / (double) size.x, + (double) origin.y / (double) size.y }; + } + } + + private void forgetScrollingPosition() { + scrollingPosition = null; + } + + private void restoreScrollingPosition() { + if (scrollingPosition != null) { + Point size = preview.getSize(); + scroll.setOrigin( + (int) Math.round(scrollingPosition[0] * size.x), + (int) Math.round(scrollingPosition[1] * size.y)); + } + } + + private void updatePreviewSize() { + Point minSize; + Rectangle bounds = scroll.getClientArea(); + if (preview.isFitHorizontal()) { + if (preview.isFitVertical()) + minSize = new Point(0, 0); // Best fit + else + minSize = new Point(0, + preview.computeSize(bounds.width, SWT.DEFAULT).y); // Fit + // to + // width + } else { + if (preview.isFitVertical()) + minSize = new Point( + preview.computeSize(SWT.DEFAULT, bounds.height).x, + 0); // Fit to height + else + minSize = preview.computeSize(SWT.DEFAULT, SWT.DEFAULT); // Custom + // scale + } + scroll.setMinSize(minSize); + } + + private void setPreviewScale(float scale) { + preview.setFitVertical(false); + preview.setFitHorizontal(false); + preview.setScale(scale); + rememberScrollingPosition(); + updatePreviewSize(); + restoreScrollingPosition(); + } + + private void setPreviewPageIndex(int pageIndex) { + if (preview.isPageLayoutComplete()) + pageIndex = Math.min(pageIndex, + preview.getPageCount() + - preview.getHorizontalPageCount() + * preview.getVerticalPageCount()); + pageIndex = Math.max(pageIndex, 0); + preview.setPageIndex(pageIndex); + updatePageNumber(); + } + } + + /** + * Executes the snippet. + * + * @param args + * command-line args. + */ + public static void main(String[] args) { + final Display display = Display.getDefault(); + + Shell shell = new UI(display).createShell(); + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/StyledTextPrintExample.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/StyledTextPrintExample.java index 31f4f1242..b6c0dd057 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/StyledTextPrintExample.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/StyledTextPrintExample.java @@ -1,157 +1,157 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.ImagePrint; -import org.eclipse.nebula.paperclips.core.LinePrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.text.StyledTextPrint; -import org.eclipse.nebula.paperclips.core.text.TextStyle; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Demonstrates use of the StyledTextPrint class. - * - * @author Matthew - */ -public class StyledTextPrintExample { - /** - * Executes the StyledTextPrint example. - * - * @param args - * the command line arguments. - */ - public static void main(String[] args) { - final Display display = new Display(); - - final Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setText("StyledTextPrintExample.java"); - shell.setLayout(new GridLayout()); - shell.setSize(600, 800); - - final PrintJob job = new PrintJob("StyledTextPrintExample.java", - createPrint()); - - Composite buttonPanel = new Composite(shell, SWT.NONE); - buttonPanel - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - buttonPanel.setLayout(new RowLayout(SWT.HORIZONTAL)); - - final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); - - Button prev = new Button(buttonPanel, SWT.PUSH); - prev.setText("<< Prev"); - prev.addListener(SWT.Selection, event -> { - preview.setPageIndex(Math.max(preview.getPageIndex() - 1, 0)); - }); - - Button next = new Button(buttonPanel, SWT.PUSH); - next.setText("Next >>"); - next.addListener(SWT.Selection, event -> { - preview.setPageIndex(Math.min(preview.getPageIndex() + 1, - preview.getPageCount() - 1)); - }); - - Button print = new Button(buttonPanel, SWT.PUSH); - print.setText("Print"); - print.addListener(SWT.Selection, event -> { - PrintDialog dialog = new PrintDialog(shell); - PrinterData printerData = dialog.open(); - if (printerData != null) - PaperClips.print(job, printerData); - }); - - preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - preview.setFitHorizontal(true); - preview.setFitVertical(true); - preview.setPrintJob(job); - - shell.open(); - - while (!shell.isDisposed()) - if (!display.readAndDispatch()) - display.sleep(); - - display.dispose(); - } - - public static Print createPrint() { - StyledTextPrint doc = new StyledTextPrint(); - - TextStyle normal = new TextStyle().font("Arial", 14, SWT.NORMAL); - TextStyle bold = normal.fontStyle(SWT.BOLD); - TextStyle big = normal.fontHeight(20); - TextStyle italic = normal.fontStyle(SWT.ITALIC); - TextStyle monospace = normal.fontName("Courier"); - TextStyle underline = normal.underline(); - TextStyle strikeout = normal.strikeout(); - - doc.setStyle(normal).append("This snippet demonstrates the use of ") - .append("StyledTextPrint", monospace) - .append(" for creating bodies of styled text.").newline() - .newline().append("StyledTextPrint", monospace) - .append(" makes sure that ").append("text ", bold) - .append("of ", italic) - .append("different ", normal.fontHeight(20)) - .append("font ", normal.fontHeight(42)) - .append("names,", normal.fontName("Courier")) - .append(" sizes, ", normal.fontHeight(10)).append("and ") - .append("styles", normal.underline()) - .append(" are aligned correctly along the base line.").newline() - .newline().append("With ").append("StyledTextPrint", monospace) - .append(" you can embed any other printable element alongside the text. ") - .append("For example, here is an image ") - .append(createSampleImage()).append(" and a horizontal line") - .append(new LinePrint(SWT.HORIZONTAL)).newline() - .setStyle(italic) - .append("Note that some elements like GridPrint tend to be broken unnaturally across lines, and " - + "therefore may not be suitable for use in a StyledTextPrint.") - .setStyle(normal).newline().newline() - .append("Many text styles are possible such as ") - .append("bold print", bold).append(", ") - .append("italic print", italic).append(", ") - .append("strikeout text", strikeout).append(", ") - .append("underlined text", underline).append(", or ") - .append("any combination of the above", - normal.fontStyle(SWT.BOLD | SWT.ITALIC).strikeout() - .underline()) - .append(".").newline().newline().append("You can also set ") - .append("foreground colors", normal.foreground(0x00A000)) - .append(" or ") - .append("background colors", normal.background(0xFFFFA0)) - .append(" on the text through the TextStyle class.").newline() - .newline().append("Enjoy!", big); - return doc; - } - - private static ImagePrint createSampleImage() { - return new ImagePrint(new ImageData( - StyledTextPrintExample.class.getResourceAsStream("sp.png")), - new Point(600, 600)); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.ImagePrint; +import org.eclipse.nebula.paperclips.core.LinePrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.text.StyledTextPrint; +import org.eclipse.nebula.paperclips.core.text.TextStyle; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * Demonstrates use of the StyledTextPrint class. + * + * @author Matthew + */ +public class StyledTextPrintExample { + /** + * Executes the StyledTextPrint example. + * + * @param args + * the command line arguments. + */ + public static void main(String[] args) { + final Display display = new Display(); + + final Shell shell = new Shell(display, SWT.SHELL_TRIM); + shell.setText("StyledTextPrintExample.java"); + shell.setLayout(new GridLayout()); + shell.setSize(600, 800); + + final PrintJob job = new PrintJob("StyledTextPrintExample.java", + createPrint()); + + Composite buttonPanel = new Composite(shell, SWT.NONE); + buttonPanel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + buttonPanel.setLayout(new RowLayout(SWT.HORIZONTAL)); + + final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); + + Button prev = new Button(buttonPanel, SWT.PUSH); + prev.setText("<< Prev"); + prev.addListener(SWT.Selection, event -> { + preview.setPageIndex(Math.max(preview.getPageIndex() - 1, 0)); + }); + + Button next = new Button(buttonPanel, SWT.PUSH); + next.setText("Next >>"); + next.addListener(SWT.Selection, event -> { + preview.setPageIndex(Math.min(preview.getPageIndex() + 1, + preview.getPageCount() - 1)); + }); + + Button print = new Button(buttonPanel, SWT.PUSH); + print.setText("Print"); + print.addListener(SWT.Selection, event -> { + PrintDialog dialog = new PrintDialog(shell); + PrinterData printerData = dialog.open(); + if (printerData != null) + PaperClips.print(job, printerData); + }); + + preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + preview.setFitHorizontal(true); + preview.setFitVertical(true); + preview.setPrintJob(job); + + shell.open(); + + while (!shell.isDisposed()) + if (!display.readAndDispatch()) + display.sleep(); + + display.dispose(); + } + + public static Print createPrint() { + StyledTextPrint doc = new StyledTextPrint(); + + TextStyle normal = new TextStyle().font("Arial", 14, SWT.NORMAL); + TextStyle bold = normal.fontStyle(SWT.BOLD); + TextStyle big = normal.fontHeight(20); + TextStyle italic = normal.fontStyle(SWT.ITALIC); + TextStyle monospace = normal.fontName("Courier"); + TextStyle underline = normal.underline(); + TextStyle strikeout = normal.strikeout(); + + doc.setStyle(normal).append("This snippet demonstrates the use of ") + .append("StyledTextPrint", monospace) + .append(" for creating bodies of styled text.").newline() + .newline().append("StyledTextPrint", monospace) + .append(" makes sure that ").append("text ", bold) + .append("of ", italic) + .append("different ", normal.fontHeight(20)) + .append("font ", normal.fontHeight(42)) + .append("names,", normal.fontName("Courier")) + .append(" sizes, ", normal.fontHeight(10)).append("and ") + .append("styles", normal.underline()) + .append(" are aligned correctly along the base line.").newline() + .newline().append("With ").append("StyledTextPrint", monospace) + .append(" you can embed any other printable element alongside the text. ") + .append("For example, here is an image ") + .append(createSampleImage()).append(" and a horizontal line") + .append(new LinePrint(SWT.HORIZONTAL)).newline() + .setStyle(italic) + .append("Note that some elements like GridPrint tend to be broken unnaturally across lines, and " + + "therefore may not be suitable for use in a StyledTextPrint.") + .setStyle(normal).newline().newline() + .append("Many text styles are possible such as ") + .append("bold print", bold).append(", ") + .append("italic print", italic).append(", ") + .append("strikeout text", strikeout).append(", ") + .append("underlined text", underline).append(", or ") + .append("any combination of the above", + normal.fontStyle(SWT.BOLD | SWT.ITALIC).strikeout() + .underline()) + .append(".").newline().newline().append("You can also set ") + .append("foreground colors", normal.foreground(0x00A000)) + .append(" or ") + .append("background colors", normal.background(0xFFFFA0)) + .append(" on the text through the TextStyle class.").newline() + .newline().append("Enjoy!", big); + return doc; + } + + private static ImagePrint createSampleImage() { + return new ImagePrint(new ImageData( + StyledTextPrintExample.class.getResourceAsStream("sp.png")), + new Point(600, 600)); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/TutorialExample1.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/TutorialExample1.java index c8b9965be..47aed6a10 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/TutorialExample1.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/TutorialExample1.java @@ -1,54 +1,54 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.swt.SWT; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * First example in the PaperClips online tutorial. - */ -public class TutorialExample1 { - /** - * Prints the words, "Hello PaperClips!" - * - * @param args - * command-line arguments. - */ - public static void main(String[] args) { - // Create the document - TextPrint text = new TextPrint("Hello PaperClips!"); - - // Show the print dialog - Display display = new Display(); - Shell shell = new Shell(display); - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - shell.dispose(); - display.dispose(); - - // Print the document to the printer the user selected. - if (printerData != null) { - PrintJob job = new PrintJob("TutorialExample1.java", text); - job.setMargins(72); - PaperClips.print(job, printerData); - } - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.swt.SWT; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * First example in the PaperClips online tutorial. + */ +public class TutorialExample1 { + /** + * Prints the words, "Hello PaperClips!" + * + * @param args + * command-line arguments. + */ + public static void main(String[] args) { + // Create the document + TextPrint text = new TextPrint("Hello PaperClips!"); + + // Show the print dialog + Display display = new Display(); + Shell shell = new Shell(display); + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + shell.dispose(); + display.dispose(); + + // Print the document to the printer the user selected. + if (printerData != null) { + PrintJob job = new PrintJob("TutorialExample1.java", text); + job.setMargins(72); + PaperClips.print(job, printerData); + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/TutorialExample2.java b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/TutorialExample2.java index 25611e6d8..93244dfe7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/TutorialExample2.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.snippets/src/org/eclipse/nebula/paperclips/snippets/TutorialExample2.java @@ -1,85 +1,85 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.snippets; - -import org.eclipse.nebula.paperclips.core.LinePrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.swt.SWT; -import org.eclipse.swt.printing.PrintDialog; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * First example in the PaperClips online tutorial. - */ -public class TutorialExample2 { - public static Print createPrint() { - // Create a grid with the following columns: - // Column 1: preferred width - // Column 2: preferred width, grows to fill excess width - // (The 5 is the grid spacing, in points. 72 points = 1".) - - GridPrint grid = new GridPrint("p, d:g", new DefaultGridLook(5, 5)); - - // Now populate the grid with the text and lines - grid.add(SWT.CENTER, new TextPrint("VITAL STATISTICS"), - GridPrint.REMAINDER); - - grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); - - grid.add(new TextPrint("Name:")); - grid.add(new TextPrint("Matthew Hall")); - grid.add(new TextPrint("Occupation:")); - grid.add(new TextPrint("Programmer")); - grid.add(new TextPrint("Eyes:")); - grid.add(new TextPrint("Blue")); - grid.add(new TextPrint("Gender:")); - grid.add(new TextPrint("Male")); - grid.add(new TextPrint("Spouse:")); - grid.add(new TextPrint("Sexy")); - - grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); - - return grid; - } - - /** - * Prints a table of vital (haha) statistics about Matthew Hall. - * - * @param args - * command-line parameters - */ - public static void main(String[] args) { - // Show the print dialog - Display display = new Display(); - Shell shell = new Shell(display); - PrintDialog dialog = new PrintDialog(shell, SWT.NONE); - PrinterData printerData = dialog.open(); - shell.dispose(); - display.dispose(); - - // Print the document to the printer the user selected. - if (printerData != null) { - PrintJob job = new PrintJob("TutorialExample2.java", createPrint()); - job.setMargins(72); - PaperClips.print(job, printerData); - } - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.snippets; + +import org.eclipse.nebula.paperclips.core.LinePrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.swt.SWT; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * First example in the PaperClips online tutorial. + */ +public class TutorialExample2 { + public static Print createPrint() { + // Create a grid with the following columns: + // Column 1: preferred width + // Column 2: preferred width, grows to fill excess width + // (The 5 is the grid spacing, in points. 72 points = 1".) + + GridPrint grid = new GridPrint("p, d:g", new DefaultGridLook(5, 5)); + + // Now populate the grid with the text and lines + grid.add(SWT.CENTER, new TextPrint("VITAL STATISTICS"), + GridPrint.REMAINDER); + + grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); + + grid.add(new TextPrint("Name:")); + grid.add(new TextPrint("Matthew Hall")); + grid.add(new TextPrint("Occupation:")); + grid.add(new TextPrint("Programmer")); + grid.add(new TextPrint("Eyes:")); + grid.add(new TextPrint("Blue")); + grid.add(new TextPrint("Gender:")); + grid.add(new TextPrint("Male")); + grid.add(new TextPrint("Spouse:")); + grid.add(new TextPrint("Sexy")); + + grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); + + return grid; + } + + /** + * Prints a table of vital (haha) statistics about Matthew Hall. + * + * @param args + * command-line parameters + */ + public static void main(String[] args) { + // Show the print dialog + Display display = new Display(); + Shell shell = new Shell(display); + PrintDialog dialog = new PrintDialog(shell, SWT.NONE); + PrinterData printerData = dialog.open(); + shell.dispose(); + display.dispose(); + + // Print the document to the printer the user selected. + if (printerData != null) { + PrintJob job = new PrintJob("TutorialExample2.java", createPrint()); + job.setMargins(72); + PaperClips.print(job, printerData); + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.classpath b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.classpath index de69eecf5..414aa5912 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.classpath +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.classpath @@ -1,11 +1,11 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.project b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.project index e5798b80e..b8535f16e 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.project +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.paperclips.tests - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.paperclips.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.settings/org.eclipse.jdt.core.prefs b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.settings/org.eclipse.jdt.core.prefs index 4ca9b1aa6..94b6c5433 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.settings/org.eclipse.jdt.core.prefs @@ -1,296 +1,296 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true -org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true -org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true -org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true -org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true +org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true +org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true +org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true +org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.settings/org.eclipse.jdt.ui.prefs b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.settings/org.eclipse.jdt.ui.prefs index 5cbd82f97..f0200ff5e 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.settings/org.eclipse.jdt.ui.prefs +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/.settings/org.eclipse.jdt.ui.prefs @@ -1,53 +1,53 @@ -#Tue Aug 11 15:07:02 MDT 2009 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile -formatter_settings_version=11 -internal.default.compliance=default -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.format_source_code=true -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=true -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +#Tue Aug 11 15:07:02 MDT 2009 +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile +formatter_settings_version=11 +internal.default.compliance=default +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.format_source_code=true +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=true +sp_cleanup.remove_unused_imports=true +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/META-INF/MANIFEST.MF b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/META-INF/MANIFEST.MF index 0116f5759..95340dee4 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/META-INF/MANIFEST.MF +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Paperclips Tests -Bundle-SymbolicName: org.eclipse.nebula.paperclips.tests -Bundle-Version: 2.1.0.qualifier -Require-Bundle: org.eclipse.nebula.paperclips.core;bundle-version="[2.0.0,3.0.0)", - org.eclipse.nebula.paperclips.snippets;bundle-version="[2.0.0,3.0.0)", - org.eclipse.nebula.paperclips.widgets;bundle-version="[2.0.0,3.0.0)", - org.eclipse.swt;bundle-version="[3.2.0,4.0.0)", - org.junit;bundle-version="[3.8.2,5.0.0)" -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Export-Package: org.eclipse.nebula.paperclips.tests.benchmark -Bundle-Vendor: Eclipse Nebula -Automatic-Module-Name: org.eclipse.nebula.paperclips.tests +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Paperclips Tests +Bundle-SymbolicName: org.eclipse.nebula.paperclips.tests +Bundle-Version: 2.1.0.qualifier +Require-Bundle: org.eclipse.nebula.paperclips.core;bundle-version="[2.0.0,3.0.0)", + org.eclipse.nebula.paperclips.snippets;bundle-version="[2.0.0,3.0.0)", + org.eclipse.nebula.paperclips.widgets;bundle-version="[2.0.0,3.0.0)", + org.eclipse.swt;bundle-version="[3.2.0,4.0.0)", + org.junit;bundle-version="[3.8.2,5.0.0)" +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Export-Package: org.eclipse.nebula.paperclips.tests.benchmark +Bundle-Vendor: Eclipse Nebula +Automatic-Module-Name: org.eclipse.nebula.paperclips.tests diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/build.properties b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/build.properties index a12d47e56..b107977f4 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/build.properties +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/build.properties @@ -1,3 +1,3 @@ -source.. = src/ -bin.includes = META-INF/,\ - . +source.. = src/ +bin.includes = META-INF/,\ + . diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/AlignPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/AlignPrintTest.java index 32073fa47..a112947d9 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/AlignPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/AlignPrintTest.java @@ -1,51 +1,51 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.AlignPrint; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; - -public class AlignPrintTest extends TestCase { - public void testConstructor_nullArgument() { - try { - new AlignPrint(null, SWT.DEFAULT, SWT.DEFAULT); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - } - } - - public void testConstructor_applyDefaultAlignments() { - AlignPrint print = new AlignPrint(new PrintStub(), SWT.DEFAULT, - SWT.DEFAULT); - Point alignment = print.getAlignment(); - assertEquals(SWT.LEFT, alignment.x); - assertEquals(SWT.TOP, alignment.y); - } - - public void testEquals() { - AlignPrint print = new AlignPrint(new PrintStub(0), SWT.CENTER, - SWT.BOTTOM); - assertEquals(print, new AlignPrint(new PrintStub(0), SWT.CENTER, - SWT.BOTTOM)); - assertFalse(print.equals(new AlignPrint(new PrintStub(1), SWT.DEFAULT, - SWT.DEFAULT))); - assertFalse(print.equals(new AlignPrint(new PrintStub(0), SWT.CENTER, - SWT.DEFAULT))); - assertFalse(print.equals(new AlignPrint(new PrintStub(0), SWT.DEFAULT, - SWT.CENTER))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.AlignPrint; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; + +public class AlignPrintTest extends TestCase { + public void testConstructor_nullArgument() { + try { + new AlignPrint(null, SWT.DEFAULT, SWT.DEFAULT); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + public void testConstructor_applyDefaultAlignments() { + AlignPrint print = new AlignPrint(new PrintStub(), SWT.DEFAULT, + SWT.DEFAULT); + Point alignment = print.getAlignment(); + assertEquals(SWT.LEFT, alignment.x); + assertEquals(SWT.TOP, alignment.y); + } + + public void testEquals() { + AlignPrint print = new AlignPrint(new PrintStub(0), SWT.CENTER, + SWT.BOTTOM); + assertEquals(print, new AlignPrint(new PrintStub(0), SWT.CENTER, + SWT.BOTTOM)); + assertFalse(print.equals(new AlignPrint(new PrintStub(1), SWT.DEFAULT, + SWT.DEFAULT))); + assertFalse(print.equals(new AlignPrint(new PrintStub(0), SWT.CENTER, + SWT.DEFAULT))); + assertFalse(print.equals(new AlignPrint(new PrintStub(0), SWT.DEFAULT, + SWT.CENTER))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BackgroundPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BackgroundPrintTest.java index 37a90e5d4..867ac1753 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BackgroundPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BackgroundPrintTest.java @@ -1,47 +1,47 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.BackgroundPrint; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.swt.graphics.RGB; - -public class BackgroundPrintTest extends TestCase { - public void testConstructor_nullArguments() { - try { - new BackgroundPrint(null, new RGB(0, 0, 0)); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - } - - try { - new BackgroundPrint(new PrintStub(), null); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - } - } - - public void testEquals() { - Print background = new BackgroundPrint(new PrintStub(0), new RGB(0, 0, - 0)); - assertEquals(background, new BackgroundPrint(new PrintStub(0), new RGB( - 0, 0, 0))); - assertFalse(background.equals(new BackgroundPrint(new PrintStub(1), - new RGB(0, 0, 0)))); - assertFalse(background.equals(new BackgroundPrint(new PrintStub(0), - new RGB(1, 1, 1)))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.BackgroundPrint; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.swt.graphics.RGB; + +public class BackgroundPrintTest extends TestCase { + public void testConstructor_nullArguments() { + try { + new BackgroundPrint(null, new RGB(0, 0, 0)); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + + try { + new BackgroundPrint(new PrintStub(), null); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + public void testEquals() { + Print background = new BackgroundPrint(new PrintStub(0), new RGB(0, 0, + 0)); + assertEquals(background, new BackgroundPrint(new PrintStub(0), new RGB( + 0, 0, 0))); + assertFalse(background.equals(new BackgroundPrint(new PrintStub(1), + new RGB(0, 0, 0)))); + assertFalse(background.equals(new BackgroundPrint(new PrintStub(0), + new RGB(1, 1, 1)))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BigPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BigPrintTest.java index 924059f95..e228af0a1 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BigPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BigPrintTest.java @@ -1,35 +1,35 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.BigPrint; -import org.eclipse.nebula.paperclips.core.Print; - -import junit.framework.TestCase; - -public class BigPrintTest extends TestCase { - public void testConstructor_nullArgument() { - try { - new BigPrint(null); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - public void testEquals() { - Print print = new BigPrint(new PrintStub(0)); - assertEquals(print, new BigPrint(new PrintStub(0))); - assertFalse(print.equals(new BigPrint(new PrintStub(1)))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.BigPrint; +import org.eclipse.nebula.paperclips.core.Print; + +import junit.framework.TestCase; + +public class BigPrintTest extends TestCase { + public void testConstructor_nullArgument() { + try { + new BigPrint(null); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testEquals() { + Print print = new BigPrint(new PrintStub(0)); + assertEquals(print, new BigPrint(new PrintStub(0))); + assertFalse(print.equals(new BigPrint(new PrintStub(1)))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BorderPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BorderPrintTest.java index 3a822d179..a2c1d7729 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BorderPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BorderPrintTest.java @@ -1,49 +1,49 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.border.BorderPrint; - -import junit.framework.TestCase; - -public class BorderPrintTest extends TestCase { - public void testConstructor_nullArguments() { - try { - new BorderPrint(null, new BorderStub()); - fail(); - } catch (IllegalArgumentException expected) { - } - - try { - new BorderPrint(new PrintStub(), null); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - public void testEquals_equivalent() { - assertEquals(new BorderPrint(new PrintStub(), new BorderStub()), - new BorderPrint(new PrintStub(), new BorderStub())); - } - - public void testEquals_different() { - BorderPrint borderPrint = new BorderPrint(new PrintStub(0), - new BorderStub()); - assertFalse(borderPrint.equals(new BorderPrint(new PrintStub(1), - new BorderStub()))); - assertFalse(borderPrint.equals(new BorderPrint(new PrintStub(0), - new BorderStub() { - }))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.border.BorderPrint; + +import junit.framework.TestCase; + +public class BorderPrintTest extends TestCase { + public void testConstructor_nullArguments() { + try { + new BorderPrint(null, new BorderStub()); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + new BorderPrint(new PrintStub(), null); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testEquals_equivalent() { + assertEquals(new BorderPrint(new PrintStub(), new BorderStub()), + new BorderPrint(new PrintStub(), new BorderStub())); + } + + public void testEquals_different() { + BorderPrint borderPrint = new BorderPrint(new PrintStub(0), + new BorderStub()); + assertFalse(borderPrint.equals(new BorderPrint(new PrintStub(1), + new BorderStub()))); + assertFalse(borderPrint.equals(new BorderPrint(new PrintStub(0), + new BorderStub() { + }))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BorderStub.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BorderStub.java index c500f48f8..f84e9c3d3 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BorderStub.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BorderStub.java @@ -1,32 +1,32 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.border.Border; -import org.eclipse.nebula.paperclips.core.border.BorderPainter; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -@SuppressWarnings("restriction") -class BorderStub implements Border { - @Override - public boolean equals(Object obj) { - return Util.sameClass(this, obj); - } - - public BorderPainter createPainter(Device device, GC gc) { - return null; - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.border.Border; +import org.eclipse.nebula.paperclips.core.border.BorderPainter; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +@SuppressWarnings("restriction") +class BorderStub implements Border { + @Override + public boolean equals(Object obj) { + return Util.sameClass(this, obj); + } + + public BorderPainter createPainter(Device device, GC gc) { + return null; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BreakPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BreakPrintTest.java index 9038e2c4b..7baad1db8 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BreakPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/BreakPrintTest.java @@ -1,28 +1,28 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.BreakPrint; - -import junit.framework.TestCase; - -public class BreakPrintTest extends TestCase { - public void testEquals_equivalent() { - assertEquals(new BreakPrint(), new BreakPrint()); - } - - public void testEquals_different() { - assertFalse(new BreakPrint().equals(new PrintStub())); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.BreakPrint; + +import junit.framework.TestCase; + +public class BreakPrintTest extends TestCase { + public void testEquals_equivalent() { + assertEquals(new BreakPrint(), new BreakPrint()); + } + + public void testEquals_different() { + assertFalse(new BreakPrint().equals(new PrintStub())); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/CellBackgroundProviderStub.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/CellBackgroundProviderStub.java index a0d6a944d..fa222d511 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/CellBackgroundProviderStub.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/CellBackgroundProviderStub.java @@ -1,30 +1,30 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.grid.CellBackgroundProvider; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.RGB; - -@SuppressWarnings("restriction") -class CellBackgroundProviderStub implements CellBackgroundProvider { - @Override - public boolean equals(Object obj) { - return Util.sameClass(this, obj); - } - - public RGB getCellBackground(int row, int column, int colspan) { - return null; - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.grid.CellBackgroundProvider; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.RGB; + +@SuppressWarnings("restriction") +class CellBackgroundProviderStub implements CellBackgroundProvider { + @Override + public boolean equals(Object obj) { + return Util.sameClass(this, obj); + } + + public RGB getCellBackground(int row, int column, int colspan) { + return null; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ColumnPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ColumnPrintTest.java index 960d60edb..4c3b1c4e7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ColumnPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ColumnPrintTest.java @@ -1,53 +1,53 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.ColumnPrint; - -import junit.framework.TestCase; - -public class ColumnPrintTest extends TestCase { - public void testConstructor_invalidArguments() { - try { - new ColumnPrint(null, 2, 0, true); - fail(); - } catch (IllegalArgumentException expected) { - } - - try { - new ColumnPrint(new PrintStub(), 1, 0, true); - fail("bad columns argument was not caught"); - } catch (IllegalArgumentException expected) { - } - - try { - new ColumnPrint(new PrintStub(), 2, -1, true); - fail("bad columnSpacing argument was not caught"); - } catch (IllegalArgumentException expected) { - } - } - - public void testEquals() { - ColumnPrint columnPrint = new ColumnPrint(new PrintStub(0), 2, 0, true); - assertEquals(columnPrint, new ColumnPrint(new PrintStub(0), 2, 0, true)); - assertFalse(columnPrint.equals(new ColumnPrint(new PrintStub(1), 2, 0, - true))); - assertFalse(columnPrint.equals(new ColumnPrint(new PrintStub(0), 3, 0, - true))); - assertFalse(columnPrint.equals(new ColumnPrint(new PrintStub(0), 2, 1, - true))); - assertFalse(columnPrint.equals(new ColumnPrint(new PrintStub(0), 2, 0, - false))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.ColumnPrint; + +import junit.framework.TestCase; + +public class ColumnPrintTest extends TestCase { + public void testConstructor_invalidArguments() { + try { + new ColumnPrint(null, 2, 0, true); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + new ColumnPrint(new PrintStub(), 1, 0, true); + fail("bad columns argument was not caught"); + } catch (IllegalArgumentException expected) { + } + + try { + new ColumnPrint(new PrintStub(), 2, -1, true); + fail("bad columnSpacing argument was not caught"); + } catch (IllegalArgumentException expected) { + } + } + + public void testEquals() { + ColumnPrint columnPrint = new ColumnPrint(new PrintStub(0), 2, 0, true); + assertEquals(columnPrint, new ColumnPrint(new PrintStub(0), 2, 0, true)); + assertFalse(columnPrint.equals(new ColumnPrint(new PrintStub(1), 2, 0, + true))); + assertFalse(columnPrint.equals(new ColumnPrint(new PrintStub(0), 3, 0, + true))); + assertFalse(columnPrint.equals(new ColumnPrint(new PrintStub(0), 2, 1, + true))); + assertFalse(columnPrint.equals(new ColumnPrint(new PrintStub(0), 2, 0, + false))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultCellBackgroundProviderTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultCellBackgroundProviderTest.java index 7d9145a3b..35beca374 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultCellBackgroundProviderTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultCellBackgroundProviderTest.java @@ -1,39 +1,39 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.grid.DefaultCellBackgroundProvider; -import org.eclipse.swt.graphics.RGB; - -public class DefaultCellBackgroundProviderTest extends TestCase { - public void testEquals_equivalent() { - DefaultCellBackgroundProvider provider1 = new DefaultCellBackgroundProvider(); - DefaultCellBackgroundProvider provider2 = new DefaultCellBackgroundProvider(); - assertEquals(provider1, provider2); - - provider1 = new DefaultCellBackgroundProvider( - new CellBackgroundProviderStub()); - assertFalse(provider1.equals(provider2)); - provider2 = new DefaultCellBackgroundProvider( - new CellBackgroundProviderStub()); - assertEquals(provider1, provider2); - - provider1.setBackground(new RGB(0, 0, 0)); - assertFalse(provider1.equals(provider2)); - provider2.setBackground(new RGB(0, 0, 0)); - assertEquals(provider1, provider2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.grid.DefaultCellBackgroundProvider; +import org.eclipse.swt.graphics.RGB; + +public class DefaultCellBackgroundProviderTest extends TestCase { + public void testEquals_equivalent() { + DefaultCellBackgroundProvider provider1 = new DefaultCellBackgroundProvider(); + DefaultCellBackgroundProvider provider2 = new DefaultCellBackgroundProvider(); + assertEquals(provider1, provider2); + + provider1 = new DefaultCellBackgroundProvider( + new CellBackgroundProviderStub()); + assertFalse(provider1.equals(provider2)); + provider2 = new DefaultCellBackgroundProvider( + new CellBackgroundProviderStub()); + assertEquals(provider1, provider2); + + provider1.setBackground(new RGB(0, 0, 0)); + assertFalse(provider1.equals(provider2)); + provider2.setBackground(new RGB(0, 0, 0)); + assertEquals(provider1, provider2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultGridLookTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultGridLookTest.java index 57cf6866b..4bbfbabbb 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultGridLookTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultGridLookTest.java @@ -1,84 +1,84 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.Rectangle; - -public class DefaultGridLookTest extends TestCase { - public void testEquals() { - final DefaultGridLook look1 = new DefaultGridLook(); - final DefaultGridLook look2 = new DefaultGridLook(); - assertEquals(look1, look2); - - look1.setBodyBackground(new RGB(0, 0, 0)); - assertFalse(look1.equals(look2)); - look2.setBodyBackground(new RGB(0, 0, 0)); - assertEquals(look1, look2); - - look1.setBodyBackgroundProvider(new CellBackgroundProviderStub()); - assertFalse(look1.equals(look2)); - look2.setBodyBackgroundProvider(new CellBackgroundProviderStub()); - assertEquals(look1, look2); - - look1.setCellBorder(new BorderStub()); - assertFalse(look1.equals(look2)); - look2.setCellBorder(new BorderStub()); - assertEquals(look1, look2); - - look1.setCellPadding(new Rectangle(1, 2, 3, 4)); - assertFalse(look1.equals(look2)); - look2.setCellPadding(1, 2, 3, 4); - assertEquals(look1, look2); - - look1.setCellSpacing(new Point(1, 2)); - assertFalse(look1.equals(look2)); - look2.setCellSpacing(new Point(1, 2)); - assertEquals(look1, look2); - - look1.setFooterBackground(new RGB(0, 0, 0)); - assertFalse(look1.equals(look2)); - look2.setFooterBackground(new RGB(0, 0, 0)); - assertEquals(look1, look2); - - look1.setFooterBackgroundProvider(new CellBackgroundProviderStub()); - assertFalse(look1.equals(look2)); - look2.setFooterBackgroundProvider(new CellBackgroundProviderStub()); - assertEquals(look1, look2); - - look1.setFooterGap(1); - assertFalse(look1.equals(look2)); - look2.setFooterGap(1); - assertEquals(look1, look2); - - look1.setHeaderBackground(new RGB(0, 0, 0)); - assertFalse(look1.equals(look2)); - look2.setHeaderBackground(new RGB(0, 0, 0)); - assertEquals(look1, look2); - - look1.setHeaderBackgroundProvider(new CellBackgroundProviderStub()); - assertFalse(look1.equals(look2)); - look2.setHeaderBackgroundProvider(new CellBackgroundProviderStub()); - assertEquals(look1, look2); - - look1.setHeaderGap(1); - assertFalse(look1.equals(look2)); - look2.setHeaderGap(1); - assertEquals(look1, look2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; + +public class DefaultGridLookTest extends TestCase { + public void testEquals() { + final DefaultGridLook look1 = new DefaultGridLook(); + final DefaultGridLook look2 = new DefaultGridLook(); + assertEquals(look1, look2); + + look1.setBodyBackground(new RGB(0, 0, 0)); + assertFalse(look1.equals(look2)); + look2.setBodyBackground(new RGB(0, 0, 0)); + assertEquals(look1, look2); + + look1.setBodyBackgroundProvider(new CellBackgroundProviderStub()); + assertFalse(look1.equals(look2)); + look2.setBodyBackgroundProvider(new CellBackgroundProviderStub()); + assertEquals(look1, look2); + + look1.setCellBorder(new BorderStub()); + assertFalse(look1.equals(look2)); + look2.setCellBorder(new BorderStub()); + assertEquals(look1, look2); + + look1.setCellPadding(new Rectangle(1, 2, 3, 4)); + assertFalse(look1.equals(look2)); + look2.setCellPadding(1, 2, 3, 4); + assertEquals(look1, look2); + + look1.setCellSpacing(new Point(1, 2)); + assertFalse(look1.equals(look2)); + look2.setCellSpacing(new Point(1, 2)); + assertEquals(look1, look2); + + look1.setFooterBackground(new RGB(0, 0, 0)); + assertFalse(look1.equals(look2)); + look2.setFooterBackground(new RGB(0, 0, 0)); + assertEquals(look1, look2); + + look1.setFooterBackgroundProvider(new CellBackgroundProviderStub()); + assertFalse(look1.equals(look2)); + look2.setFooterBackgroundProvider(new CellBackgroundProviderStub()); + assertEquals(look1, look2); + + look1.setFooterGap(1); + assertFalse(look1.equals(look2)); + look2.setFooterGap(1); + assertEquals(look1, look2); + + look1.setHeaderBackground(new RGB(0, 0, 0)); + assertFalse(look1.equals(look2)); + look2.setHeaderBackground(new RGB(0, 0, 0)); + assertEquals(look1, look2); + + look1.setHeaderBackgroundProvider(new CellBackgroundProviderStub()); + assertFalse(look1.equals(look2)); + look2.setHeaderBackgroundProvider(new CellBackgroundProviderStub()); + assertEquals(look1, look2); + + look1.setHeaderGap(1); + assertFalse(look1.equals(look2)); + look2.setHeaderGap(1); + assertEquals(look1, look2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultPageNumberFormatTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultPageNumberFormatTest.java index 97f2273e0..4bf60c6f4 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultPageNumberFormatTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/DefaultPageNumberFormatTest.java @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.page.DefaultPageNumberFormat; - -import junit.framework.TestCase; - -public class DefaultPageNumberFormatTest extends TestCase { - public void testEquals() { - assertEquals(new DefaultPageNumberFormat(), - new DefaultPageNumberFormat()); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.page.DefaultPageNumberFormat; + +import junit.framework.TestCase; + +public class DefaultPageNumberFormatTest extends TestCase { + public void testEquals() { + assertEquals(new DefaultPageNumberFormat(), + new DefaultPageNumberFormat()); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/EmptyPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/EmptyPrintTest.java index 0d261183e..f375e630a 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/EmptyPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/EmptyPrintTest.java @@ -1,63 +1,63 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.EmptyPrint; -import org.eclipse.swt.graphics.Point; - -public class EmptyPrintTest extends TestCase { - public void testConstructor_invalidArguments() { - try { - new EmptyPrint(null); - fail(); - } catch (NullPointerException expected) { - } - - try { - new EmptyPrint(new Point(-1, 0)); - fail(); - } catch (IllegalArgumentException expected) { - } - - try { - new EmptyPrint(new Point(0, -1)); - fail(); - } catch (IllegalArgumentException expected) { - } - - try { - new EmptyPrint(-1, 0); - fail(); - } catch (IllegalArgumentException expected) { - } - - try { - new EmptyPrint(0, -1); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - public void testEquals_equivalent() { - assertEquals(new EmptyPrint(), new EmptyPrint(0, 0)); - } - - public void testEquals_different() { - EmptyPrint emptyPrint = new EmptyPrint(0, 0); - assertFalse(emptyPrint.equals(new EmptyPrint(1, 0))); - assertFalse(emptyPrint.equals(new EmptyPrint(0, 1))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.EmptyPrint; +import org.eclipse.swt.graphics.Point; + +public class EmptyPrintTest extends TestCase { + public void testConstructor_invalidArguments() { + try { + new EmptyPrint(null); + fail(); + } catch (NullPointerException expected) { + } + + try { + new EmptyPrint(new Point(-1, 0)); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + new EmptyPrint(new Point(0, -1)); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + new EmptyPrint(-1, 0); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + new EmptyPrint(0, -1); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testEquals_equivalent() { + assertEquals(new EmptyPrint(), new EmptyPrint(0, 0)); + } + + public void testEquals_different() { + EmptyPrint emptyPrint = new EmptyPrint(0, 0); + assertFalse(emptyPrint.equals(new EmptyPrint(1, 0))); + assertFalse(emptyPrint.equals(new EmptyPrint(0, 1))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/GapBorderTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/GapBorderTest.java index a9b313c54..bd29fd569 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/GapBorderTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/GapBorderTest.java @@ -1,61 +1,61 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.border.GapBorder; - -import junit.framework.TestCase; - -public class GapBorderTest extends TestCase { - public void testEquals() { - GapBorder border1 = new GapBorder(); - GapBorder border2 = new GapBorder(); - assertEquals(border1, border2); - - border1.top = 2; - assertFalse(border1.equals(border2)); - border2.top = 2; - assertEquals(border1, border2); - - border1.left = 2; - assertFalse(border1.equals(border2)); - border2.left = 2; - assertEquals(border1, border2); - - border1.right = 2; - assertFalse(border1.equals(border2)); - border2.right = 2; - assertEquals(border1, border2); - - border1.bottom = 2; - assertFalse(border1.equals(border2)); - border2.bottom = 2; - assertEquals(border1, border2); - - border1.openTop = 2; - assertFalse(border1.equals(border2)); - border2.openTop = 2; - assertEquals(border1, border2); - - border1.openBottom = 2; - assertFalse(border1.equals(border2)); - border2.openBottom = 2; - assertEquals(border1, border2); - - border1.setGap(1); - assertFalse(border1.equals(border2)); - border2.setGap(1); - assertEquals(border1, border2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.border.GapBorder; + +import junit.framework.TestCase; + +public class GapBorderTest extends TestCase { + public void testEquals() { + GapBorder border1 = new GapBorder(); + GapBorder border2 = new GapBorder(); + assertEquals(border1, border2); + + border1.top = 2; + assertFalse(border1.equals(border2)); + border2.top = 2; + assertEquals(border1, border2); + + border1.left = 2; + assertFalse(border1.equals(border2)); + border2.left = 2; + assertEquals(border1, border2); + + border1.right = 2; + assertFalse(border1.equals(border2)); + border2.right = 2; + assertEquals(border1, border2); + + border1.bottom = 2; + assertFalse(border1.equals(border2)); + border2.bottom = 2; + assertEquals(border1, border2); + + border1.openTop = 2; + assertFalse(border1.equals(border2)); + border2.openTop = 2; + assertEquals(border1, border2); + + border1.openBottom = 2; + assertFalse(border1.equals(border2)); + border2.openBottom = 2; + assertEquals(border1, border2); + + border1.setGap(1); + assertFalse(border1.equals(border2)); + border2.setGap(1); + assertEquals(border1, border2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ImagePrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ImagePrintTest.java index 08564ce9e..9367633c7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ImagePrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ImagePrintTest.java @@ -1,49 +1,49 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.ImagePrint; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.PaletteData; -import org.eclipse.swt.graphics.Point; - -public class ImagePrintTest extends TestCase { - public void testEquals() { - ImagePrint image1 = new ImagePrint(createImageData(100)); - ImagePrint image2 = new ImagePrint(createImageData(100)); - assertEquals(image1, image2); - - image1 = new ImagePrint(createImageData(200)); - assertFalse(image1.equals(image2)); - image2 = new ImagePrint(createImageData(200)); - assertEquals(image1, image2); - - image1.setDPI(new Point(100, 100)); - assertFalse(image1.equals(image2)); - image2.setDPI(100, 100); - assertEquals(image1, image2); - - image1.setSize(new Point(100, 100)); - assertFalse(image1.equals(image2)); - image2.setSize(100, 100); - assertEquals(image1, image2); - } - - private ImageData createImageData(int size) { - return new ImageData(size, size, 24, new PaletteData(0xFF0000, - 0x00FF00, 0x0000FF)); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.ImagePrint; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.Point; + +public class ImagePrintTest extends TestCase { + public void testEquals() { + ImagePrint image1 = new ImagePrint(createImageData(100)); + ImagePrint image2 = new ImagePrint(createImageData(100)); + assertEquals(image1, image2); + + image1 = new ImagePrint(createImageData(200)); + assertFalse(image1.equals(image2)); + image2 = new ImagePrint(createImageData(200)); + assertEquals(image1, image2); + + image1.setDPI(new Point(100, 100)); + assertFalse(image1.equals(image2)); + image2.setDPI(100, 100); + assertEquals(image1, image2); + + image1.setSize(new Point(100, 100)); + assertFalse(image1.equals(image2)); + image2.setSize(100, 100); + assertEquals(image1, image2); + } + + private ImageData createImageData(int size) { + return new ImageData(size, size, 24, new PaletteData(0xFF0000, + 0x00FF00, 0x0000FF)); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LayerEntryTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LayerEntryTest.java index 4b999a01d..4e3110439 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LayerEntryTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LayerEntryTest.java @@ -1,42 +1,42 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.internal.LayerEntryImpl; -import org.eclipse.nebula.paperclips.core.internal.LayerEntryImpl; -import org.eclipse.swt.SWT; - -public class LayerEntryTest extends TestCase { - public void testConstructor_invalidArguments() { - try { - new LayerEntryImpl(null, SWT.LEFT); - fail(); - } catch (IllegalArgumentException expected) { - } - - assertEquals(SWT.LEFT, - new LayerEntryImpl(new PrintStub(), 0).getHorizontalAlignment()); - } - - public void testEquals() { - LayerEntry entry = new LayerEntryImpl(new PrintStub(0), SWT.LEFT); - assertEquals(entry, new LayerEntryImpl(new PrintStub(0), SWT.LEFT)); - assertFalse(entry - .equals(new LayerEntryImpl(new PrintStub(1), SWT.LEFT))); - assertFalse(entry.equals(new LayerEntryImpl(new PrintStub(0), - SWT.CENTER))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.internal.LayerEntryImpl; +import org.eclipse.nebula.paperclips.core.internal.LayerEntryImpl; +import org.eclipse.swt.SWT; + +public class LayerEntryTest extends TestCase { + public void testConstructor_invalidArguments() { + try { + new LayerEntryImpl(null, SWT.LEFT); + fail(); + } catch (IllegalArgumentException expected) { + } + + assertEquals(SWT.LEFT, + new LayerEntryImpl(new PrintStub(), 0).getHorizontalAlignment()); + } + + public void testEquals() { + LayerEntry entry = new LayerEntryImpl(new PrintStub(0), SWT.LEFT); + assertEquals(entry, new LayerEntryImpl(new PrintStub(0), SWT.LEFT)); + assertFalse(entry + .equals(new LayerEntryImpl(new PrintStub(1), SWT.LEFT))); + assertFalse(entry.equals(new LayerEntryImpl(new PrintStub(0), + SWT.CENTER))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LayerPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LayerPrintTest.java index a47b8160e..cfdcf836a 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LayerPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LayerPrintTest.java @@ -1,37 +1,37 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.LayerPrint; -import org.eclipse.swt.SWT; - -public class LayerPrintTest extends TestCase { - public void testEquals() { - LayerPrint lp1 = new LayerPrint(); - LayerPrint lp2 = new LayerPrint(); - assertEquals(lp1, lp2); - - lp1.add(new PrintStub()); - assertFalse(lp1.equals(lp2)); - lp2.add(new PrintStub()); - assertEquals(lp1, lp2); - - lp1.add(new PrintStub(), SWT.CENTER); - assertFalse(lp1.equals(lp2)); - lp2.add(new PrintStub(), SWT.CENTER); - assertEquals(lp1, lp2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.LayerPrint; +import org.eclipse.swt.SWT; + +public class LayerPrintTest extends TestCase { + public void testEquals() { + LayerPrint lp1 = new LayerPrint(); + LayerPrint lp2 = new LayerPrint(); + assertEquals(lp1, lp2); + + lp1.add(new PrintStub()); + assertFalse(lp1.equals(lp2)); + lp2.add(new PrintStub()); + assertEquals(lp1, lp2); + + lp1.add(new PrintStub(), SWT.CENTER); + assertFalse(lp1.equals(lp2)); + lp2.add(new PrintStub(), SWT.CENTER); + assertEquals(lp1, lp2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LineBorderTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LineBorderTest.java index 59d85db64..6c6c808f9 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LineBorderTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LineBorderTest.java @@ -1,42 +1,42 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.swt.graphics.RGB; - -public class LineBorderTest extends TestCase { - public void testEquals() { - LineBorder border1 = new LineBorder(); - LineBorder border2 = new LineBorder(); - assertEquals(border1, border2); - - border1.setGapSize(10); - assertFalse(border1.equals(border2)); - border2.setGapSize(10); - assertEquals(border1, border2); - - border1.setLineWidth(10); - assertFalse(border1.equals(border2)); - border2.setLineWidth(10); - assertEquals(border1, border2); - - border1.setRGB(new RGB(127, 127, 127)); - assertFalse(border1.equals(border2)); - border2.setRGB(new RGB(127, 127, 127)); - assertEquals(border1, border2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.swt.graphics.RGB; + +public class LineBorderTest extends TestCase { + public void testEquals() { + LineBorder border1 = new LineBorder(); + LineBorder border2 = new LineBorder(); + assertEquals(border1, border2); + + border1.setGapSize(10); + assertFalse(border1.equals(border2)); + border2.setGapSize(10); + assertEquals(border1, border2); + + border1.setLineWidth(10); + assertFalse(border1.equals(border2)); + border2.setLineWidth(10); + assertEquals(border1, border2); + + border1.setRGB(new RGB(127, 127, 127)); + assertFalse(border1.equals(border2)); + border2.setRGB(new RGB(127, 127, 127)); + assertEquals(border1, border2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LineBreakPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LineBreakPrintTest.java index 47ab57c08..378071313 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LineBreakPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LineBreakPrintTest.java @@ -1,39 +1,39 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.text.LineBreakPrint; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontData; - -public class LineBreakPrintTest extends TestCase { - public void testConstructor_invalidArgument() { - try { - new LineBreakPrint(null); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - public void testEquals() { - FontData fontData = new FontData("Arial", 14, SWT.NORMAL); - LineBreakPrint lineBreakPrint = new LineBreakPrint(fontData); - - assertEquals(lineBreakPrint, new LineBreakPrint(fontData)); - assertFalse(lineBreakPrint.equals(new LineBreakPrint(new FontData( - "Arial", 12, SWT.NORMAL)))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.text.LineBreakPrint; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontData; + +public class LineBreakPrintTest extends TestCase { + public void testConstructor_invalidArgument() { + try { + new LineBreakPrint(null); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testEquals() { + FontData fontData = new FontData("Arial", 14, SWT.NORMAL); + LineBreakPrint lineBreakPrint = new LineBreakPrint(fontData); + + assertEquals(lineBreakPrint, new LineBreakPrint(fontData)); + assertFalse(lineBreakPrint.equals(new LineBreakPrint(new FontData( + "Arial", 12, SWT.NORMAL)))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LinePrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LinePrintTest.java index 114810aae..01c66d37c 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LinePrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/LinePrintTest.java @@ -1,47 +1,47 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.LinePrint; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.RGB; - -public class LinePrintTest extends TestCase { - public void testConstructor_invalidArgument() { - assertEquals(SWT.HORIZONTAL, new LinePrint(0).getOrientation()); - } - - public void testEquals() { - LinePrint line1 = new LinePrint(SWT.HORIZONTAL); - LinePrint line2 = new LinePrint(SWT.HORIZONTAL); - assertEquals(line1, line2); - - line1 = new LinePrint(SWT.VERTICAL); - assertFalse(line1.equals(line2)); - line2 = new LinePrint(SWT.VERTICAL); - assertEquals(line1, line2); - - line1.setRGB(new RGB(127, 127, 127)); - assertFalse(line1.equals(line2)); - line2.setRGB(new RGB(127, 127, 127)); - assertEquals(line1, line2); - - line1.setThickness(2.3); - assertFalse(line1.equals(line2)); - line2.setThickness(2.3); - assertEquals(line1, line2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.LinePrint; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; + +public class LinePrintTest extends TestCase { + public void testConstructor_invalidArgument() { + assertEquals(SWT.HORIZONTAL, new LinePrint(0).getOrientation()); + } + + public void testEquals() { + LinePrint line1 = new LinePrint(SWT.HORIZONTAL); + LinePrint line2 = new LinePrint(SWT.HORIZONTAL); + assertEquals(line1, line2); + + line1 = new LinePrint(SWT.VERTICAL); + assertFalse(line1.equals(line2)); + line2 = new LinePrint(SWT.VERTICAL); + assertEquals(line1, line2); + + line1.setRGB(new RGB(127, 127, 127)); + assertFalse(line1.equals(line2)); + line2.setRGB(new RGB(127, 127, 127)); + assertEquals(line1, line2); + + line1.setThickness(2.3); + assertFalse(line1.equals(line2)); + line2.setThickness(2.3); + assertEquals(line1, line2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/MarginsTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/MarginsTest.java index cb6cdf321..cabaa781e 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/MarginsTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/MarginsTest.java @@ -1,46 +1,46 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.Margins; - -import junit.framework.TestCase; - -public class MarginsTest extends TestCase { - public void testEquals() { - Margins m1 = new Margins(0); - Margins m2 = new Margins(0); - assertEquals(m1, m2); - - m1.top = 1; - assertFalse(m1.equals(m2)); - m2.top = 1; - assertEquals(m1, m2); - - m1.left = 1; - assertFalse(m1.equals(m2)); - m2.left = 1; - assertEquals(m1, m2); - - m1.right = 1; - assertFalse(m1.equals(m2)); - m2.right = 1; - assertEquals(m1, m2); - - m1.bottom = 1; - assertFalse(m1.equals(m2)); - m2.bottom = 1; - assertEquals(m1, m2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.Margins; + +import junit.framework.TestCase; + +public class MarginsTest extends TestCase { + public void testEquals() { + Margins m1 = new Margins(0); + Margins m2 = new Margins(0); + assertEquals(m1, m2); + + m1.top = 1; + assertFalse(m1.equals(m2)); + m2.top = 1; + assertEquals(m1, m2); + + m1.left = 1; + assertFalse(m1.equals(m2)); + m2.left = 1; + assertEquals(m1, m2); + + m1.right = 1; + assertFalse(m1.equals(m2)); + m2.right = 1; + assertEquals(m1, m2); + + m1.bottom = 1; + assertFalse(m1.equals(m2)); + m2.bottom = 1; + assertEquals(m1, m2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/NoBreakPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/NoBreakPrintTest.java index ed2ba9d2a..9ebd9e609 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/NoBreakPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/NoBreakPrintTest.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.NoBreakPrint; - -import junit.framework.TestCase; - -public class NoBreakPrintTest extends TestCase { - public void testConstructor() { - try { - new NoBreakPrint(null); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - public void testEquals() { - NoBreakPrint noBreak = new NoBreakPrint(new PrintStub(0)); - assertEquals(noBreak, new NoBreakPrint(new PrintStub(0))); - assertFalse(noBreak.equals(new NoBreakPrint(new PrintStub(1)))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.NoBreakPrint; + +import junit.framework.TestCase; + +public class NoBreakPrintTest extends TestCase { + public void testConstructor() { + try { + new NoBreakPrint(null); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testEquals() { + NoBreakPrint noBreak = new NoBreakPrint(new PrintStub(0)); + assertEquals(noBreak, new NoBreakPrint(new PrintStub(0))); + assertFalse(noBreak.equals(new NoBreakPrint(new PrintStub(1)))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberFormatStub.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberFormatStub.java index a5421d0bc..01b9b0aee 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberFormatStub.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberFormatStub.java @@ -1,30 +1,30 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.nebula.paperclips.core.page.PageNumber; -import org.eclipse.nebula.paperclips.core.page.PageNumberFormat; - -@SuppressWarnings("restriction") -class PageNumberFormatStub implements PageNumberFormat { - @Override - public boolean equals(Object obj) { - return Util.sameClass(this, obj); - } - - public String format(PageNumber pageNumber) { - return null; - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.nebula.paperclips.core.page.PageNumber; +import org.eclipse.nebula.paperclips.core.page.PageNumberFormat; + +@SuppressWarnings("restriction") +class PageNumberFormatStub implements PageNumberFormat { + @Override + public boolean equals(Object obj) { + return Util.sameClass(this, obj); + } + + public String format(PageNumber pageNumber) { + return null; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberPageDecorationTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberPageDecorationTest.java index 27a8f5a95..becda182c 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberPageDecorationTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberPageDecorationTest.java @@ -1,49 +1,49 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.page.PageNumberPageDecoration; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; - -public class PageNumberPageDecorationTest extends TestCase { - public void testEquals() { - PageNumberPageDecoration decoration1 = new PageNumberPageDecoration(); - PageNumberPageDecoration decoration2 = new PageNumberPageDecoration(); - assertEquals(decoration1, decoration2); - - decoration1.setRGB(new RGB(127, 127, 127)); - assertFalse(decoration1.equals(decoration2)); - decoration2.setRGB(new RGB(127, 127, 127)); - assertEquals(decoration1, decoration2); - - decoration1.setAlign(SWT.CENTER); - assertFalse(decoration1.equals(decoration2)); - decoration2.setAlign(SWT.CENTER); - assertEquals(decoration1, decoration2); - - decoration1.setFontData(new FontData("Arial", 12, SWT.BOLD)); - assertFalse(decoration1.equals(decoration2)); - decoration2.setFontData(new FontData("Arial", 12, SWT.BOLD)); - assertEquals(decoration1, decoration2); - - decoration1.setFormat(new PageNumberFormatStub()); - assertFalse(decoration1.equals(decoration2)); - decoration2.setFormat(new PageNumberFormatStub()); - assertEquals(decoration1, decoration2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.page.PageNumberPageDecoration; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; + +public class PageNumberPageDecorationTest extends TestCase { + public void testEquals() { + PageNumberPageDecoration decoration1 = new PageNumberPageDecoration(); + PageNumberPageDecoration decoration2 = new PageNumberPageDecoration(); + assertEquals(decoration1, decoration2); + + decoration1.setRGB(new RGB(127, 127, 127)); + assertFalse(decoration1.equals(decoration2)); + decoration2.setRGB(new RGB(127, 127, 127)); + assertEquals(decoration1, decoration2); + + decoration1.setAlign(SWT.CENTER); + assertFalse(decoration1.equals(decoration2)); + decoration2.setAlign(SWT.CENTER); + assertEquals(decoration1, decoration2); + + decoration1.setFontData(new FontData("Arial", 12, SWT.BOLD)); + assertFalse(decoration1.equals(decoration2)); + decoration2.setFontData(new FontData("Arial", 12, SWT.BOLD)); + assertEquals(decoration1, decoration2); + + decoration1.setFormat(new PageNumberFormatStub()); + assertFalse(decoration1.equals(decoration2)); + decoration2.setFormat(new PageNumberFormatStub()); + assertEquals(decoration1, decoration2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberPrintTest.java index f03fcab46..05ee30b25 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PageNumberPrintTest.java @@ -1,96 +1,96 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.nebula.paperclips.core.page.PageNumber; -import org.eclipse.nebula.paperclips.core.page.PageNumberPrint; -import org.eclipse.nebula.paperclips.core.text.TextStyle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontData; - -import junit.framework.TestCase; - -@SuppressWarnings("restriction") -public class PageNumberPrintTest extends TestCase { - public void testConstructor_illegalArguments() { - try { - new PageNumberPrint(null); - fail(); - } catch (IllegalArgumentException expected) { - } - - try { - new PageNumberPrint(new PageNumberStub(0), (TextStyle) null); - fail(); - } catch (IllegalArgumentException expected) { - } - - assertEquals(SWT.LEFT, - new PageNumberPrint(new PageNumberStub(0), 0).getAlign()); - } - - public void testEquals() { - PageNumberPrint pageNumber1 = new PageNumberPrint( - new PageNumberStub(0)); - PageNumberPrint pageNumber2 = new PageNumberPrint( - new PageNumberStub(0)); - assertEquals(pageNumber1, pageNumber2); - - pageNumber1.setAlign(SWT.CENTER); - assertFalse(pageNumber1.equals(pageNumber2)); - pageNumber2.setAlign(SWT.CENTER); - assertEquals(pageNumber1, pageNumber2); - - pageNumber1.setFontData(new FontData("Arial", 12, SWT.BOLD)); - assertFalse(pageNumber1.equals(pageNumber2)); - pageNumber2.setFontData(new FontData("Arial", 12, SWT.BOLD)); - assertEquals(pageNumber1, pageNumber2); - - pageNumber1.setPageNumber(new PageNumberStub(1)); - assertFalse(pageNumber1.equals(pageNumber2)); - pageNumber2.setPageNumber(new PageNumberStub(1)); - assertEquals(pageNumber1, pageNumber2); - - pageNumber1.setPageNumberFormat(new PageNumberFormatStub()); - assertFalse(pageNumber1.equals(pageNumber2)); - pageNumber2.setPageNumberFormat(new PageNumberFormatStub()); - assertEquals(pageNumber1, pageNumber2); - } - - static class PageNumberStub implements PageNumber { - private int id; - - public PageNumberStub(int id) { - this.id = id; - } - - @Override - public boolean equals(Object obj) { - if (!Util.sameClass(this, obj)) - return false; - - PageNumberStub that = (PageNumberStub) obj; - return this.id == that.id; - } - - public int getPageCount() { - return 0; - } - - public int getPageNumber() { - return 0; - } - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.nebula.paperclips.core.page.PageNumber; +import org.eclipse.nebula.paperclips.core.page.PageNumberPrint; +import org.eclipse.nebula.paperclips.core.text.TextStyle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontData; + +import junit.framework.TestCase; + +@SuppressWarnings("restriction") +public class PageNumberPrintTest extends TestCase { + public void testConstructor_illegalArguments() { + try { + new PageNumberPrint(null); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + new PageNumberPrint(new PageNumberStub(0), (TextStyle) null); + fail(); + } catch (IllegalArgumentException expected) { + } + + assertEquals(SWT.LEFT, + new PageNumberPrint(new PageNumberStub(0), 0).getAlign()); + } + + public void testEquals() { + PageNumberPrint pageNumber1 = new PageNumberPrint( + new PageNumberStub(0)); + PageNumberPrint pageNumber2 = new PageNumberPrint( + new PageNumberStub(0)); + assertEquals(pageNumber1, pageNumber2); + + pageNumber1.setAlign(SWT.CENTER); + assertFalse(pageNumber1.equals(pageNumber2)); + pageNumber2.setAlign(SWT.CENTER); + assertEquals(pageNumber1, pageNumber2); + + pageNumber1.setFontData(new FontData("Arial", 12, SWT.BOLD)); + assertFalse(pageNumber1.equals(pageNumber2)); + pageNumber2.setFontData(new FontData("Arial", 12, SWT.BOLD)); + assertEquals(pageNumber1, pageNumber2); + + pageNumber1.setPageNumber(new PageNumberStub(1)); + assertFalse(pageNumber1.equals(pageNumber2)); + pageNumber2.setPageNumber(new PageNumberStub(1)); + assertEquals(pageNumber1, pageNumber2); + + pageNumber1.setPageNumberFormat(new PageNumberFormatStub()); + assertFalse(pageNumber1.equals(pageNumber2)); + pageNumber2.setPageNumberFormat(new PageNumberFormatStub()); + assertEquals(pageNumber1, pageNumber2); + } + + static class PageNumberStub implements PageNumber { + private int id; + + public PageNumberStub(int id) { + this.id = id; + } + + @Override + public boolean equals(Object obj) { + if (!Util.sameClass(this, obj)) + return false; + + PageNumberStub that = (PageNumberStub) obj; + return this.id == that.id; + } + + public int getPageCount() { + return 0; + } + + public int getPageNumber() { + return 0; + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PagePrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PagePrintTest.java index 5390eff17..841c9fb66 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PagePrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PagePrintTest.java @@ -1,66 +1,66 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.nebula.paperclips.core.page.PageDecoration; -import org.eclipse.nebula.paperclips.core.page.PageNumber; -import org.eclipse.nebula.paperclips.core.page.PagePrint; - -import junit.framework.TestCase; - -@SuppressWarnings("restriction") -public class PagePrintTest extends TestCase { - public void testEquals() { - PagePrint page1 = new PagePrint(new PrintStub(0)); - PagePrint page2 = new PagePrint(new PrintStub(0)); - assertEquals(page1, page2); - - page1.setBody(new PrintStub(1)); - assertFalse(page1.equals(page2)); - page2.setBody(new PrintStub(1)); - assertEquals(page1, page2); - - page1.setHeader(new PageDecorationStub()); - assertFalse(page1.equals(page2)); - page2.setHeader(new PageDecorationStub()); - assertEquals(page1, page2); - - page1.setHeaderGap(10); - assertFalse(page1.equals(page2)); - page2.setHeaderGap(10); - assertEquals(page1, page2); - - page1.setFooter(new PageDecorationStub()); - assertFalse(page1.equals(page2)); - page2.setFooter(new PageDecorationStub()); - assertEquals(page1, page2); - - page1.setFooterGap(10); - assertFalse(page1.equals(page2)); - page2.setFooterGap(10); - assertEquals(page1, page2); - } - - static class PageDecorationStub implements PageDecoration { - @Override - public boolean equals(Object obj) { - return Util.sameClass(this, obj); - } - - public Print createPrint(PageNumber pageNumber) { - return null; - } - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.nebula.paperclips.core.page.PageDecoration; +import org.eclipse.nebula.paperclips.core.page.PageNumber; +import org.eclipse.nebula.paperclips.core.page.PagePrint; + +import junit.framework.TestCase; + +@SuppressWarnings("restriction") +public class PagePrintTest extends TestCase { + public void testEquals() { + PagePrint page1 = new PagePrint(new PrintStub(0)); + PagePrint page2 = new PagePrint(new PrintStub(0)); + assertEquals(page1, page2); + + page1.setBody(new PrintStub(1)); + assertFalse(page1.equals(page2)); + page2.setBody(new PrintStub(1)); + assertEquals(page1, page2); + + page1.setHeader(new PageDecorationStub()); + assertFalse(page1.equals(page2)); + page2.setHeader(new PageDecorationStub()); + assertEquals(page1, page2); + + page1.setHeaderGap(10); + assertFalse(page1.equals(page2)); + page2.setHeaderGap(10); + assertEquals(page1, page2); + + page1.setFooter(new PageDecorationStub()); + assertFalse(page1.equals(page2)); + page2.setFooter(new PageDecorationStub()); + assertEquals(page1, page2); + + page1.setFooterGap(10); + assertFalse(page1.equals(page2)); + page2.setFooterGap(10); + assertEquals(page1, page2); + } + + static class PageDecorationStub implements PageDecoration { + @Override + public boolean equals(Object obj) { + return Util.sameClass(this, obj); + } + + public Print createPrint(PageNumber pageNumber) { + return null; + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PrintJobTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PrintJobTest.java index cd6bfae92..2b20412fd 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PrintJobTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PrintJobTest.java @@ -1,47 +1,47 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.PrintJob; - -import junit.framework.TestCase; - -public class PrintJobTest extends TestCase { - public void testEquals() { - PrintJob job1 = new PrintJob("name", new PrintStub(0)); - PrintJob job2 = new PrintJob("name", new PrintStub(0)); - assertEquals(job1, job2); - - job1 = new PrintJob("name2", new PrintStub(0)); - assertFalse(job1.equals(job2)); - job2 = new PrintJob("name2", new PrintStub(0)); - assertEquals(job1, job2); - - job1 = new PrintJob("name2", new PrintStub(1)); - assertFalse(job1.equals(job2)); - job2 = new PrintJob("name2", new PrintStub(1)); - assertEquals(job1, job2); - - job1.setOrientation(PaperClips.ORIENTATION_LANDSCAPE); - assertFalse(job1.equals(job2)); - job2.setOrientation(PaperClips.ORIENTATION_LANDSCAPE); - assertEquals(job1, job2); - - job1.setMargins(144); - assertFalse(job1.equals(job2)); - job2.setMargins(144); - assertEquals(job1, job2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.PrintJob; + +import junit.framework.TestCase; + +public class PrintJobTest extends TestCase { + public void testEquals() { + PrintJob job1 = new PrintJob("name", new PrintStub(0)); + PrintJob job2 = new PrintJob("name", new PrintStub(0)); + assertEquals(job1, job2); + + job1 = new PrintJob("name2", new PrintStub(0)); + assertFalse(job1.equals(job2)); + job2 = new PrintJob("name2", new PrintStub(0)); + assertEquals(job1, job2); + + job1 = new PrintJob("name2", new PrintStub(1)); + assertFalse(job1.equals(job2)); + job2 = new PrintJob("name2", new PrintStub(1)); + assertEquals(job1, job2); + + job1.setOrientation(PaperClips.ORIENTATION_LANDSCAPE); + assertFalse(job1.equals(job2)); + job2.setOrientation(PaperClips.ORIENTATION_LANDSCAPE); + assertEquals(job1, job2); + + job1.setMargins(144); + assertFalse(job1.equals(job2)); + job2.setMargins(144); + assertEquals(job1, job2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PrintStub.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PrintStub.java index 280fe87aa..850122ba0 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PrintStub.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/PrintStub.java @@ -1,44 +1,44 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -@SuppressWarnings("restriction") -public final class PrintStub implements Print { - private int id; - - public PrintStub() { - this(0); - } - - public PrintStub(int id) { - this.id = id; - } - - @Override - public boolean equals(Object obj) { - if (!Util.sameClass(this, obj)) - return false; - - PrintStub that = (PrintStub) obj; - return this.id == that.id; - } - - public PrintIterator iterator(Device device, GC gc) { - return null; - } +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +@SuppressWarnings("restriction") +public final class PrintStub implements Print { + private int id; + + public PrintStub() { + this(0); + } + + public PrintStub(int id) { + this.id = id; + } + + @Override + public boolean equals(Object obj) { + if (!Util.sameClass(this, obj)) + return false; + + PrintStub that = (PrintStub) obj; + return this.id == that.id; + } + + public PrintIterator iterator(Device device, GC gc) { + return null; + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/RotatePrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/RotatePrintTest.java index 77f395931..fb75a179e 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/RotatePrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/RotatePrintTest.java @@ -1,36 +1,36 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.RotatePrint; - -import junit.framework.TestCase; - -public class RotatePrintTest extends TestCase { - public void testEquals() { - RotatePrint rotate1 = new RotatePrint(new PrintStub(0), 90); - RotatePrint rotate2 = new RotatePrint(new PrintStub(0), 90); - assertEquals(rotate1, rotate2); - - rotate1 = new RotatePrint(new PrintStub(1), 90); - assertFalse(rotate1.equals(rotate2)); - rotate2 = new RotatePrint(new PrintStub(1), 90); - assertEquals(rotate1, rotate2); - - rotate1 = new RotatePrint(new PrintStub(1), 180); - assertFalse(rotate1.equals(rotate2)); - rotate2 = new RotatePrint(new PrintStub(1), 180); - assertEquals(rotate1, rotate2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.RotatePrint; + +import junit.framework.TestCase; + +public class RotatePrintTest extends TestCase { + public void testEquals() { + RotatePrint rotate1 = new RotatePrint(new PrintStub(0), 90); + RotatePrint rotate2 = new RotatePrint(new PrintStub(0), 90); + assertEquals(rotate1, rotate2); + + rotate1 = new RotatePrint(new PrintStub(1), 90); + assertFalse(rotate1.equals(rotate2)); + rotate2 = new RotatePrint(new PrintStub(1), 90); + assertEquals(rotate1, rotate2); + + rotate1 = new RotatePrint(new PrintStub(1), 180); + assertFalse(rotate1.equals(rotate2)); + rotate2 = new RotatePrint(new PrintStub(1), 180); + assertEquals(rotate1, rotate2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ScalePrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ScalePrintTest.java index 83ee93152..27af8ff7b 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ScalePrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/ScalePrintTest.java @@ -1,36 +1,36 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.ScalePrint; - -import junit.framework.TestCase; - -public class ScalePrintTest extends TestCase { - public void testEquals() { - ScalePrint scale1 = new ScalePrint(new PrintStub(0), null); - ScalePrint scale2 = new ScalePrint(new PrintStub(0), null); - assertEquals(scale1, scale2); - - scale1 = new ScalePrint(new PrintStub(1), null); - assertFalse(scale1.equals(scale2)); - scale2 = new ScalePrint(new PrintStub(1), null); - assertEquals(scale1, scale2); - - scale1 = new ScalePrint(new PrintStub(1), new Double(0.5)); - assertFalse(scale1.equals(scale2)); - scale2 = new ScalePrint(new PrintStub(1), new Double(0.5)); - assertEquals(scale1, scale2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.ScalePrint; + +import junit.framework.TestCase; + +public class ScalePrintTest extends TestCase { + public void testEquals() { + ScalePrint scale1 = new ScalePrint(new PrintStub(0), null); + ScalePrint scale2 = new ScalePrint(new PrintStub(0), null); + assertEquals(scale1, scale2); + + scale1 = new ScalePrint(new PrintStub(1), null); + assertFalse(scale1.equals(scale2)); + scale2 = new ScalePrint(new PrintStub(1), null); + assertEquals(scale1, scale2); + + scale1 = new ScalePrint(new PrintStub(1), new Double(0.5)); + assertFalse(scale1.equals(scale2)); + scale2 = new ScalePrint(new PrintStub(1), new Double(0.5)); + assertEquals(scale1, scale2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SeriesPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SeriesPrintTest.java index 79ca0e85e..cd2d00a18 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SeriesPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SeriesPrintTest.java @@ -1,31 +1,31 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.SeriesPrint; - -import junit.framework.TestCase; - -public class SeriesPrintTest extends TestCase { - public void testEquals() { - SeriesPrint series1 = new SeriesPrint(); - SeriesPrint series2 = new SeriesPrint(); - assertEquals(series1, series2); - - series1.add(new PrintStub()); - assertFalse(series1.equals(series2)); - series2.add(new PrintStub()); - assertEquals(series1, series2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.SeriesPrint; + +import junit.framework.TestCase; + +public class SeriesPrintTest extends TestCase { + public void testEquals() { + SeriesPrint series1 = new SeriesPrint(); + SeriesPrint series2 = new SeriesPrint(); + assertEquals(series1, series2); + + series1.add(new PrintStub()); + assertFalse(series1.equals(series2)); + series2.add(new PrintStub()); + assertEquals(series1, series2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SidewaysPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SidewaysPrintTest.java index 997e29d17..e1550d147 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SidewaysPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SidewaysPrintTest.java @@ -1,36 +1,36 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.SidewaysPrint; - -import junit.framework.TestCase; - -public class SidewaysPrintTest extends TestCase { - public void testEquals() { - SidewaysPrint sideways1 = new SidewaysPrint(new PrintStub(0), 90); - SidewaysPrint sideways2 = new SidewaysPrint(new PrintStub(0), 90); - assertEquals(sideways1, sideways2); - - sideways1 = new SidewaysPrint(new PrintStub(1), 90); - assertFalse(sideways1.equals(sideways2)); - sideways2 = new SidewaysPrint(new PrintStub(1), 90); - assertEquals(sideways1, sideways2); - - sideways1 = new SidewaysPrint(new PrintStub(1), 180); - assertFalse(sideways1.equals(sideways2)); - sideways2 = new SidewaysPrint(new PrintStub(1), 180); - assertEquals(sideways1, sideways2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.SidewaysPrint; + +import junit.framework.TestCase; + +public class SidewaysPrintTest extends TestCase { + public void testEquals() { + SidewaysPrint sideways1 = new SidewaysPrint(new PrintStub(0), 90); + SidewaysPrint sideways2 = new SidewaysPrint(new PrintStub(0), 90); + assertEquals(sideways1, sideways2); + + sideways1 = new SidewaysPrint(new PrintStub(1), 90); + assertFalse(sideways1.equals(sideways2)); + sideways2 = new SidewaysPrint(new PrintStub(1), 90); + assertEquals(sideways1, sideways2); + + sideways1 = new SidewaysPrint(new PrintStub(1), 180); + assertFalse(sideways1.equals(sideways2)); + sideways2 = new SidewaysPrint(new PrintStub(1), 180); + assertEquals(sideways1, sideways2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SimplePageDecorationTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SimplePageDecorationTest.java index abf690c13..c167bb191 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SimplePageDecorationTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/SimplePageDecorationTest.java @@ -1,26 +1,26 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import org.eclipse.nebula.paperclips.core.page.SimplePageDecoration; - -import junit.framework.TestCase; - -public class SimplePageDecorationTest extends TestCase { - public void testEquals() { - Object obj = new SimplePageDecoration(new PrintStub(0)); - assertEquals(obj, new SimplePageDecoration(new PrintStub(0))); - assertFalse(obj.equals(new SimplePageDecoration(new PrintStub(1)))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import org.eclipse.nebula.paperclips.core.page.SimplePageDecoration; + +import junit.framework.TestCase; + +public class SimplePageDecorationTest extends TestCase { + public void testEquals() { + Object obj = new SimplePageDecoration(new PrintStub(0)); + assertEquals(obj, new SimplePageDecoration(new PrintStub(0))); + assertFalse(obj.equals(new SimplePageDecoration(new PrintStub(1)))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/StyledTextPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/StyledTextPrintTest.java index c4c5ba7a2..3fd05c40b 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/StyledTextPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/StyledTextPrintTest.java @@ -1,38 +1,38 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.text.StyledTextPrint; -import org.eclipse.nebula.paperclips.core.text.TextStyle; -import org.eclipse.swt.SWT; - -public class StyledTextPrintTest extends TestCase { - public void testEquals() { - StyledTextPrint styled1 = new StyledTextPrint(); - StyledTextPrint styled2 = new StyledTextPrint(); - assertEquals(styled1, styled2); - - styled1.append(new PrintStub()); - assertFalse(styled1.equals(styled2)); - styled2.append(new PrintStub()); - assertEquals(styled1, styled2); - - styled1.setStyle(new TextStyle().align(SWT.CENTER)); - assertFalse(styled1.equals(styled2)); - styled2.setStyle(new TextStyle().align(SWT.CENTER)); - assertEquals(styled1, styled2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.text.StyledTextPrint; +import org.eclipse.nebula.paperclips.core.text.TextStyle; +import org.eclipse.swt.SWT; + +public class StyledTextPrintTest extends TestCase { + public void testEquals() { + StyledTextPrint styled1 = new StyledTextPrint(); + StyledTextPrint styled2 = new StyledTextPrint(); + assertEquals(styled1, styled2); + + styled1.append(new PrintStub()); + assertFalse(styled1.equals(styled2)); + styled2.append(new PrintStub()); + assertEquals(styled1, styled2); + + styled1.setStyle(new TextStyle().align(SWT.CENTER)); + assertFalse(styled1.equals(styled2)); + styled2.setStyle(new TextStyle().align(SWT.CENTER)); + assertEquals(styled1, styled2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/TextPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/TextPrintTest.java index 96d5b0f28..97e845366 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/TextPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/TextPrintTest.java @@ -1,38 +1,38 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.core.text.TextStyle; -import org.eclipse.swt.SWT; - -public class TextPrintTest extends TestCase { - public void testEquals() { - TextPrint text1 = new TextPrint("text"); - TextPrint text2 = new TextPrint("text"); - assertEquals(text1, text2); - - text1.setStyle(new TextStyle().align(SWT.CENTER)); - assertFalse(text1.equals(text2)); - text2.setStyle(new TextStyle().align(SWT.CENTER)); - assertEquals(text1, text2); - - text1.setWordSplitting(false); - assertFalse(text1.equals(text2)); - text2.setWordSplitting(false); - assertEquals(text1, text2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.core.text.TextStyle; +import org.eclipse.swt.SWT; + +public class TextPrintTest extends TestCase { + public void testEquals() { + TextPrint text1 = new TextPrint("text"); + TextPrint text2 = new TextPrint("text"); + assertEquals(text1, text2); + + text1.setStyle(new TextStyle().align(SWT.CENTER)); + assertFalse(text1.equals(text2)); + text2.setStyle(new TextStyle().align(SWT.CENTER)); + assertEquals(text1, text2); + + text1.setWordSplitting(false); + assertFalse(text1.equals(text2)); + text2.setWordSplitting(false); + assertEquals(text1, text2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/TextStyleTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/TextStyleTest.java index 2e6fbde42..a57c6a4b8 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/TextStyleTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/TextStyleTest.java @@ -1,59 +1,59 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.text.TextStyle; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; - -public class TextStyleTest extends TestCase { - public void testEquals() { - TextStyle style1 = new TextStyle(); - TextStyle style2 = new TextStyle(); - assertEquals(style1, style2); - - style1 = style1.align(SWT.CENTER); - assertFalse(style1.equals(style2)); - style2 = style2.align(SWT.CENTER); - assertEquals(style1, style2); - - style1 = style1.background(new RGB(127, 127, 127)); - assertFalse(style1.equals(style2)); - style2 = style2.background(new RGB(127, 127, 127)); - assertEquals(style1, style2); - - style1 = style1.font(new FontData("Arial", 12, SWT.BOLD)); - assertFalse(style1.equals(style2)); - style2 = style2.font(new FontData("Arial", 12, SWT.BOLD)); - assertEquals(style1, style2); - - style1 = style1.foreground(new RGB(127, 127, 127)); - assertFalse(style1.equals(style2)); - style2 = style2.foreground(new RGB(127, 127, 127)); - assertEquals(style1, style2); - - style1 = style1.strikeout(); - assertFalse(style1.equals(style2)); - style2 = style2.strikeout(); - assertEquals(style1, style2); - - style1 = style1.underline(); - assertFalse(style1.equals(style2)); - style2 = style2.underline(); - assertEquals(style1, style2); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.text.TextStyle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; + +public class TextStyleTest extends TestCase { + public void testEquals() { + TextStyle style1 = new TextStyle(); + TextStyle style2 = new TextStyle(); + assertEquals(style1, style2); + + style1 = style1.align(SWT.CENTER); + assertFalse(style1.equals(style2)); + style2 = style2.align(SWT.CENTER); + assertEquals(style1, style2); + + style1 = style1.background(new RGB(127, 127, 127)); + assertFalse(style1.equals(style2)); + style2 = style2.background(new RGB(127, 127, 127)); + assertEquals(style1, style2); + + style1 = style1.font(new FontData("Arial", 12, SWT.BOLD)); + assertFalse(style1.equals(style2)); + style2 = style2.font(new FontData("Arial", 12, SWT.BOLD)); + assertEquals(style1, style2); + + style1 = style1.foreground(new RGB(127, 127, 127)); + assertFalse(style1.equals(style2)); + style2 = style2.foreground(new RGB(127, 127, 127)); + assertEquals(style1, style2); + + style1 = style1.strikeout(); + assertFalse(style1.equals(style2)); + style2 = style2.strikeout(); + assertEquals(style1, style2); + + style1 = style1.underline(); + assertFalse(style1.equals(style2)); + style2 = style2.underline(); + assertEquals(style1, style2); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridCellTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridCellTest.java index d67f0c0e2..0ea093b87 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridCellTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridCellTest.java @@ -1,38 +1,38 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import org.eclipse.nebula.paperclips.core.PrintStub; -import org.eclipse.nebula.paperclips.core.grid.internal.GridCellImpl; -import org.eclipse.swt.SWT; - -import junit.framework.TestCase; - -public class GridCellTest extends TestCase { - @SuppressWarnings("restriction") - public void testEquals() { - GridCell cell = new GridCellImpl(SWT.DEFAULT, SWT.DEFAULT, - new PrintStub(0), 1); - assertTrue(cell.equals(new GridCellImpl(SWT.DEFAULT, SWT.DEFAULT, - new PrintStub(0), 1))); - assertFalse(cell.equals(new GridCellImpl(SWT.CENTER, SWT.DEFAULT, - new PrintStub(0), 1))); - assertFalse(cell.equals(new GridCellImpl(SWT.DEFAULT, SWT.CENTER, - new PrintStub(0), 1))); - assertFalse(cell.equals(new GridCellImpl(SWT.DEFAULT, SWT.DEFAULT, - new PrintStub(1), 1))); - assertFalse(cell.equals(new GridCellImpl(SWT.DEFAULT, SWT.DEFAULT, - new PrintStub(0), 2))); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import org.eclipse.nebula.paperclips.core.PrintStub; +import org.eclipse.nebula.paperclips.core.grid.internal.GridCellImpl; +import org.eclipse.swt.SWT; + +import junit.framework.TestCase; + +public class GridCellTest extends TestCase { + @SuppressWarnings("restriction") + public void testEquals() { + GridCell cell = new GridCellImpl(SWT.DEFAULT, SWT.DEFAULT, + new PrintStub(0), 1); + assertTrue(cell.equals(new GridCellImpl(SWT.DEFAULT, SWT.DEFAULT, + new PrintStub(0), 1))); + assertFalse(cell.equals(new GridCellImpl(SWT.CENTER, SWT.DEFAULT, + new PrintStub(0), 1))); + assertFalse(cell.equals(new GridCellImpl(SWT.DEFAULT, SWT.CENTER, + new PrintStub(0), 1))); + assertFalse(cell.equals(new GridCellImpl(SWT.DEFAULT, SWT.DEFAULT, + new PrintStub(1), 1))); + assertFalse(cell.equals(new GridCellImpl(SWT.DEFAULT, SWT.DEFAULT, + new PrintStub(0), 2))); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridColumnTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridColumnTest.java index 9b51a27ff..c20e85472 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridColumnTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridColumnTest.java @@ -1,52 +1,52 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import junit.framework.TestCase; - -import org.eclipse.nebula.paperclips.core.grid.GridColumn; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.swt.SWT; - -public class GridColumnTest extends TestCase { - public void testEquals_equivalent() { - GridColumn c1 = GridColumn.parse("l:p:g"); - GridColumn c2 = new GridColumn(SWT.LEFT, GridPrint.PREFERRED, 1); - assertEquals(c1, c2); - } - - public void testEquals_different() { - GridColumn gc = new GridColumn(SWT.LEFT, SWT.DEFAULT, 0); - assertFalse(gc.equals(new GridColumn(SWT.CENTER, SWT.DEFAULT, 0))); - assertFalse(gc.equals(new GridColumn(SWT.LEFT, GridPrint.PREFERRED, 0))); - assertFalse(gc.equals(new GridColumn(SWT.LEFT, SWT.DEFAULT, 1))); - } - - public void testInchConversion() { - assertEquals(72, GridColumn.parse("1 inch").size); - assertEquals(90, GridColumn.parse("1.25in").size); - assertEquals(108, GridColumn.parse("1.5INCH").size); - assertEquals(126, GridColumn.parse("1.75 IN").size); - } - - public void testCentimeterConversion() { - assertEquals(72, GridColumn.parse("2.54cm").size); - assertEquals(284, GridColumn.parse("10cm").size); // ceil(283.464) - } - - public void testMillimeterConversion() { - assertEquals(72, GridColumn.parse("25.4mm").size); - assertEquals(284, GridColumn.parse("100mm").size); // ceil(2834.64) - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import junit.framework.TestCase; + +import org.eclipse.nebula.paperclips.core.grid.GridColumn; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.swt.SWT; + +public class GridColumnTest extends TestCase { + public void testEquals_equivalent() { + GridColumn c1 = GridColumn.parse("l:p:g"); + GridColumn c2 = new GridColumn(SWT.LEFT, GridPrint.PREFERRED, 1); + assertEquals(c1, c2); + } + + public void testEquals_different() { + GridColumn gc = new GridColumn(SWT.LEFT, SWT.DEFAULT, 0); + assertFalse(gc.equals(new GridColumn(SWT.CENTER, SWT.DEFAULT, 0))); + assertFalse(gc.equals(new GridColumn(SWT.LEFT, GridPrint.PREFERRED, 0))); + assertFalse(gc.equals(new GridColumn(SWT.LEFT, SWT.DEFAULT, 1))); + } + + public void testInchConversion() { + assertEquals(72, GridColumn.parse("1 inch").size); + assertEquals(90, GridColumn.parse("1.25in").size); + assertEquals(108, GridColumn.parse("1.5INCH").size); + assertEquals(126, GridColumn.parse("1.75 IN").size); + } + + public void testCentimeterConversion() { + assertEquals(72, GridColumn.parse("2.54cm").size); + assertEquals(284, GridColumn.parse("10cm").size); // ceil(283.464) + } + + public void testMillimeterConversion() { + assertEquals(72, GridColumn.parse("25.4mm").size); + assertEquals(284, GridColumn.parse("100mm").size); // ceil(2834.64) + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridPrintTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridPrintTest.java index 4704abeaa..e8e749d99 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridPrintTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/grid/GridPrintTest.java @@ -1,102 +1,102 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.grid; - -import org.eclipse.nebula.paperclips.core.PrintStub; -import org.eclipse.nebula.paperclips.core.internal.util.Util; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; - -import junit.framework.TestCase; - -@SuppressWarnings("restriction") -public class GridPrintTest extends TestCase { - public void testConstructor_invalidArguments() { - try { - new GridPrint((GridLook) null); - fail(); - } catch (IllegalArgumentException expected) { - } - - try { - new GridPrint((GridColumn[]) null); - fail(); - } catch (IllegalArgumentException expected) { - } - - try { - new GridPrint((GridColumn[]) null); - fail(); - } catch (IllegalArgumentException expected) { - } - - try { - new GridPrint((String) null); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - public void testEquals() { - GridPrint g1 = new GridPrint(); - GridPrint g2 = new GridPrint(); - assertEquals(g1, g2); - - g1.addColumns("p, 80pt, d"); - assertFalse(g1.equals(g2)); - g2.addColumns("p, 80pt, d"); - assertEquals(g1, g2); - - g1.setLook(new GridLookStub()); - assertFalse(g1.equals(g2)); - g2.setLook(new GridLookStub()); - assertEquals(g1, g2); - - g1.setCellClippingEnabled(false); - assertFalse(g1.equals(g2)); - g2.setCellClippingEnabled(false); - assertEquals(g1, g2); - - g1.setColumnGroups(new int[][] { { 0, 1 } }); - assertFalse(g1.equals(g2)); - g2.setColumnGroups(new int[][] { { 0, 1 } }); - assertEquals(g1, g2); - - g1.add(new PrintStub()); - assertFalse(g1.equals(g2)); - g2.add(new PrintStub()); - assertEquals(g1, g2); - - g1.addHeader(new PrintStub()); - assertFalse(g1.equals(g2)); - g2.addHeader(new PrintStub()); - assertEquals(g1, g2); - - g1.addFooter(new PrintStub()); - assertFalse(g1.equals(g2)); - g2.addFooter(new PrintStub()); - assertEquals(g1, g2); - } - - static class GridLookStub implements GridLook { - @Override - public boolean equals(Object obj) { - return Util.sameClass(this, obj); - } - - public GridLookPainter getPainter(Device device, GC gc) { - return null; - } - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.grid; + +import org.eclipse.nebula.paperclips.core.PrintStub; +import org.eclipse.nebula.paperclips.core.internal.util.Util; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; + +import junit.framework.TestCase; + +@SuppressWarnings("restriction") +public class GridPrintTest extends TestCase { + public void testConstructor_invalidArguments() { + try { + new GridPrint((GridLook) null); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + new GridPrint((GridColumn[]) null); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + new GridPrint((GridColumn[]) null); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + new GridPrint((String) null); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testEquals() { + GridPrint g1 = new GridPrint(); + GridPrint g2 = new GridPrint(); + assertEquals(g1, g2); + + g1.addColumns("p, 80pt, d"); + assertFalse(g1.equals(g2)); + g2.addColumns("p, 80pt, d"); + assertEquals(g1, g2); + + g1.setLook(new GridLookStub()); + assertFalse(g1.equals(g2)); + g2.setLook(new GridLookStub()); + assertEquals(g1, g2); + + g1.setCellClippingEnabled(false); + assertFalse(g1.equals(g2)); + g2.setCellClippingEnabled(false); + assertEquals(g1, g2); + + g1.setColumnGroups(new int[][] { { 0, 1 } }); + assertFalse(g1.equals(g2)); + g2.setColumnGroups(new int[][] { { 0, 1 } }); + assertEquals(g1, g2); + + g1.add(new PrintStub()); + assertFalse(g1.equals(g2)); + g2.add(new PrintStub()); + assertEquals(g1, g2); + + g1.addHeader(new PrintStub()); + assertFalse(g1.equals(g2)); + g2.addHeader(new PrintStub()); + assertEquals(g1, g2); + + g1.addFooter(new PrintStub()); + assertFalse(g1.equals(g2)); + g2.addFooter(new PrintStub()); + assertEquals(g1, g2); + } + + static class GridLookStub implements GridLook { + @Override + public boolean equals(Object obj) { + return Util.sameClass(this, obj); + } + + public GridLookPainter getPainter(Device device, GC gc) { + return null; + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/internal/SWTUtilTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/internal/SWTUtilTest.java index 16fa2c241..d3805bc8a 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/internal/SWTUtilTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/internal/SWTUtilTest.java @@ -1,65 +1,65 @@ -/* - * Copyright (c) 2007-2008 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.internal; - -import org.eclipse.nebula.paperclips.core.internal.util.SWTUtil; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.PaletteData; -import org.eclipse.swt.graphics.RGB; - -import junit.framework.TestCase; - -@SuppressWarnings("restriction") -public class SWTUtilTest extends TestCase { - public void testDeriveRGB() { - assertEquals(new RGB(255, 0, 0), SWTUtil.deriveRGB(0xFF0000)); - assertEquals(new RGB(0, 255, 0), SWTUtil.deriveRGB(0x00FF00)); - assertEquals(new RGB(0, 0, 255), SWTUtil.deriveRGB(0x0000FF)); - } - - public void testEqualImageData_opaque() { - ImageData imageData = createImageData(100, 0, (byte) 0xFF); - assertTrue( - SWTUtil.equal(imageData, createImageData(100, 0, (byte) 0xFF))); - assertFalse( - SWTUtil.equal(imageData, createImageData(101, 0, (byte) 0xFF))); - assertFalse( - SWTUtil.equal(imageData, createImageData(100, 1, (byte) 0xFF))); - } - - public void testEqualImageData_transparent() { - assertTrue(SWTUtil.equal(createImageData(100, 0xFFFFFF, (byte) 0x7F), - createImageData(100, 0xFFFFFF, (byte) 0x7F))); - assertFalse(SWTUtil.equal(createImageData(99, 0xFFFFFF, (byte) 0x7F), - createImageData(99, 0xFFFFFF, (byte) 0xFF))); - assertTrue(SWTUtil.equal(createImageData(100, 0x000000, (byte) 0x00), - createImageData(100, 0xFFFFFF, (byte) 0x00))); - } - - private ImageData createImageData(int size, int color, byte alpha) { - ImageData imageData = new ImageData(size, size, 24, - new PaletteData(0xFF0000, 0x00FF00, 0x0000FF)); - int[] pixels = new int[size]; - byte[] alphas = new byte[size]; - for (int x = 0; x < size; x++) { - pixels[x] = color; - alphas[x] = alpha; - } - for (int y = 0; y < size; y++) { - imageData.setPixels(0, y, size, pixels, 0); - imageData.setAlphas(0, y, size, alphas, 0); - } - return imageData; - } -} +/* + * Copyright (c) 2007-2008 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.internal; + +import org.eclipse.nebula.paperclips.core.internal.util.SWTUtil; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.RGB; + +import junit.framework.TestCase; + +@SuppressWarnings("restriction") +public class SWTUtilTest extends TestCase { + public void testDeriveRGB() { + assertEquals(new RGB(255, 0, 0), SWTUtil.deriveRGB(0xFF0000)); + assertEquals(new RGB(0, 255, 0), SWTUtil.deriveRGB(0x00FF00)); + assertEquals(new RGB(0, 0, 255), SWTUtil.deriveRGB(0x0000FF)); + } + + public void testEqualImageData_opaque() { + ImageData imageData = createImageData(100, 0, (byte) 0xFF); + assertTrue( + SWTUtil.equal(imageData, createImageData(100, 0, (byte) 0xFF))); + assertFalse( + SWTUtil.equal(imageData, createImageData(101, 0, (byte) 0xFF))); + assertFalse( + SWTUtil.equal(imageData, createImageData(100, 1, (byte) 0xFF))); + } + + public void testEqualImageData_transparent() { + assertTrue(SWTUtil.equal(createImageData(100, 0xFFFFFF, (byte) 0x7F), + createImageData(100, 0xFFFFFF, (byte) 0x7F))); + assertFalse(SWTUtil.equal(createImageData(99, 0xFFFFFF, (byte) 0x7F), + createImageData(99, 0xFFFFFF, (byte) 0xFF))); + assertTrue(SWTUtil.equal(createImageData(100, 0x000000, (byte) 0x00), + createImageData(100, 0xFFFFFF, (byte) 0x00))); + } + + private ImageData createImageData(int size, int color, byte alpha) { + ImageData imageData = new ImageData(size, size, 24, + new PaletteData(0xFF0000, 0x00FF00, 0x0000FF)); + int[] pixels = new int[size]; + byte[] alphas = new byte[size]; + for (int x = 0; x < size; x++) { + pixels[x] = color; + alphas[x] = alpha; + } + for (int y = 0; y < size; y++) { + imageData.setPixels(0, y, size, pixels, 0); + imageData.setAlphas(0, y, size, alphas, 0); + } + return imageData; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/internal/UtilTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/internal/UtilTest.java index 1f2aeeefb..c71276831 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/internal/UtilTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/core/internal/UtilTest.java @@ -1,105 +1,105 @@ -/* - * Copyright (c) 2007-2008 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.core.internal; - -import org.eclipse.nebula.paperclips.core.internal.util.Util; - -import junit.framework.TestCase; - -@SuppressWarnings("restriction") -public class UtilTest extends TestCase { - public void testSameClass_same() { - Object o1 = new Object(); - Object o2 = new Object(); - assertTrue(Util.sameClass(o1, o2)); - } - - public void testSameClass_different() { - Object o1 = new Object(); - Object o2 = new Object() { - }; // subclass - assertFalse(Util.sameClass(o1, o2)); - - assertFalse(Util.sameClass(null, o2)); - assertFalse(Util.sameClass(o1, null)); - } - - public void testEqual_equivalent() { - Object o1 = new Stub(); - Object o2 = new Stub(); - assertTrue(Util.equal(o1, o2)); - } - - public void testEqual_different() { - Object o1 = new Object(); - Object o2 = new Object(); - assertFalse(Util.equal(o1, o2)); - assertFalse(Util.equal(null, o2)); - assertFalse(Util.equal(o1, null)); - } - - public void testEqual_equivalentArray() { - assertTrue(Util.equal(new byte[] { 0, 1 }, new byte[] { 0, 1 })); - assertTrue(Util.equal(new short[] { 0, 1 }, new short[] { 0, 1 })); - assertTrue(Util.equal(new int[] { 0, 1 }, new int[] { 0, 1 })); - assertTrue(Util.equal(new long[] { 0, 1 }, new long[] { 0, 1 })); - assertTrue(Util.equal(new char[] { 0, 1 }, new char[] { 0, 1 })); - assertTrue(Util.equal(new float[] { 0, 1 }, new float[] { 0, 1 })); - assertTrue(Util.equal(new double[] { 0, 1 }, new double[] { 0, 1 })); - assertTrue(Util.equal(new boolean[] { false, true }, - new boolean[] { false, true })); - assertTrue(Util.equal(new Object[] { new Stub(), new Stub() }, - new Object[] { new Stub(), new Stub() })); - } - - public void testEqual_differentArray() { - assertFalse(Util.equal(new byte[] { 0, 1 }, new byte[] { 0, 2 })); - assertFalse(Util.equal(new short[] { 0, 1 }, new short[] { 0, 2 })); - assertFalse(Util.equal(new int[] { 0, 1 }, new int[] { 0, 2 })); - assertFalse(Util.equal(new long[] { 0, 1 }, new long[] { 0, 2 })); - assertFalse(Util.equal(new char[] { 0, 1 }, new char[] { 0, 2 })); - assertFalse(Util.equal(new float[] { 0, 1 }, new float[] { 0, 2 })); - assertFalse(Util.equal(new double[] { 0, 1 }, new double[] { 0, 2 })); - assertFalse(Util.equal(new boolean[] { false, true }, - new boolean[] { false, false })); - assertFalse(Util.equal(new Object[] { new Stub(), new Stub() }, - new Object[] { new Stub(), new Object() })); - } - - public void testEqual_equivalentNestedArray() { - assertTrue(Util.equal(new Object[] { new Object[] { new Stub() } }, - new Object[] { new Object[] { new Stub() } })); - assertTrue( - Util.equal(new int[][] { { 0, 1 } }, new int[][] { { 0, 1 } })); - } - - public void testEqual_differentNestedArray() { - assertFalse(Util.equal(new Object[] { new Object[] { new Stub() } }, - new Object[] { new Object[] { new Object() } })); - assertFalse( - Util.equal(new int[][] { { 0, 1 } }, new int[][] { { 0, 2 } })); - } - - public void testEqual_double() { - assertTrue(Util.equal(2.0, 2.0)); - assertFalse(Util.equal(2.0, 1.0)); - } - - public class Stub { - @Override - public boolean equals(Object obj) { - return Util.sameClass(this, obj); - } - } -} +/* + * Copyright (c) 2007-2008 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.core.internal; + +import org.eclipse.nebula.paperclips.core.internal.util.Util; + +import junit.framework.TestCase; + +@SuppressWarnings("restriction") +public class UtilTest extends TestCase { + public void testSameClass_same() { + Object o1 = new Object(); + Object o2 = new Object(); + assertTrue(Util.sameClass(o1, o2)); + } + + public void testSameClass_different() { + Object o1 = new Object(); + Object o2 = new Object() { + }; // subclass + assertFalse(Util.sameClass(o1, o2)); + + assertFalse(Util.sameClass(null, o2)); + assertFalse(Util.sameClass(o1, null)); + } + + public void testEqual_equivalent() { + Object o1 = new Stub(); + Object o2 = new Stub(); + assertTrue(Util.equal(o1, o2)); + } + + public void testEqual_different() { + Object o1 = new Object(); + Object o2 = new Object(); + assertFalse(Util.equal(o1, o2)); + assertFalse(Util.equal(null, o2)); + assertFalse(Util.equal(o1, null)); + } + + public void testEqual_equivalentArray() { + assertTrue(Util.equal(new byte[] { 0, 1 }, new byte[] { 0, 1 })); + assertTrue(Util.equal(new short[] { 0, 1 }, new short[] { 0, 1 })); + assertTrue(Util.equal(new int[] { 0, 1 }, new int[] { 0, 1 })); + assertTrue(Util.equal(new long[] { 0, 1 }, new long[] { 0, 1 })); + assertTrue(Util.equal(new char[] { 0, 1 }, new char[] { 0, 1 })); + assertTrue(Util.equal(new float[] { 0, 1 }, new float[] { 0, 1 })); + assertTrue(Util.equal(new double[] { 0, 1 }, new double[] { 0, 1 })); + assertTrue(Util.equal(new boolean[] { false, true }, + new boolean[] { false, true })); + assertTrue(Util.equal(new Object[] { new Stub(), new Stub() }, + new Object[] { new Stub(), new Stub() })); + } + + public void testEqual_differentArray() { + assertFalse(Util.equal(new byte[] { 0, 1 }, new byte[] { 0, 2 })); + assertFalse(Util.equal(new short[] { 0, 1 }, new short[] { 0, 2 })); + assertFalse(Util.equal(new int[] { 0, 1 }, new int[] { 0, 2 })); + assertFalse(Util.equal(new long[] { 0, 1 }, new long[] { 0, 2 })); + assertFalse(Util.equal(new char[] { 0, 1 }, new char[] { 0, 2 })); + assertFalse(Util.equal(new float[] { 0, 1 }, new float[] { 0, 2 })); + assertFalse(Util.equal(new double[] { 0, 1 }, new double[] { 0, 2 })); + assertFalse(Util.equal(new boolean[] { false, true }, + new boolean[] { false, false })); + assertFalse(Util.equal(new Object[] { new Stub(), new Stub() }, + new Object[] { new Stub(), new Object() })); + } + + public void testEqual_equivalentNestedArray() { + assertTrue(Util.equal(new Object[] { new Object[] { new Stub() } }, + new Object[] { new Object[] { new Stub() } })); + assertTrue( + Util.equal(new int[][] { { 0, 1 } }, new int[][] { { 0, 1 } })); + } + + public void testEqual_differentNestedArray() { + assertFalse(Util.equal(new Object[] { new Object[] { new Stub() } }, + new Object[] { new Object[] { new Object() } })); + assertFalse( + Util.equal(new int[][] { { 0, 1 } }, new int[][] { { 0, 2 } })); + } + + public void testEqual_double() { + assertTrue(Util.equal(2.0, 2.0)); + assertFalse(Util.equal(2.0, 1.0)); + } + + public class Stub { + @Override + public boolean equals(Object obj) { + return Util.sameClass(this, obj); + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/Benchmark.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/Benchmark.java index bc34796a5..a56ac3ce5 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/Benchmark.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/Benchmark.java @@ -1,86 +1,86 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.tests.benchmark; - -import java.io.PrintStream; -import java.text.NumberFormat; -import java.util.Locale; - -public class Benchmark { - private int runCount = 1; - private Clock clock = getDefaultClock(); - private String name = "Unnamed benchmark"; - private PrintStream printStream = System.out; - - public Benchmark() { - } - - public Benchmark setName(String name) { - this.name = name; - return this; - } - - public Benchmark setClock(Clock clock) { - this.clock = clock; - return this; - } - - public Benchmark setRunCount(int runCount) { - this.runCount = runCount; - return this; - } - - public Benchmark setPrintStream(PrintStream printStream) { - this.printStream = printStream; - return this; - } - - public long execute(Runnable runnable) { - long total = 0; - printStream.println("Benchmarking '" + name + "':"); - for (int i = 0; i < runCount; i++) { - long time = time(clock, runnable); - printStream.println("\tRun " + (i + 1) + "/" + runCount + ":\t" - + time + "ms"); - total += time; - } - printStream.println("Total: \t" + total + "ms"); - printStream.println("Average:\t" - + getNumberFormat().format((float) total / (float) runCount) - + "ms"); - return total; - } - - private NumberFormat getNumberFormat() { - NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US); - numberFormat.setMinimumFractionDigits(1); - numberFormat.setMaximumFractionDigits(1); - return numberFormat; - } - - public static long time(Runnable runnable) { - return time(getDefaultClock(), runnable); - } - - private static SystemClock getDefaultClock() { - return new SystemClock(); - } - - public static long time(Clock clock, Runnable runnable) { - long before = clock.getTime(); - runnable.run(); - long after = clock.getTime(); - return after - before; - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.tests.benchmark; + +import java.io.PrintStream; +import java.text.NumberFormat; +import java.util.Locale; + +public class Benchmark { + private int runCount = 1; + private Clock clock = getDefaultClock(); + private String name = "Unnamed benchmark"; + private PrintStream printStream = System.out; + + public Benchmark() { + } + + public Benchmark setName(String name) { + this.name = name; + return this; + } + + public Benchmark setClock(Clock clock) { + this.clock = clock; + return this; + } + + public Benchmark setRunCount(int runCount) { + this.runCount = runCount; + return this; + } + + public Benchmark setPrintStream(PrintStream printStream) { + this.printStream = printStream; + return this; + } + + public long execute(Runnable runnable) { + long total = 0; + printStream.println("Benchmarking '" + name + "':"); + for (int i = 0; i < runCount; i++) { + long time = time(clock, runnable); + printStream.println("\tRun " + (i + 1) + "/" + runCount + ":\t" + + time + "ms"); + total += time; + } + printStream.println("Total: \t" + total + "ms"); + printStream.println("Average:\t" + + getNumberFormat().format((float) total / (float) runCount) + + "ms"); + return total; + } + + private NumberFormat getNumberFormat() { + NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US); + numberFormat.setMinimumFractionDigits(1); + numberFormat.setMaximumFractionDigits(1); + return numberFormat; + } + + public static long time(Runnable runnable) { + return time(getDefaultClock(), runnable); + } + + private static SystemClock getDefaultClock() { + return new SystemClock(); + } + + public static long time(Clock clock, Runnable runnable) { + long before = clock.getTime(); + runnable.run(); + long after = clock.getTime(); + return after - before; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/BenchmarkTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/BenchmarkTest.java index c2182f2af..aaa9030fd 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/BenchmarkTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/BenchmarkTest.java @@ -1,86 +1,86 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.tests.benchmark; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -import junit.framework.TestCase; - -public class BenchmarkTest extends TestCase { - StopClock clock; - ByteArrayOutputStream output; - Benchmark benchmark; - RunnableStub runnable; - int executionTime; - - protected void setUp() throws Exception { - super.setUp(); - clock = new StopClock(0); - output = new ByteArrayOutputStream(); - final PrintStream printStream = new PrintStream(output); - benchmark = new Benchmark().setName(getName()).setClock(clock) - .setPrintStream(printStream); - runnable = new RunnableStub(); - executionTime = 100; - } - - protected void tearDown() throws Exception { - output.close(); - } - - public void testTime() { - assertEquals(executionTime, Benchmark.time(clock, runnable)); - assertEquals(1, runnable.callbackCount); - } - - public void testExecute() { - assertEquals(executionTime, benchmark.execute(runnable)); - } - - public void testSetRunCount() { - int runCount = 10; - assertEquals(runCount * executionTime, benchmark.setRunCount(10) - .execute(runnable)); - assertEquals(runCount, runnable.callbackCount); - } - - public void testOutput() throws Exception { - String newline = System.getProperty("line.separator"); - String expected = "Benchmarking 'testOutput':" + newline - + "\tRun 1/3:\t10ms" + newline + "\tRun 2/3:\t20ms" + newline - + "\tRun 3/3:\t30ms" + newline + "Total: \t60ms" + newline - + "Average:\t20.0ms" + newline; - - final int[] runTimes = { 10, 20, 30 }; - benchmark.setRunCount(runTimes.length).execute(new Runnable() { - int runIndex = 0; - - public void run() { - clock.time += runTimes[runIndex++]; - } - }); - - assertEquals(expected, output.toString()); - } - - class RunnableStub implements Runnable { - int callbackCount = 0; - - public void run() { - callbackCount++; - clock.time += executionTime; - } - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.tests.benchmark; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import junit.framework.TestCase; + +public class BenchmarkTest extends TestCase { + StopClock clock; + ByteArrayOutputStream output; + Benchmark benchmark; + RunnableStub runnable; + int executionTime; + + protected void setUp() throws Exception { + super.setUp(); + clock = new StopClock(0); + output = new ByteArrayOutputStream(); + final PrintStream printStream = new PrintStream(output); + benchmark = new Benchmark().setName(getName()).setClock(clock) + .setPrintStream(printStream); + runnable = new RunnableStub(); + executionTime = 100; + } + + protected void tearDown() throws Exception { + output.close(); + } + + public void testTime() { + assertEquals(executionTime, Benchmark.time(clock, runnable)); + assertEquals(1, runnable.callbackCount); + } + + public void testExecute() { + assertEquals(executionTime, benchmark.execute(runnable)); + } + + public void testSetRunCount() { + int runCount = 10; + assertEquals(runCount * executionTime, benchmark.setRunCount(10) + .execute(runnable)); + assertEquals(runCount, runnable.callbackCount); + } + + public void testOutput() throws Exception { + String newline = System.getProperty("line.separator"); + String expected = "Benchmarking 'testOutput':" + newline + + "\tRun 1/3:\t10ms" + newline + "\tRun 2/3:\t20ms" + newline + + "\tRun 3/3:\t30ms" + newline + "Total: \t60ms" + newline + + "Average:\t20.0ms" + newline; + + final int[] runTimes = { 10, 20, 30 }; + benchmark.setRunCount(runTimes.length).execute(new Runnable() { + int runIndex = 0; + + public void run() { + clock.time += runTimes[runIndex++]; + } + }); + + assertEquals(expected, output.toString()); + } + + class RunnableStub implements Runnable { + int callbackCount = 0; + + public void run() { + callbackCount++; + clock.time += executionTime; + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/Clock.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/Clock.java index eef831fa3..72f4585b7 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/Clock.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/Clock.java @@ -1,18 +1,18 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.tests.benchmark; - -public interface Clock { - public long getTime(); -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.tests.benchmark; + +public interface Clock { + public long getTime(); +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/StopClock.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/StopClock.java index ed945208d..5436b85f6 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/StopClock.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/StopClock.java @@ -1,30 +1,30 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.tests.benchmark; - -public class StopClock implements Clock { - public StopClock() { - this(0); - } - - public StopClock(long initial) { - this.time = initial; - } - - public long time; - - public long getTime() { - return time; - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.tests.benchmark; + +public class StopClock implements Clock { + public StopClock() { + this(0); + } + + public StopClock(long initial) { + this.time = initial; + } + + public long time; + + public long getTime() { + return time; + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/StopClockTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/StopClockTest.java index 2d9bbc085..1f546afef 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/StopClockTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/StopClockTest.java @@ -1,32 +1,32 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.tests.benchmark; - -import junit.framework.TestCase; - -public class StopClockTest extends TestCase { - public void testConstructor() { - assertEquals(0, new StopClock().getTime()); - assertEquals(0, new StopClock(0).getTime()); - assertEquals(10, new StopClock(10).getTime()); - } - - public void testGetTime() { - StopClock clock = new StopClock(); - clock.time = 0; - assertEquals(0, clock.getTime()); - clock.time = 50; - assertEquals(50, clock.getTime()); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.tests.benchmark; + +import junit.framework.TestCase; + +public class StopClockTest extends TestCase { + public void testConstructor() { + assertEquals(0, new StopClock().getTime()); + assertEquals(0, new StopClock(0).getTime()); + assertEquals(10, new StopClock(10).getTime()); + } + + public void testGetTime() { + StopClock clock = new StopClock(); + clock.time = 0; + assertEquals(0, clock.getTime()); + clock.time = 50; + assertEquals(50, clock.getTime()); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/SystemClock.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/SystemClock.java index 426e54dea..699fb79fe 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/SystemClock.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/SystemClock.java @@ -1,20 +1,20 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.tests.benchmark; - -public class SystemClock implements Clock { - public long getTime() { - return System.currentTimeMillis(); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.tests.benchmark; + +public class SystemClock implements Clock { + public long getTime() { + return System.currentTimeMillis(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/SystemClockTest.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/SystemClockTest.java index 03b972438..8c7daf9ea 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/SystemClockTest.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/benchmark/SystemClockTest.java @@ -1,27 +1,27 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.tests.benchmark; - -import junit.framework.TestCase; - -public class SystemClockTest extends TestCase { - public void testGetTime() { - final Clock clock = new SystemClock(); - - long before = System.currentTimeMillis(); - long clockTime = clock.getTime(); - long after = System.currentTimeMillis(); - assertTrue(before <= clockTime && clockTime <= after); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.tests.benchmark; + +import junit.framework.TestCase; + +public class SystemClockTest extends TestCase { + public void testGetTime() { + final Clock clock = new SystemClock(); + + long before = System.currentTimeMillis(); + long clockTime = clock.getTime(); + long after = System.currentTimeMillis(); + assertTrue(before <= clockTime && clockTime <= after); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/main/SnippetBenchmarks.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/main/SnippetBenchmarks.java index 3c6428df6..f3dadcd64 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/main/SnippetBenchmarks.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/main/SnippetBenchmarks.java @@ -1,116 +1,116 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.tests.main; - -import java.text.NumberFormat; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.snippets.Snippet2; -import org.eclipse.nebula.paperclips.snippets.Snippet3; -import org.eclipse.nebula.paperclips.snippets.Snippet4; -import org.eclipse.nebula.paperclips.snippets.Snippet5; -import org.eclipse.nebula.paperclips.snippets.Snippet6; -import org.eclipse.nebula.paperclips.snippets.Snippet7; -import org.eclipse.nebula.paperclips.snippets.Snippet8; -import org.eclipse.nebula.paperclips.tests.benchmark.Benchmark; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.widgets.Display; - -/** - * Benchmarks the time required to layout the various snippets. - * - * @author Matthew - */ -public class SnippetBenchmarks { - /** - * Executes the benchmark. - * - * @param args - * command-line args. - */ - public static void main(String[] args) { - // Bug in SWT--a Display must be instantiated under Linux in order to - // use printer - Display.getDefault(); - - benchmarkSnippet8(); - } - - private static void benchmarkSnippet8() { - final Printer printer = new Printer(); - printer.startJob("benchmarkSnippet8"); - - final PrintJob job = new PrintJob("Snippet8", Snippet8.createPrint()); - - final GC gc = new GC(printer); - new Benchmark().setName("getPageEnumeration").setRunCount(10).execute( - new Runnable() { - public void run() { - PaperClips.getPageEnumeration(job, printer, gc) - .nextPage(); - } - }); - gc.dispose(); - - new Benchmark().setName("getPages").setRunCount(10).execute( - new Runnable() { - public void run() { - PaperClips.getPages(job, printer); - } - }); - - printer.cancelJob(); - printer.dispose(); - } - - static void benchmarkSnippets() { - String[] names = {"Snippet2", "Snippet3", "Snippet4", "Snippet5", - "Snippet6", "Snippet7"}; - Print[] documents = {Snippet2.createPrint(), Snippet3.createPrint(), - Snippet4.createPrint(), Snippet5.createPrint(), - Snippet6.createPrint(), Snippet7.createPrint()}; - final Printer printer = new Printer(); - printer.startJob("benchmarkSnippets"); - final int RUN_COUNT = 100; - - long total = 0; - for (int i = 0; i < documents.length; i++) { - final PrintJob job = new PrintJob(names[i], documents[i]) - .setMargins(108); - total += new Benchmark().setRunCount(RUN_COUNT).setName(names[i]) - .execute(new Runnable() { - public void run() { - PaperClips.getPages(job, printer); - } - }); - } - - printer.cancelJob(); - printer.dispose(); - - printFinalResult(total, total / (double) (RUN_COUNT * documents.length)); - } - - private static void printFinalResult(long total, final double average) { - System.out.println(); - System.out.println("Grand total:\t" + total + "ms"); - NumberFormat format = NumberFormat.getNumberInstance(); - format.setMinimumFractionDigits(1); - format.setMaximumFractionDigits(1); - System.out.println("Average: \t" + format.format(average) + "ms"); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.tests.main; + +import java.text.NumberFormat; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.snippets.Snippet2; +import org.eclipse.nebula.paperclips.snippets.Snippet3; +import org.eclipse.nebula.paperclips.snippets.Snippet4; +import org.eclipse.nebula.paperclips.snippets.Snippet5; +import org.eclipse.nebula.paperclips.snippets.Snippet6; +import org.eclipse.nebula.paperclips.snippets.Snippet7; +import org.eclipse.nebula.paperclips.snippets.Snippet8; +import org.eclipse.nebula.paperclips.tests.benchmark.Benchmark; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.widgets.Display; + +/** + * Benchmarks the time required to layout the various snippets. + * + * @author Matthew + */ +public class SnippetBenchmarks { + /** + * Executes the benchmark. + * + * @param args + * command-line args. + */ + public static void main(String[] args) { + // Bug in SWT--a Display must be instantiated under Linux in order to + // use printer + Display.getDefault(); + + benchmarkSnippet8(); + } + + private static void benchmarkSnippet8() { + final Printer printer = new Printer(); + printer.startJob("benchmarkSnippet8"); + + final PrintJob job = new PrintJob("Snippet8", Snippet8.createPrint()); + + final GC gc = new GC(printer); + new Benchmark().setName("getPageEnumeration").setRunCount(10).execute( + new Runnable() { + public void run() { + PaperClips.getPageEnumeration(job, printer, gc) + .nextPage(); + } + }); + gc.dispose(); + + new Benchmark().setName("getPages").setRunCount(10).execute( + new Runnable() { + public void run() { + PaperClips.getPages(job, printer); + } + }); + + printer.cancelJob(); + printer.dispose(); + } + + static void benchmarkSnippets() { + String[] names = {"Snippet2", "Snippet3", "Snippet4", "Snippet5", + "Snippet6", "Snippet7"}; + Print[] documents = {Snippet2.createPrint(), Snippet3.createPrint(), + Snippet4.createPrint(), Snippet5.createPrint(), + Snippet6.createPrint(), Snippet7.createPrint()}; + final Printer printer = new Printer(); + printer.startJob("benchmarkSnippets"); + final int RUN_COUNT = 100; + + long total = 0; + for (int i = 0; i < documents.length; i++) { + final PrintJob job = new PrintJob(names[i], documents[i]) + .setMargins(108); + total += new Benchmark().setRunCount(RUN_COUNT).setName(names[i]) + .execute(new Runnable() { + public void run() { + PaperClips.getPages(job, printer); + } + }); + } + + printer.cancelJob(); + printer.dispose(); + + printFinalResult(total, total / (double) (RUN_COUNT * documents.length)); + } + + private static void printFinalResult(long total, final double average) { + System.out.println(); + System.out.println("Grand total:\t" + total + "ms"); + NumberFormat format = NumberFormat.getNumberInstance(); + format.setMinimumFractionDigits(1); + format.setMaximumFractionDigits(1); + System.out.println("Average: \t" + format.format(average) + "ms"); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/main/TestWhetherBorderPrintHoldsSomeContentForLastPage.java b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/main/TestWhetherBorderPrintHoldsSomeContentForLastPage.java index bb92c8c35..63a4a1088 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/main/TestWhetherBorderPrintHoldsSomeContentForLastPage.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.tests/src/org/eclipse/nebula/paperclips/tests/main/TestWhetherBorderPrintHoldsSomeContentForLastPage.java @@ -1,64 +1,64 @@ -/* - * Copyright (c) 2007 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.tests.main; - -import org.eclipse.nebula.paperclips.core.ColumnPrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.border.BorderPrint; -import org.eclipse.nebula.paperclips.core.border.LineBorder; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Display; - -/** - * Prints "The quick brown fox jumps over the lazy dog." in increasingly large - * blocks, using a BreakPrint every 5 blocks to force printing to advance to the - * next column / page. - * - * @author Matthew - */ -public class TestWhetherBorderPrintHoldsSomeContentForLastPage { - public static Print createPrint() { - GridPrint grid = new GridPrint("d:g", new DefaultGridLook(10, 10)); - - String text = "The quick brown fox jumps over the lazy dog."; - String printText = text; - - LineBorder border = new LineBorder(); - for (int i = 0; i < 100; i++, printText += " " + text) { - grid.add(new BorderPrint(new TextPrint(printText), border)); - } - - return new ColumnPrint(grid, 2, 10); - } - - /** - * Prints the BreakPrintExample to the default printer. - * - * @param args - * command-line args - */ - public static void main(String[] args) { - // Workaround for SWT bug on GTK - force SWT to initialize so we don't - // crash. - Display.getDefault(); - - PaperClips.print(new PrintJob("BreakPrintExample.java", createPrint()), - new PrinterData()); - } -} +/* + * Copyright (c) 2007 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.tests.main; + +import org.eclipse.nebula.paperclips.core.ColumnPrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.border.BorderPrint; +import org.eclipse.nebula.paperclips.core.border.LineBorder; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Display; + +/** + * Prints "The quick brown fox jumps over the lazy dog." in increasingly large + * blocks, using a BreakPrint every 5 blocks to force printing to advance to the + * next column / page. + * + * @author Matthew + */ +public class TestWhetherBorderPrintHoldsSomeContentForLastPage { + public static Print createPrint() { + GridPrint grid = new GridPrint("d:g", new DefaultGridLook(10, 10)); + + String text = "The quick brown fox jumps over the lazy dog."; + String printText = text; + + LineBorder border = new LineBorder(); + for (int i = 0; i < 100; i++, printText += " " + text) { + grid.add(new BorderPrint(new TextPrint(printText), border)); + } + + return new ColumnPrint(grid, 2, 10); + } + + /** + * Prints the BreakPrintExample to the default printer. + * + * @param args + * command-line args + */ + public static void main(String[] args) { + // Workaround for SWT bug on GTK - force SWT to initialize so we don't + // crash. + Display.getDefault(); + + PaperClips.print(new PrintJob("BreakPrintExample.java", createPrint()), + new PrinterData()); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.classpath b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.classpath index 540ee9402..7aa94b021 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.classpath +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.settings/org.eclipse.jdt.core.prefs b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.settings/org.eclipse.jdt.core.prefs index 5b8f53c16..ea1ed8042 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.settings/org.eclipse.jdt.core.prefs @@ -1,366 +1,366 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true -org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true -org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true -org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true -org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.doc.comment.support=enabled +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning +org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true +org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true +org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true +org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true +org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.settings/org.eclipse.jdt.ui.prefs b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.settings/org.eclipse.jdt.ui.prefs index 1fe313cc2..4ba394e23 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.settings/org.eclipse.jdt.ui.prefs +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/.settings/org.eclipse.jdt.ui.prefs @@ -1,52 +1,52 @@ -#Tue Aug 11 15:07:13 MDT 2009 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile -formatter_settings_version=11 -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.format_source_code=true -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=true -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +#Tue Aug 11 15:07:13 MDT 2009 +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile +formatter_settings_version=11 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.format_source_code=true +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=true +sp_cleanup.remove_unused_imports=true +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/META-INF/MANIFEST.MF b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/META-INF/MANIFEST.MF index a8669bdb9..1a7ec8d45 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/META-INF/MANIFEST.MF +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Paperclips UI -Bundle-SymbolicName: org.eclipse.nebula.paperclips.widgets -Bundle-Version: 2.1.0.qualifier -Bundle-Vendor: Eclipse Nebula -Require-Bundle: org.eclipse.nebula.paperclips.core;bundle-version="[2.0.0,3.0.0)", - org.eclipse.swt;bundle-version="[3.2.0,4.0.0)" -Export-Package: org.eclipse.nebula.paperclips.widgets -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Automatic-Module-Name: org.eclipse.nebula.paperclips.widgets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Paperclips UI +Bundle-SymbolicName: org.eclipse.nebula.paperclips.widgets +Bundle-Version: 2.1.0.qualifier +Bundle-Vendor: Eclipse Nebula +Require-Bundle: org.eclipse.nebula.paperclips.core;bundle-version="[2.0.0,3.0.0)", + org.eclipse.swt;bundle-version="[3.2.0,4.0.0)" +Export-Package: org.eclipse.nebula.paperclips.widgets +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Automatic-Module-Name: org.eclipse.nebula.paperclips.widgets diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/build.properties b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/build.properties index 57ebdfabe..f83bbad9a 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/build.properties +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/build.properties @@ -1,6 +1,6 @@ -source.. = src/ -output.. = class/ -bin.includes = META-INF/,\ - .,\ - about.html - +source.. = src/ +output.. = class/ +bin.includes = META-INF/,\ + .,\ + about.html + diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintPieceCanvas.java b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintPieceCanvas.java index 1c2a2b0a9..4b93a7df1 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintPieceCanvas.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintPieceCanvas.java @@ -1,81 +1,81 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.widgets; - -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; - -/** - * A canvas for displaying Print objects. - * - * @author Matthew - */ -public class PrintPieceCanvas extends Canvas { - PrintPiece piece = null; - - /** - * Constructs a PrintCanvas with the given parent and style. - * - * @param parent - * the parent Composite. - * @param style - * the style parameter. - */ - public PrintPieceCanvas(Composite parent, int style) { - super(parent, style); - - setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND)); - - addListener(SWT.Paint, event -> { - if (piece == null) - return; - - Rectangle client = getClientArea(); - piece.paint(event.gc, client.x, client.y); - }); - addListener(SWT.Dispose, event -> { - disposePrintPiece(); - }); - } - - /** - * Displays the given Print in this PrintCanvas. - * - * @param piece - * the PrintPiece to display. - */ - public void setPrintPiece(PrintPiece piece) { - disposePrintPiece(); - this.piece = piece; - redraw(); - } - - /** - * Returns the PrintPiece being displayed by this PrintCanvas. - * - * @return the PrintPiece being displayed by this PrintCanvas. - */ - public PrintPiece getPrintPiece() { - return piece; - } - - private void disposePrintPiece() { - if (piece != null) - piece.dispose(); - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.widgets; + +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; + +/** + * A canvas for displaying Print objects. + * + * @author Matthew + */ +public class PrintPieceCanvas extends Canvas { + PrintPiece piece = null; + + /** + * Constructs a PrintCanvas with the given parent and style. + * + * @param parent + * the parent Composite. + * @param style + * the style parameter. + */ + public PrintPieceCanvas(Composite parent, int style) { + super(parent, style); + + setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND)); + + addListener(SWT.Paint, event -> { + if (piece == null) + return; + + Rectangle client = getClientArea(); + piece.paint(event.gc, client.x, client.y); + }); + addListener(SWT.Dispose, event -> { + disposePrintPiece(); + }); + } + + /** + * Displays the given Print in this PrintCanvas. + * + * @param piece + * the PrintPiece to display. + */ + public void setPrintPiece(PrintPiece piece) { + disposePrintPiece(); + this.piece = piece; + redraw(); + } + + /** + * Returns the PrintPiece being displayed by this PrintCanvas. + * + * @return the PrintPiece being displayed by this PrintCanvas. + */ + public PrintPiece getPrintPiece() { + return piece; + } + + private void disposePrintPiece() { + if (piece != null) + piece.dispose(); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintPreview.java b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintPreview.java index b9959d2a0..b2b98993c 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintPreview.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintPreview.java @@ -1,842 +1,842 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.widgets; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.nebula.paperclips.core.PageEnumeration; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -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.graphics.Transform; -import org.eclipse.swt.printing.Printer; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; - -/** - * A WYSIWYG (what you see is what you get) print preview panel. This control - * displays a preview of what a PrintJob will look like on paper, depending on - * the selected printer. - *

- *
Styles:
- *
(none)
- *
Events:
- *
(none)
- *
- * - * @author Matthew Hall - */ -public class PrintPreview extends Canvas { - private static final int ALL_PAGES = -1; - - private PrintJob printJob = null; - private PrinterData printerData = PaperClips.getDefaultPrinterData(); - private int pageIndex = 0; - private boolean fitHorizontal = true; - private boolean fitVertical = true; - private float scale = 1.0f; - private int horizontalPageCount = 1; - private int verticalPageCount = 1; - private boolean lazy = false; - - // The bounds of the paper on the printer device. - private Point paperSize = null; - private Printer printer = null; - private GC gc = null; - - private PageEnumeration pageEnumeration = null; - private List pages = null; - private Point pageDisplaySize = null; - private Point[] pageDisplayLocations = null; - - // Margins and page spacing include paper boilerplate. - private Rectangle margins = new Rectangle(10, 10, 10, 10); - private Point pageSpacing = new Point(10, 10); - - /** - * Constructs a PrintPreview control. - * - * @param parent - * the parent control. - * @param style - * the control style. - */ - public PrintPreview(Composite parent, int style) { - super(parent, style | SWT.DOUBLE_BUFFERED); - - addListener(SWT.Paint, event -> { - paint(event); - }); - - addListener(SWT.Resize, event -> { - invalidatePageDisplayBounds(); - redraw(); - }); - - addListener(SWT.Dispose, event -> { - disposeResources(); - }); - } - - /** - * Returns the print job. - * - * @return the print job. - */ - public PrintJob getPrintJob() { - checkWidget(); - return printJob; - } - - /** - * Sets the print job to preview. - * - * @param printJob - * the print job to preview. - */ - public void setPrintJob(PrintJob printJob) { - checkWidget(); - this.printJob = printJob; - this.pageIndex = 0; - disposePages(); - redraw(); - } - - /** - * Returns the PrinterData for the printer to preview on. - * - * @return the PrinterData for the printer to preview on. - */ - public PrinterData getPrinterData() { - checkWidget(); - return printerData; - } - - /** - * Sets the PrinterData for the printer to preview on. - * - * @param printerData - * the PrinterData for the printer to preview on. - */ - public void setPrinterData(PrinterData printerData) { - checkWidget(); - this.printerData = printerData; - this.pageIndex = 0; - disposePrinter(); // disposes pages too - redraw(); - } - - /** - * Returns the index of the first visible page. - * - * @return the index of the first visible page. - */ - public int getPageIndex() { - checkWidget(); - return pageIndex; - } - - /** - * Sets the index of the first visible page to the argument. - * - * @param pageIndex - * the page index. - */ - public void setPageIndex(int pageIndex) { - checkWidget(); - this.pageIndex = pageIndex; - redraw(); - } - - /** - * Returns the known number of pages in the print job. If - * {@link #setLazyPageLayout(boolean)} is set to true, this method returns - * the number of pages laid out so far. This method returns 0 when - * {@link #getPrintJob()} is null or {@link #getPrinterData()} is null. - * - * @return the known number of pages in the print job. - */ - public int getPageCount() { - checkWidget(); - fetchPages(lazy ? horizontalPageCount * verticalPageCount : ALL_PAGES); - return pages == null ? 0 : pages.size(); - } - - /** - * Returns whether all pages have been laid out. - * - * @return whether all pages have been laid out. - */ - public boolean isPageLayoutComplete() { - checkWidget(); - fetchPages(horizontalPageCount * verticalPageCount); - return pageEnumeration == null || !pageEnumeration.hasNext(); - } - - /** - * Returns whether the page scales to fit the document horizontally. - * - * @return whether the page scales to fit the document horizontally. - */ - public boolean isFitHorizontal() { - checkWidget(); - return fitHorizontal; - } - - /** - * Sets whether the page scales to fit the document horizontally. - * - * @param fitHorizontal - * whether the page scales to fit the document horizontally. - */ - public void setFitHorizontal(boolean fitHorizontal) { - checkWidget(); - if (this.fitHorizontal != fitHorizontal) { - this.fitHorizontal = fitHorizontal; - invalidatePageDisplayBounds(); - redraw(); - } - } - - /** - * Returns whether the page scales to fit the document vertically. - * - * @return whether the page scales to fit the document vertically. - */ - public boolean isFitVertical() { - checkWidget(); - return fitVertical; - } - - /** - * Sets whether the page scales to fit the document vertically. - * - * @param fitVertical - * whether the page scales to fit the document vertically. - */ - public void setFitVertical(boolean fitVertical) { - checkWidget(); - if (this.fitVertical != fitVertical) { - this.fitVertical = fitVertical; - invalidatePageDisplayBounds(); - redraw(); - } - } - - /** - * Returns the view scale. The document displays at this scale when - * !(isFitHorizontal() || isFitVertical()). - * - * @return the view scale. - */ - public float getScale() { - checkWidget(); - return scale; - } - - /** - * Sets the view scale. - * - * @param scale - * the view scale. A scale of 1.0 causes the document to appear - * at full size on the computer screen. - */ - public void setScale(float scale) { - checkWidget(); - this.scale = checkScale(scale); - if (!(fitVertical || fitHorizontal)) { - invalidatePageDisplayBounds(); - redraw(); - } - } - - private static float checkScale(float scale) { - if (!(scale > 0)) - PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Scale must be > 0"); //$NON-NLS-1$ - return scale; - } - - /** - * Returns how many pages will be displayed in the horizontal direction. - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @return how many pages will be displayed in the horizontal direction. - */ - public int getHorizontalPageCount() { - checkWidget(); - return horizontalPageCount; - } - - /** - * Sets how many pages will be displayed in the horizontal direction. - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @param horizontalPages - * how many pages will be displayed in the horizontal direction. - */ - public void setHorizontalPageCount(int horizontalPages) { - checkWidget(); - if (horizontalPages < 1) - horizontalPages = 1; - this.horizontalPageCount = horizontalPages; - invalidatePageDisplayBounds(); - redraw(); - } - - /** - * Returns how many pages will be displayed in the vertical direction. - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @return how many pages will be displayed in the vertical direction. - */ - public int getVerticalPageCount() { - checkWidget(); - return verticalPageCount; - } - - /** - * Sets how many pages will be displayed in the vertical direction. - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @param verticalPages - * how many pages will be displayed in the vertical direction. - */ - public void setVerticalPageCount(int verticalPages) { - checkWidget(); - if (verticalPages < 1) - verticalPages = 1; - this.verticalPageCount = verticalPages; - invalidatePageDisplayBounds(); - redraw(); - } - - /** - * Returns whether the preview lays out pages lazily. Note that total page - * counts in page numbers will not display correctly when this is enabled. - * - * @return whether the preview lays out pages lazily. - */ - public boolean isLazyPageLayout() { - checkWidget(); - return lazy; - } - - /** - * Sets whether the preview lays out pages lazily. Note that total page - * counts in page numbers will not display correctly when this is enabled. - * - * @param lazy - * whether the preview lays out pages lazily. - */ - public void setLazyPageLayout(boolean lazy) { - checkWidget(); - this.lazy = lazy; - } - - /** - * Begins lazy loading in the background, invoking the callback runnable - * periodically as pages are laid out. - *

- * NOTE: This API is experimental and subject to change. - * - * @param callback - * runnable that will be invoked periodically as pages are laid - * out. - */ - // TODO finalize experimental API - public void startBackgroundLayout(final Runnable callback) { - if (isPageLayoutComplete()) - return; - - final int DELAY = 10; - getDisplay().timerExec(DELAY, new Runnable() { - public void run() { - if (isDisposed()) - return; - if (!isPageLayoutComplete() && pages != null) { - fetchPages(pages.size() + 1); - if (!isPageLayoutComplete()) { - getDisplay().timerExec(DELAY, this); - } - } - callback.run(); - } - }); - } - - private void invalidatePageDisplayBounds() { - pageDisplaySize = null; - pageDisplayLocations = null; - } - - private void paint(Event event) { - drawBackground(event); - - if (printJob == null || printerData == null) - return; - - getPrinter(); - getPaperSize(); - fetchPages(pageIndex + verticalPageCount * horizontalPageCount); - - getPageDisplaySize(); - getPageDisplayLocations(); - - if (printer == null || paperSize == null || pages == null - || pageDisplaySize == null || pageDisplayLocations == null - || pageIndex < 0 || pageIndex >= pages.size()) - return; - - int count = Math.min(verticalPageCount * horizontalPageCount, - pages.size() - pageIndex); - for (int i = 0; i < count; i++) { - paintPage(event, pages.get(pageIndex + i), pageDisplayLocations[i]); - } - } - - private void paintPage(Event event, PrintPiece page, Point location) { - // Check whether any "paper" is in the dirty region - Rectangle rectangle = new Rectangle(location.x, location.y, - pageDisplaySize.x, pageDisplaySize.y); - Rectangle dirtyBounds = new Rectangle(event.x, event.y, event.width, - event.height); - Rectangle dirtyPaperBounds = dirtyBounds.intersection(rectangle); - if (dirtyPaperBounds.width == 0 || dirtyPaperBounds.height == 0) - return; - - Image printerImage = null; - GC printerGC = null; - Transform printerTransform = null; - Image displayImage = null; - - try { - printerImage = new Image(printer, dirtyPaperBounds.width, - dirtyPaperBounds.height); - printerGC = new GC(printerImage); - configureAntialiasing(printerGC); - printerTransform = new Transform(printer); - - printerGC.getTransform(printerTransform); - printerTransform.translate(rectangle.x - dirtyPaperBounds.x, - rectangle.y - dirtyPaperBounds.y); - printerTransform.scale( - (float) rectangle.width / (float) paperSize.x, - (float) rectangle.height / (float) paperSize.y); - printerGC.setTransform(printerTransform); - page.paint(printerGC, 0, 0); - - displayImage = new Image(event.display, - printerImage.getImageData()); - event.gc.drawImage(displayImage, dirtyPaperBounds.x, - dirtyPaperBounds.y); - } finally { - disposeResources(printerImage, printerGC, printerTransform, - displayImage, page); - } - } - - private void disposeResources(Image printerImage, GC printerGC, - Transform printerTransform, Image displayImage, PrintPiece page) { - if (printerImage != null) - printerImage.dispose(); - if (displayImage != null) - displayImage.dispose(); - if (printerGC != null) - printerGC.dispose(); - if (printerTransform != null) - printerTransform.dispose(); - page.dispose(); - } - - private void configureAntialiasing(GC printerGC) { - printerGC.setAdvanced(true); - printerGC.setAntialias(SWT.ON); - printerGC.setTextAntialias(SWT.ON); - printerGC.setInterpolation(SWT.HIGH); - } - - private Printer getPrinter() { - if (printer == null && printerData != null) { - printer = new Printer(printerData); - PaperClips.startDummyJob(printer, ""); //$NON-NLS-1$ - disposePages(); // just in case - pageDisplaySize = null; - pageDisplayLocations = null; - } - return printer; - } - - private GC getGC() { - if (gc == null && printer != null) { - gc = new GC(printer); - gc.setAdvanced(true); - } - return gc; - } - - private boolean orientationRequiresRotate() { - int orientation = printJob.getOrientation(); - Rectangle bounds = PaperClips.getPaperBounds(printer); - return (orientation == PaperClips.ORIENTATION_PORTRAIT - && bounds.width > bounds.height) - || (orientation == PaperClips.ORIENTATION_LANDSCAPE - && bounds.height > bounds.width); - } - - private Point getPaperSize() { - Printer printer = getPrinter(); - if (paperSize == null && printer != null && printJob != null) { - Rectangle paperBounds = PaperClips.getPaperBounds(printer); - this.paperSize = orientationRequiresRotate() - ? new Point(paperBounds.height, paperBounds.width) - : new Point(paperBounds.width, paperBounds.height); - } - return paperSize; - } - - private void fetchPages(int endIndex) { - if (getPrintJob() == null || getPrinter() == null) - return; - if (pageEnumeration == null) { - if (getGC() == null) - return; - pageEnumeration = PaperClips.getPageEnumeration(printJob, printer, - gc); - } - if (pages == null) - pages = new ArrayList<>(); - boolean doRotate = orientationRequiresRotate(); - boolean allPages = endIndex == ALL_PAGES || !lazy; - while (pageEnumeration.hasNext() - && (allPages || pages.size() < endIndex)) { - PrintPiece page = pageEnumeration.nextPage(); - if (page != null) { - if (doRotate) - page = new RotateClockwisePrintPiece(printer, page); - pages.add(page); - } - } - if (!pageEnumeration.hasNext()) - disposeGC(); - } - - private void drawBackground(Event event) { - Color oldBackground = event.gc.getBackground(); - Color bg = event.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); - try { - event.gc.setBackground(bg); - event.gc.fillRectangle(event.x, event.y, event.width, event.height); - event.gc.setBackground(oldBackground); - } finally { - bg.dispose(); - } - } - - /** - * Calculates the absolute scale that the print preview is displaying at. If - * either of the fitHorizontal or fitVertical properties are true, this is - * the scale allows the page to fit within this control's current bounds. - * Otherwise the value of the scale property is returned. - * - * @return the absolute scale that the print preview is displaying at. - */ - public float getAbsoluteScale() { - checkWidget(); - return getAbsoluteScale(getSize()); - } - - /** - * Returns a Rectangle whose x, y, width, and height fields respectively - * indicate the margin at the left, top, right, and bottom edges of the - * control. - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @return a Rectangle whose x, y, width, and height fields respectively - * indicate the margin at the left, top, right, and bottom edges of - * the control. - */ - public Rectangle getMargins() { - checkWidget(); - return new Rectangle(margins.x, margins.y, margins.width, - margins.height); - } - - /** - * Sets the margins at each edge of the control to the argument. - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @param margins - * a Rectangle whose x, y, width, and height fields respectively - * indicate the margin at the left, top, right, and bottom edges - * of the control. - */ - public void setMargins(Rectangle margins) { - checkWidget(); - if (margins == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - this.margins = new Rectangle(margins.x, margins.y, margins.width, - margins.height); - invalidatePageDisplayBounds(); - redraw(); - } - - /** - * Returns a Point whose x and y fields respectively indicate the horizontal - * and vertical spacing between pages on the control. - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @return a Point whose x and y fields respectively indicate the horizontal - * and vertical spacing between pages on the control. - */ - public Point getPageSpacing() { - return new Point(pageSpacing.x, pageSpacing.y); - } - - /** - * Sets the horizontal and vertical spacing between pages to the argument. - *

- * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE - * FUTURE. - * - * @param pageSpacing - * a Point whose x and y fields respectively indicate the - * horizontal and vertical spacing between pages on the control. - */ - public void setPageSpacing(Point pageSpacing) { - checkWidget(); - if (pageSpacing == null) - SWT.error(SWT.ERROR_NULL_ARGUMENT); - this.pageSpacing = new Point(pageSpacing.x, pageSpacing.y); - invalidatePageDisplayBounds(); - redraw(); - } - - private Point getBoilerplateSize() { - return new Point( - margins.x + margins.width - + (horizontalPageCount - 1) * pageSpacing.x, - margins.y + margins.height - + (verticalPageCount - 1) * pageSpacing.y); - } - - private float getAbsoluteScale(Point controlSize) { - float result = scale; - - if (getPrinter() != null && (fitHorizontal || fitVertical)) { - Rectangle trim = computeTrim(0, 0, 0, 0); - controlSize.x -= trim.width; - controlSize.y -= trim.height; - - Point boilerplate = getBoilerplateSize(); - controlSize.x -= boilerplate.x; - controlSize.x /= horizontalPageCount; - controlSize.y -= boilerplate.y; - controlSize.y /= verticalPageCount; - - Point displayDPI = getDisplay().getDPI(); - Point printerDPI = getPrinter().getDPI(); - Point paperSize = getPaperSize(); - - if (fitHorizontal) { - float screenWidth = (float) controlSize.x - / (float) displayDPI.x; // inches - float paperWidth = (float) paperSize.x / (float) printerDPI.x; // inches - float scaleX = screenWidth / paperWidth; - if (fitVertical) { - float screenHeight = (float) controlSize.y - / (float) displayDPI.y; // inches - float paperHeight = (float) paperSize.y - / (float) printerDPI.y; // inches - float scaleY = screenHeight / paperHeight; - result = Math.min(scaleX, scaleY); - } else { - result = scaleX; - } - } else { - float screenHeight = (float) controlSize.y - / (float) displayDPI.y; // inches - float paperHeight = (float) paperSize.y / (float) printerDPI.y; // inches - float scaleY = screenHeight / paperHeight; - result = scaleY; - } - } - return result; - } - - private Point getPageDisplaySize() { - if (pageDisplaySize == null) { - Point size = getSize(); - Point displayDPI = getDisplay().getDPI(); - Point printerDPI = printer.getDPI(); - float absoluteScale = getAbsoluteScale(size); - float scaleX = absoluteScale * displayDPI.x / printerDPI.x; - float scaleY = absoluteScale * displayDPI.y / printerDPI.y; - - pageDisplaySize = new Point((int) (scaleX * paperSize.x), - (int) (scaleY * paperSize.y)); - } - return pageDisplaySize; - } - - private Point[] getPageDisplayLocations() { - if (pageDisplayLocations == null) { - // Center pages horizontally - Rectangle clientArea = getClientArea(); - int x0 = clientArea.x + margins.x; - clientArea.width -= getBoilerplateSize().x; - clientArea.width -= (pageDisplaySize.x * horizontalPageCount); - if (clientArea.width > 0) - x0 += clientArea.width / 2; - - pageDisplayLocations = new Point[horizontalPageCount - * verticalPageCount]; - - int y = clientArea.y + margins.y; - for (int r = 0; r < verticalPageCount; r++) { - int x = x0; - for (int c = 0; c < horizontalPageCount; c++) { - pageDisplayLocations[r * horizontalPageCount - + c] = new Point(x, y); - x += pageDisplaySize.x + pageSpacing.x; - } - y += pageDisplaySize.y + pageSpacing.y; - } - } - return pageDisplayLocations; - } - - private void disposePages() { - if (pages != null) { - pageEnumeration = null; - for (int i = 0; i < pages.size(); i++) - pages.get(i).dispose(); - pages = null; - paperSize = null; - invalidatePageDisplayBounds(); - } - } - - private void disposePrinter() { - disposePages(); - if (printer != null) { - disposeGC(); - PaperClips.endDummyJob(printer); - printer.dispose(); - printer = null; - } - } - - private void disposeGC() { - if (gc != null) { - gc.dispose(); - gc = null; - } - } - - private void disposeResources() { - disposePages(); - disposePrinter(); - } - - @Override - public Point computeSize(int wHint, int hHint, boolean changed) { - checkWidget(); - - Point size = new Point(wHint, hHint); - - fetchPages(horizontalPageCount * verticalPageCount); - if (getPrinter() == null || pages == null) { - Point boilerplate = getBoilerplateSize(); - if (wHint == SWT.DEFAULT) - size.x = boilerplate.x; - if (hHint == SWT.DEFAULT) - size.y = boilerplate.y; - return addTrim(size); - } - - double scale; - if (wHint != SWT.DEFAULT) { - if (hHint != SWT.DEFAULT) { - return addTrim(size); - } - size.y = Integer.MAX_VALUE; - scale = getAbsoluteScale(size); - } else if (hHint != SWT.DEFAULT) { - size.x = Integer.MAX_VALUE; - scale = getAbsoluteScale(size); - } else { - scale = this.scale; - } - - return computeSize(scale); - } - - /** - * Returns the control size needed to display a full page at the given - * scale. - * - * @param scale - * the absolute scale. A scale of 1, for example, yields a "life - * size" preview. - * @return the control size needed to display a full page at the given - * scale. - */ - public Point computeSize(double scale) { - checkWidget(); - - Point size = getBoilerplateSize(); - - fetchPages(horizontalPageCount * verticalPageCount); - if (getPrinter() != null && pages != null) { - Point displayDPI = getDisplay().getDPI(); - Point printerDPI = getPrinter().getDPI(); - Point paperSize = getPaperSize(); - - size.x += horizontalPageCount - * (int) (scale * paperSize.x * displayDPI.x / printerDPI.x); - size.y += verticalPageCount - * (int) (scale * paperSize.y * displayDPI.y / printerDPI.y); - } - - return addTrim(size); - } - - private Point addTrim(Point size) { - Rectangle trim = computeTrim(0, 0, 0, 0); - return new Point(size.x + trim.width, size.y + trim.height); - } -} +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.widgets; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.nebula.paperclips.core.PageEnumeration; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +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.graphics.Transform; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; + +/** + * A WYSIWYG (what you see is what you get) print preview panel. This control + * displays a preview of what a PrintJob will look like on paper, depending on + * the selected printer. + *

+ *
Styles:
+ *
(none)
+ *
Events:
+ *
(none)
+ *
+ * + * @author Matthew Hall + */ +public class PrintPreview extends Canvas { + private static final int ALL_PAGES = -1; + + private PrintJob printJob = null; + private PrinterData printerData = PaperClips.getDefaultPrinterData(); + private int pageIndex = 0; + private boolean fitHorizontal = true; + private boolean fitVertical = true; + private float scale = 1.0f; + private int horizontalPageCount = 1; + private int verticalPageCount = 1; + private boolean lazy = false; + + // The bounds of the paper on the printer device. + private Point paperSize = null; + private Printer printer = null; + private GC gc = null; + + private PageEnumeration pageEnumeration = null; + private List pages = null; + private Point pageDisplaySize = null; + private Point[] pageDisplayLocations = null; + + // Margins and page spacing include paper boilerplate. + private Rectangle margins = new Rectangle(10, 10, 10, 10); + private Point pageSpacing = new Point(10, 10); + + /** + * Constructs a PrintPreview control. + * + * @param parent + * the parent control. + * @param style + * the control style. + */ + public PrintPreview(Composite parent, int style) { + super(parent, style | SWT.DOUBLE_BUFFERED); + + addListener(SWT.Paint, event -> { + paint(event); + }); + + addListener(SWT.Resize, event -> { + invalidatePageDisplayBounds(); + redraw(); + }); + + addListener(SWT.Dispose, event -> { + disposeResources(); + }); + } + + /** + * Returns the print job. + * + * @return the print job. + */ + public PrintJob getPrintJob() { + checkWidget(); + return printJob; + } + + /** + * Sets the print job to preview. + * + * @param printJob + * the print job to preview. + */ + public void setPrintJob(PrintJob printJob) { + checkWidget(); + this.printJob = printJob; + this.pageIndex = 0; + disposePages(); + redraw(); + } + + /** + * Returns the PrinterData for the printer to preview on. + * + * @return the PrinterData for the printer to preview on. + */ + public PrinterData getPrinterData() { + checkWidget(); + return printerData; + } + + /** + * Sets the PrinterData for the printer to preview on. + * + * @param printerData + * the PrinterData for the printer to preview on. + */ + public void setPrinterData(PrinterData printerData) { + checkWidget(); + this.printerData = printerData; + this.pageIndex = 0; + disposePrinter(); // disposes pages too + redraw(); + } + + /** + * Returns the index of the first visible page. + * + * @return the index of the first visible page. + */ + public int getPageIndex() { + checkWidget(); + return pageIndex; + } + + /** + * Sets the index of the first visible page to the argument. + * + * @param pageIndex + * the page index. + */ + public void setPageIndex(int pageIndex) { + checkWidget(); + this.pageIndex = pageIndex; + redraw(); + } + + /** + * Returns the known number of pages in the print job. If + * {@link #setLazyPageLayout(boolean)} is set to true, this method returns + * the number of pages laid out so far. This method returns 0 when + * {@link #getPrintJob()} is null or {@link #getPrinterData()} is null. + * + * @return the known number of pages in the print job. + */ + public int getPageCount() { + checkWidget(); + fetchPages(lazy ? horizontalPageCount * verticalPageCount : ALL_PAGES); + return pages == null ? 0 : pages.size(); + } + + /** + * Returns whether all pages have been laid out. + * + * @return whether all pages have been laid out. + */ + public boolean isPageLayoutComplete() { + checkWidget(); + fetchPages(horizontalPageCount * verticalPageCount); + return pageEnumeration == null || !pageEnumeration.hasNext(); + } + + /** + * Returns whether the page scales to fit the document horizontally. + * + * @return whether the page scales to fit the document horizontally. + */ + public boolean isFitHorizontal() { + checkWidget(); + return fitHorizontal; + } + + /** + * Sets whether the page scales to fit the document horizontally. + * + * @param fitHorizontal + * whether the page scales to fit the document horizontally. + */ + public void setFitHorizontal(boolean fitHorizontal) { + checkWidget(); + if (this.fitHorizontal != fitHorizontal) { + this.fitHorizontal = fitHorizontal; + invalidatePageDisplayBounds(); + redraw(); + } + } + + /** + * Returns whether the page scales to fit the document vertically. + * + * @return whether the page scales to fit the document vertically. + */ + public boolean isFitVertical() { + checkWidget(); + return fitVertical; + } + + /** + * Sets whether the page scales to fit the document vertically. + * + * @param fitVertical + * whether the page scales to fit the document vertically. + */ + public void setFitVertical(boolean fitVertical) { + checkWidget(); + if (this.fitVertical != fitVertical) { + this.fitVertical = fitVertical; + invalidatePageDisplayBounds(); + redraw(); + } + } + + /** + * Returns the view scale. The document displays at this scale when + * !(isFitHorizontal() || isFitVertical()). + * + * @return the view scale. + */ + public float getScale() { + checkWidget(); + return scale; + } + + /** + * Sets the view scale. + * + * @param scale + * the view scale. A scale of 1.0 causes the document to appear + * at full size on the computer screen. + */ + public void setScale(float scale) { + checkWidget(); + this.scale = checkScale(scale); + if (!(fitVertical || fitHorizontal)) { + invalidatePageDisplayBounds(); + redraw(); + } + } + + private static float checkScale(float scale) { + if (!(scale > 0)) + PaperClips.error(SWT.ERROR_INVALID_ARGUMENT, "Scale must be > 0"); //$NON-NLS-1$ + return scale; + } + + /** + * Returns how many pages will be displayed in the horizontal direction. + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @return how many pages will be displayed in the horizontal direction. + */ + public int getHorizontalPageCount() { + checkWidget(); + return horizontalPageCount; + } + + /** + * Sets how many pages will be displayed in the horizontal direction. + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @param horizontalPages + * how many pages will be displayed in the horizontal direction. + */ + public void setHorizontalPageCount(int horizontalPages) { + checkWidget(); + if (horizontalPages < 1) + horizontalPages = 1; + this.horizontalPageCount = horizontalPages; + invalidatePageDisplayBounds(); + redraw(); + } + + /** + * Returns how many pages will be displayed in the vertical direction. + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @return how many pages will be displayed in the vertical direction. + */ + public int getVerticalPageCount() { + checkWidget(); + return verticalPageCount; + } + + /** + * Sets how many pages will be displayed in the vertical direction. + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @param verticalPages + * how many pages will be displayed in the vertical direction. + */ + public void setVerticalPageCount(int verticalPages) { + checkWidget(); + if (verticalPages < 1) + verticalPages = 1; + this.verticalPageCount = verticalPages; + invalidatePageDisplayBounds(); + redraw(); + } + + /** + * Returns whether the preview lays out pages lazily. Note that total page + * counts in page numbers will not display correctly when this is enabled. + * + * @return whether the preview lays out pages lazily. + */ + public boolean isLazyPageLayout() { + checkWidget(); + return lazy; + } + + /** + * Sets whether the preview lays out pages lazily. Note that total page + * counts in page numbers will not display correctly when this is enabled. + * + * @param lazy + * whether the preview lays out pages lazily. + */ + public void setLazyPageLayout(boolean lazy) { + checkWidget(); + this.lazy = lazy; + } + + /** + * Begins lazy loading in the background, invoking the callback runnable + * periodically as pages are laid out. + *

+ * NOTE: This API is experimental and subject to change. + * + * @param callback + * runnable that will be invoked periodically as pages are laid + * out. + */ + // TODO finalize experimental API + public void startBackgroundLayout(final Runnable callback) { + if (isPageLayoutComplete()) + return; + + final int DELAY = 10; + getDisplay().timerExec(DELAY, new Runnable() { + public void run() { + if (isDisposed()) + return; + if (!isPageLayoutComplete() && pages != null) { + fetchPages(pages.size() + 1); + if (!isPageLayoutComplete()) { + getDisplay().timerExec(DELAY, this); + } + } + callback.run(); + } + }); + } + + private void invalidatePageDisplayBounds() { + pageDisplaySize = null; + pageDisplayLocations = null; + } + + private void paint(Event event) { + drawBackground(event); + + if (printJob == null || printerData == null) + return; + + getPrinter(); + getPaperSize(); + fetchPages(pageIndex + verticalPageCount * horizontalPageCount); + + getPageDisplaySize(); + getPageDisplayLocations(); + + if (printer == null || paperSize == null || pages == null + || pageDisplaySize == null || pageDisplayLocations == null + || pageIndex < 0 || pageIndex >= pages.size()) + return; + + int count = Math.min(verticalPageCount * horizontalPageCount, + pages.size() - pageIndex); + for (int i = 0; i < count; i++) { + paintPage(event, pages.get(pageIndex + i), pageDisplayLocations[i]); + } + } + + private void paintPage(Event event, PrintPiece page, Point location) { + // Check whether any "paper" is in the dirty region + Rectangle rectangle = new Rectangle(location.x, location.y, + pageDisplaySize.x, pageDisplaySize.y); + Rectangle dirtyBounds = new Rectangle(event.x, event.y, event.width, + event.height); + Rectangle dirtyPaperBounds = dirtyBounds.intersection(rectangle); + if (dirtyPaperBounds.width == 0 || dirtyPaperBounds.height == 0) + return; + + Image printerImage = null; + GC printerGC = null; + Transform printerTransform = null; + Image displayImage = null; + + try { + printerImage = new Image(printer, dirtyPaperBounds.width, + dirtyPaperBounds.height); + printerGC = new GC(printerImage); + configureAntialiasing(printerGC); + printerTransform = new Transform(printer); + + printerGC.getTransform(printerTransform); + printerTransform.translate(rectangle.x - dirtyPaperBounds.x, + rectangle.y - dirtyPaperBounds.y); + printerTransform.scale( + (float) rectangle.width / (float) paperSize.x, + (float) rectangle.height / (float) paperSize.y); + printerGC.setTransform(printerTransform); + page.paint(printerGC, 0, 0); + + displayImage = new Image(event.display, + printerImage.getImageData()); + event.gc.drawImage(displayImage, dirtyPaperBounds.x, + dirtyPaperBounds.y); + } finally { + disposeResources(printerImage, printerGC, printerTransform, + displayImage, page); + } + } + + private void disposeResources(Image printerImage, GC printerGC, + Transform printerTransform, Image displayImage, PrintPiece page) { + if (printerImage != null) + printerImage.dispose(); + if (displayImage != null) + displayImage.dispose(); + if (printerGC != null) + printerGC.dispose(); + if (printerTransform != null) + printerTransform.dispose(); + page.dispose(); + } + + private void configureAntialiasing(GC printerGC) { + printerGC.setAdvanced(true); + printerGC.setAntialias(SWT.ON); + printerGC.setTextAntialias(SWT.ON); + printerGC.setInterpolation(SWT.HIGH); + } + + private Printer getPrinter() { + if (printer == null && printerData != null) { + printer = new Printer(printerData); + PaperClips.startDummyJob(printer, ""); //$NON-NLS-1$ + disposePages(); // just in case + pageDisplaySize = null; + pageDisplayLocations = null; + } + return printer; + } + + private GC getGC() { + if (gc == null && printer != null) { + gc = new GC(printer); + gc.setAdvanced(true); + } + return gc; + } + + private boolean orientationRequiresRotate() { + int orientation = printJob.getOrientation(); + Rectangle bounds = PaperClips.getPaperBounds(printer); + return (orientation == PaperClips.ORIENTATION_PORTRAIT + && bounds.width > bounds.height) + || (orientation == PaperClips.ORIENTATION_LANDSCAPE + && bounds.height > bounds.width); + } + + private Point getPaperSize() { + Printer printer = getPrinter(); + if (paperSize == null && printer != null && printJob != null) { + Rectangle paperBounds = PaperClips.getPaperBounds(printer); + this.paperSize = orientationRequiresRotate() + ? new Point(paperBounds.height, paperBounds.width) + : new Point(paperBounds.width, paperBounds.height); + } + return paperSize; + } + + private void fetchPages(int endIndex) { + if (getPrintJob() == null || getPrinter() == null) + return; + if (pageEnumeration == null) { + if (getGC() == null) + return; + pageEnumeration = PaperClips.getPageEnumeration(printJob, printer, + gc); + } + if (pages == null) + pages = new ArrayList<>(); + boolean doRotate = orientationRequiresRotate(); + boolean allPages = endIndex == ALL_PAGES || !lazy; + while (pageEnumeration.hasNext() + && (allPages || pages.size() < endIndex)) { + PrintPiece page = pageEnumeration.nextPage(); + if (page != null) { + if (doRotate) + page = new RotateClockwisePrintPiece(printer, page); + pages.add(page); + } + } + if (!pageEnumeration.hasNext()) + disposeGC(); + } + + private void drawBackground(Event event) { + Color oldBackground = event.gc.getBackground(); + Color bg = event.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); + try { + event.gc.setBackground(bg); + event.gc.fillRectangle(event.x, event.y, event.width, event.height); + event.gc.setBackground(oldBackground); + } finally { + bg.dispose(); + } + } + + /** + * Calculates the absolute scale that the print preview is displaying at. If + * either of the fitHorizontal or fitVertical properties are true, this is + * the scale allows the page to fit within this control's current bounds. + * Otherwise the value of the scale property is returned. + * + * @return the absolute scale that the print preview is displaying at. + */ + public float getAbsoluteScale() { + checkWidget(); + return getAbsoluteScale(getSize()); + } + + /** + * Returns a Rectangle whose x, y, width, and height fields respectively + * indicate the margin at the left, top, right, and bottom edges of the + * control. + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @return a Rectangle whose x, y, width, and height fields respectively + * indicate the margin at the left, top, right, and bottom edges of + * the control. + */ + public Rectangle getMargins() { + checkWidget(); + return new Rectangle(margins.x, margins.y, margins.width, + margins.height); + } + + /** + * Sets the margins at each edge of the control to the argument. + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @param margins + * a Rectangle whose x, y, width, and height fields respectively + * indicate the margin at the left, top, right, and bottom edges + * of the control. + */ + public void setMargins(Rectangle margins) { + checkWidget(); + if (margins == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + this.margins = new Rectangle(margins.x, margins.y, margins.width, + margins.height); + invalidatePageDisplayBounds(); + redraw(); + } + + /** + * Returns a Point whose x and y fields respectively indicate the horizontal + * and vertical spacing between pages on the control. + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @return a Point whose x and y fields respectively indicate the horizontal + * and vertical spacing between pages on the control. + */ + public Point getPageSpacing() { + return new Point(pageSpacing.x, pageSpacing.y); + } + + /** + * Sets the horizontal and vertical spacing between pages to the argument. + *

+ * THIS API IS EXPERIMENTAL AND MAY BE REMOVED OR CHANGED IN THE + * FUTURE. + * + * @param pageSpacing + * a Point whose x and y fields respectively indicate the + * horizontal and vertical spacing between pages on the control. + */ + public void setPageSpacing(Point pageSpacing) { + checkWidget(); + if (pageSpacing == null) + SWT.error(SWT.ERROR_NULL_ARGUMENT); + this.pageSpacing = new Point(pageSpacing.x, pageSpacing.y); + invalidatePageDisplayBounds(); + redraw(); + } + + private Point getBoilerplateSize() { + return new Point( + margins.x + margins.width + + (horizontalPageCount - 1) * pageSpacing.x, + margins.y + margins.height + + (verticalPageCount - 1) * pageSpacing.y); + } + + private float getAbsoluteScale(Point controlSize) { + float result = scale; + + if (getPrinter() != null && (fitHorizontal || fitVertical)) { + Rectangle trim = computeTrim(0, 0, 0, 0); + controlSize.x -= trim.width; + controlSize.y -= trim.height; + + Point boilerplate = getBoilerplateSize(); + controlSize.x -= boilerplate.x; + controlSize.x /= horizontalPageCount; + controlSize.y -= boilerplate.y; + controlSize.y /= verticalPageCount; + + Point displayDPI = getDisplay().getDPI(); + Point printerDPI = getPrinter().getDPI(); + Point paperSize = getPaperSize(); + + if (fitHorizontal) { + float screenWidth = (float) controlSize.x + / (float) displayDPI.x; // inches + float paperWidth = (float) paperSize.x / (float) printerDPI.x; // inches + float scaleX = screenWidth / paperWidth; + if (fitVertical) { + float screenHeight = (float) controlSize.y + / (float) displayDPI.y; // inches + float paperHeight = (float) paperSize.y + / (float) printerDPI.y; // inches + float scaleY = screenHeight / paperHeight; + result = Math.min(scaleX, scaleY); + } else { + result = scaleX; + } + } else { + float screenHeight = (float) controlSize.y + / (float) displayDPI.y; // inches + float paperHeight = (float) paperSize.y / (float) printerDPI.y; // inches + float scaleY = screenHeight / paperHeight; + result = scaleY; + } + } + return result; + } + + private Point getPageDisplaySize() { + if (pageDisplaySize == null) { + Point size = getSize(); + Point displayDPI = getDisplay().getDPI(); + Point printerDPI = printer.getDPI(); + float absoluteScale = getAbsoluteScale(size); + float scaleX = absoluteScale * displayDPI.x / printerDPI.x; + float scaleY = absoluteScale * displayDPI.y / printerDPI.y; + + pageDisplaySize = new Point((int) (scaleX * paperSize.x), + (int) (scaleY * paperSize.y)); + } + return pageDisplaySize; + } + + private Point[] getPageDisplayLocations() { + if (pageDisplayLocations == null) { + // Center pages horizontally + Rectangle clientArea = getClientArea(); + int x0 = clientArea.x + margins.x; + clientArea.width -= getBoilerplateSize().x; + clientArea.width -= (pageDisplaySize.x * horizontalPageCount); + if (clientArea.width > 0) + x0 += clientArea.width / 2; + + pageDisplayLocations = new Point[horizontalPageCount + * verticalPageCount]; + + int y = clientArea.y + margins.y; + for (int r = 0; r < verticalPageCount; r++) { + int x = x0; + for (int c = 0; c < horizontalPageCount; c++) { + pageDisplayLocations[r * horizontalPageCount + + c] = new Point(x, y); + x += pageDisplaySize.x + pageSpacing.x; + } + y += pageDisplaySize.y + pageSpacing.y; + } + } + return pageDisplayLocations; + } + + private void disposePages() { + if (pages != null) { + pageEnumeration = null; + for (int i = 0; i < pages.size(); i++) + pages.get(i).dispose(); + pages = null; + paperSize = null; + invalidatePageDisplayBounds(); + } + } + + private void disposePrinter() { + disposePages(); + if (printer != null) { + disposeGC(); + PaperClips.endDummyJob(printer); + printer.dispose(); + printer = null; + } + } + + private void disposeGC() { + if (gc != null) { + gc.dispose(); + gc = null; + } + } + + private void disposeResources() { + disposePages(); + disposePrinter(); + } + + @Override + public Point computeSize(int wHint, int hHint, boolean changed) { + checkWidget(); + + Point size = new Point(wHint, hHint); + + fetchPages(horizontalPageCount * verticalPageCount); + if (getPrinter() == null || pages == null) { + Point boilerplate = getBoilerplateSize(); + if (wHint == SWT.DEFAULT) + size.x = boilerplate.x; + if (hHint == SWT.DEFAULT) + size.y = boilerplate.y; + return addTrim(size); + } + + double scale; + if (wHint != SWT.DEFAULT) { + if (hHint != SWT.DEFAULT) { + return addTrim(size); + } + size.y = Integer.MAX_VALUE; + scale = getAbsoluteScale(size); + } else if (hHint != SWT.DEFAULT) { + size.x = Integer.MAX_VALUE; + scale = getAbsoluteScale(size); + } else { + scale = this.scale; + } + + return computeSize(scale); + } + + /** + * Returns the control size needed to display a full page at the given + * scale. + * + * @param scale + * the absolute scale. A scale of 1, for example, yields a "life + * size" preview. + * @return the control size needed to display a full page at the given + * scale. + */ + public Point computeSize(double scale) { + checkWidget(); + + Point size = getBoilerplateSize(); + + fetchPages(horizontalPageCount * verticalPageCount); + if (getPrinter() != null && pages != null) { + Point displayDPI = getDisplay().getDPI(); + Point printerDPI = getPrinter().getDPI(); + Point paperSize = getPaperSize(); + + size.x += horizontalPageCount + * (int) (scale * paperSize.x * displayDPI.x / printerDPI.x); + size.y += verticalPageCount + * (int) (scale * paperSize.y * displayDPI.y / printerDPI.y); + } + + return addTrim(size); + } + + private Point addTrim(Point size) { + Rectangle trim = computeTrim(0, 0, 0, 0); + return new Point(size.x + trim.width, size.y + trim.height); + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintViewer.java b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintViewer.java index 99cd4f260..cfaa40633 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintViewer.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/PrintViewer.java @@ -1,209 +1,209 @@ -/* - * Copyright (c) 2005 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.widgets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintIterator; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -/** - * A JFace-style {@link Print} viewer which displays a Print in a scrollable - * pane. - * - * @author Matthew - */ -public class PrintViewer { - private final ScrolledComposite sc; - private final PrintPieceCanvas canvas; - private Print print; - - private int canvasWidth; - - private BackgroundUpdater backgroundUpdater; - - /** - * Constructs a PrintPreview with the given parent and style. - * - * @param parent - * the parent component of the scroll pane. - * @param style - * the style of the scroll pane. - */ - public PrintViewer(Composite parent, int style) { - sc = new ScrolledComposite(parent, style | SWT.V_SCROLL | SWT.H_SCROLL); - sc.setExpandHorizontal(true); - sc.setExpandVertical(true); - sc.addListener(SWT.Resize, event -> { - if (sc.getClientArea().width != canvasWidth) - updateCanvas(); - }); - canvas = new PrintPieceCanvas(sc, SWT.DOUBLE_BUFFERED); - sc.setContent(canvas); - } - - /** - * Returns the viewer component wrapped by this PrintPreview. - * - * @return the viewer component wrapped by this PrintPreview. - */ - public Control getControl() { - return sc; - } - - /** - * Sets the Print to be displayed. - * - * @param print - * the Print to display. - */ - public void setPrint(Print print) { - this.print = print; - updateCanvas(); - } - - /** - * Returns the Print being displayed. - * - * @return the Print being displayed. - */ - public Print getPrint() { - return print; - } - - void updateCanvas() { - if (print == null) { - sc.setMinSize(0, 0); - canvas.setPrintPiece(null); - return; - } - - GC gc = null; - try { - gc = new GC(canvas); - - PrintIterator iterator = print.iterator(canvas.getDisplay(), gc); - sc.setMinWidth(iterator.minimumSize().x); - - int canvasWidth = Math.max(iterator.minimumSize().x, - sc.getClientArea().width); - if (this.canvasWidth == canvasWidth) - return; - this.canvasWidth = canvasWidth; - - if (backgroundUpdater != null) { - backgroundUpdater.cancelled = true; - backgroundUpdater = null; - } - - PrintPiece piece = PaperClips.next(iterator, canvasWidth, - Integer.MAX_VALUE); - - boolean printIsVerticallyGreedy = piece != null - && piece.getSize().y == Integer.MAX_VALUE; - if (printIsVerticallyGreedy) - sc.getDisplay().timerExec(50, - backgroundUpdater = new BackgroundUpdater()); - setPrintPiece(piece, !printIsVerticallyGreedy); - } finally { - if (gc != null) - gc.dispose(); - } - } - - private void setPrintPiece(PrintPiece piece, boolean updateMinHeight) { - if (updateMinHeight) - sc.setMinHeight(piece == null ? 0 : piece.getSize().y); - canvas.setPrintPiece(piece); - } - - private class BackgroundUpdater implements Runnable { - private boolean cancelled = false; - private int minHeight; - private int maxHeight; - private PrintIterator iterator; - private PrintPiece piece; - - public void run() { - if (cancelled || print == null) - return; - - GC gc = null; - try { - gc = new GC(canvas); - - iterator = print.iterator(canvas.getDisplay(), gc); - piece = canvas.getPrintPiece(); - - determineValidHeightRange(); - binarySearchRangeForSmallestValidHeight(); - - setPrintPiece(piece, true); - } finally { - if (gc != null) - gc.dispose(); - } - } - - private void determineValidHeightRange() { - minHeight = iterator.preferredSize().y; - maxHeight = Math.max(minHeight, 4096); - while (true) { - PrintIterator testIter = iterator.copy(); - PrintPiece testPiece = PaperClips.next(testIter, canvasWidth, - maxHeight); - final int factor = 4; - if (testPiece == null) { - // Theoretically this will never happen since we started at - // preferred height - minHeight = maxHeight + 1; - maxHeight = minHeight * factor; - } else if (testIter.hasNext()) { - testPiece.dispose(); - minHeight = maxHeight + 1; - maxHeight = minHeight * factor; - } else { - piece.dispose(); - piece = testPiece; - break; - } - } - } - - private void binarySearchRangeForSmallestValidHeight() { - while (minHeight < maxHeight) { - int testHeight = minHeight + (maxHeight - minHeight) / 2; - PrintIterator testIter = iterator.copy(); - PrintPiece testPiece = PaperClips.next(testIter, canvasWidth, - testHeight); - - if (testPiece == null) { - minHeight = testHeight + 1; - } else if (testIter.hasNext()) { - testPiece.dispose(); - minHeight = testHeight + 1; - } else { - maxHeight = Math.min(testHeight, testPiece.getSize().y); - piece.dispose(); - piece = testPiece; - } - } - } - } -} +/* + * Copyright (c) 2005 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.widgets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintIterator; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** + * A JFace-style {@link Print} viewer which displays a Print in a scrollable + * pane. + * + * @author Matthew + */ +public class PrintViewer { + private final ScrolledComposite sc; + private final PrintPieceCanvas canvas; + private Print print; + + private int canvasWidth; + + private BackgroundUpdater backgroundUpdater; + + /** + * Constructs a PrintPreview with the given parent and style. + * + * @param parent + * the parent component of the scroll pane. + * @param style + * the style of the scroll pane. + */ + public PrintViewer(Composite parent, int style) { + sc = new ScrolledComposite(parent, style | SWT.V_SCROLL | SWT.H_SCROLL); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + sc.addListener(SWT.Resize, event -> { + if (sc.getClientArea().width != canvasWidth) + updateCanvas(); + }); + canvas = new PrintPieceCanvas(sc, SWT.DOUBLE_BUFFERED); + sc.setContent(canvas); + } + + /** + * Returns the viewer component wrapped by this PrintPreview. + * + * @return the viewer component wrapped by this PrintPreview. + */ + public Control getControl() { + return sc; + } + + /** + * Sets the Print to be displayed. + * + * @param print + * the Print to display. + */ + public void setPrint(Print print) { + this.print = print; + updateCanvas(); + } + + /** + * Returns the Print being displayed. + * + * @return the Print being displayed. + */ + public Print getPrint() { + return print; + } + + void updateCanvas() { + if (print == null) { + sc.setMinSize(0, 0); + canvas.setPrintPiece(null); + return; + } + + GC gc = null; + try { + gc = new GC(canvas); + + PrintIterator iterator = print.iterator(canvas.getDisplay(), gc); + sc.setMinWidth(iterator.minimumSize().x); + + int canvasWidth = Math.max(iterator.minimumSize().x, + sc.getClientArea().width); + if (this.canvasWidth == canvasWidth) + return; + this.canvasWidth = canvasWidth; + + if (backgroundUpdater != null) { + backgroundUpdater.cancelled = true; + backgroundUpdater = null; + } + + PrintPiece piece = PaperClips.next(iterator, canvasWidth, + Integer.MAX_VALUE); + + boolean printIsVerticallyGreedy = piece != null + && piece.getSize().y == Integer.MAX_VALUE; + if (printIsVerticallyGreedy) + sc.getDisplay().timerExec(50, + backgroundUpdater = new BackgroundUpdater()); + setPrintPiece(piece, !printIsVerticallyGreedy); + } finally { + if (gc != null) + gc.dispose(); + } + } + + private void setPrintPiece(PrintPiece piece, boolean updateMinHeight) { + if (updateMinHeight) + sc.setMinHeight(piece == null ? 0 : piece.getSize().y); + canvas.setPrintPiece(piece); + } + + private class BackgroundUpdater implements Runnable { + private boolean cancelled = false; + private int minHeight; + private int maxHeight; + private PrintIterator iterator; + private PrintPiece piece; + + public void run() { + if (cancelled || print == null) + return; + + GC gc = null; + try { + gc = new GC(canvas); + + iterator = print.iterator(canvas.getDisplay(), gc); + piece = canvas.getPrintPiece(); + + determineValidHeightRange(); + binarySearchRangeForSmallestValidHeight(); + + setPrintPiece(piece, true); + } finally { + if (gc != null) + gc.dispose(); + } + } + + private void determineValidHeightRange() { + minHeight = iterator.preferredSize().y; + maxHeight = Math.max(minHeight, 4096); + while (true) { + PrintIterator testIter = iterator.copy(); + PrintPiece testPiece = PaperClips.next(testIter, canvasWidth, + maxHeight); + final int factor = 4; + if (testPiece == null) { + // Theoretically this will never happen since we started at + // preferred height + minHeight = maxHeight + 1; + maxHeight = minHeight * factor; + } else if (testIter.hasNext()) { + testPiece.dispose(); + minHeight = maxHeight + 1; + maxHeight = minHeight * factor; + } else { + piece.dispose(); + piece = testPiece; + break; + } + } + } + + private void binarySearchRangeForSmallestValidHeight() { + while (minHeight < maxHeight) { + int testHeight = minHeight + (maxHeight - minHeight) / 2; + PrintIterator testIter = iterator.copy(); + PrintPiece testPiece = PaperClips.next(testIter, canvasWidth, + testHeight); + + if (testPiece == null) { + minHeight = testHeight + 1; + } else if (testIter.hasNext()) { + testPiece.dispose(); + minHeight = testHeight + 1; + } else { + maxHeight = Math.min(testHeight, testPiece.getSize().y); + piece.dispose(); + piece = testPiece; + } + } + } + } +} diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/RotateClockwisePrintPiece.java b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/RotateClockwisePrintPiece.java index 6ff8c9dd3..0bb6f4f51 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/RotateClockwisePrintPiece.java +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/RotateClockwisePrintPiece.java @@ -1,70 +1,70 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - */ -package org.eclipse.nebula.paperclips.widgets; - -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.PrintPiece; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Device; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Transform; - -class RotateClockwisePrintPiece implements PrintPiece { - private final Device device; - private final PrintPiece target; - private final Point size; - - RotateClockwisePrintPiece(Device device, PrintPiece target) { - if (device == null || target == null) - PaperClips.error(SWT.ERROR_NULL_ARGUMENT); - this.device = device; - this.target = target; - Point targetSize = target.getSize(); - this.size = new Point(targetSize.y, targetSize.x); - } - - public void dispose() { - target.dispose(); - } - - public Point getSize() { - return new Point(size.x, size.y); - } - - public void paint(GC gc, int x, int y) { - Transform oldTransform = null; - Transform newTransform = null; - try { - oldTransform = new Transform(device); - gc.getTransform(oldTransform); - - newTransform = new Transform(device); - gc.getTransform(newTransform); - newTransform.translate(x, y); - newTransform.translate(size.x, 0); - newTransform.rotate(90); - gc.setTransform(newTransform); - - target.paint(gc, 0, 0); - - gc.setTransform(oldTransform); - } finally { - if (oldTransform != null) - oldTransform.dispose(); - if (newTransform != null) - newTransform.dispose(); - } - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + */ +package org.eclipse.nebula.paperclips.widgets; + +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.PrintPiece; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Transform; + +class RotateClockwisePrintPiece implements PrintPiece { + private final Device device; + private final PrintPiece target; + private final Point size; + + RotateClockwisePrintPiece(Device device, PrintPiece target) { + if (device == null || target == null) + PaperClips.error(SWT.ERROR_NULL_ARGUMENT); + this.device = device; + this.target = target; + Point targetSize = target.getSize(); + this.size = new Point(targetSize.y, targetSize.x); + } + + public void dispose() { + target.dispose(); + } + + public Point getSize() { + return new Point(size.x, size.y); + } + + public void paint(GC gc, int x, int y) { + Transform oldTransform = null; + Transform newTransform = null; + try { + oldTransform = new Transform(device); + gc.getTransform(oldTransform); + + newTransform = new Transform(device); + gc.getTransform(newTransform); + newTransform.translate(x, y); + newTransform.translate(size.x, 0); + newTransform.rotate(90); + gc.setTransform(newTransform); + + target.paint(gc, 0, 0); + + gc.setTransform(oldTransform); + } finally { + if (oldTransform != null) + oldTransform.dispose(); + if (newTransform != null) + newTransform.dispose(); + } + } } \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/package.html b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/package.html index 9dc7db2e9..6d268f443 100644 --- a/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/package.html +++ b/widgets/paperclips/org.eclipse.nebula.paperclips.widgets/src/org/eclipse/nebula/paperclips/widgets/package.html @@ -1,6 +1,6 @@ - - - -SWT controls for viewing Prints on-screen. - + + + +SWT controls for viewing Prints on-screen. + \ No newline at end of file diff --git a/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/.classpath b/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/.classpath +++ b/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/.settings/org.eclipse.jdt.core.prefs b/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/.settings/org.eclipse.jdt.core.prefs index 230c1b474..a58ebdcad 100644 --- a/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/.settings/org.eclipse.jdt.core.prefs @@ -1,15 +1,15 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/META-INF/MANIFEST.MF b/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/META-INF/MANIFEST.MF index 1aab19a5a..b8eb57b2d 100644 --- a/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/META-INF/MANIFEST.MF +++ b/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/META-INF/MANIFEST.MF @@ -1,13 +1,13 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName -Bundle-SymbolicName: org.eclipse.nebula.widgets.paperclips.example;singleton:=true -Bundle-Version: 2.1.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-Vendor: %providerName -Require-Bundle: org.eclipse.nebula.examples;bundle-version="1.0.4", - org.eclipse.nebula.paperclips.core;bundle-version="[2.0.0,3.0.0)", - org.eclipse.nebula.paperclips.widgets;bundle-version="[2.0.0,3.0.0)", - org.eclipse.swt;bundle-version="[3.2.0,4.0.0)" -Bundle-Localization: plugin -Automatic-Module-Name: org.eclipse.nebula.widgets.paperclips.example +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.nebula.widgets.paperclips.example;singleton:=true +Bundle-Version: 2.1.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.nebula.examples;bundle-version="1.0.4", + org.eclipse.nebula.paperclips.core;bundle-version="[2.0.0,3.0.0)", + org.eclipse.nebula.paperclips.widgets;bundle-version="[2.0.0,3.0.0)", + org.eclipse.swt;bundle-version="[3.2.0,4.0.0)" +Bundle-Localization: plugin +Automatic-Module-Name: org.eclipse.nebula.widgets.paperclips.example diff --git a/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/src/org/eclipse/nebula/widgets/paperclips/example/PaperclipsExampleTab.java b/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/src/org/eclipse/nebula/widgets/paperclips/example/PaperclipsExampleTab.java index e81cddcd1..680b0397a 100644 --- a/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/src/org/eclipse/nebula/widgets/paperclips/example/PaperclipsExampleTab.java +++ b/widgets/paperclips/org.eclipse.nebula.widgets.paperclips.example/src/org/eclipse/nebula/widgets/paperclips/example/PaperclipsExampleTab.java @@ -1,127 +1,127 @@ -/* - * Copyright (c) 2006 Matthew Hall and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Matthew Hall - initial API and implementation - * Cedric Brun - adapt to embed in the ExampleTab - */ -package org.eclipse.nebula.widgets.paperclips.example; - -import org.eclipse.nebula.examples.AbstractExampleTab; -import org.eclipse.nebula.paperclips.core.ImagePrint; -import org.eclipse.nebula.paperclips.core.LinePrint; -import org.eclipse.nebula.paperclips.core.PaperClips; -import org.eclipse.nebula.paperclips.core.Print; -import org.eclipse.nebula.paperclips.core.PrintJob; -import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; -import org.eclipse.nebula.paperclips.core.grid.GridPrint; -import org.eclipse.nebula.paperclips.core.text.TextPrint; -import org.eclipse.nebula.paperclips.widgets.PrintPreview; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.printing.PrinterData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -public class PaperclipsExampleTab extends AbstractExampleTab { - - public Control createControl(Composite parent) { - Composite shell = new Composite(parent, SWT.None); - - final PrintJob job = new PrintJob("GridPrintVerticalAlignmentExample.java", createPrint()); - shell.setLayout(new org.eclipse.swt.layout.GridLayout()); - - Composite buttonPanel = new Composite(shell, SWT.NONE); - buttonPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - buttonPanel.setLayout(new RowLayout(SWT.HORIZONTAL)); - - final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); - - Button prev = new Button(buttonPanel, SWT.PUSH); - prev.setText("<< Prev"); - prev.addListener(SWT.Selection, event -> { - preview.setPageIndex(Math.max(preview.getPageIndex() - 1, 0)); - }); - - Button next = new Button(buttonPanel, SWT.PUSH); - next.setText("Next >>"); - next.addListener(SWT.Selection, event -> { - preview.setPageIndex(Math.min(preview.getPageIndex() + 1, preview.getPageCount() - 1)); - }); - - Button print = new Button(buttonPanel, SWT.PUSH); - print.setText("Print"); - print.addListener(SWT.Selection, event -> { - PaperClips.print(job, new PrinterData()); - }); - - preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - preview.setFitHorizontal(true); - preview.setFitVertical(true); - preview.setPrintJob(job); - return shell; - } - - public static Print createPrint() { - DefaultGridLook look = new DefaultGridLook(5, 5); - look.setHeaderGap(5); - GridPrint grid = new GridPrint("d:g, d, d:g, d, d:g, d, d:g", look); - - ImageData imageData = new ImageData(PaperclipsExampleTab.class.getResourceAsStream("logo.png")); - ImagePrint image = new ImagePrint(imageData); - image.setDPI(300, 300); - - Print verticalRule = new LinePrint(SWT.VERTICAL); - - grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 1")); - grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 2")); - grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 3")); - grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 4")); - - grid.addHeader(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); - - grid.add(SWT.LEFT, SWT.CENTER, image); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.DEFAULT, SWT.DEFAULT, new TextPrint("triple\nline\nleft\n")); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.CENTER, SWT.CENTER, new TextPrint("double line\ncenter", SWT.CENTER)); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.RIGHT, SWT.BOTTOM, new TextPrint("single line right")); - - grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); - - grid.add(SWT.CENTER, SWT.CENTER, new TextPrint("several\nlines\nof\ntext\nhere", SWT.CENTER)); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.LEFT, SWT.FILL, verticalRule); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.CENTER, SWT.FILL, verticalRule); - grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); - grid.add(SWT.RIGHT, SWT.FILL, verticalRule); - - return grid; - } - - public void createParameters(Composite parent) { - // do nothing - - } - - public String[] createLinks() { - String[] links = { - "Paperclips Snippets" }; - return links; - } +/* + * Copyright (c) 2006 Matthew Hall and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Matthew Hall - initial API and implementation + * Cedric Brun - adapt to embed in the ExampleTab + */ +package org.eclipse.nebula.widgets.paperclips.example; + +import org.eclipse.nebula.examples.AbstractExampleTab; +import org.eclipse.nebula.paperclips.core.ImagePrint; +import org.eclipse.nebula.paperclips.core.LinePrint; +import org.eclipse.nebula.paperclips.core.PaperClips; +import org.eclipse.nebula.paperclips.core.Print; +import org.eclipse.nebula.paperclips.core.PrintJob; +import org.eclipse.nebula.paperclips.core.grid.DefaultGridLook; +import org.eclipse.nebula.paperclips.core.grid.GridPrint; +import org.eclipse.nebula.paperclips.core.text.TextPrint; +import org.eclipse.nebula.paperclips.widgets.PrintPreview; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.printing.PrinterData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +public class PaperclipsExampleTab extends AbstractExampleTab { + + public Control createControl(Composite parent) { + Composite shell = new Composite(parent, SWT.None); + + final PrintJob job = new PrintJob("GridPrintVerticalAlignmentExample.java", createPrint()); + shell.setLayout(new org.eclipse.swt.layout.GridLayout()); + + Composite buttonPanel = new Composite(shell, SWT.NONE); + buttonPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + buttonPanel.setLayout(new RowLayout(SWT.HORIZONTAL)); + + final PrintPreview preview = new PrintPreview(shell, SWT.BORDER); + + Button prev = new Button(buttonPanel, SWT.PUSH); + prev.setText("<< Prev"); + prev.addListener(SWT.Selection, event -> { + preview.setPageIndex(Math.max(preview.getPageIndex() - 1, 0)); + }); + + Button next = new Button(buttonPanel, SWT.PUSH); + next.setText("Next >>"); + next.addListener(SWT.Selection, event -> { + preview.setPageIndex(Math.min(preview.getPageIndex() + 1, preview.getPageCount() - 1)); + }); + + Button print = new Button(buttonPanel, SWT.PUSH); + print.setText("Print"); + print.addListener(SWT.Selection, event -> { + PaperClips.print(job, new PrinterData()); + }); + + preview.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + preview.setFitHorizontal(true); + preview.setFitVertical(true); + preview.setPrintJob(job); + return shell; + } + + public static Print createPrint() { + DefaultGridLook look = new DefaultGridLook(5, 5); + look.setHeaderGap(5); + GridPrint grid = new GridPrint("d:g, d, d:g, d, d:g, d, d:g", look); + + ImageData imageData = new ImageData(PaperclipsExampleTab.class.getResourceAsStream("logo.png")); + ImagePrint image = new ImagePrint(imageData); + image.setDPI(300, 300); + + Print verticalRule = new LinePrint(SWT.VERTICAL); + + grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 1")); + grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 2")); + grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 3")); + grid.addHeader(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.addHeader(SWT.CENTER, SWT.DEFAULT, new TextPrint("Column 4")); + + grid.addHeader(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); + + grid.add(SWT.LEFT, SWT.CENTER, image); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.DEFAULT, SWT.DEFAULT, new TextPrint("triple\nline\nleft\n")); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.CENTER, SWT.CENTER, new TextPrint("double line\ncenter", SWT.CENTER)); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.RIGHT, SWT.BOTTOM, new TextPrint("single line right")); + + grid.add(new LinePrint(SWT.HORIZONTAL), GridPrint.REMAINDER); + + grid.add(SWT.CENTER, SWT.CENTER, new TextPrint("several\nlines\nof\ntext\nhere", SWT.CENTER)); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.LEFT, SWT.FILL, verticalRule); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.CENTER, SWT.FILL, verticalRule); + grid.add(SWT.DEFAULT, SWT.FILL, verticalRule); + grid.add(SWT.RIGHT, SWT.FILL, verticalRule); + + return grid; + } + + public void createParameters(Composite parent) { + // do nothing + + } + + public String[] createLinks() { + String[] links = { + "Paperclips Snippets" }; + return links; + } } \ No newline at end of file diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/.project b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/.project index 7dad9528d..32fc5c112 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/.project +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/.project @@ -1,17 +1,17 @@ - - - org.eclipse.nebula.widgets.passwordrevealer.feature - - - - - - org.eclipse.pde.FeatureBuilder - - - - - - org.eclipse.pde.FeatureNature - - + + + org.eclipse.nebula.widgets.passwordrevealer.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/build.properties b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/build.properties index f9fa03db0..b40f03f72 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/build.properties +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/build.properties @@ -1,4 +1,4 @@ -bin.includes = feature.xml,\ - epl-2.0.html,\ - feature.properties,\ - license.html +bin.includes = feature.xml,\ + epl-2.0.html,\ + feature.properties,\ + license.html diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/feature.properties b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/feature.properties index ce26a1b1f..9dd2dd546 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/feature.properties +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/feature.properties @@ -1,148 +1,148 @@ -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Java\u2122 ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +Eclipse Foundation Software User Agreement\n\ +\n\ +November 22, 2017\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ +AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ +THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ +TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ +BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ +AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ +APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ +MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public License\n\ +Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ +available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ +"Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code, documentation\n\ +and other files maintained in the Eclipse Foundation source code repository\n\ +("Repository") in software modules ("Modules") and made available as\n\ +downloadable archives ("Downloads").\n\ +\n\ +- Content may be structured and packaged into modules to facilitate\n\ + delivering, extending, and upgrading the Content. Typical modules may\n\ + include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ + features ("Features").\n\ +- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ + (Java\u2122 ARchive) in a directory named "plugins".\n\ +- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ + associated material. Each Feature may be packaged as a sub-directory in a\n\ + directory named "features". Within a Feature, files named "feature.xml" may\n\ + contain a list of the names and version numbers of the Plug-ins and/or\n\ + Fragments associated with that Feature.\n\ +- Features may also include other Features ("Included Features"). Within a\n\ + Feature, files named "feature.xml" may contain a list of the names and\n\ + version numbers of Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be contained in\n\ +files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ +and Included Features should be contained in files named "license.html"\n\ +("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ +directory of a Download or Module including, but not limited to the following\n\ +locations:\n\ +\n\ +- The top-level (root) directory\n\ +- Plug-in and Fragment directories\n\ +- Inside Plug-ins and Fragments packaged as JARs\n\ +- Sub-directories of the directory named "src" of certain Plug-ins\n\ +- Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using\n\ +the Provisioning Technology (as defined below), you must agree to a license\n\ +("Feature Update License") during the installation process. If the Feature\n\ +contains Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform you\n\ +where you can locate them. Feature Update Licenses may be found in the "license"\n\ +property of files named "feature.properties" found within a Feature. Such\n\ +Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your use of\n\ +the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ +OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ +- Eclipse Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/epl-v10.html)\n\ +- Eclipse Distribution License Version 1.0 (available at\n\ + http://www.eclipse.org/licenses/edl-v1.0.html)\n\ +- Common Public License Version 1.0 (available at\n\ + http://www.eclipse.org/legal/cpl-v10.html)\n\ +- Apache Software License 1.1 (available at\n\ + http://www.apache.org/licenses/LICENSE)\n\ +- Apache Software License 2.0 (available at\n\ + http://www.apache.org/licenses/LICENSE-2.0)\n\ +- Mozilla Public License Version 1.1 (available at\n\ + http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ +USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ +provided, please contact the Eclipse Foundation to determine what terms and\n\ +conditions govern that particular Content.\n\ +\n\ +Use of Provisioning Technology\n\ +\n\ +The Eclipse Foundation makes available provisioning software, examples of which\n\ +include, but are not limited to, p2 and the Eclipse Update Manager\n\ +("Provisioning Technology") for the purpose of allowing users to install\n\ +software, documentation, information and/or other materials (collectively\n\ +"Installable Software"). This capability is provided with the intent of allowing\n\ +such users to install, extend and update Eclipse-based products. Information\n\ +about packaging Installable Software is available at\n\ +http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ +\n\ +You may use Provisioning Technology to allow other parties to install\n\ +Installable Software. You shall be responsible for enabling the applicable\n\ +license agreements relating to the Installable Software to be presented to, and\n\ +accepted by, the users of the Provisioning Technology in accordance with the\n\ +Specification. By using Provisioning Technology in such a manner and making it\n\ +available in accordance with the Specification, you further acknowledge your\n\ +agreement to, and the acquisition of all necessary rights to permit the\n\ +following:\n\ +\n\ +1. A series of actions may occur ("Provisioning Process") in which a user may\n\ + execute the Provisioning Technology on a machine ("Target Machine") with the\n\ + intent of installing, extending or updating the functionality of an\n\ + Eclipse-based product.\n\ +2. During the Provisioning Process, the Provisioning Technology may cause third\n\ + party Installable Software or a portion thereof to be accessed and copied to\n\ + the Target Machine.\n\ +3. Pursuant to the Specification, you will provide to the user the terms and\n\ + conditions that govern the use of the Installable Software ("Installable\n\ + Software Agreement") and such Installable Software Agreement shall be\n\ + accessed from the Target Machine in accordance with the Specification. Such\n\ + Installable Software Agreement must inform the user of the terms and\n\ + conditions that govern the Installable Software and must solicit acceptance\n\ + by the end user in the manner prescribed in such Installable\n\ + Software Agreement. Upon such indication of agreement by the user, the\n\ + provisioning Technology will complete installation of the\n\ + Installable Software.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are currently\n\ +may have restrictions on the import, possession, and use, and/or re-export to\n\ +another country, of encryption software. BEFORE using any encryption software,\n\ +please check the country's laws, regulations and policies concerning the import,\n\ +possession, or use, and re-export of encryption software, to see if this is\n\ +permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ +United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/feature.xml b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/feature.xml index e8e3a3bd4..c62c44340 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/feature.xml +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/feature.xml @@ -1,29 +1,29 @@ - - - - - PasswordRevealer - - - - %license - - - - - - + + + + + PasswordRevealer + + + + %license + + + + + + diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/pom.xml b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/pom.xml index 5cbd2e571..34ab6d26d 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/pom.xml +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.feature/pom.xml @@ -1,31 +1,31 @@ - - - - 4.0.0 - - - org.eclipse.nebula - passwordrevealer - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.passwordrevealer.feature - eclipse-feature - 1.0.0-SNAPSHOT - - Password Revealer Feature - - + + + + 4.0.0 + + + org.eclipse.nebula + passwordrevealer + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.passwordrevealer.feature + eclipse-feature + 1.0.0-SNAPSHOT + + Password Revealer Feature + + diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.classpath b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.classpath +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.project b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.project index 3add0d340..b5394eadd 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.project +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.passwordrevealer.snippets - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.passwordrevealer.snippets + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.settings/org.eclipse.jdt.core.prefs b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/META-INF/MANIFEST.MF b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/META-INF/MANIFEST.MF index f77de2e8f..366fb23d3 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/META-INF/MANIFEST.MF +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Password Revealer Snippets -Bundle-SymbolicName: org.eclipse.nebula.widgets.passwordrevealer.snippets -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.nebula.widgets.passwordrevealer;bundle-version="1.0.0", - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.passwordrevealer.snippets +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Password Revealer Snippets +Bundle-SymbolicName: org.eclipse.nebula.widgets.passwordrevealer.snippets +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.eclipse.nebula.widgets.passwordrevealer;bundle-version="1.0.0", + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.passwordrevealer.snippets diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/build.properties b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/build.properties +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/pom.xml b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/pom.xml index 3f93df16a..9807007c3 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/pom.xml +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - passwordrevealer - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.passwordrevealer.snippets - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + passwordrevealer + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.passwordrevealer.snippets + eclipse-plugin + + diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/src/org/eclipse/nebula/widgets/passwordrevealer/snippets/PasswordRevealerSnippet.java b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/src/org/eclipse/nebula/widgets/passwordrevealer/snippets/PasswordRevealerSnippet.java index c7abb6975..3386d54a0 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/src/org/eclipse/nebula/widgets/passwordrevealer/snippets/PasswordRevealerSnippet.java +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer.snippets/src/org/eclipse/nebula/widgets/passwordrevealer/snippets/PasswordRevealerSnippet.java @@ -1,93 +1,93 @@ -/******************************************************************************* - * Copyright (c) 2019 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron@gmail.com) - *******************************************************************************/ -package org.eclipse.nebula.widgets.passwordrevealer.snippets; - -import org.eclipse.nebula.widgets.passwordrevealer.PasswordRevealer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * A snippet for the Password Revealer Widget - */ -public class PasswordRevealerSnippet { - public static void main(final String[] args) { - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new GridLayout(1, false)); - shell.setText("Password Revealer Snippet"); - - final Image image = new Image(display, PasswordRevealerSnippet.class.getResourceAsStream("eye.png")); - final Image clickImage = new Image(display, PasswordRevealerSnippet.class.getResourceAsStream("eye-slash.png")); - shell.addListener(SWT.Dispose, e -> { - image.dispose(); - clickImage.dispose(); - }); - - final Label lbl1 = new Label(shell, SWT.NONE); - lbl1.setText("Password Revealer:"); - final GridData gdLabel1 = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); - gdLabel1.widthHint = 150; - lbl1.setLayoutData(gdLabel1); - - final PasswordRevealer revealer = new PasswordRevealer(shell, SWT.NONE); - final GridData gd = new GridData(GridData.FILL, GridData.CENTER, true, false); - gd.widthHint = 250; - revealer.setLayoutData(gd); - revealer.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY)); - revealer.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - - new Label(shell, SWT.NONE); - - final Label lbl2 = new Label(shell, SWT.NONE); - lbl2.setText("Password Revealer with other icon:"); - final GridData gdLabel2 = new GridData(GridData.FILL, GridData.CENTER, true, false); - gdLabel2.widthHint = 150; - lbl2.setLayoutData(gdLabel2); - - final PasswordRevealer revealer2 = new PasswordRevealer(shell, SWT.NONE); - final GridData gd2 = new GridData(GridData.FILL, GridData.CENTER, true, false); - gd2.widthHint = 250; - revealer2.setLayoutData(gd2); - revealer2.setImage(image); - revealer2.setClickImage(clickImage); - - new Label(shell, SWT.NONE); - - final Label lbl3 = new Label(shell, SWT.NONE); - lbl3.setText("Password Revealer with push style:"); - final GridData gdLabel3 = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); - gdLabel3.widthHint = 200; - lbl3.setLayoutData(gdLabel3); - - final PasswordRevealer revealer3 = new PasswordRevealer(shell, SWT.PUSH); - final GridData gd3 = new GridData(GridData.FILL, GridData.CENTER, true, false); - gd3.widthHint = 250; - revealer3.setLayoutData(gd3); - - - shell.pack(); - shell.open(); - - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - display.dispose(); - } - -} +/******************************************************************************* + * Copyright (c) 2019 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron@gmail.com) + *******************************************************************************/ +package org.eclipse.nebula.widgets.passwordrevealer.snippets; + +import org.eclipse.nebula.widgets.passwordrevealer.PasswordRevealer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * A snippet for the Password Revealer Widget + */ +public class PasswordRevealerSnippet { + public static void main(final String[] args) { + final Display display = new Display(); + final Shell shell = new Shell(display); + shell.setLayout(new GridLayout(1, false)); + shell.setText("Password Revealer Snippet"); + + final Image image = new Image(display, PasswordRevealerSnippet.class.getResourceAsStream("eye.png")); + final Image clickImage = new Image(display, PasswordRevealerSnippet.class.getResourceAsStream("eye-slash.png")); + shell.addListener(SWT.Dispose, e -> { + image.dispose(); + clickImage.dispose(); + }); + + final Label lbl1 = new Label(shell, SWT.NONE); + lbl1.setText("Password Revealer:"); + final GridData gdLabel1 = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); + gdLabel1.widthHint = 150; + lbl1.setLayoutData(gdLabel1); + + final PasswordRevealer revealer = new PasswordRevealer(shell, SWT.NONE); + final GridData gd = new GridData(GridData.FILL, GridData.CENTER, true, false); + gd.widthHint = 250; + revealer.setLayoutData(gd); + revealer.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY)); + revealer.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + new Label(shell, SWT.NONE); + + final Label lbl2 = new Label(shell, SWT.NONE); + lbl2.setText("Password Revealer with other icon:"); + final GridData gdLabel2 = new GridData(GridData.FILL, GridData.CENTER, true, false); + gdLabel2.widthHint = 150; + lbl2.setLayoutData(gdLabel2); + + final PasswordRevealer revealer2 = new PasswordRevealer(shell, SWT.NONE); + final GridData gd2 = new GridData(GridData.FILL, GridData.CENTER, true, false); + gd2.widthHint = 250; + revealer2.setLayoutData(gd2); + revealer2.setImage(image); + revealer2.setClickImage(clickImage); + + new Label(shell, SWT.NONE); + + final Label lbl3 = new Label(shell, SWT.NONE); + lbl3.setText("Password Revealer with push style:"); + final GridData gdLabel3 = new GridData(GridData.BEGINNING, GridData.CENTER, true, false); + gdLabel3.widthHint = 200; + lbl3.setLayoutData(gdLabel3); + + final PasswordRevealer revealer3 = new PasswordRevealer(shell, SWT.PUSH); + final GridData gd3 = new GridData(GridData.FILL, GridData.CENTER, true, false); + gd3.widthHint = 250; + revealer3.setLayoutData(gd3); + + + shell.pack(); + shell.open(); + + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + display.dispose(); + } + +} diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.classpath b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.classpath index ca3785c41..e801ebfb4 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.classpath +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.project b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.project index 98e538e96..b146ac530 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.project +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.project @@ -1,28 +1,28 @@ - - - org.eclipse.nebula.widgets.passwordrevealer - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - + + + org.eclipse.nebula.widgets.passwordrevealer + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.settings/org.eclipse.jdt.core.prefs b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.settings/org.eclipse.jdt.core.prefs index 11265a345..7adc0fb9a 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.settings/org.eclipse.jdt.core.prefs +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/META-INF/MANIFEST.MF b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/META-INF/MANIFEST.MF index ef4a20f24..ace124a74 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/META-INF/MANIFEST.MF +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Nebula Password Revealer Widget -Bundle-SymbolicName: org.eclipse.nebula.widgets.passwordrevealer -Bundle-Version: 1.0.0.qualifier -Bundle-Vendor: Eclipse Nebula -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Export-Package: org.eclipse.nebula.widgets.passwordrevealer -Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, - org.eclipse.swt -Automatic-Module-Name: org.eclipse.nebula.widgets.passwordrevealer +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Nebula Password Revealer Widget +Bundle-SymbolicName: org.eclipse.nebula.widgets.passwordrevealer +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: Eclipse Nebula +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Export-Package: org.eclipse.nebula.widgets.passwordrevealer +Require-Bundle: org.eclipse.nebula.widgets.opal.commons;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.swt +Automatic-Module-Name: org.eclipse.nebula.widgets.passwordrevealer diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/build.properties b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/build.properties index 41eb6ade2..34d2e4d2d 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/build.properties +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/build.properties @@ -1,4 +1,4 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/pom.xml b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/pom.xml index 35982cc63..7d29a6d91 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/pom.xml +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/pom.xml @@ -1,24 +1,24 @@ - - - - 4.0.0 - - - org.eclipse.nebula - passwordrevealer - 1.0.0-SNAPSHOT - - - org.eclipse.nebula.widgets.passwordrevealer - eclipse-plugin - - + + + + 4.0.0 + + + org.eclipse.nebula + passwordrevealer + 1.0.0-SNAPSHOT + + + org.eclipse.nebula.widgets.passwordrevealer + eclipse-plugin + + diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/src/org/eclipse/nebula/widgets/passwordrevealer/EyeButton.java b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/src/org/eclipse/nebula/widgets/passwordrevealer/EyeButton.java index 05afa7b79..c8c7ce40c 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/src/org/eclipse/nebula/widgets/passwordrevealer/EyeButton.java +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/src/org/eclipse/nebula/widgets/passwordrevealer/EyeButton.java @@ -1,185 +1,185 @@ -/******************************************************************************* - * Copyright (c) 2019 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.passwordrevealer; - -import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.graphics.Color; -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.Canvas; -import org.eclipse.swt.widgets.Composite; - -class EyeButton extends Canvas { - private static final int CIRCLE_RAY = 4; - private boolean mouseIn; - private boolean pressed; - private final Color color; - private Image image, clickImage; - private boolean isPushMode; - private boolean pushState; - - EyeButton(final Composite parent, final int style) { - super(parent, SWT.DOUBLE_BUFFERED); - isPushMode = (style & SWT.PUSH) == SWT.PUSH; - addListeners(); - color = new Color(parent.getDisplay(), 0, 127, 222); - SWTGraphicUtil.addDisposer(this, color); - setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); - pushState = false; - } - - private void addListeners() { - addPaintListener(e -> { - paintControl(e); - }); - - addListener(SWT.MouseEnter, event -> { - mouseIn = true; - redraw(); - }); - - addListener(SWT.MouseExit, event -> { - mouseIn = false; - pressed = false; - redraw(); - }); - - addListener(SWT.MouseDown, event -> { - if (isPushMode) { - return; - } - - pressed = true; - ((PasswordRevealer) getParent()).revealPassword(); - redraw(); - }); - - addListener(SWT.MouseUp, event -> { - if (isPushMode) { - pushState = !pushState; - if (pushState) { - ((PasswordRevealer) getParent()).revealPassword(); - } else { - ((PasswordRevealer) getParent()).hidePassword(); - } - return; - } - - pressed = false; - ((PasswordRevealer) getParent()).hidePassword(); - redraw(); - }); - } - - private void paintControl(final PaintEvent e) { - final GC gc = e.gc; - if (!mouseIn && !pressed) { - if (image != null) { - drawImage(gc, image); - } else { - drawEye(gc, getDisplay().getSystemColor(SWT.COLOR_GRAY)); - } - return; - } - - if (mouseIn && !pressed) { - if (image != null) { - drawImage(gc, image); - } else { - drawEye(gc, color); - } - return; - } - - if (clickImage == null && image != null) { - drawImage(gc, image); - return; - } else if (clickImage != null) { - drawImage(gc, clickImage); - return; - - } - - final Rectangle rect = getClientArea(); - gc.setBackground(color); - gc.fillRectangle(rect); - - drawEye(gc, getDisplay().getSystemColor(SWT.COLOR_WHITE)); - } - - private void drawEye(final GC gc, final Color clr) { - gc.setAdvanced(true); - gc.setAntialias(SWT.ON); - gc.setLineWidth(2); - - final Rectangle rect = getClientArea(); - final int eyeWidth = (int) (rect.width * .7); - final int eyeHeight = (int) (rect.height * .5); - gc.setForeground(clr); - gc.drawOval((int) (rect.width * .15), (int) (rect.height * .25), eyeWidth, eyeHeight); - - gc.setBackground(clr); - gc.fillOval(rect.width / 2 - CIRCLE_RAY / 2, rect.height / 2 - CIRCLE_RAY / 2, CIRCLE_RAY, CIRCLE_RAY); - } - - private void drawImage(final GC gc, final Image img) { - final Rectangle rect = getClientArea(); - final Rectangle imageBounds = img.getBounds(); - final int middleX = (rect.width - imageBounds.width) / 2; - final int middleY = (rect.height - imageBounds.height) / 2; - gc.drawImage(img, middleX, middleY); - } - - @Override - public Point computeSize(final int wHint, final int hHint, final boolean changed) { - final PasswordRevealer parent = (PasswordRevealer) getParent(); - final int preferred = parent.passwordField.computeSize(SWT.DEFAULT, hHint, changed).y; - int minWidth, minHeight; - if (image == null) { - minWidth = minHeight = 20; - } else { - minWidth = image.getBounds().width; - minHeight = image.getBounds().height; - if (clickImage != null) { - minWidth = Math.max(clickImage.getBounds().width, minWidth); - minHeight = Math.max(clickImage.getBounds().height, minHeight); - } - } - return super.computeSize(Math.max(preferred, minWidth), Math.max(preferred, minHeight), changed); - } - - void setImage(final Image image) { - this.image = image; - } - - void setClickImage(final Image clickImage) { - this.clickImage = clickImage; - } - - Image getImage() { - return image; - } - - Image getClickImage() { - return clickImage; - } - - void setPushMode(boolean pushMode) { - isPushMode = pushMode; - } - -} +/******************************************************************************* + * Copyright (c) 2019 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.passwordrevealer; + +import org.eclipse.nebula.widgets.opal.commons.SWTGraphicUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.Color; +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.Canvas; +import org.eclipse.swt.widgets.Composite; + +class EyeButton extends Canvas { + private static final int CIRCLE_RAY = 4; + private boolean mouseIn; + private boolean pressed; + private final Color color; + private Image image, clickImage; + private boolean isPushMode; + private boolean pushState; + + EyeButton(final Composite parent, final int style) { + super(parent, SWT.DOUBLE_BUFFERED); + isPushMode = (style & SWT.PUSH) == SWT.PUSH; + addListeners(); + color = new Color(parent.getDisplay(), 0, 127, 222); + SWTGraphicUtil.addDisposer(this, color); + setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE)); + pushState = false; + } + + private void addListeners() { + addPaintListener(e -> { + paintControl(e); + }); + + addListener(SWT.MouseEnter, event -> { + mouseIn = true; + redraw(); + }); + + addListener(SWT.MouseExit, event -> { + mouseIn = false; + pressed = false; + redraw(); + }); + + addListener(SWT.MouseDown, event -> { + if (isPushMode) { + return; + } + + pressed = true; + ((PasswordRevealer) getParent()).revealPassword(); + redraw(); + }); + + addListener(SWT.MouseUp, event -> { + if (isPushMode) { + pushState = !pushState; + if (pushState) { + ((PasswordRevealer) getParent()).revealPassword(); + } else { + ((PasswordRevealer) getParent()).hidePassword(); + } + return; + } + + pressed = false; + ((PasswordRevealer) getParent()).hidePassword(); + redraw(); + }); + } + + private void paintControl(final PaintEvent e) { + final GC gc = e.gc; + if (!mouseIn && !pressed) { + if (image != null) { + drawImage(gc, image); + } else { + drawEye(gc, getDisplay().getSystemColor(SWT.COLOR_GRAY)); + } + return; + } + + if (mouseIn && !pressed) { + if (image != null) { + drawImage(gc, image); + } else { + drawEye(gc, color); + } + return; + } + + if (clickImage == null && image != null) { + drawImage(gc, image); + return; + } else if (clickImage != null) { + drawImage(gc, clickImage); + return; + + } + + final Rectangle rect = getClientArea(); + gc.setBackground(color); + gc.fillRectangle(rect); + + drawEye(gc, getDisplay().getSystemColor(SWT.COLOR_WHITE)); + } + + private void drawEye(final GC gc, final Color clr) { + gc.setAdvanced(true); + gc.setAntialias(SWT.ON); + gc.setLineWidth(2); + + final Rectangle rect = getClientArea(); + final int eyeWidth = (int) (rect.width * .7); + final int eyeHeight = (int) (rect.height * .5); + gc.setForeground(clr); + gc.drawOval((int) (rect.width * .15), (int) (rect.height * .25), eyeWidth, eyeHeight); + + gc.setBackground(clr); + gc.fillOval(rect.width / 2 - CIRCLE_RAY / 2, rect.height / 2 - CIRCLE_RAY / 2, CIRCLE_RAY, CIRCLE_RAY); + } + + private void drawImage(final GC gc, final Image img) { + final Rectangle rect = getClientArea(); + final Rectangle imageBounds = img.getBounds(); + final int middleX = (rect.width - imageBounds.width) / 2; + final int middleY = (rect.height - imageBounds.height) / 2; + gc.drawImage(img, middleX, middleY); + } + + @Override + public Point computeSize(final int wHint, final int hHint, final boolean changed) { + final PasswordRevealer parent = (PasswordRevealer) getParent(); + final int preferred = parent.passwordField.computeSize(SWT.DEFAULT, hHint, changed).y; + int minWidth, minHeight; + if (image == null) { + minWidth = minHeight = 20; + } else { + minWidth = image.getBounds().width; + minHeight = image.getBounds().height; + if (clickImage != null) { + minWidth = Math.max(clickImage.getBounds().width, minWidth); + minHeight = Math.max(clickImage.getBounds().height, minHeight); + } + } + return super.computeSize(Math.max(preferred, minWidth), Math.max(preferred, minHeight), changed); + } + + void setImage(final Image image) { + this.image = image; + } + + void setClickImage(final Image clickImage) { + this.clickImage = clickImage; + } + + Image getImage() { + return image; + } + + Image getClickImage() { + return clickImage; + } + + void setPushMode(boolean pushMode) { + isPushMode = pushMode; + } + +} diff --git a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/src/org/eclipse/nebula/widgets/passwordrevealer/PasswordRevealer.java b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/src/org/eclipse/nebula/widgets/passwordrevealer/PasswordRevealer.java index c884b95f1..1cc3b5f11 100644 --- a/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/src/org/eclipse/nebula/widgets/passwordrevealer/PasswordRevealer.java +++ b/widgets/passwordrevealer/org.eclipse.nebula.widgets.passwordrevealer/src/org/eclipse/nebula/widgets/passwordrevealer/PasswordRevealer.java @@ -1,2367 +1,2367 @@ -/******************************************************************************* - * Copyright (c) 2019 Laurent CARON. - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API - * and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.passwordrevealer; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.events.DragDetectListener; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.GestureListener; -import org.eclipse.swt.events.HelpListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.MenuDetectListener; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.events.MouseWheelListener; -import org.eclipse.swt.events.SegmentEvent; -import org.eclipse.swt.events.SegmentListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.events.TouchListener; -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Cursor; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Widget; - -/** - * Instances of this class are selectable user interface - * objects that allow the user to enter and modify passwords. - * A "eye" button is drawned on the right side of the widget. - * If SWT.PUSH is set, when one clicks on the button the password is revealed and the button is switched on. - * When one clicks again, the password is displayed as a password (characters are replaced by dots) and the button is switched off. - * if SWT.PUSH is not set, when one clicks on the button the password is revealed, and when the user stops clicking the password is displayed with dots. - *

- *

- *
Styles:
- *
CENTER, ICON_CANCEL, ICON_SEARCH, LEFT, MULTI, PASSWORD, SEARCH, SINGLE, RIGHT, READ_ONLY, WRAP, PUSH
- *
Events:
- *
DefaultSelection, Modify, Verify, OrientationChange
- *
- *

- * Note: Only one of the styles MULTI and SINGLE may be specified, - * and only one of the styles LEFT, CENTER, and RIGHT may be specified. - *

- *

- * Note: The styles ICON_CANCEL and ICON_SEARCH are hints used in combination with SEARCH. - * When the platform supports the hint, the text control shows these icons. When an icon - * is selected, a default selection event is sent with the detail field set to one of - * ICON_CANCEL or ICON_SEARCH. Normally, application code does not need to check the - * detail. In the case of ICON_CANCEL, the text is cleared before the default selection - * event is sent causing the application to search for an empty string. - *

- *

- * IMPORTANT: This class is not intended to be subclassed. - *

- * - * @see Text snippets - * @see SWT Example: ControlExample - * @see Sample code and further information - * @noextend This class is not intended to be subclassed by clients. - */ -public class PasswordRevealer extends Composite { - - protected Text passwordField; - private final EyeButton eyeButton; - private final char defaultEchoChar; - private boolean isPushMode; - - /** - * Constructs a new instance of this class given its parent and a style value - * describing its behavior and appearance. - *

- * The style value is either one of the style constants defined in class - * SWT which is applicable to instances of this class, or must be - * built by bitwise OR'ing together (that is, using the - * int "|" operator) two or more of those SWT style - * constants. The class description lists the style constants that are - * applicable to the class. Style bits are also inherited from superclasses. - *

- * - * @param parent a composite control which will be the parent of the new - * instance (cannot be null) - * @param style the style of control to construct - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the - * thread that created the parent
  • - *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed - * subclass
  • - *
- * - * @see Widget#getStyle() - */ - public PasswordRevealer(final Composite parent, final int style) { - super(parent, SWT.BORDER); - isPushMode = (style & SWT.PUSH) == SWT.PUSH; - final GridLayout gl = new GridLayout(2, false); - gl.horizontalSpacing = gl.verticalSpacing = gl.marginHeight = gl.marginWidth = 0; - gl.marginBottom = gl.marginLeft = gl.marginRight = gl.marginTop = 0; - setLayout(gl); - - super.setBackground(parent.getBackground()); - passwordField = new Text(this, removeFields(style, SWT.BORDER, SWT.PUSH) | SWT.PASSWORD); - passwordField.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - defaultEchoChar = passwordField.getEchoChar(); - - eyeButton = new EyeButton(this, isPushMode ? SWT.PUSH : SWT.NONE); - eyeButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); - } - - private int removeFields(final int original, final int... styles) { - int returnedStyle = original; - for (final int toBeRemoved : styles) { - if ((returnedStyle & toBeRemoved) != 0) { - returnedStyle = returnedStyle & ~toBeRemoved; - } - } - return returnedStyle; - } - - void revealPassword() { - passwordField.setEchoChar('\0'); - } - - void hidePassword() { - passwordField.setEchoChar(defaultEchoChar); - } - - // Inherithed methods - - /** - * Adds the listener to the collection of listeners who will - * be notified when the receiver's text is modified, by sending - * it one of the messages defined in the ModifyListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #removeModifyListener - */ - public void addModifyListener(final ModifyListener listener) { - passwordField.addModifyListener(listener); - } - - /** - * Adds a segment listener. - *

- * A SegmentEvent is sent whenever text content is being modified or - * a segment listener is added or removed. You can - * customize the appearance of text by indicating certain characters to be inserted - * at certain text offsets. This may be used for bidi purposes, e.g. when - * adjacent segments of right-to-left text should not be reordered relative to - * each other. - * E.g., multiple Java string literals in a right-to-left language - * should generally remain in logical order to each other, that is, the - * way they are stored. - *

- *

- * Warning: This API is currently only implemented on Windows and GTK. - * SegmentEvents won't be sent on Cocoa. - *

- * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see SegmentEvent - * @see SegmentListener - * @see #removeSegmentListener - * - * @since 3.8 - */ - public void addSegmentListener(final SegmentListener listener) { - passwordField.addSegmentListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the control is selected by the user, by sending - * it one of the messages defined in the SelectionListener - * interface. - *

- * widgetSelected is not called for texts. - * widgetDefaultSelected is typically called when ENTER is pressed in a single-line text, - * or when ENTER is pressed in a search text. If the receiver has the SWT.SEARCH | SWT.ICON_CANCEL style - * and the user cancels the search, the event object detail field contains the value SWT.ICON_CANCEL. - * Likewise, if the receiver has the SWT.ICON_SEARCH style and the icon search is selected, the - * event object detail field contains the value SWT.ICON_SEARCH. - *

- * - * @param listener the listener which should be notified when the control is selected by the user - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #removeSelectionListener - * @see SelectionEvent - */ - public void addSelectionListener(final SelectionListener listener) { - passwordField.addSelectionListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the receiver's text is verified, by sending - * it one of the messages defined in the VerifyListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see VerifyListener - * @see #removeVerifyListener - */ - public void addVerifyListener(final VerifyListener listener) { - passwordField.addVerifyListener(listener); - } - - /** - * Appends a string. - *

- * The new text is appended to the text at - * the end of the widget. - *

- * - * @param string the string to be appended - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the string is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void append(final String string) { - passwordField.append(string); - } - - /** - * Clears the selection. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void clearSelection() { - passwordField.clearSelection(); - } - - /** - * Copies the selected text. - *

- * The current selection is copied to the clipboard. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void copy() { - passwordField.copy(); - } - - /** - * Cuts the selected text. - *

- * The current selection is first copied to the - * clipboard and then deleted from the widget. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void cut() { - passwordField.cut(); - } - - /** - * Returns the line number of the caret. - *

- * The line number of the caret is returned. - *

- * - * @return the line number - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getCaretLineNumber() { - return passwordField.getCaretLineNumber(); - } - - /** - * Returns a point describing the location of the caret relative - * to the receiver. - * - * @return a point, the location of the caret - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Point getCaretLocation() { - return passwordField.getCaretLocation(); - } - - /** - * Returns the character position of the caret. - *

- * Indexing is zero based. - *

- * - * @return the position of the caret - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getCaretPosition() { - return passwordField.getCaretPosition(); - } - - /** - * Returns the number of characters. - * - * @return number of characters in the widget - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getCharCount() { - return passwordField.getCharCount(); - } - - /** - * Returns the image displayed when the "reveal button" is clicked. - * - * @return the image. If null it means that the default button is used - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Image getClickImage() { - checkWidget(); - return eyeButton.getClickImage(); - } - - /** - * Returns the double click enabled flag. - *

- * The double click flag enables or disables the - * default action of the text widget when the user - * double clicks. - *

- * - * @return whether or not double click is enabled - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public boolean getDoubleClickEnabled() { - return passwordField.getDoubleClickEnabled(); - } - - /** - * Returns the echo character. - *

- * The echo character is the character that is - * displayed when the user enters text or the - * text is changed by the programmer. - *

- * - * @return the echo character - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see #setEchoChar - */ - public char getEchoChar() { - return passwordField.getEchoChar(); - } - - /** - * Returns the editable state. - * - * @return whether or not the receiver is editable - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public boolean getEditable() { - return passwordField.getEditable(); - } - - /** - * Returns the image used when the user wants to reveal the password of lines. - * - * @return the image. null means that the icon is the default one - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Image getImage() { - checkWidget(); - return eyeButton.getImage(); - } - - /** - * Returns the number of lines. - * - * @return the number of lines in the widget - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getLineCount() { - return passwordField.getLineCount(); - } - - /** - * Returns the line delimiter. - * - * @return a string that is the line delimiter - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see #DELIMITER - */ - public String getLineDelimiter() { - return passwordField.getLineDelimiter(); - } - - /** - * Returns the height of a line. - * - * @return the height of a row of text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getLineHeight() { - return passwordField.getLineHeight(); - } - - /** - * Returns the widget message. The message text is displayed - * as a hint for the user, indicating the purpose of the field. - *

- * Typically this is used in conjunction with SWT.SEARCH. - *

- * - * @return the widget message - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @since 3.3 - */ - public String getMessage() { - return passwordField.getMessage(); - } - - /** - * Returns a Point whose x coordinate is the - * character position representing the start of the selected - * text, and whose y coordinate is the character position - * representing the end of the selection. An "empty" selection - * is indicated by the x and y coordinates having the same value. - *

- * Indexing is zero based. The range of a selection is from - * 0..N where N is the number of characters in the widget. - *

- * - * @return a point representing the selection start and end - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public Point getSelection() { - return passwordField.getSelection(); - } - - /** - * Returns the number of selected characters. - * - * @return the number of selected characters. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getSelectionCount() { - return passwordField.getSelectionCount(); - } - - /** - * Gets the selected text, or an empty string if there is no current selection. - * - * @return the selected text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public String getSelectionText() { - return passwordField.getSelectionText(); - } - - /** - * Returns the number of tabs. - *

- * Tab stop spacing is specified in terms of the - * space (' ') character. The width of a single - * tab stop is the pixel width of the spaces. - *

- * - * @return the number of tab characters - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getTabs() { - return passwordField.getTabs(); - } - - /** - * Returns the widget text. - *

- * The text for a text widget is the characters in the widget, or - * an empty string if this has never been set. - *

- * - * @return the widget text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public String getText() { - return passwordField.getText(); - } - - /** - * Returns the widget's text as a character array. - *

- * The text for a text widget is the characters in the widget, or - * a zero-length array if this has never been set. - *

- *

- * Note: Use this API to prevent the text from being written into a String - * object whose lifecycle is outside of your control. This can help protect - * the text, for example, when the widget is used as a password field. - * However, the text can't be protected if an {@link SWT#Segments} or - * {@link SWT#Verify} listener has been added to the widget. - *

- * - * @return a character array that contains the widget's text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see #setTextChars(char[]) - * - * @since 3.7 - */ - public char[] getTextChars() { - return passwordField.getTextChars(); - } - - /** - * Returns a range of text. Returns an empty string if the - * start of the range is greater than the end. - *

- * Indexing is zero based. The range of - * a selection is from 0..N-1 where N is - * the number of characters in the widget. - *

- * - * @param start the start of the range - * @param end the end of the range - * @return the range of text - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public String getText(final int start, final int end) { - return passwordField.getText(start, end); - } - - /** - * Returns the maximum number of characters that the receiver is capable of holding. - *

- * If this has not been changed by setTextLimit(), - * it will be the constant Text.LIMIT. - *

- * - * @return the text limit - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see #LIMIT - */ - public int getTextLimit() { - return passwordField.getTextLimit(); - } - - /** - * Returns the zero-relative index of the line which is currently - * at the top of the receiver. - *

- * This index can change when lines are scrolled or new lines are added or removed. - *

- * - * @return the index of the top line - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getTopIndex() { - return passwordField.getTopIndex(); - } - - /** - * Returns the zero-relative index of the line which is currently - * at the top of the receiver. - *

- * This index can change when lines are scrolled or new lines are added or removed. - *

- * - * @return the index of the top line - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public int getTopPixel() { - return passwordField.getTopPixel(); - } - - /** - * Inserts a string. - *

- * The old selection is replaced with the new text. - *

- * - * @param string the string - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the string is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void insert(final String string) { - passwordField.insert(string); - } - - /** - * Pastes text from clipboard. - *

- * The selected text is deleted from the widget - * and new text inserted from the clipboard. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void paste() { - passwordField.paste(); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the receiver's text is modified. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see ModifyListener - * @see #addModifyListener - */ - public void removeModifyListener(final ModifyListener listener) { - passwordField.removeModifyListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the receiver's text is modified. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see SegmentEvent - * @see SegmentListener - * @see #addSegmentListener - * - * @since 3.8 - */ - public void removeSegmentListener(final SegmentListener listener) { - passwordField.removeSegmentListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the control is selected by the user. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see SelectionListener - * @see #addSelectionListener - */ - public void removeSelectionListener(final SelectionListener listener) { - passwordField.removeSelectionListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the control is verified. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see VerifyListener - * @see #addVerifyListener - */ - public void removeVerifyListener(final VerifyListener listener) { - passwordField.removeVerifyListener(listener); - } - - /** - * Selects all the text in the receiver. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void selectAll() { - passwordField.selectAll(); - } - - /** - * Sets the double click enabled flag. - *

- * The double click flag enables or disables the - * default action of the text widget when the user - * double clicks. - *

- *

- * Note: This operation is a hint and is not supported on - * platforms that do not have this concept. - *

- * - * @param doubleClick the new double click flag - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setDoubleClickEnabled(final boolean doubleClick) { - passwordField.setDoubleClickEnabled(doubleClick); - } - - /** - * Sets the echo character. - *

- * The echo character is the character that is - * displayed when the user enters text or the - * text is changed by the programmer. Setting - * the echo character to '\0' clears the echo - * character and redraws the original text. - * If for any reason the echo character is invalid, - * or if the platform does not allow modification - * of the echo character, the default echo character - * for the platform is used. - *

- * - * @param echo the new echo character - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setEchoChar(final char echo) { - passwordField.setEchoChar(echo); - } - - /** - * Sets the editable state. - * - * @param editable the new editable state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setEditable(final boolean editable) { - passwordField.setEditable(editable); - } - - /** - * Sets the font that the receiver will use to paint textual information - * to the font specified by the argument, or to the default font for that - * kind of control if the argument is null. - * - * @param font the new font (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setFont(final Font font) { - super.setFont(font); - passwordField.setFont(font); - } - - /** - * Sets the image on which the user should click if he wants to reveal the password. - * - * @param image the new image. If null, the default "eye" icon will be displayed - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setImage(final Image image) { - checkWidget(); - eyeButton.setImage(image); - } - - /** - * Sets the widget message. The message text is displayed - * as a hint for the user, indicating the purpose of the field. - *

- * Typically this is used in conjunction with SWT.SEARCH. - *

- * - * @param message the new message - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the message is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @since 3.3 - */ - public void setMessage(final String message) { - passwordField.setMessage(message); - } - - /** - * Sets the orientation of the receiver, which must be one - * of the constants SWT.LEFT_TO_RIGHT or SWT.RIGHT_TO_LEFT. - *

- * Note: This operation is a hint and is not supported on - * platforms that do not have this concept. - *

- * - * @param orientation new orientation style - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - */ - @Override - public void setOrientation(final int orientation) { - passwordField.setOrientation(orientation); - } - - /** - * Sets the eye's button behaviour. - * - * @param pushMode new push mode - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - */ - public void setPushMode(boolean pushMode) { - checkWidget(); - this.isPushMode = pushMode; - eyeButton.setPushMode(pushMode); - } - - /** - * Sets the selection. - *

- * Indexing is zero based. The range of - * a selection is from 0..N where N is - * the number of characters in the widget. - *

- *

- * Text selections are specified in terms of - * caret positions. In a text widget that - * contains N characters, there are N+1 caret - * positions, ranging from 0..N. This differs - * from other functions that address character - * position such as getText () that use the - * regular array indexing rules. - *

- * - * @param start new caret position - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setSelection(final int start) { - passwordField.setSelection(start); - } - - /** - * Sets the selection to the range specified - * by the given start and end indices. - *

- * Indexing is zero based. The range of - * a selection is from 0..N where N is - * the number of characters in the widget. - *

- *

- * Text selections are specified in terms of - * caret positions. In a text widget that - * contains N characters, there are N+1 caret - * positions, ranging from 0..N. This differs - * from other functions that address character - * position such as getText () that use the - * usual array indexing rules. - *

- * - * @param start the start of the range - * @param end the end of the range - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setSelection(final int start, final int end) { - passwordField.setSelection(start, end); - } - - /** - * Sets the selection to the range specified - * by the given point, where the x coordinate - * represents the start index and the y coordinate - * represents the end index. - *

- * Indexing is zero based. The range of - * a selection is from 0..N where N is - * the number of characters in the widget. - *

- *

- * Text selections are specified in terms of - * caret positions. In a text widget that - * contains N characters, there are N+1 caret - * positions, ranging from 0..N. This differs - * from other functions that address character - * position such as getText () that use the - * usual array indexing rules. - *

- * - * @param selection the point - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the point is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setSelection(final Point selection) { - passwordField.setSelection(selection); - } - - /** - * Sets the number of tabs. - *

- * Tab stop spacing is specified in terms of the - * space (' ') character. The width of a single - * tab stop is the pixel width of the spaces. - *

- * - * @param tabs the number of tabs - * - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setTabs(final int tabs) { - passwordField.setTabs(tabs); - } - - /** - * Sets the contents of the receiver to the given string. If the receiver has style - * SINGLE and the argument contains multiple lines of text, the result of this - * operation is undefined and may vary from platform to platform. - *

- * Note: If control characters like '\n', '\t' etc. are used - * in the string, then the behavior is platform dependent. - *

- * - * @param string the new text - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the string is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setText(final String string) { - passwordField.setText(string); - } - - /** - * Sets the contents of the receiver to the characters in the array. If the receiver - * has style SWT.SINGLE and the argument contains multiple lines of text - * then the result of this operation is undefined and may vary between platforms. - *

- * Note: Use this API to prevent the text from being written into a String - * object whose lifecycle is outside of your control. This can help protect - * the text, for example, when the widget is used as a password field. - * However, the text can't be protected if an {@link SWT#Segments} or - * {@link SWT#Verify} listener has been added to the widget. - *

- * - * @param text a character array that contains the new text - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the array is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see #getTextChars() - * - * @since 3.7 - */ - public void setTextChars(final char[] text) { - passwordField.setTextChars(text); - } - - /** - * Sets the maximum number of characters that the receiver - * is capable of holding to be the argument. - *

- * Instead of trying to set the text limit to zero, consider - * creating a read-only text widget. - *

- *

- * To reset this value to the default, use setTextLimit(Text.LIMIT). - * Specifying a limit value larger than Text.LIMIT sets the - * receiver's limit to Text.LIMIT. - *

- * - * @param limit new text limit - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_CANNOT_BE_ZERO - if the limit is zero
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see #LIMIT - */ - public void setTextLimit(final int limit) { - passwordField.setTextLimit(limit); - } - - /** - * Sets the zero-relative index of the line which is currently - * at the top of the receiver. This index can change when lines - * are scrolled or new lines are added and removed. - * - * @param index the index of the top item - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setTopIndex(final int index) { - passwordField.setTopIndex(index); - } - - /** - * Shows the selection. - *

- * If the selection is already showing - * in the receiver, this method simply returns. Otherwise, - * lines are scrolled until the selection is visible. - *

- * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void showSelection() { - passwordField.showSelection(); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when a drag gesture occurs, by sending it - * one of the messages defined in the DragDetectListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see DragDetectListener - * @see #removeDragDetectListener - * - * @since 3.3 - */ - @Override - public void addDragDetectListener(final DragDetectListener listener) { - super.addDragDetectListener(listener); - eyeButton.addDragDetectListener(listener); - passwordField.addDragDetectListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the control gains or loses focus, by sending - * it one of the messages defined in the FocusListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see FocusListener - * @see #removeFocusListener - */ - @Override - public void addFocusListener(final FocusListener listener) { - super.addFocusListener(listener); - eyeButton.addFocusListener(listener); - passwordField.addFocusListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when gesture events are generated for the control, - * by sending it one of the messages defined in the - * GestureListener interface. - *

- * NOTE: If setTouchEnabled(true) has previously been - * invoked on the receiver then setTouchEnabled(false) - * must be invoked on it to specify that gesture events should be - * sent instead of touch events. - *

- *

- * Warning: This API is currently only implemented on Windows and Cocoa. - * SWT doesn't send Gesture or Touch events on GTK. - *

- * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see GestureListener - * @see #removeGestureListener - * @see #setTouchEnabled - * - * @since 3.7 - */ - @Override - public void addGestureListener(final GestureListener listener) { - super.addGestureListener(listener); - eyeButton.addGestureListener(listener); - passwordField.addGestureListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when help events are generated for the control, - * by sending it one of the messages defined in the - * HelpListener interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see HelpListener - * @see #removeHelpListener - */ - @Override - public void addHelpListener(final HelpListener listener) { - super.addHelpListener(listener); - eyeButton.addHelpListener(listener); - passwordField.addHelpListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when keys are pressed and released on the system keyboard, by sending - * it one of the messages defined in the KeyListener - * interface. - *

- * When a key listener is added to a control, the control - * will take part in widget traversal. By default, all - * traversal keys (such as the tab key and so on) are - * delivered to the control. In order for a control to take - * part in traversal, it should listen for traversal events. - * Otherwise, the user can traverse into a control but not - * out. Note that native controls such as table and tree - * implement key traversal in the operating system. It is - * not necessary to add traversal listeners for these controls, - * unless you want to override the default traversal. - *

- * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see KeyListener - * @see #removeKeyListener - */ - @Override - public void addKeyListener(final KeyListener listener) { - super.addKeyListener(listener); - eyeButton.addKeyListener(listener); - passwordField.addKeyListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the platform-specific context menu trigger - * has occurred, by sending it one of the messages defined in - * the MenuDetectListener interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MenuDetectListener - * @see #removeMenuDetectListener - * - * @since 3.3 - */ - @Override - public void addMenuDetectListener(final MenuDetectListener listener) { - super.addMenuDetectListener(listener); - eyeButton.addMenuDetectListener(listener); - passwordField.addMenuDetectListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when mouse buttons are pressed and released, by sending - * it one of the messages defined in the MouseListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MouseListener - * @see #removeMouseListener - */ - @Override - public void addMouseListener(final MouseListener listener) { - super.addMouseListener(listener); - eyeButton.addMouseListener(listener); - passwordField.addMouseListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the mouse passes or hovers over controls, by sending - * it one of the messages defined in the MouseTrackListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MouseTrackListener - * @see #removeMouseTrackListener - */ - @Override - public void addMouseTrackListener(final MouseTrackListener listener) { - super.addMouseTrackListener(listener); - eyeButton.addMouseTrackListener(listener); - passwordField.addMouseTrackListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the mouse moves, by sending it one of the - * messages defined in the MouseMoveListener - * interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MouseMoveListener - * @see #removeMouseMoveListener - */ - @Override - public void addMouseMoveListener(final MouseMoveListener listener) { - super.addMouseMoveListener(listener); - eyeButton.addMouseMoveListener(listener); - passwordField.addMouseMoveListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when the mouse wheel is scrolled, by sending - * it one of the messages defined in the - * MouseWheelListener interface. - * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MouseWheelListener - * @see #removeMouseWheelListener - * - * @since 3.3 - */ - @Override - public void addMouseWheelListener(final MouseWheelListener listener) { - super.addMouseWheelListener(listener); - eyeButton.addMouseWheelListener(listener); - passwordField.addMouseWheelListener(listener); - } - - /** - * Adds the listener to the collection of listeners who will - * be notified when touch events occur, by sending it - * one of the messages defined in the TouchListener - * interface. - *

- * NOTE: You must also call setTouchEnabled(true) to - * specify that touch events should be sent, which will cause gesture - * events to not be sent. - *

- *

- * Warning: This API is currently only implemented on Windows and Cocoa. - * SWT doesn't send Gesture or Touch events on GTK. - *

- * - * @param listener the listener which should be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see TouchListener - * @see #removeTouchListener - * @see #setTouchEnabled - * - * @since 3.7 - */ - @Override - public void addTouchListener(final TouchListener listener) { - super.addTouchListener(listener); - eyeButton.addTouchListener(listener); - passwordField.addTouchListener(listener); - } - - /** - * Forces the receiver to have the keyboard focus, causing - * all keyboard events to be delivered to it. - * - * @return true if the control got focus, and false if it was unable to. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see #setFocus - */ - @Override - public boolean forceFocus() { - return passwordField.forceFocus(); - } - - /** - * Returns true if the receiver has the user-interface - * focus, and false otherwise. - * - * @return the receiver's focus state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public boolean isFocusControl() { - return passwordField.isFocusControl(); - } - - /** - * Returns true if the eye button is a "push" button, and false otherwise. - * - * @return the eye button push mode - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public boolean isPushMode() { - checkWidget(); - return isPushMode; - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the control gains or loses focus. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see FocusListener - * @see #addFocusListener - */ - @Override - public void removeFocusListener(final FocusListener listener) { - super.removeFocusListener(listener); - eyeButton.removeFocusListener(listener); - passwordField.removeFocusListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when gesture events are generated for the control. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see GestureListener - * @see #addGestureListener - * - * @since 3.7 - */ - @Override - public void removeGestureListener(final GestureListener listener) { - super.removeGestureListener(listener); - eyeButton.removeGestureListener(listener); - passwordField.removeGestureListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the help events are generated for the control. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see HelpListener - * @see #addHelpListener - */ - @Override - public void removeHelpListener(final HelpListener listener) { - super.removeHelpListener(listener); - eyeButton.removeHelpListener(listener); - passwordField.removeHelpListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when keys are pressed and released on the system keyboard. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see KeyListener - * @see #addKeyListener - */ - @Override - public void removeKeyListener(final KeyListener listener) { - super.removeKeyListener(listener); - eyeButton.removeKeyListener(listener); - passwordField.removeKeyListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the platform-specific context menu trigger has - * occurred. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MenuDetectListener - * @see #addMenuDetectListener - * - * @since 3.3 - */ - @Override - public void removeMenuDetectListener(final MenuDetectListener listener) { - super.removeMenuDetectListener(listener); - eyeButton.removeMenuDetectListener(listener); - passwordField.removeMenuDetectListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the mouse passes or hovers over controls. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MouseTrackListener - * @see #addMouseTrackListener - */ - @Override - public void removeMouseTrackListener(final MouseTrackListener listener) { - super.removeMouseTrackListener(listener); - eyeButton.removeMouseTrackListener(listener); - passwordField.removeMouseTrackListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when mouse buttons are pressed and released. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MouseListener - * @see #addMouseListener - */ - @Override - public void removeMouseListener(final MouseListener listener) { - super.removeMouseListener(listener); - eyeButton.removeMouseListener(listener); - passwordField.removeMouseListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the mouse moves. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MouseMoveListener - * @see #addMouseMoveListener - */ - @Override - public void removeMouseMoveListener(final MouseMoveListener listener) { - super.removeMouseMoveListener(listener); - eyeButton.removeMouseMoveListener(listener); - passwordField.removeMouseMoveListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when the mouse wheel is scrolled. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see MouseWheelListener - * @see #addMouseWheelListener - * - * @since 3.3 - */ - @Override - public void removeMouseWheelListener(final MouseWheelListener listener) { - super.removeMouseWheelListener(listener); - eyeButton.removeMouseWheelListener(listener); - passwordField.removeMouseWheelListener(listener); - } - - /** - * Removes the listener from the collection of listeners who will - * be notified when touch events occur. - * - * @param listener the listener which should no longer be notified - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see TouchListener - * @see #addTouchListener - * - * @since 3.7 - */ - @Override - public void removeTouchListener(final TouchListener listener) { - super.removeTouchListener(listener); - eyeButton.removeTouchListener(listener); - passwordField.removeTouchListener(listener); - } - - /** - * Sets the receiver's background color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is a hint and may be overridden by the platform. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setBackground(final Color color) { - super.setBackground(color); - eyeButton.setBackground(color); - passwordField.setBackground(color); - } - - /** - * If the argument is true, causes the receiver to have - * all mouse events delivered to it until the method is called with - * false as the argument. Note that on some platforms, - * a mouse button must currently be down for capture to be assigned. - * - * @param capture true to capture the mouse, and false to release it - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setCapture(final boolean capture) { - super.setCapture(capture); - eyeButton.setCapture(capture); - passwordField.setCapture(capture); - } - - /** - * Set the image displayed when the "reveal button" is clicked. - * - * @param image the new image. If null, the default image will be displayed. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - public void setClickImage(final Image image) { - checkWidget(); - eyeButton.setClickImage(image); - ; - } - - /** - * Sets the receiver's cursor to the cursor specified by the - * argument, or to the default cursor for that kind of control - * if the argument is null. - *

- * When the mouse pointer passes over a control its appearance - * is changed to match the control's cursor. - *

- * - * @param cursor the new cursor (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setCursor(final Cursor cursor) { - super.setCursor(cursor); - eyeButton.setCursor(cursor); - passwordField.setCursor(cursor); - } - - /** - * Sets the receiver's drag detect state. If the argument is - * true, the receiver will detect drag gestures, - * otherwise these gestures will be ignored. - * - * @param dragDetect the new drag detect state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @since 3.3 - */ - @Override - public void setDragDetect(final boolean dragDetect) { - super.setDragDetect(dragDetect); - eyeButton.setDragDetect(dragDetect); - passwordField.setDragDetect(dragDetect); - } - - /** - * Causes the receiver to have the keyboard focus, - * such that all keyboard events will be delivered to it. Focus - * reassignment will respect applicable platform constraints. - * - * @return true if the control got focus, and false if it was unable to. - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- * - * @see #forceFocus - */ - @Override - public boolean setFocus() { - return passwordField.setFocus(); - } - - /** - * Sets the receiver's foreground color to the color specified - * by the argument, or to the default system color for the control - * if the argument is null. - *

- * Note: This operation is a hint and may be overridden by the platform. - *

- * - * @param color the new color (or null) - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setForeground(final Color color) { - super.setForeground(color); - eyeButton.setForeground(color); - passwordField.setForeground(color); - } - - /** - * Sets the receiver's pop up menu to the argument. - * All controls may optionally have a pop up - * menu that is displayed when the user requests one for - * the control. The sequence of key strokes, button presses - * and/or button releases that are used to request a pop up - * menu is platform specific. - *

- * Note: Disposing of a control that has a pop up menu will - * dispose of the menu. To avoid this behavior, set the - * menu to null before the control is disposed. - *

- * - * @param menu the new pop up menu - * - * @exception IllegalArgumentException - *
    - *
  • ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu
  • - *
  • ERROR_INVALID_PARENT - if the menu is not in the same widget tree
  • - *
  • ERROR_INVALID_ARGUMENT - if the menu has been disposed
  • - *
- * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setMenu(final Menu menu) { - super.setMenu(menu); - eyeButton.setMenu(menu); - passwordField.setMenu(menu); - } - - /** - * Sets the receiver's tool tip text to the argument, which - * may be null indicating that the default tool tip for the - * control will be shown. For a control that has a default - * tool tip, such as the Tree control on Windows, setting - * the tool tip text to an empty string replaces the default, - * causing no tool tip text to be shown. - *

- * The mnemonic indicator (character '&') is not displayed in a tool tip. - * To display a single '&' in the tool tip, the character '&' can be - * escaped by doubling it in the string. - *

- *

- * NOTE: This operation is a hint and behavior is platform specific, on Windows - * for CJK-style mnemonics of the form " (&C)" at the end of the tooltip text - * are not shown in tooltip. - *

- * - * @param string the new tool tip text (or null) - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - *
- */ - @Override - public void setToolTipText(final String string) { - super.setToolTipText(string); - eyeButton.setToolTipText(string); - passwordField.setToolTipText(string); - } - - /** - * Sets whether this control should send touch events (by default controls do not). - * Setting this to false causes the receiver to send gesture events - * instead. No exception is thrown if a touch-based input device is not - * detected (this can be determined with Display#getTouchEnabled()). - * - * @param enabled the new touch-enabled state - * - * @exception SWTException - *
    - *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • - *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • - * - * @see Display#getTouchEnabled - * - * @since 3.7 - */ - @Override - public void setTouchEnabled(final boolean enabled) { - super.setTouchEnabled(enabled); - eyeButton.setTouchEnabled(enabled); - passwordField.setTouchEnabled(enabled); - } - - /** - * Based on the argument, perform one of the expected platform - * traversal action. The argument should be one of the constants: - * SWT.TRAVERSE_ESCAPE, SWT.TRAVERSE_RETURN, - * SWT.TRAVERSE_TAB_NEXT, SWT.TRAVERSE_TAB_PREVIOUS, - * SWT.TRAVERSE_ARROW_NEXT, SWT.TRAVERSE_ARROW_PREVIOUS, - * SWT.TRAVERSE_PAGE_NEXT and SWT.TRAVERSE_PAGE_PREVIOUS. - * - * @param traversal the type of traversal - * @return true if the traversal succeeded - * - * @exception SWTException - *
      - *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • - *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • - *
    - */ - @Override - public boolean traverse(final int traversal) { - return passwordField.traverse(traversal); - } - - /** - * Performs a platform traversal action corresponding to a KeyDown event. - * - *

    - * Valid traversal values are - * SWT.TRAVERSE_NONE, SWT.TRAVERSE_MNEMONIC, - * SWT.TRAVERSE_ESCAPE, SWT.TRAVERSE_RETURN, - * SWT.TRAVERSE_TAB_NEXT, SWT.TRAVERSE_TAB_PREVIOUS, - * SWT.TRAVERSE_ARROW_NEXT, SWT.TRAVERSE_ARROW_PREVIOUS, - * SWT.TRAVERSE_PAGE_NEXT and SWT.TRAVERSE_PAGE_PREVIOUS. - * If traversal is SWT.TRAVERSE_NONE then the Traverse - * event is created with standard values based on the KeyDown event. If - * traversal is one of the other traversal constants then the Traverse - * event is created with this detail, and its doit is taken from the - * KeyDown event. - *

    - * - * @param traversal the type of traversal, or SWT.TRAVERSE_NONE to compute - * this from event - * @param event the KeyDown event - * - * @return true if the traversal succeeded - * - * @exception IllegalArgumentException - *
      - *
    • ERROR_NULL_ARGUMENT if the event is null
    • - *
    - * @exception SWTException - *
      - *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • - *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • - *
    - * - * @since 3.6 - */ - @Override - public boolean traverse(final int traversal, final Event event) { - return passwordField.traverse(traversal, event); - } - - /** - * Performs a platform traversal action corresponding to a KeyDown event. - * - *

    - * Valid traversal values are - * SWT.TRAVERSE_NONE, SWT.TRAVERSE_MNEMONIC, - * SWT.TRAVERSE_ESCAPE, SWT.TRAVERSE_RETURN, - * SWT.TRAVERSE_TAB_NEXT, SWT.TRAVERSE_TAB_PREVIOUS, - * SWT.TRAVERSE_ARROW_NEXT, SWT.TRAVERSE_ARROW_PREVIOUS, - * SWT.TRAVERSE_PAGE_NEXT and SWT.TRAVERSE_PAGE_PREVIOUS. - * If traversal is SWT.TRAVERSE_NONE then the Traverse - * event is created with standard values based on the KeyDown event. If - * traversal is one of the other traversal constants then the Traverse - * event is created with this detail, and its doit is taken from the - * KeyDown event. - *

    - * - * @param traversal the type of traversal, or SWT.TRAVERSE_NONE to compute - * this from event - * @param event the KeyDown event - * - * @return true if the traversal succeeded - * - * @exception IllegalArgumentException - *
      - *
    • ERROR_NULL_ARGUMENT if the event is null
    • - *
    - * @exception SWTException - *
      - *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • - *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • - *
    - * - * @since 3.6 - */ - @Override - public boolean traverse(final int traversal, final KeyEvent event) { - checkWidget(); - return passwordField.traverse(traversal, event); - } - -} +/******************************************************************************* + * Copyright (c) 2019 Laurent CARON. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API + * and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.passwordrevealer; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.events.DragDetectListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.GestureListener; +import org.eclipse.swt.events.HelpListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MenuDetectListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.SegmentEvent; +import org.eclipse.swt.events.SegmentListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.TouchListener; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Widget; + +/** + * Instances of this class are selectable user interface + * objects that allow the user to enter and modify passwords. + * A "eye" button is drawned on the right side of the widget. + * If SWT.PUSH is set, when one clicks on the button the password is revealed and the button is switched on. + * When one clicks again, the password is displayed as a password (characters are replaced by dots) and the button is switched off. + * if SWT.PUSH is not set, when one clicks on the button the password is revealed, and when the user stops clicking the password is displayed with dots. + *

    + *

    + *
    Styles:
    + *
    CENTER, ICON_CANCEL, ICON_SEARCH, LEFT, MULTI, PASSWORD, SEARCH, SINGLE, RIGHT, READ_ONLY, WRAP, PUSH
    + *
    Events:
    + *
    DefaultSelection, Modify, Verify, OrientationChange
    + *
    + *

    + * Note: Only one of the styles MULTI and SINGLE may be specified, + * and only one of the styles LEFT, CENTER, and RIGHT may be specified. + *

    + *

    + * Note: The styles ICON_CANCEL and ICON_SEARCH are hints used in combination with SEARCH. + * When the platform supports the hint, the text control shows these icons. When an icon + * is selected, a default selection event is sent with the detail field set to one of + * ICON_CANCEL or ICON_SEARCH. Normally, application code does not need to check the + * detail. In the case of ICON_CANCEL, the text is cleared before the default selection + * event is sent causing the application to search for an empty string. + *

    + *

    + * IMPORTANT: This class is not intended to be subclassed. + *

    + * + * @see Text snippets + * @see SWT Example: ControlExample + * @see Sample code and further information + * @noextend This class is not intended to be subclassed by clients. + */ +public class PasswordRevealer extends Composite { + + protected Text passwordField; + private final EyeButton eyeButton; + private final char defaultEchoChar; + private boolean isPushMode; + + /** + * Constructs a new instance of this class given its parent and a style value + * describing its behavior and appearance. + *

    + * The style value is either one of the style constants defined in class + * SWT which is applicable to instances of this class, or must be + * built by bitwise OR'ing together (that is, using the + * int "|" operator) two or more of those SWT style + * constants. The class description lists the style constants that are + * applicable to the class. Style bits are also inherited from superclasses. + *

    + * + * @param parent a composite control which will be the parent of the new + * instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the parent is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the + * thread that created the parent
    • + *
    • ERROR_INVALID_SUBCLASS - if this class is not an allowed + * subclass
    • + *
    + * + * @see Widget#getStyle() + */ + public PasswordRevealer(final Composite parent, final int style) { + super(parent, SWT.BORDER); + isPushMode = (style & SWT.PUSH) == SWT.PUSH; + final GridLayout gl = new GridLayout(2, false); + gl.horizontalSpacing = gl.verticalSpacing = gl.marginHeight = gl.marginWidth = 0; + gl.marginBottom = gl.marginLeft = gl.marginRight = gl.marginTop = 0; + setLayout(gl); + + super.setBackground(parent.getBackground()); + passwordField = new Text(this, removeFields(style, SWT.BORDER, SWT.PUSH) | SWT.PASSWORD); + passwordField.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + defaultEchoChar = passwordField.getEchoChar(); + + eyeButton = new EyeButton(this, isPushMode ? SWT.PUSH : SWT.NONE); + eyeButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false)); + } + + private int removeFields(final int original, final int... styles) { + int returnedStyle = original; + for (final int toBeRemoved : styles) { + if ((returnedStyle & toBeRemoved) != 0) { + returnedStyle = returnedStyle & ~toBeRemoved; + } + } + return returnedStyle; + } + + void revealPassword() { + passwordField.setEchoChar('\0'); + } + + void hidePassword() { + passwordField.setEchoChar(defaultEchoChar); + } + + // Inherithed methods + + /** + * Adds the listener to the collection of listeners who will + * be notified when the receiver's text is modified, by sending + * it one of the messages defined in the ModifyListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see ModifyListener + * @see #removeModifyListener + */ + public void addModifyListener(final ModifyListener listener) { + passwordField.addModifyListener(listener); + } + + /** + * Adds a segment listener. + *

    + * A SegmentEvent is sent whenever text content is being modified or + * a segment listener is added or removed. You can + * customize the appearance of text by indicating certain characters to be inserted + * at certain text offsets. This may be used for bidi purposes, e.g. when + * adjacent segments of right-to-left text should not be reordered relative to + * each other. + * E.g., multiple Java string literals in a right-to-left language + * should generally remain in logical order to each other, that is, the + * way they are stored. + *

    + *

    + * Warning: This API is currently only implemented on Windows and GTK. + * SegmentEvents won't be sent on Cocoa. + *

    + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see SegmentEvent + * @see SegmentListener + * @see #removeSegmentListener + * + * @since 3.8 + */ + public void addSegmentListener(final SegmentListener listener) { + passwordField.addSegmentListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the control is selected by the user, by sending + * it one of the messages defined in the SelectionListener + * interface. + *

    + * widgetSelected is not called for texts. + * widgetDefaultSelected is typically called when ENTER is pressed in a single-line text, + * or when ENTER is pressed in a search text. If the receiver has the SWT.SEARCH | SWT.ICON_CANCEL style + * and the user cancels the search, the event object detail field contains the value SWT.ICON_CANCEL. + * Likewise, if the receiver has the SWT.ICON_SEARCH style and the icon search is selected, the + * event object detail field contains the value SWT.ICON_SEARCH. + *

    + * + * @param listener the listener which should be notified when the control is selected by the user + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ + public void addSelectionListener(final SelectionListener listener) { + passwordField.addSelectionListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the receiver's text is verified, by sending + * it one of the messages defined in the VerifyListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see VerifyListener + * @see #removeVerifyListener + */ + public void addVerifyListener(final VerifyListener listener) { + passwordField.addVerifyListener(listener); + } + + /** + * Appends a string. + *

    + * The new text is appended to the text at + * the end of the widget. + *

    + * + * @param string the string to be appended + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the string is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void append(final String string) { + passwordField.append(string); + } + + /** + * Clears the selection. + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void clearSelection() { + passwordField.clearSelection(); + } + + /** + * Copies the selected text. + *

    + * The current selection is copied to the clipboard. + *

    + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void copy() { + passwordField.copy(); + } + + /** + * Cuts the selected text. + *

    + * The current selection is first copied to the + * clipboard and then deleted from the widget. + *

    + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void cut() { + passwordField.cut(); + } + + /** + * Returns the line number of the caret. + *

    + * The line number of the caret is returned. + *

    + * + * @return the line number + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public int getCaretLineNumber() { + return passwordField.getCaretLineNumber(); + } + + /** + * Returns a point describing the location of the caret relative + * to the receiver. + * + * @return a point, the location of the caret + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public Point getCaretLocation() { + return passwordField.getCaretLocation(); + } + + /** + * Returns the character position of the caret. + *

    + * Indexing is zero based. + *

    + * + * @return the position of the caret + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public int getCaretPosition() { + return passwordField.getCaretPosition(); + } + + /** + * Returns the number of characters. + * + * @return number of characters in the widget + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public int getCharCount() { + return passwordField.getCharCount(); + } + + /** + * Returns the image displayed when the "reveal button" is clicked. + * + * @return the image. If null it means that the default button is used + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public Image getClickImage() { + checkWidget(); + return eyeButton.getClickImage(); + } + + /** + * Returns the double click enabled flag. + *

    + * The double click flag enables or disables the + * default action of the text widget when the user + * double clicks. + *

    + * + * @return whether or not double click is enabled + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public boolean getDoubleClickEnabled() { + return passwordField.getDoubleClickEnabled(); + } + + /** + * Returns the echo character. + *

    + * The echo character is the character that is + * displayed when the user enters text or the + * text is changed by the programmer. + *

    + * + * @return the echo character + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see #setEchoChar + */ + public char getEchoChar() { + return passwordField.getEchoChar(); + } + + /** + * Returns the editable state. + * + * @return whether or not the receiver is editable + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public boolean getEditable() { + return passwordField.getEditable(); + } + + /** + * Returns the image used when the user wants to reveal the password of lines. + * + * @return the image. null means that the icon is the default one + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public Image getImage() { + checkWidget(); + return eyeButton.getImage(); + } + + /** + * Returns the number of lines. + * + * @return the number of lines in the widget + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public int getLineCount() { + return passwordField.getLineCount(); + } + + /** + * Returns the line delimiter. + * + * @return a string that is the line delimiter + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see #DELIMITER + */ + public String getLineDelimiter() { + return passwordField.getLineDelimiter(); + } + + /** + * Returns the height of a line. + * + * @return the height of a row of text + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public int getLineHeight() { + return passwordField.getLineHeight(); + } + + /** + * Returns the widget message. The message text is displayed + * as a hint for the user, indicating the purpose of the field. + *

    + * Typically this is used in conjunction with SWT.SEARCH. + *

    + * + * @return the widget message + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @since 3.3 + */ + public String getMessage() { + return passwordField.getMessage(); + } + + /** + * Returns a Point whose x coordinate is the + * character position representing the start of the selected + * text, and whose y coordinate is the character position + * representing the end of the selection. An "empty" selection + * is indicated by the x and y coordinates having the same value. + *

    + * Indexing is zero based. The range of a selection is from + * 0..N where N is the number of characters in the widget. + *

    + * + * @return a point representing the selection start and end + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public Point getSelection() { + return passwordField.getSelection(); + } + + /** + * Returns the number of selected characters. + * + * @return the number of selected characters. + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public int getSelectionCount() { + return passwordField.getSelectionCount(); + } + + /** + * Gets the selected text, or an empty string if there is no current selection. + * + * @return the selected text + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public String getSelectionText() { + return passwordField.getSelectionText(); + } + + /** + * Returns the number of tabs. + *

    + * Tab stop spacing is specified in terms of the + * space (' ') character. The width of a single + * tab stop is the pixel width of the spaces. + *

    + * + * @return the number of tab characters + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public int getTabs() { + return passwordField.getTabs(); + } + + /** + * Returns the widget text. + *

    + * The text for a text widget is the characters in the widget, or + * an empty string if this has never been set. + *

    + * + * @return the widget text + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public String getText() { + return passwordField.getText(); + } + + /** + * Returns the widget's text as a character array. + *

    + * The text for a text widget is the characters in the widget, or + * a zero-length array if this has never been set. + *

    + *

    + * Note: Use this API to prevent the text from being written into a String + * object whose lifecycle is outside of your control. This can help protect + * the text, for example, when the widget is used as a password field. + * However, the text can't be protected if an {@link SWT#Segments} or + * {@link SWT#Verify} listener has been added to the widget. + *

    + * + * @return a character array that contains the widget's text + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see #setTextChars(char[]) + * + * @since 3.7 + */ + public char[] getTextChars() { + return passwordField.getTextChars(); + } + + /** + * Returns a range of text. Returns an empty string if the + * start of the range is greater than the end. + *

    + * Indexing is zero based. The range of + * a selection is from 0..N-1 where N is + * the number of characters in the widget. + *

    + * + * @param start the start of the range + * @param end the end of the range + * @return the range of text + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public String getText(final int start, final int end) { + return passwordField.getText(start, end); + } + + /** + * Returns the maximum number of characters that the receiver is capable of holding. + *

    + * If this has not been changed by setTextLimit(), + * it will be the constant Text.LIMIT. + *

    + * + * @return the text limit + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see #LIMIT + */ + public int getTextLimit() { + return passwordField.getTextLimit(); + } + + /** + * Returns the zero-relative index of the line which is currently + * at the top of the receiver. + *

    + * This index can change when lines are scrolled or new lines are added or removed. + *

    + * + * @return the index of the top line + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public int getTopIndex() { + return passwordField.getTopIndex(); + } + + /** + * Returns the zero-relative index of the line which is currently + * at the top of the receiver. + *

    + * This index can change when lines are scrolled or new lines are added or removed. + *

    + * + * @return the index of the top line + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public int getTopPixel() { + return passwordField.getTopPixel(); + } + + /** + * Inserts a string. + *

    + * The old selection is replaced with the new text. + *

    + * + * @param string the string + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the string is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void insert(final String string) { + passwordField.insert(string); + } + + /** + * Pastes text from clipboard. + *

    + * The selected text is deleted from the widget + * and new text inserted from the clipboard. + *

    + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void paste() { + passwordField.paste(); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the receiver's text is modified. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see ModifyListener + * @see #addModifyListener + */ + public void removeModifyListener(final ModifyListener listener) { + passwordField.removeModifyListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the receiver's text is modified. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see SegmentEvent + * @see SegmentListener + * @see #addSegmentListener + * + * @since 3.8 + */ + public void removeSegmentListener(final SegmentListener listener) { + passwordField.removeSegmentListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see SelectionListener + * @see #addSelectionListener + */ + public void removeSelectionListener(final SelectionListener listener) { + passwordField.removeSelectionListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the control is verified. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the listener is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @see VerifyListener + * @see #addVerifyListener + */ + public void removeVerifyListener(final VerifyListener listener) { + passwordField.removeVerifyListener(listener); + } + + /** + * Selects all the text in the receiver. + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void selectAll() { + passwordField.selectAll(); + } + + /** + * Sets the double click enabled flag. + *

    + * The double click flag enables or disables the + * default action of the text widget when the user + * double clicks. + *

    + *

    + * Note: This operation is a hint and is not supported on + * platforms that do not have this concept. + *

    + * + * @param doubleClick the new double click flag + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void setDoubleClickEnabled(final boolean doubleClick) { + passwordField.setDoubleClickEnabled(doubleClick); + } + + /** + * Sets the echo character. + *

    + * The echo character is the character that is + * displayed when the user enters text or the + * text is changed by the programmer. Setting + * the echo character to '\0' clears the echo + * character and redraws the original text. + * If for any reason the echo character is invalid, + * or if the platform does not allow modification + * of the echo character, the default echo character + * for the platform is used. + *

    + * + * @param echo the new echo character + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void setEchoChar(final char echo) { + passwordField.setEchoChar(echo); + } + + /** + * Sets the editable state. + * + * @param editable the new editable state + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void setEditable(final boolean editable) { + passwordField.setEditable(editable); + } + + /** + * Sets the font that the receiver will use to paint textual information + * to the font specified by the argument, or to the default font for that + * kind of control if the argument is null. + * + * @param font the new font (or null) + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_INVALID_ARGUMENT - if the argument has been disposed
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + @Override + public void setFont(final Font font) { + super.setFont(font); + passwordField.setFont(font); + } + + /** + * Sets the image on which the user should click if he wants to reveal the password. + * + * @param image the new image. If null, the default "eye" icon will be displayed + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_INVALID_ARGUMENT - if the argument has been disposed
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void setImage(final Image image) { + checkWidget(); + eyeButton.setImage(image); + } + + /** + * Sets the widget message. The message text is displayed + * as a hint for the user, indicating the purpose of the field. + *

    + * Typically this is used in conjunction with SWT.SEARCH. + *

    + * + * @param message the new message + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the message is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + * @since 3.3 + */ + public void setMessage(final String message) { + passwordField.setMessage(message); + } + + /** + * Sets the orientation of the receiver, which must be one + * of the constants SWT.LEFT_TO_RIGHT or SWT.RIGHT_TO_LEFT. + *

    + * Note: This operation is a hint and is not supported on + * platforms that do not have this concept. + *

    + * + * @param orientation new orientation style + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + */ + @Override + public void setOrientation(final int orientation) { + passwordField.setOrientation(orientation); + } + + /** + * Sets the eye's button behaviour. + * + * @param pushMode new push mode + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + * + */ + public void setPushMode(boolean pushMode) { + checkWidget(); + this.isPushMode = pushMode; + eyeButton.setPushMode(pushMode); + } + + /** + * Sets the selection. + *

    + * Indexing is zero based. The range of + * a selection is from 0..N where N is + * the number of characters in the widget. + *

    + *

    + * Text selections are specified in terms of + * caret positions. In a text widget that + * contains N characters, there are N+1 caret + * positions, ranging from 0..N. This differs + * from other functions that address character + * position such as getText () that use the + * regular array indexing rules. + *

    + * + * @param start new caret position + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void setSelection(final int start) { + passwordField.setSelection(start); + } + + /** + * Sets the selection to the range specified + * by the given start and end indices. + *

    + * Indexing is zero based. The range of + * a selection is from 0..N where N is + * the number of characters in the widget. + *

    + *

    + * Text selections are specified in terms of + * caret positions. In a text widget that + * contains N characters, there are N+1 caret + * positions, ranging from 0..N. This differs + * from other functions that address character + * position such as getText () that use the + * usual array indexing rules. + *

    + * + * @param start the start of the range + * @param end the end of the range + * + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void setSelection(final int start, final int end) { + passwordField.setSelection(start, end); + } + + /** + * Sets the selection to the range specified + * by the given point, where the x coordinate + * represents the start index and the y coordinate + * represents the end index. + *

    + * Indexing is zero based. The range of + * a selection is from 0..N where N is + * the number of characters in the widget. + *

    + *

    + * Text selections are specified in terms of + * caret positions. In a text widget that + * contains N characters, there are N+1 caret + * positions, ranging from 0..N. This differs + * from other functions that address character + * position such as getText () that use the + * usual array indexing rules. + *

    + * + * @param selection the point + * + * @exception IllegalArgumentException + *
      + *
    • ERROR_NULL_ARGUMENT - if the point is null
    • + *
    + * @exception SWTException + *
      + *
    • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    • + *
    • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
    • + *
    + */ + public void setSelection(final Point selection) { + passwordField.setSelection(selection); + } + + /** + * Sets the number of tabs. + *

    + * Tab stop spacing is specified in terms of the + * space (' ') character. The width of a single + * tab stop is the pixel width of the spaces. + *

    + * + * @param tabs the number of tabs + * + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setTabs(final int tabs) { + passwordField.setTabs(tabs); + } + + /** + * Sets the contents of the receiver to the given string. If the receiver has style + * SINGLE and the argument contains multiple lines of text, the result of this + * operation is undefined and may vary from platform to platform. + *

+ * Note: If control characters like '\n', '\t' etc. are used + * in the string, then the behavior is platform dependent. + *

+ * + * @param string the new text + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the string is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setText(final String string) { + passwordField.setText(string); + } + + /** + * Sets the contents of the receiver to the characters in the array. If the receiver + * has style SWT.SINGLE and the argument contains multiple lines of text + * then the result of this operation is undefined and may vary between platforms. + *

+ * Note: Use this API to prevent the text from being written into a String + * object whose lifecycle is outside of your control. This can help protect + * the text, for example, when the widget is used as a password field. + * However, the text can't be protected if an {@link SWT#Segments} or + * {@link SWT#Verify} listener has been added to the widget. + *

+ * + * @param text a character array that contains the new text + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the array is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see #getTextChars() + * + * @since 3.7 + */ + public void setTextChars(final char[] text) { + passwordField.setTextChars(text); + } + + /** + * Sets the maximum number of characters that the receiver + * is capable of holding to be the argument. + *

+ * Instead of trying to set the text limit to zero, consider + * creating a read-only text widget. + *

+ *

+ * To reset this value to the default, use setTextLimit(Text.LIMIT). + * Specifying a limit value larger than Text.LIMIT sets the + * receiver's limit to Text.LIMIT. + *

+ * + * @param limit new text limit + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_CANNOT_BE_ZERO - if the limit is zero
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see #LIMIT + */ + public void setTextLimit(final int limit) { + passwordField.setTextLimit(limit); + } + + /** + * Sets the zero-relative index of the line which is currently + * at the top of the receiver. This index can change when lines + * are scrolled or new lines are added and removed. + * + * @param index the index of the top item + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setTopIndex(final int index) { + passwordField.setTopIndex(index); + } + + /** + * Shows the selection. + *

+ * If the selection is already showing + * in the receiver, this method simply returns. Otherwise, + * lines are scrolled until the selection is visible. + *

+ * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void showSelection() { + passwordField.showSelection(); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when a drag gesture occurs, by sending it + * one of the messages defined in the DragDetectListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see DragDetectListener + * @see #removeDragDetectListener + * + * @since 3.3 + */ + @Override + public void addDragDetectListener(final DragDetectListener listener) { + super.addDragDetectListener(listener); + eyeButton.addDragDetectListener(listener); + passwordField.addDragDetectListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the control gains or loses focus, by sending + * it one of the messages defined in the FocusListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see FocusListener + * @see #removeFocusListener + */ + @Override + public void addFocusListener(final FocusListener listener) { + super.addFocusListener(listener); + eyeButton.addFocusListener(listener); + passwordField.addFocusListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when gesture events are generated for the control, + * by sending it one of the messages defined in the + * GestureListener interface. + *

+ * NOTE: If setTouchEnabled(true) has previously been + * invoked on the receiver then setTouchEnabled(false) + * must be invoked on it to specify that gesture events should be + * sent instead of touch events. + *

+ *

+ * Warning: This API is currently only implemented on Windows and Cocoa. + * SWT doesn't send Gesture or Touch events on GTK. + *

+ * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see GestureListener + * @see #removeGestureListener + * @see #setTouchEnabled + * + * @since 3.7 + */ + @Override + public void addGestureListener(final GestureListener listener) { + super.addGestureListener(listener); + eyeButton.addGestureListener(listener); + passwordField.addGestureListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when help events are generated for the control, + * by sending it one of the messages defined in the + * HelpListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see HelpListener + * @see #removeHelpListener + */ + @Override + public void addHelpListener(final HelpListener listener) { + super.addHelpListener(listener); + eyeButton.addHelpListener(listener); + passwordField.addHelpListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when keys are pressed and released on the system keyboard, by sending + * it one of the messages defined in the KeyListener + * interface. + *

+ * When a key listener is added to a control, the control + * will take part in widget traversal. By default, all + * traversal keys (such as the tab key and so on) are + * delivered to the control. In order for a control to take + * part in traversal, it should listen for traversal events. + * Otherwise, the user can traverse into a control but not + * out. Note that native controls such as table and tree + * implement key traversal in the operating system. It is + * not necessary to add traversal listeners for these controls, + * unless you want to override the default traversal. + *

+ * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see KeyListener + * @see #removeKeyListener + */ + @Override + public void addKeyListener(final KeyListener listener) { + super.addKeyListener(listener); + eyeButton.addKeyListener(listener); + passwordField.addKeyListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the platform-specific context menu trigger + * has occurred, by sending it one of the messages defined in + * the MenuDetectListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MenuDetectListener + * @see #removeMenuDetectListener + * + * @since 3.3 + */ + @Override + public void addMenuDetectListener(final MenuDetectListener listener) { + super.addMenuDetectListener(listener); + eyeButton.addMenuDetectListener(listener); + passwordField.addMenuDetectListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when mouse buttons are pressed and released, by sending + * it one of the messages defined in the MouseListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MouseListener + * @see #removeMouseListener + */ + @Override + public void addMouseListener(final MouseListener listener) { + super.addMouseListener(listener); + eyeButton.addMouseListener(listener); + passwordField.addMouseListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the mouse passes or hovers over controls, by sending + * it one of the messages defined in the MouseTrackListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MouseTrackListener + * @see #removeMouseTrackListener + */ + @Override + public void addMouseTrackListener(final MouseTrackListener listener) { + super.addMouseTrackListener(listener); + eyeButton.addMouseTrackListener(listener); + passwordField.addMouseTrackListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the mouse moves, by sending it one of the + * messages defined in the MouseMoveListener + * interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MouseMoveListener + * @see #removeMouseMoveListener + */ + @Override + public void addMouseMoveListener(final MouseMoveListener listener) { + super.addMouseMoveListener(listener); + eyeButton.addMouseMoveListener(listener); + passwordField.addMouseMoveListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when the mouse wheel is scrolled, by sending + * it one of the messages defined in the + * MouseWheelListener interface. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MouseWheelListener + * @see #removeMouseWheelListener + * + * @since 3.3 + */ + @Override + public void addMouseWheelListener(final MouseWheelListener listener) { + super.addMouseWheelListener(listener); + eyeButton.addMouseWheelListener(listener); + passwordField.addMouseWheelListener(listener); + } + + /** + * Adds the listener to the collection of listeners who will + * be notified when touch events occur, by sending it + * one of the messages defined in the TouchListener + * interface. + *

+ * NOTE: You must also call setTouchEnabled(true) to + * specify that touch events should be sent, which will cause gesture + * events to not be sent. + *

+ *

+ * Warning: This API is currently only implemented on Windows and Cocoa. + * SWT doesn't send Gesture or Touch events on GTK. + *

+ * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see TouchListener + * @see #removeTouchListener + * @see #setTouchEnabled + * + * @since 3.7 + */ + @Override + public void addTouchListener(final TouchListener listener) { + super.addTouchListener(listener); + eyeButton.addTouchListener(listener); + passwordField.addTouchListener(listener); + } + + /** + * Forces the receiver to have the keyboard focus, causing + * all keyboard events to be delivered to it. + * + * @return true if the control got focus, and false if it was unable to. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see #setFocus + */ + @Override + public boolean forceFocus() { + return passwordField.forceFocus(); + } + + /** + * Returns true if the receiver has the user-interface + * focus, and false otherwise. + * + * @return the receiver's focus state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public boolean isFocusControl() { + return passwordField.isFocusControl(); + } + + /** + * Returns true if the eye button is a "push" button, and false otherwise. + * + * @return the eye button push mode + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public boolean isPushMode() { + checkWidget(); + return isPushMode; + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the control gains or loses focus. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see FocusListener + * @see #addFocusListener + */ + @Override + public void removeFocusListener(final FocusListener listener) { + super.removeFocusListener(listener); + eyeButton.removeFocusListener(listener); + passwordField.removeFocusListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when gesture events are generated for the control. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see GestureListener + * @see #addGestureListener + * + * @since 3.7 + */ + @Override + public void removeGestureListener(final GestureListener listener) { + super.removeGestureListener(listener); + eyeButton.removeGestureListener(listener); + passwordField.removeGestureListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the help events are generated for the control. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see HelpListener + * @see #addHelpListener + */ + @Override + public void removeHelpListener(final HelpListener listener) { + super.removeHelpListener(listener); + eyeButton.removeHelpListener(listener); + passwordField.removeHelpListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when keys are pressed and released on the system keyboard. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see KeyListener + * @see #addKeyListener + */ + @Override + public void removeKeyListener(final KeyListener listener) { + super.removeKeyListener(listener); + eyeButton.removeKeyListener(listener); + passwordField.removeKeyListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the platform-specific context menu trigger has + * occurred. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MenuDetectListener + * @see #addMenuDetectListener + * + * @since 3.3 + */ + @Override + public void removeMenuDetectListener(final MenuDetectListener listener) { + super.removeMenuDetectListener(listener); + eyeButton.removeMenuDetectListener(listener); + passwordField.removeMenuDetectListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the mouse passes or hovers over controls. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MouseTrackListener + * @see #addMouseTrackListener + */ + @Override + public void removeMouseTrackListener(final MouseTrackListener listener) { + super.removeMouseTrackListener(listener); + eyeButton.removeMouseTrackListener(listener); + passwordField.removeMouseTrackListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when mouse buttons are pressed and released. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MouseListener + * @see #addMouseListener + */ + @Override + public void removeMouseListener(final MouseListener listener) { + super.removeMouseListener(listener); + eyeButton.removeMouseListener(listener); + passwordField.removeMouseListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the mouse moves. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MouseMoveListener + * @see #addMouseMoveListener + */ + @Override + public void removeMouseMoveListener(final MouseMoveListener listener) { + super.removeMouseMoveListener(listener); + eyeButton.removeMouseMoveListener(listener); + passwordField.removeMouseMoveListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when the mouse wheel is scrolled. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see MouseWheelListener + * @see #addMouseWheelListener + * + * @since 3.3 + */ + @Override + public void removeMouseWheelListener(final MouseWheelListener listener) { + super.removeMouseWheelListener(listener); + eyeButton.removeMouseWheelListener(listener); + passwordField.removeMouseWheelListener(listener); + } + + /** + * Removes the listener from the collection of listeners who will + * be notified when touch events occur. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_NULL_ARGUMENT - if the listener is null
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see TouchListener + * @see #addTouchListener + * + * @since 3.7 + */ + @Override + public void removeTouchListener(final TouchListener listener) { + super.removeTouchListener(listener); + eyeButton.removeTouchListener(listener); + passwordField.removeTouchListener(listener); + } + + /** + * Sets the receiver's background color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setBackground(final Color color) { + super.setBackground(color); + eyeButton.setBackground(color); + passwordField.setBackground(color); + } + + /** + * If the argument is true, causes the receiver to have + * all mouse events delivered to it until the method is called with + * false as the argument. Note that on some platforms, + * a mouse button must currently be down for capture to be assigned. + * + * @param capture true to capture the mouse, and false to release it + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setCapture(final boolean capture) { + super.setCapture(capture); + eyeButton.setCapture(capture); + passwordField.setCapture(capture); + } + + /** + * Set the image displayed when the "reveal button" is clicked. + * + * @param image the new image. If null, the default image will be displayed. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + public void setClickImage(final Image image) { + checkWidget(); + eyeButton.setClickImage(image); + ; + } + + /** + * Sets the receiver's cursor to the cursor specified by the + * argument, or to the default cursor for that kind of control + * if the argument is null. + *

+ * When the mouse pointer passes over a control its appearance + * is changed to match the control's cursor. + *

+ * + * @param cursor the new cursor (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setCursor(final Cursor cursor) { + super.setCursor(cursor); + eyeButton.setCursor(cursor); + passwordField.setCursor(cursor); + } + + /** + * Sets the receiver's drag detect state. If the argument is + * true, the receiver will detect drag gestures, + * otherwise these gestures will be ignored. + * + * @param dragDetect the new drag detect state + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @since 3.3 + */ + @Override + public void setDragDetect(final boolean dragDetect) { + super.setDragDetect(dragDetect); + eyeButton.setDragDetect(dragDetect); + passwordField.setDragDetect(dragDetect); + } + + /** + * Causes the receiver to have the keyboard focus, + * such that all keyboard events will be delivered to it. Focus + * reassignment will respect applicable platform constraints. + * + * @return true if the control got focus, and false if it was unable to. + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ * + * @see #forceFocus + */ + @Override + public boolean setFocus() { + return passwordField.setFocus(); + } + + /** + * Sets the receiver's foreground color to the color specified + * by the argument, or to the default system color for the control + * if the argument is null. + *

+ * Note: This operation is a hint and may be overridden by the platform. + *

+ * + * @param color the new color (or null) + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_INVALID_ARGUMENT - if the argument has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setForeground(final Color color) { + super.setForeground(color); + eyeButton.setForeground(color); + passwordField.setForeground(color); + } + + /** + * Sets the receiver's pop up menu to the argument. + * All controls may optionally have a pop up + * menu that is displayed when the user requests one for + * the control. The sequence of key strokes, button presses + * and/or button releases that are used to request a pop up + * menu is platform specific. + *

+ * Note: Disposing of a control that has a pop up menu will + * dispose of the menu. To avoid this behavior, set the + * menu to null before the control is disposed. + *

+ * + * @param menu the new pop up menu + * + * @exception IllegalArgumentException + *
    + *
  • ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu
  • + *
  • ERROR_INVALID_PARENT - if the menu is not in the same widget tree
  • + *
  • ERROR_INVALID_ARGUMENT - if the menu has been disposed
  • + *
+ * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setMenu(final Menu menu) { + super.setMenu(menu); + eyeButton.setMenu(menu); + passwordField.setMenu(menu); + } + + /** + * Sets the receiver's tool tip text to the argument, which + * may be null indicating that the default tool tip for the + * control will be shown. For a control that has a default + * tool tip, such as the Tree control on Windows, setting + * the tool tip text to an empty string replaces the default, + * causing no tool tip text to be shown. + *

+ * The mnemonic indicator (character '&') is not displayed in a tool tip. + * To display a single '&' in the tool tip, the character '&' can be + * escaped by doubling it in the string. + *

+ *

+ * NOTE: This operation is a hint and behavior is platform specific, on Windows + * for CJK-style mnemonics of the form " (&C)" at the end of the tooltip text + * are not shown in tooltip. + *

+ * + * @param string the new tool tip text (or null) + * + * @exception SWTException + *
    + *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • + *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • + *
+ */ + @Override + public void setToolTipText(final String string) { + super.setToolTipText(string); + eyeButton.setToolTipText(string); + passwordField.setToolTipText(string); + } + + /** + * Sets whether this control should send touch events (by default controls do not). + * Setting this to false causes the receiver to send gesture events + * instead. No exception is thrown if a touch-based input device is not + * detected (this can be determined with Display#getTouchEnabled()). + * + * @param enabled the new touch-enabled state + * + * @exception SWTException + *
"; - - public static String getHyperlink(String url, String name) { - return String.format("%s", url, name); - } - - public static String textToHtml(String text) { - if (text == null) { - return ""; - } - text = text.replaceAll("&", "&"); - text = text.replaceAll(">", ">"); - text = text.replaceAll("<", "<"); - text = text.replaceAll("\"", """); - text = text.replaceAll("\\n", "
"); - text = text.replaceAll("[\\x0B\\f\\r]+", ""); - return text; - } - - public static String htmlToText(String html) { - if (html == null) { - return ""; - } - html = html.replaceAll("&", "&"); - html = html.replaceAll(">", ">"); - html = html.replaceAll("<", "<"); - html = html.replaceAll(""", "\""); - html = html.replaceAll(" ", " "); - return html; - } - - public static String getUrlPageHtml(String urlStr, InetSocketAddress addr) { - StringBuilder buffer = new StringBuilder(); - try { - URL url = new URL(urlStr); - URLConnection connection = url.openConnection(new Proxy(Proxy.Type.HTTP, addr)); - BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream())); - String line = null; - while ((line = rd.readLine()) != null) { - buffer.append(line); - } - rd.close(); - return buffer.toString(); - } catch (Exception ex) { - XViewerLog.log(Activator.class, Level.SEVERE, "Can't getUrlPageHtml"); - return simplePage("Exception opening url " + ex.getLocalizedMessage()); - } - } - - public static String titledPage(String title, String text) { - return simplePage("" + title + "" + text); - } - - public static String pageEncoding(String html) { - return HTTP_CHARSET_ENCODING + html; - } - - public static String simplePage(String text) { - return pageEncoding("" + text + ""); - } - - public static String simplePageNoPageEncoding(String text) { - return "" + text + ""; - } - - public static String getLabelStr(String labelFont, String str) { - return labelFont + "" + textToHtml(str) + ""; - } - - public static String getLabelValueStr(String labelFont, String label, String value) { - return getLabelStr(labelFont, label) + value; - } - - public static String getLabelValueStr(String label, String value) { - return getLabelStr(LABEL_FONT, label + ":") + "  " + value; - } - - public static String color(String color, String str) { - return "" + str + ""; - } - - public static String boldColor(String color, String str) { - return "" + textToHtml(str) + ""; - } - - public static String bold(String str) { - return "" + textToHtml(str) + ""; - } - - public static String boldColorTags(String color, String str) { - return "" + str + ""; - } - - public static String imageBlock(String description, String filename) { - String filenames[] = new String[1]; - filenames[0] = filename; - return imageBlock(description, filenames); - } - - public static String imageBlock(String description, String filenames[]) { - StringBuilder str = new StringBuilder(); - str.append("
"); - if (!description.equals("")) { - str.append(description); - str.append(HtmlUtil.newline()); - } - for (int i = 0; i < filenames.length; i++) { - str.append("
"); - } - str.append("
"); - return str.toString(); - } - - public static String urlBlock(String description, String urls[]) { - StringBuilder str = new StringBuilder(""); - if (!description.equals("")) { - str.append(description); - str.append(HtmlUtil.newline()); - } - for (int i = 0; i < urls.length; i++) { - str.append(""); - str.append(urls[i]); - str.append("
"); - } - str.append("
"); - return str.toString(); - } - - public static String heading(int heading, String str, String id) { - return "" + textToHtml( - str) + ""; - } - - public static String heading(int heading, String str) { - return heading(heading, str, null); - } - - public static String padSpace(int num, String str) { - StringBuilder out = new StringBuilder(); - for (int i = 0; i < num; i++) { - out.append(" "); - } - out.append(str); - return out.toString(); - } - - public static String addSpace(int num) { - StringBuilder out = new StringBuilder(); - for (int i = 0; i < num; i++) { - out.append(" "); - } - return out.toString(); - } - - public static String para(String str) { - return "

" + textToHtml(str) + "

"; - } - - public static String italics(String str) { - return "" + textToHtml(str) + ""; - } - - public static String pre(String str) { - return "
" + str + "
"; - } - - public static String newline() { - return newline(1); - } - - public static String newline(int num) { - StringBuilder str = new StringBuilder(); - for (int i = 0; i < num; i++) { - str.append("
"); - } - return str + ""; - } - - public static String name(int num) { - return nameTarget("" + num); - } - - public static String nameTarget(String str) { - if (str == null) { - return ""; - } - return ""; - } - - public static String nameLink(int num, String text) { - return nameLink("" + num, text); - } - - public static String nameLink(String name, String text) { - return "" + text + ""; - } - - public static String nameLink(String name) { - return "" + name + ""; - } - - public static String simpleTable(String str) { - return simpleTable(str, 100); - } - - /** - * Create a table with one row/colum containing str - */ - public static String simpleTable(String str, int width) { - return "" + "" + "
" + str + "
"; - } - - /** - * Create a table with one row/colum containing str - */ - public static String borderTable(String str, int width, String bgcolor, String caption) { - return startBorderTable(width, bgcolor, caption) + str + endBorderTable(); - } - - public static String startBorderTable(int width, String bgcolor, String caption) { - String capStr = ""; - if (!caption.equals("")) { - capStr = "" + caption + ""; - } - return "" + capStr + "
"; - } - - public static String endBorderTable() { - return "
"; - } - - /** - * Create a table with one row multi column containing str[] - * - * @param str = array of strings for columns - * @return Return multi-column table string - */ - public static String multiColumnTable(String[] str) { - return multiColumnTable(str, 85); - } - - /** - * Create a table with one row multi column containing str[] - * - * @param str - array of strings for columns - * @param width - percent (1..100) of screen for table - * @return Return multi-column table string - */ - public static String multiColumnTable(String[] str, int width) { - StringBuilder sb = new StringBuilder(""); - for (int i = 0; i < str.length; i++) { - sb.append(""); - } - sb.append("
"); - sb.append(str[i]); - sb.append("
"); - return sb.toString(); - } - - public static String beginMultiColumnTable(int width) { - return beginMultiColumnTable(width, 0); - } - - public static String beginMultiColumnTable(int width, int border) { - return beginMultiColumnTable(width, border, null); - } - - public static String beginMultiColumnTable(int width, int border, Integer color) { - return ""; - } - - public static String endMultiColumnTable() { - return "
"; - } - - public static String addRowMultiColumnTable(String... str) { - return addRowMultiColumnTable(str, null, null); - } - - public static String addRowMultiColumnTable(String[] str, String[] colOptions) { - return addRowMultiColumnTable(str, colOptions, null); - } - - public static String addRowMultiColumnTable(String[] str, String[] colOptions, String backgroundColor) { - StringBuilder sb = new StringBuilder(""); - if (backgroundColor != null) { - sb.append(""); - } - String show = ""; - for (int i = 0; i < str.length; i++) { - show = str[i]; - if (show == null || show.equals("")) { - show = HtmlUtil.addSpace(1); - } - String colOptionStr = ""; - if (colOptions != null) { - colOptionStr = colOptions[i]; - } - sb.append(""); - sb.append(show); - sb.append(""); - } - sb.append(""); - return sb.toString(); - } - - public static String addRowSpanMultiColumnTable(String str, int span) { - return "" + str + ""; - } - - public static class CellItem { - String text; - private final String fgColor; - private final String bgColor; - - public CellItem(String text) { - this(text, null, null); - } - - public CellItem(String text, String fgColor, String bgColor) { - this.text = text; - this.fgColor = fgColor; - this.bgColor = bgColor; - } - } - - public static String addRowMultiColumnTable(Collection items) { - StringBuilder s = new StringBuilder(""); - for (CellItem item : items) { - if (item.text == null || "".equals(item.text)) { - item.text = "."; - } - if (item.bgColor != null) { - s.append(""); - } else { - s.append(""); - } - s.append(HtmlUtil.color(item.fgColor, item.text)); - s.append(""); - } - s.append(""); - return s.toString(); - } - - public static String addHeaderRowMultiColumnTable(String[] str) { - return addHeaderRowMultiColumnTable(str, null); - } - - public static String addHeaderRowMultiColumnTable(String[] str, Integer width[]) { - StringBuilder s = new StringBuilder(""); - String widthStr = ""; - for (int i = 0; i < str.length; i++) { - if (width != null) { - widthStr = " width =\"" + width[i] + "\""; - } - s.append(""); - s.append(str[i]); - s.append(""); - } - s.append(""); - return s.toString(); - } - - public static String addSimpleTableRow(String str) { - return "" + str + ""; - } - - public static String beginSimpleTable() { - return ""; - } - - public static String beginSimpleTable(int border, int width) { - return "
"; - } - - public static String endSimpleTable() { - return "
"; - } - - public static String createTable(List datas, String[] headers, int numColumns, int cellPadding, int border) { - StringBuilder table = new StringBuilder(begin); - - if (datas == null) { - throw new IllegalArgumentException("The data can not be null"); - } - if (datas.size() % numColumns != 0) { - throw new IllegalArgumentException( - "The table could not be created becuase the data does not match the column size"); - } - if (border > 0) { - table.append("border=\"" + border + "\""); - } - if (cellPadding > 0) { - table.append("cellpadding=\"" + cellPadding + "\""); - } - table.append(">"); - - if (headers != null && headers.length == numColumns) { - table.append(""); - for (String header : headers) { - table.append("" + header + ""); - } - table.append(""); - } - - int colIndex = 0; - for (String data : datas) { - - if (colIndex == 0) { - table.append(""); - } - table.append("" + data + ""); - colIndex++; - - if (colIndex == numColumns) { - table.append(""); - colIndex = 0; - } - } - return table.toString(); - } - - public static String getPreData(String data) { - return "" + HtmlUtil.pre( - HtmlUtil.textToHtml(data)); - } - +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.xviewer.util.internal; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.URL; +import java.net.URLConnection; +import java.util.Collection; +import java.util.List; +import java.util.logging.Level; + +import org.eclipse.nebula.widgets.xviewer.Activator; + +/** + * @author Donald G. Dunne + */ +public class HtmlUtil { + private static final String HTTP_CHARSET_ENCODING = + ""; + private static final String begin = ""; + + public static String getHyperlink(String url, String name) { + return String.format("%s", url, name); + } + + public static String textToHtml(String text) { + if (text == null) { + return ""; + } + text = text.replaceAll("&", "&"); + text = text.replaceAll(">", ">"); + text = text.replaceAll("<", "<"); + text = text.replaceAll("\"", """); + text = text.replaceAll("\\n", "
"); + text = text.replaceAll("[\\x0B\\f\\r]+", ""); + return text; + } + + public static String htmlToText(String html) { + if (html == null) { + return ""; + } + html = html.replaceAll("&", "&"); + html = html.replaceAll(">", ">"); + html = html.replaceAll("<", "<"); + html = html.replaceAll(""", "\""); + html = html.replaceAll(" ", " "); + return html; + } + + public static String getUrlPageHtml(String urlStr, InetSocketAddress addr) { + StringBuilder buffer = new StringBuilder(); + try { + URL url = new URL(urlStr); + URLConnection connection = url.openConnection(new Proxy(Proxy.Type.HTTP, addr)); + BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String line = null; + while ((line = rd.readLine()) != null) { + buffer.append(line); + } + rd.close(); + return buffer.toString(); + } catch (Exception ex) { + XViewerLog.log(Activator.class, Level.SEVERE, "Can't getUrlPageHtml"); + return simplePage("Exception opening url " + ex.getLocalizedMessage()); + } + } + + public static String titledPage(String title, String text) { + return simplePage("" + title + "" + text); + } + + public static String pageEncoding(String html) { + return HTTP_CHARSET_ENCODING + html; + } + + public static String simplePage(String text) { + return pageEncoding("" + text + ""); + } + + public static String simplePageNoPageEncoding(String text) { + return "" + text + ""; + } + + public static String getLabelStr(String labelFont, String str) { + return labelFont + "" + textToHtml(str) + ""; + } + + public static String getLabelValueStr(String labelFont, String label, String value) { + return getLabelStr(labelFont, label) + value; + } + + public static String getLabelValueStr(String label, String value) { + return getLabelStr(LABEL_FONT, label + ":") + "  " + value; + } + + public static String color(String color, String str) { + return "" + str + ""; + } + + public static String boldColor(String color, String str) { + return "" + textToHtml(str) + ""; + } + + public static String bold(String str) { + return "" + textToHtml(str) + ""; + } + + public static String boldColorTags(String color, String str) { + return "" + str + ""; + } + + public static String imageBlock(String description, String filename) { + String filenames[] = new String[1]; + filenames[0] = filename; + return imageBlock(description, filenames); + } + + public static String imageBlock(String description, String filenames[]) { + StringBuilder str = new StringBuilder(); + str.append("
"); + if (!description.equals("")) { + str.append(description); + str.append(HtmlUtil.newline()); + } + for (int i = 0; i < filenames.length; i++) { + str.append("
"); + } + str.append("
"); + return str.toString(); + } + + public static String urlBlock(String description, String urls[]) { + StringBuilder str = new StringBuilder(""); + if (!description.equals("")) { + str.append(description); + str.append(HtmlUtil.newline()); + } + for (int i = 0; i < urls.length; i++) { + str.append(""); + str.append(urls[i]); + str.append("
"); + } + str.append("
"); + return str.toString(); + } + + public static String heading(int heading, String str, String id) { + return "" + textToHtml( + str) + ""; + } + + public static String heading(int heading, String str) { + return heading(heading, str, null); + } + + public static String padSpace(int num, String str) { + StringBuilder out = new StringBuilder(); + for (int i = 0; i < num; i++) { + out.append(" "); + } + out.append(str); + return out.toString(); + } + + public static String addSpace(int num) { + StringBuilder out = new StringBuilder(); + for (int i = 0; i < num; i++) { + out.append(" "); + } + return out.toString(); + } + + public static String para(String str) { + return "

" + textToHtml(str) + "

"; + } + + public static String italics(String str) { + return "" + textToHtml(str) + ""; + } + + public static String pre(String str) { + return "
" + str + "
"; + } + + public static String newline() { + return newline(1); + } + + public static String newline(int num) { + StringBuilder str = new StringBuilder(); + for (int i = 0; i < num; i++) { + str.append("
"); + } + return str + ""; + } + + public static String name(int num) { + return nameTarget("" + num); + } + + public static String nameTarget(String str) { + if (str == null) { + return ""; + } + return ""; + } + + public static String nameLink(int num, String text) { + return nameLink("" + num, text); + } + + public static String nameLink(String name, String text) { + return "" + text + ""; + } + + public static String nameLink(String name) { + return "" + name + ""; + } + + public static String simpleTable(String str) { + return simpleTable(str, 100); + } + + /** + * Create a table with one row/colum containing str + */ + public static String simpleTable(String str, int width) { + return "" + "" + "
" + str + "
"; + } + + /** + * Create a table with one row/colum containing str + */ + public static String borderTable(String str, int width, String bgcolor, String caption) { + return startBorderTable(width, bgcolor, caption) + str + endBorderTable(); + } + + public static String startBorderTable(int width, String bgcolor, String caption) { + String capStr = ""; + if (!caption.equals("")) { + capStr = "" + caption + ""; + } + return "" + capStr + "
"; + } + + public static String endBorderTable() { + return "
"; + } + + /** + * Create a table with one row multi column containing str[] + * + * @param str = array of strings for columns + * @return Return multi-column table string + */ + public static String multiColumnTable(String[] str) { + return multiColumnTable(str, 85); + } + + /** + * Create a table with one row multi column containing str[] + * + * @param str - array of strings for columns + * @param width - percent (1..100) of screen for table + * @return Return multi-column table string + */ + public static String multiColumnTable(String[] str, int width) { + StringBuilder sb = new StringBuilder(""); + for (int i = 0; i < str.length; i++) { + sb.append(""); + } + sb.append("
"); + sb.append(str[i]); + sb.append("
"); + return sb.toString(); + } + + public static String beginMultiColumnTable(int width) { + return beginMultiColumnTable(width, 0); + } + + public static String beginMultiColumnTable(int width, int border) { + return beginMultiColumnTable(width, border, null); + } + + public static String beginMultiColumnTable(int width, int border, Integer color) { + return ""; + } + + public static String endMultiColumnTable() { + return "
"; + } + + public static String addRowMultiColumnTable(String... str) { + return addRowMultiColumnTable(str, null, null); + } + + public static String addRowMultiColumnTable(String[] str, String[] colOptions) { + return addRowMultiColumnTable(str, colOptions, null); + } + + public static String addRowMultiColumnTable(String[] str, String[] colOptions, String backgroundColor) { + StringBuilder sb = new StringBuilder(""); + if (backgroundColor != null) { + sb.append(""); + } + String show = ""; + for (int i = 0; i < str.length; i++) { + show = str[i]; + if (show == null || show.equals("")) { + show = HtmlUtil.addSpace(1); + } + String colOptionStr = ""; + if (colOptions != null) { + colOptionStr = colOptions[i]; + } + sb.append(""); + sb.append(show); + sb.append(""); + } + sb.append(""); + return sb.toString(); + } + + public static String addRowSpanMultiColumnTable(String str, int span) { + return "" + str + ""; + } + + public static class CellItem { + String text; + private final String fgColor; + private final String bgColor; + + public CellItem(String text) { + this(text, null, null); + } + + public CellItem(String text, String fgColor, String bgColor) { + this.text = text; + this.fgColor = fgColor; + this.bgColor = bgColor; + } + } + + public static String addRowMultiColumnTable(Collection items) { + StringBuilder s = new StringBuilder(""); + for (CellItem item : items) { + if (item.text == null || "".equals(item.text)) { + item.text = "."; + } + if (item.bgColor != null) { + s.append(""); + } else { + s.append(""); + } + s.append(HtmlUtil.color(item.fgColor, item.text)); + s.append(""); + } + s.append(""); + return s.toString(); + } + + public static String addHeaderRowMultiColumnTable(String[] str) { + return addHeaderRowMultiColumnTable(str, null); + } + + public static String addHeaderRowMultiColumnTable(String[] str, Integer width[]) { + StringBuilder s = new StringBuilder(""); + String widthStr = ""; + for (int i = 0; i < str.length; i++) { + if (width != null) { + widthStr = " width =\"" + width[i] + "\""; + } + s.append(""); + s.append(str[i]); + s.append(""); + } + s.append(""); + return s.toString(); + } + + public static String addSimpleTableRow(String str) { + return "" + str + ""; + } + + public static String beginSimpleTable() { + return ""; + } + + public static String beginSimpleTable(int border, int width) { + return "
"; + } + + public static String endSimpleTable() { + return "
"; + } + + public static String createTable(List datas, String[] headers, int numColumns, int cellPadding, int border) { + StringBuilder table = new StringBuilder(begin); + + if (datas == null) { + throw new IllegalArgumentException("The data can not be null"); + } + if (datas.size() % numColumns != 0) { + throw new IllegalArgumentException( + "The table could not be created becuase the data does not match the column size"); + } + if (border > 0) { + table.append("border=\"" + border + "\""); + } + if (cellPadding > 0) { + table.append("cellpadding=\"" + cellPadding + "\""); + } + table.append(">"); + + if (headers != null && headers.length == numColumns) { + table.append(""); + for (String header : headers) { + table.append("" + header + ""); + } + table.append(""); + } + + int colIndex = 0; + for (String data : datas) { + + if (colIndex == 0) { + table.append(""); + } + table.append("" + data + ""); + colIndex++; + + if (colIndex == numColumns) { + table.append(""); + colIndex = 0; + } + } + return table.toString(); + } + + public static String getPreData(String data) { + return "" + HtmlUtil.pre( + HtmlUtil.textToHtml(data)); + } + } \ No newline at end of file diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/OverlayUtil.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/OverlayUtil.java index 854e8ead9..c8e05911d 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/OverlayUtil.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/OverlayUtil.java @@ -1,130 +1,130 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal; - -import java.util.ArrayList; -import java.util.Collection; - -import org.eclipse.jface.resource.CompositeImageDescriptor; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; - -/** - * @author Donald G. Dunne - */ -public class OverlayUtil extends CompositeImageDescriptor { - - private final Image baseImage; - private ImageDescriptor overlayImageDescriptor; - private int xValue = 0; - private int yValue = 0; - private Collection imageInfo; - - public static enum Location { - TOP_LEFT, - TOP_RIGHT, - BOT_LEFT, - BOT_RIGHT - }; - - public static class ImageInfo { - public ImageDescriptor descriptor; - public Location location; - - public ImageInfo(ImageDescriptor descriptor, Location location) { - this.descriptor = descriptor; - this.location = location; - } - } - - public OverlayUtil(Image baseImage, Collection imageInfo) { - this.baseImage = baseImage; - this.imageInfo = imageInfo; - } - - public OverlayUtil(Image baseImage, ImageDescriptor overlayImageDescriptor, Location location) { - this.baseImage = baseImage; - this.overlayImageDescriptor = overlayImageDescriptor; - this.imageInfo = new ArrayList<>(2); - imageInfo.add(new ImageInfo(overlayImageDescriptor, location)); - } - - public OverlayUtil(Image baseImage, ImageDescriptor overlayImageDescriptor) { - this(baseImage, overlayImageDescriptor, 0, 0); - } - - public OverlayUtil(Image baseImage, ImageDescriptor overlayImageDescriptor, int xValue, int yValue) { - if (baseImage == null) { - throw new IllegalArgumentException("baseImage can not be null"); - } - if (overlayImageDescriptor == null) { - throw new IllegalArgumentException("overlayImageDescriptor can not be null"); - } - - this.baseImage = baseImage; - this.overlayImageDescriptor = overlayImageDescriptor; - this.xValue = xValue; - this.yValue = yValue; - } - - /** - * Set x,y pixel to draw the overlay image eg: 8,8 for bottom right of a 16x16 image 0,0 for top left - */ - public void setXY(int xValue, int yValue) { - this.xValue = xValue; - this.yValue = yValue; - } - - @Override - protected void drawCompositeImage(int width, int height) { - // To draw a composite image, the base image should be - // drawn first (first layer) and then the overlay image - // (second layer) - // Draw the base image using the base image's image data - drawImage(baseImage.getImageData(), 0, 0); - - if (imageInfo == null) { - // Overlaying the icon in the top left corner i.e. x and y - // coordinates are both zero - drawImage(overlayImageDescriptor.getImageData(), xValue, yValue); - } else { - for (ImageInfo info : imageInfo) { - if (info.location == Location.TOP_LEFT) { - drawImage(info.descriptor.getImageData(), 0, 0); - } else if (info.location == Location.BOT_LEFT) { - drawImage(info.descriptor.getImageData(), 0, 8); - } else if (info.location == Location.TOP_RIGHT) { - drawImage(info.descriptor.getImageData(), 8, 0); - } else if (info.location == Location.BOT_RIGHT) { - drawImage(info.descriptor.getImageData(), 8, 8); - } - } - } - } - - @Override - protected Point getSize() { - int baseWidth = baseImage.getBounds().width; - int baseHeight = baseImage.getBounds().height; - - Image overImg = overlayImageDescriptor.createImage(); - int overWidth = overImg.getBounds().width; - int overHeight = overImg.getBounds().height; - overlayImageDescriptor.destroyResource(overImg); - - return new Point(baseWidth > overWidth ? baseWidth : overWidth, baseHeight > overHeight ? baseHeight : overHeight); - } - +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.jface.resource.CompositeImageDescriptor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; + +/** + * @author Donald G. Dunne + */ +public class OverlayUtil extends CompositeImageDescriptor { + + private final Image baseImage; + private ImageDescriptor overlayImageDescriptor; + private int xValue = 0; + private int yValue = 0; + private Collection imageInfo; + + public static enum Location { + TOP_LEFT, + TOP_RIGHT, + BOT_LEFT, + BOT_RIGHT + }; + + public static class ImageInfo { + public ImageDescriptor descriptor; + public Location location; + + public ImageInfo(ImageDescriptor descriptor, Location location) { + this.descriptor = descriptor; + this.location = location; + } + } + + public OverlayUtil(Image baseImage, Collection imageInfo) { + this.baseImage = baseImage; + this.imageInfo = imageInfo; + } + + public OverlayUtil(Image baseImage, ImageDescriptor overlayImageDescriptor, Location location) { + this.baseImage = baseImage; + this.overlayImageDescriptor = overlayImageDescriptor; + this.imageInfo = new ArrayList<>(2); + imageInfo.add(new ImageInfo(overlayImageDescriptor, location)); + } + + public OverlayUtil(Image baseImage, ImageDescriptor overlayImageDescriptor) { + this(baseImage, overlayImageDescriptor, 0, 0); + } + + public OverlayUtil(Image baseImage, ImageDescriptor overlayImageDescriptor, int xValue, int yValue) { + if (baseImage == null) { + throw new IllegalArgumentException("baseImage can not be null"); + } + if (overlayImageDescriptor == null) { + throw new IllegalArgumentException("overlayImageDescriptor can not be null"); + } + + this.baseImage = baseImage; + this.overlayImageDescriptor = overlayImageDescriptor; + this.xValue = xValue; + this.yValue = yValue; + } + + /** + * Set x,y pixel to draw the overlay image eg: 8,8 for bottom right of a 16x16 image 0,0 for top left + */ + public void setXY(int xValue, int yValue) { + this.xValue = xValue; + this.yValue = yValue; + } + + @Override + protected void drawCompositeImage(int width, int height) { + // To draw a composite image, the base image should be + // drawn first (first layer) and then the overlay image + // (second layer) + // Draw the base image using the base image's image data + drawImage(baseImage.getImageData(), 0, 0); + + if (imageInfo == null) { + // Overlaying the icon in the top left corner i.e. x and y + // coordinates are both zero + drawImage(overlayImageDescriptor.getImageData(), xValue, yValue); + } else { + for (ImageInfo info : imageInfo) { + if (info.location == Location.TOP_LEFT) { + drawImage(info.descriptor.getImageData(), 0, 0); + } else if (info.location == Location.BOT_LEFT) { + drawImage(info.descriptor.getImageData(), 0, 8); + } else if (info.location == Location.TOP_RIGHT) { + drawImage(info.descriptor.getImageData(), 8, 0); + } else if (info.location == Location.BOT_RIGHT) { + drawImage(info.descriptor.getImageData(), 8, 8); + } + } + } + } + + @Override + protected Point getSize() { + int baseWidth = baseImage.getBounds().width; + int baseHeight = baseImage.getBounds().height; + + Image overImg = overlayImageDescriptor.createImage(); + int overWidth = overImg.getBounds().width; + int overHeight = overImg.getBounds().height; + overlayImageDescriptor.destroyResource(overImg); + + return new Point(baseWidth > overWidth ? baseWidth : overWidth, baseHeight > overHeight ? baseHeight : overHeight); + } + } \ No newline at end of file diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/PatternFilter.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/PatternFilter.java index c7f769b5a..7e6cb6475 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/PatternFilter.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/PatternFilter.java @@ -1,341 +1,341 @@ -/******************************************************************************* - * Copyright (c) 2004, 2009 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal; - -import java.text.BreakIterator; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.StructuredViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerFilter; - -/** - * A filter used in conjunction with FilteredTree. In order to determine if a node should be filtered it - * uses the content and label provider of the tree to do pattern matching on its children. This causes the entire tree - * structure to be realized. Note that the label provider must implement ILabelProvider. - * - * @see org.eclipse.ui.dialogs.FilteredTree - * @since 3.2 - */ -public class PatternFilter extends ViewerFilter { - /* - * Cache of filtered elements in the tree - */ - @SuppressWarnings("rawtypes") - private final Map cache = new HashMap(); - - /* - * Maps parent elements to TRUE or FALSE - */ - @SuppressWarnings("rawtypes") - private final Map foundAnyCache = new HashMap(); - - private boolean useCache = false; - - /** - * Whether to include a leading wildcard for all provided patterns. A trailing wildcard is always included. - */ - private boolean includeLeadingWildcard = false; - - /** - * The string pattern matcher used for this pattern filter. - */ - private StringMatcher matcher; - - private boolean useEarlyReturnIfMatcherIsNull = true; - - private static Object[] EMPTY = new Object[0]; - - /** - * @see org.eclipse.jface.viewers.ViewerFilter#filter(org.eclipse.jface.viewers.Viewer, java.lang.Object, - * java.lang.Object[]) - */ - @SuppressWarnings("unchecked") - @Override - public final Object[] filter(Viewer viewer, Object parent, Object[] elements) { - // we don't want to optimize if we've extended the filter ... this - // needs to be addressed in 3.4 - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=186404 - if (matcher == null && useEarlyReturnIfMatcherIsNull) { - return elements; - } - - if (!useCache) { - return super.filter(viewer, parent, elements); - } - - Object[] filtered = (Object[]) cache.get(parent); - if (filtered == null) { - Boolean foundAny = (Boolean) foundAnyCache.get(parent); - if (foundAny != null && !foundAny.booleanValue()) { - filtered = EMPTY; - } else { - filtered = super.filter(viewer, parent, elements); - } - cache.put(parent, filtered); - } - return filtered; - } - - /** - * Returns true if any of the elements makes it through the filter. This method uses caching if enabled; the - * computation is done in computeAnyVisible. - * - * @param viewer - * @param parent - * @param elements the elements (must not be an empty array) - * @return true if any of the elements makes it through the filter. - */ - @SuppressWarnings("unchecked") - private boolean isAnyVisible(Viewer viewer, Object parent, Object[] elements) { - if (matcher == null) { - return true; - } - - if (!useCache) { - return computeAnyVisible(viewer, elements); - } - - Object[] filtered = (Object[]) cache.get(parent); - if (filtered != null) { - return filtered.length > 0; - } - Boolean foundAny = (Boolean) foundAnyCache.get(parent); - if (foundAny == null) { - foundAny = computeAnyVisible(viewer, elements) ? Boolean.TRUE : Boolean.FALSE; - foundAnyCache.put(parent, foundAny); - } - return foundAny.booleanValue(); - } - - /** - * Returns true if any of the elements makes it through the filter. - * - * @param viewer the viewer - * @param elements the elements to test - * @return true if any of the elements makes it through the filter - */ - private boolean computeAnyVisible(Viewer viewer, Object[] elements) { - boolean elementFound = false; - for (int i = 0; i < elements.length && !elementFound; i++) { - Object element = elements[i]; - elementFound = isElementVisible(viewer, element); - } - return elementFound; - } - - /** - * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, - * java.lang.Object) - */ - @Override - public final boolean select(Viewer viewer, Object parentElement, Object element) { - return isElementVisible(viewer, element); - } - - /** - * Sets whether a leading wildcard should be attached to each pattern string. - * - * @param includeLeadingWildcard Whether a leading wildcard should be added. - */ - public final void setIncludeLeadingWildcard(final boolean includeLeadingWildcard) { - this.includeLeadingWildcard = includeLeadingWildcard; - } - - /** - * The pattern string for which this filter should select elements in the viewer. - * - * @param patternString - */ - public void setPattern(String patternString) { - // these 2 strings allow the PatternFilter to be extended in - // 3.3 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=186404 - if ("org.eclipse.ui.keys.optimization.true".equals(patternString)) { //$NON-NLS-1$ - useEarlyReturnIfMatcherIsNull = true; - return; - } else if ("org.eclipse.ui.keys.optimization.false".equals(patternString)) { //$NON-NLS-1$ - useEarlyReturnIfMatcherIsNull = false; - return; - } - clearCaches(); - if (patternString == null || patternString.equals("")) { //$NON-NLS-1$ - matcher = null; - } else { - String pattern = patternString + "*"; //$NON-NLS-1$ - if (includeLeadingWildcard) { - pattern = "*" + pattern; //$NON-NLS-1$ - } - matcher = new StringMatcher(pattern, true, false); - } - } - - /** - * Clears the caches used for optimizing this filter. Needs to be called whenever the tree content changes. - */ - public void clearCaches() { - cache.clear(); - foundAnyCache.clear(); - } - - /** - * Answers whether the given String matches the pattern. - * - * @param string the String to test - * @return whether the string matches the pattern - */ - private boolean match(String string) { - if (matcher == null) { - return true; - } - return matcher.match(string); - } - - /** - * Answers whether the given element is a valid selection in the filtered tree. For example, if a tree has items that - * are categorized, the category itself may not be a valid selection since it is used merely to organize the - * elements. - * - * @param element - * @return true if this element is eligible for automatic selection - */ - public boolean isElementSelectable(Object element) { - return element != null; - } - - /** - * Answers whether the given element in the given viewer matches the filter pattern. This is a default implementation - * that will show a leaf element in the tree based on whether the provided filter text matches the text of the given - * element's text, or that of it's children (if the element has any). Subclasses may override this method. - * - * @param viewer the tree viewer in which the element resides - * @param element the element in the tree to check for a match - * @return true if the element matches the filter pattern - */ - public boolean isElementVisible(Viewer viewer, Object element) { - return isParentMatch(viewer, element) || isLeafMatch(viewer, element); - } - - /** - * Check if the parent (category) is a match to the filter text. The default behavior returns true if the element has - * at least one child element that is a match with the filter text. Subclasses may override this method. - * - * @param viewer the viewer that contains the element - * @param element the tree element to check - * @return true if the given element has children that matches the filter text - */ - protected boolean isParentMatch(Viewer viewer, Object element) { - Object[] children = - ((ITreeContentProvider) ((AbstractTreeViewer) viewer).getContentProvider()).getChildren(element); - - if ((children != null) && (children.length > 0)) { - return isAnyVisible(viewer, element, children); - } - return false; - } - - /** - * Check if the current (leaf) element is a match with the filter text. The default behavior checks that the label of - * the element is a match. Subclasses should override this method. - * - * @param viewer the viewer that contains the element - * @param element the tree element to check - * @return true if the given element's label matches the filter text - */ - public boolean isLeafMatch(Viewer viewer, Object element) { - String labelText = ((ILabelProvider) ((StructuredViewer) viewer).getLabelProvider()).getText(element); - - if (labelText == null) { - return false; - } - return wordMatches(labelText); - } - - /** - * Take the given filter text and break it down into words using a BreakIterator. - * - * @param text - * @return an array of words - */ - @SuppressWarnings({"rawtypes", "unchecked"}) - private String[] getWords(String text) { - List words = new ArrayList(); - // Break the text up into words, separating based on whitespace and - // common punctuation. - // Previously used String.split(..., "\\W"), where "\W" is a regular - // expression (see the Javadoc for class Pattern). - // Need to avoid both String.split and regular expressions, in order to - // compile against JCL Foundation (bug 80053). - // Also need to do this in an NL-sensitive way. The use of BreakIterator - // was suggested in bug 90579. - BreakIterator iter = BreakIterator.getWordInstance(); - iter.setText(text); - int i = iter.first(); - while (i != java.text.BreakIterator.DONE && i < text.length()) { - int j = iter.following(i); - if (j == java.text.BreakIterator.DONE) { - j = text.length(); - } - // match the word - if (Character.isLetterOrDigit(text.charAt(i))) { - String word = text.substring(i, j); - words.add(word); - } - i = j; - } - return (String[]) words.toArray(new String[words.size()]); - } - - /** - * Return whether or not if any of the words in text satisfy the match critera. - * - * @param text the text to match - * @return boolean true if one of the words in text satisifes the match criteria. - */ - protected boolean wordMatches(String text) { - if (text == null) { - return false; - } - - //If the whole text matches we are all set - if (match(text)) { - return true; - } - - // Otherwise check if any of the words of the text matches - String[] words = getWords(text); - for (int i = 0; i < words.length; i++) { - String word = words[i]; - if (match(word)) { - return true; - } - } - - return false; - } - - /** - * Can be called by the filtered tree to turn on caching. - * - * @param useCache The useCache to set. - */ - public void setUseCache(boolean useCache) { - this.useCache = useCache; - } -} +/******************************************************************************* + * Copyright (c) 2004, 2009 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal; + +import java.text.BreakIterator; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +/** + * A filter used in conjunction with FilteredTree. In order to determine if a node should be filtered it + * uses the content and label provider of the tree to do pattern matching on its children. This causes the entire tree + * structure to be realized. Note that the label provider must implement ILabelProvider. + * + * @see org.eclipse.ui.dialogs.FilteredTree + * @since 3.2 + */ +public class PatternFilter extends ViewerFilter { + /* + * Cache of filtered elements in the tree + */ + @SuppressWarnings("rawtypes") + private final Map cache = new HashMap(); + + /* + * Maps parent elements to TRUE or FALSE + */ + @SuppressWarnings("rawtypes") + private final Map foundAnyCache = new HashMap(); + + private boolean useCache = false; + + /** + * Whether to include a leading wildcard for all provided patterns. A trailing wildcard is always included. + */ + private boolean includeLeadingWildcard = false; + + /** + * The string pattern matcher used for this pattern filter. + */ + private StringMatcher matcher; + + private boolean useEarlyReturnIfMatcherIsNull = true; + + private static Object[] EMPTY = new Object[0]; + + /** + * @see org.eclipse.jface.viewers.ViewerFilter#filter(org.eclipse.jface.viewers.Viewer, java.lang.Object, + * java.lang.Object[]) + */ + @SuppressWarnings("unchecked") + @Override + public final Object[] filter(Viewer viewer, Object parent, Object[] elements) { + // we don't want to optimize if we've extended the filter ... this + // needs to be addressed in 3.4 + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=186404 + if (matcher == null && useEarlyReturnIfMatcherIsNull) { + return elements; + } + + if (!useCache) { + return super.filter(viewer, parent, elements); + } + + Object[] filtered = (Object[]) cache.get(parent); + if (filtered == null) { + Boolean foundAny = (Boolean) foundAnyCache.get(parent); + if (foundAny != null && !foundAny.booleanValue()) { + filtered = EMPTY; + } else { + filtered = super.filter(viewer, parent, elements); + } + cache.put(parent, filtered); + } + return filtered; + } + + /** + * Returns true if any of the elements makes it through the filter. This method uses caching if enabled; the + * computation is done in computeAnyVisible. + * + * @param viewer + * @param parent + * @param elements the elements (must not be an empty array) + * @return true if any of the elements makes it through the filter. + */ + @SuppressWarnings("unchecked") + private boolean isAnyVisible(Viewer viewer, Object parent, Object[] elements) { + if (matcher == null) { + return true; + } + + if (!useCache) { + return computeAnyVisible(viewer, elements); + } + + Object[] filtered = (Object[]) cache.get(parent); + if (filtered != null) { + return filtered.length > 0; + } + Boolean foundAny = (Boolean) foundAnyCache.get(parent); + if (foundAny == null) { + foundAny = computeAnyVisible(viewer, elements) ? Boolean.TRUE : Boolean.FALSE; + foundAnyCache.put(parent, foundAny); + } + return foundAny.booleanValue(); + } + + /** + * Returns true if any of the elements makes it through the filter. + * + * @param viewer the viewer + * @param elements the elements to test + * @return true if any of the elements makes it through the filter + */ + private boolean computeAnyVisible(Viewer viewer, Object[] elements) { + boolean elementFound = false; + for (int i = 0; i < elements.length && !elementFound; i++) { + Object element = elements[i]; + elementFound = isElementVisible(viewer, element); + } + return elementFound; + } + + /** + * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, + * java.lang.Object) + */ + @Override + public final boolean select(Viewer viewer, Object parentElement, Object element) { + return isElementVisible(viewer, element); + } + + /** + * Sets whether a leading wildcard should be attached to each pattern string. + * + * @param includeLeadingWildcard Whether a leading wildcard should be added. + */ + public final void setIncludeLeadingWildcard(final boolean includeLeadingWildcard) { + this.includeLeadingWildcard = includeLeadingWildcard; + } + + /** + * The pattern string for which this filter should select elements in the viewer. + * + * @param patternString + */ + public void setPattern(String patternString) { + // these 2 strings allow the PatternFilter to be extended in + // 3.3 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=186404 + if ("org.eclipse.ui.keys.optimization.true".equals(patternString)) { //$NON-NLS-1$ + useEarlyReturnIfMatcherIsNull = true; + return; + } else if ("org.eclipse.ui.keys.optimization.false".equals(patternString)) { //$NON-NLS-1$ + useEarlyReturnIfMatcherIsNull = false; + return; + } + clearCaches(); + if (patternString == null || patternString.equals("")) { //$NON-NLS-1$ + matcher = null; + } else { + String pattern = patternString + "*"; //$NON-NLS-1$ + if (includeLeadingWildcard) { + pattern = "*" + pattern; //$NON-NLS-1$ + } + matcher = new StringMatcher(pattern, true, false); + } + } + + /** + * Clears the caches used for optimizing this filter. Needs to be called whenever the tree content changes. + */ + public void clearCaches() { + cache.clear(); + foundAnyCache.clear(); + } + + /** + * Answers whether the given String matches the pattern. + * + * @param string the String to test + * @return whether the string matches the pattern + */ + private boolean match(String string) { + if (matcher == null) { + return true; + } + return matcher.match(string); + } + + /** + * Answers whether the given element is a valid selection in the filtered tree. For example, if a tree has items that + * are categorized, the category itself may not be a valid selection since it is used merely to organize the + * elements. + * + * @param element + * @return true if this element is eligible for automatic selection + */ + public boolean isElementSelectable(Object element) { + return element != null; + } + + /** + * Answers whether the given element in the given viewer matches the filter pattern. This is a default implementation + * that will show a leaf element in the tree based on whether the provided filter text matches the text of the given + * element's text, or that of it's children (if the element has any). Subclasses may override this method. + * + * @param viewer the tree viewer in which the element resides + * @param element the element in the tree to check for a match + * @return true if the element matches the filter pattern + */ + public boolean isElementVisible(Viewer viewer, Object element) { + return isParentMatch(viewer, element) || isLeafMatch(viewer, element); + } + + /** + * Check if the parent (category) is a match to the filter text. The default behavior returns true if the element has + * at least one child element that is a match with the filter text. Subclasses may override this method. + * + * @param viewer the viewer that contains the element + * @param element the tree element to check + * @return true if the given element has children that matches the filter text + */ + protected boolean isParentMatch(Viewer viewer, Object element) { + Object[] children = + ((ITreeContentProvider) ((AbstractTreeViewer) viewer).getContentProvider()).getChildren(element); + + if ((children != null) && (children.length > 0)) { + return isAnyVisible(viewer, element, children); + } + return false; + } + + /** + * Check if the current (leaf) element is a match with the filter text. The default behavior checks that the label of + * the element is a match. Subclasses should override this method. + * + * @param viewer the viewer that contains the element + * @param element the tree element to check + * @return true if the given element's label matches the filter text + */ + public boolean isLeafMatch(Viewer viewer, Object element) { + String labelText = ((ILabelProvider) ((StructuredViewer) viewer).getLabelProvider()).getText(element); + + if (labelText == null) { + return false; + } + return wordMatches(labelText); + } + + /** + * Take the given filter text and break it down into words using a BreakIterator. + * + * @param text + * @return an array of words + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + private String[] getWords(String text) { + List words = new ArrayList(); + // Break the text up into words, separating based on whitespace and + // common punctuation. + // Previously used String.split(..., "\\W"), where "\W" is a regular + // expression (see the Javadoc for class Pattern). + // Need to avoid both String.split and regular expressions, in order to + // compile against JCL Foundation (bug 80053). + // Also need to do this in an NL-sensitive way. The use of BreakIterator + // was suggested in bug 90579. + BreakIterator iter = BreakIterator.getWordInstance(); + iter.setText(text); + int i = iter.first(); + while (i != java.text.BreakIterator.DONE && i < text.length()) { + int j = iter.following(i); + if (j == java.text.BreakIterator.DONE) { + j = text.length(); + } + // match the word + if (Character.isLetterOrDigit(text.charAt(i))) { + String word = text.substring(i, j); + words.add(word); + } + i = j; + } + return (String[]) words.toArray(new String[words.size()]); + } + + /** + * Return whether or not if any of the words in text satisfy the match critera. + * + * @param text the text to match + * @return boolean true if one of the words in text satisifes the match criteria. + */ + protected boolean wordMatches(String text) { + if (text == null) { + return false; + } + + //If the whole text matches we are all set + if (match(text)) { + return true; + } + + // Otherwise check if any of the words of the text matches + String[] words = getWords(text); + for (int i = 0; i < words.length; i++) { + String word = words[i]; + if (match(word)) { + return true; + } + } + + return false; + } + + /** + * Can be called by the filtered tree to turn on caching. + * + * @param useCache The useCache to set. + */ + public void setUseCache(boolean useCache) { + this.useCache = useCache; + } +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/StringMatcher.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/StringMatcher.java index 4266d1e17..928bdd918 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/StringMatcher.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/StringMatcher.java @@ -1,383 +1,383 @@ -package org.eclipse.nebula.widgets.xviewer.util.internal; - -import java.util.Vector; - -/** - * Copied from JDT UI - * A string pattern matcher. Supports '*' and '?' wildcards. - */ -public class StringMatcher { - protected String fPattern; - protected int fLength; // pattern length - protected boolean fIgnoreWildCards; - protected boolean fIgnoreCase; - protected boolean fHasLeadingStar; - protected boolean fHasTrailingStar; - protected String fSegments[]; //the given pattern is split into * separated segments - - /* boundary value beyond which we don't need to search in the text */ - protected int fBound = 0; - - protected static final char fSingleWildCard = '\u0000'; - - public static class Position { - int start; //inclusive - int end; //exclusive - - public Position(int start, int end) { - this.start = start; - this.end = end; - } - - public int getStart() { - return start; - } - - public int getEnd() { - return end; - } - } - - /** - * StringMatcher constructor takes in a String object that is a simple - * pattern. The pattern may contain '*' for 0 and many characters and - * '?' for exactly one character. - * - * Literal '*' and '?' characters must be escaped in the pattern - * e.g., "\*" means literal "*", etc. - * - * Escaping any other character (including the escape character itself), - * just results in that character in the pattern. - * e.g., "\a" means "a" and "\\" means "\" - * - * If invoking the StringMatcher with string literals in Java, don't forget - * escape characters are represented by "\\". - * - * @param pattern the pattern to match text against - * @param ignoreCase if true, case is ignored - * @param ignoreWildCards if true, wild cards and their escape sequences are ignored - * (everything is taken literally). - */ - public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) { - if (pattern == null) - throw new IllegalArgumentException(); - fIgnoreCase = ignoreCase; - fIgnoreWildCards = ignoreWildCards; - fPattern = pattern; - fLength = pattern.length(); - - if (fIgnoreWildCards) { - parseNoWildCards(); - } else { - parseWildCards(); - } - } - - /** - * Find the first occurrence of the pattern between startend(exclusive). - * @param text the String object to search in - * @param start the starting index of the search range, inclusive - * @param end the ending index of the search range, exclusive - * @return an StringMatcher.Position object that keeps the starting - * (inclusive) and ending positions (exclusive) of the first occurrence of the - * pattern in the specified range of the text; return null if not found or subtext - * is empty (start==end). A pair of zeros is returned if pattern is empty string - * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc" - * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned - */ - public StringMatcher.Position find(String text, int start, int end) { - if (text == null) - throw new IllegalArgumentException(); - - int tlen = text.length(); - if (start < 0) - start = 0; - if (end > tlen) - end = tlen; - if (end < 0 || start >= end) - return null; - if (fLength == 0) - return new Position(start, start); - if (fIgnoreWildCards) { - int x = posIn(text, start, end); - if (x < 0) - return null; - return new Position(x, x + fLength); - } - - int segCount = fSegments.length; - if (segCount == 0)//pattern contains only '*'(s) - return new Position(start, end); - - int curPos = start; - int matchStart = -1; - int i; - for (i = 0; i < segCount && curPos < end; ++i) { - String current = fSegments[i]; - int nextMatch = regExpPosIn(text, curPos, end, current); - if (nextMatch < 0) - return null; - if (i == 0) - matchStart = nextMatch; - curPos = nextMatch + current.length(); - } - if (i < segCount) - return null; - return new Position(matchStart, curPos); - } - - /** - * match the given text with the pattern - * @return true if matched eitherwise false - * @param text a String object - */ - public boolean match(String text) { - return match(text, 0, text.length()); - } - - /** - * Given the starting (inclusive) and the ending (exclusive) positions in the - * text, determine if the given substring matches with aPattern - * @return true if the specified portion of the text matches the pattern - * @param text a String object that contains the substring to match - * @param start marks the starting position (inclusive) of the substring - * @param end marks the ending index (exclusive) of the substring - */ - public boolean match(String text, int start, int end) { - if (null == text) - throw new IllegalArgumentException(); - - if (start > end) - return false; - - if (fIgnoreWildCards) - return (end - start == fLength) && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength); - int segCount = fSegments.length; - if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) // pattern contains only '*'(s) - return true; - if (start == end) - return fLength == 0; - if (fLength == 0) - return start == end; - - int tlen = text.length(); - if (start < 0) - start = 0; - if (end > tlen) - end = tlen; - - int tCurPos = start; - int bound = end - fBound; - if (bound < 0) - return false; - int i = 0; - String current = fSegments[i]; - int segLength = current.length(); - - /* process first segment */ - if (!fHasLeadingStar) { - if (!regExpRegionMatches(text, start, current, 0, segLength)) { - return false; - } - ++i; - tCurPos = tCurPos + segLength; - } - if ((fSegments.length == 1) && (!fHasLeadingStar) && (!fHasTrailingStar)) { - // only one segment to match, no wildcards specified - return tCurPos == end; - } - /* process middle segments */ - while (i < segCount) { - current = fSegments[i]; - int currentMatch; - int k = current.indexOf(fSingleWildCard); - if (k < 0) { - currentMatch = textPosIn(text, tCurPos, end, current); - if (currentMatch < 0) - return false; - } else { - currentMatch = regExpPosIn(text, tCurPos, end, current); - if (currentMatch < 0) - return false; - } - tCurPos = currentMatch + current.length(); - i++; - } - - /* process final segment */ - if (!fHasTrailingStar && tCurPos != end) { - int clen = current.length(); - return regExpRegionMatches(text, end - clen, current, 0, clen); - } - return i == segCount; - } - - /** - * This method parses the given pattern into segments seperated by wildcard '*' characters. - * Since wildcards are not being used in this case, the pattern consists of a single segment. - */ - private void parseNoWildCards() { - fSegments = new String[1]; - fSegments[0] = fPattern; - fBound = fLength; - } - - /** - * Parses the given pattern into segments seperated by wildcard '*' characters. - */ - private void parseWildCards() { - if (fPattern.startsWith("*"))//$NON-NLS-1$ - fHasLeadingStar = true; - if (fPattern.endsWith("*")) {//$NON-NLS-1$ - /* make sure it's not an escaped wildcard */ - if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') { - fHasTrailingStar = true; - } - } - - Vector temp = new Vector<>(); - - int pos = 0; - StringBuilder buf = new StringBuilder(); - while (pos < fLength) { - char c = fPattern.charAt(pos++); - switch (c) { - case '\\' : - if (pos >= fLength) { - buf.append(c); - } else { - char next = fPattern.charAt(pos++); - /* if it's an escape sequence */ - if (next == '*' || next == '?' || next == '\\') { - buf.append(next); - } else { - /* not an escape sequence, just insert literally */ - buf.append(c); - buf.append(next); - } - } - break; - case '*' : - if (buf.length() > 0) { - /* new segment */ - temp.addElement(buf.toString()); - fBound += buf.length(); - buf.setLength(0); - } - break; - case '?' : - /* append special character representing single match wildcard */ - buf.append(fSingleWildCard); - break; - default : - buf.append(c); - } - } - - /* add last buffer to segment list */ - if (buf.length() > 0) { - temp.addElement(buf.toString()); - fBound += buf.length(); - } - - fSegments = new String[temp.size()]; - temp.copyInto(fSegments); - } - - /** - * @param text a string which contains no wildcard - * @param start the starting index in the text for search, inclusive - * @param end the stopping point of search, exclusive - * @return the starting index in the text of the pattern , or -1 if not found - */ - protected int posIn(String text, int start, int end) {//no wild card in pattern - int max = end - fLength; - - if (!fIgnoreCase) { - int i = text.indexOf(fPattern, start); - if (i == -1 || i > max) - return -1; - return i; - } - - for (int i = start; i <= max; ++i) { - if (text.regionMatches(true, i, fPattern, 0, fLength)) - return i; - } - - return -1; - } - - /** - * @param text a simple regular expression that may only contain '?'(s) - * @param start the starting index in the text for search, inclusive - * @param end the stopping point of search, exclusive - * @param p a simple regular expression that may contains '?' - * @return the starting index in the text of the pattern , or -1 if not found - */ - protected int regExpPosIn(String text, int start, int end, String p) { - int plen = p.length(); - - int max = end - plen; - for (int i = start; i <= max; ++i) { - if (regExpRegionMatches(text, i, p, 0, plen)) - return i; - } - return -1; - } - - protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) { - while (plen-- > 0) { - char tchar = text.charAt(tStart++); - char pchar = p.charAt(pStart++); - - /* process wild cards */ - if (!fIgnoreWildCards) { - /* skip single wild cards */ - if (pchar == fSingleWildCard) { - continue; - } - } - if (pchar == tchar) - continue; - if (fIgnoreCase) { - if (Character.toUpperCase(tchar) == Character.toUpperCase(pchar)) - continue; - // comparing after converting to upper case doesn't handle all cases; - // also compare after converting to lower case - if (Character.toLowerCase(tchar) == Character.toLowerCase(pchar)) - continue; - } - return false; - } - return true; - } - - /** - * @param text the string to match - * @param start the starting index in the text for search, inclusive - * @param end the stopping point of search, exclusive - * @param p a string that has no wildcard - * @return the starting index in the text of the pattern , or -1 if not found - */ - protected int textPosIn(String text, int start, int end, String p) { - - int plen = p.length(); - int max = end - plen; - - if (!fIgnoreCase) { - int i = text.indexOf(p, start); - if (i == -1 || i > max) - return -1; - return i; - } - - for (int i = start; i <= max; ++i) { - if (text.regionMatches(true, i, p, 0, plen)) - return i; - } - - return -1; - } -} +package org.eclipse.nebula.widgets.xviewer.util.internal; + +import java.util.Vector; + +/** + * Copied from JDT UI + * A string pattern matcher. Supports '*' and '?' wildcards. + */ +public class StringMatcher { + protected String fPattern; + protected int fLength; // pattern length + protected boolean fIgnoreWildCards; + protected boolean fIgnoreCase; + protected boolean fHasLeadingStar; + protected boolean fHasTrailingStar; + protected String fSegments[]; //the given pattern is split into * separated segments + + /* boundary value beyond which we don't need to search in the text */ + protected int fBound = 0; + + protected static final char fSingleWildCard = '\u0000'; + + public static class Position { + int start; //inclusive + int end; //exclusive + + public Position(int start, int end) { + this.start = start; + this.end = end; + } + + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } + } + + /** + * StringMatcher constructor takes in a String object that is a simple + * pattern. The pattern may contain '*' for 0 and many characters and + * '?' for exactly one character. + * + * Literal '*' and '?' characters must be escaped in the pattern + * e.g., "\*" means literal "*", etc. + * + * Escaping any other character (including the escape character itself), + * just results in that character in the pattern. + * e.g., "\a" means "a" and "\\" means "\" + * + * If invoking the StringMatcher with string literals in Java, don't forget + * escape characters are represented by "\\". + * + * @param pattern the pattern to match text against + * @param ignoreCase if true, case is ignored + * @param ignoreWildCards if true, wild cards and their escape sequences are ignored + * (everything is taken literally). + */ + public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) { + if (pattern == null) + throw new IllegalArgumentException(); + fIgnoreCase = ignoreCase; + fIgnoreWildCards = ignoreWildCards; + fPattern = pattern; + fLength = pattern.length(); + + if (fIgnoreWildCards) { + parseNoWildCards(); + } else { + parseWildCards(); + } + } + + /** + * Find the first occurrence of the pattern between startend(exclusive). + * @param text the String object to search in + * @param start the starting index of the search range, inclusive + * @param end the ending index of the search range, exclusive + * @return an StringMatcher.Position object that keeps the starting + * (inclusive) and ending positions (exclusive) of the first occurrence of the + * pattern in the specified range of the text; return null if not found or subtext + * is empty (start==end). A pair of zeros is returned if pattern is empty string + * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc" + * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned + */ + public StringMatcher.Position find(String text, int start, int end) { + if (text == null) + throw new IllegalArgumentException(); + + int tlen = text.length(); + if (start < 0) + start = 0; + if (end > tlen) + end = tlen; + if (end < 0 || start >= end) + return null; + if (fLength == 0) + return new Position(start, start); + if (fIgnoreWildCards) { + int x = posIn(text, start, end); + if (x < 0) + return null; + return new Position(x, x + fLength); + } + + int segCount = fSegments.length; + if (segCount == 0)//pattern contains only '*'(s) + return new Position(start, end); + + int curPos = start; + int matchStart = -1; + int i; + for (i = 0; i < segCount && curPos < end; ++i) { + String current = fSegments[i]; + int nextMatch = regExpPosIn(text, curPos, end, current); + if (nextMatch < 0) + return null; + if (i == 0) + matchStart = nextMatch; + curPos = nextMatch + current.length(); + } + if (i < segCount) + return null; + return new Position(matchStart, curPos); + } + + /** + * match the given text with the pattern + * @return true if matched eitherwise false + * @param text a String object + */ + public boolean match(String text) { + return match(text, 0, text.length()); + } + + /** + * Given the starting (inclusive) and the ending (exclusive) positions in the + * text, determine if the given substring matches with aPattern + * @return true if the specified portion of the text matches the pattern + * @param text a String object that contains the substring to match + * @param start marks the starting position (inclusive) of the substring + * @param end marks the ending index (exclusive) of the substring + */ + public boolean match(String text, int start, int end) { + if (null == text) + throw new IllegalArgumentException(); + + if (start > end) + return false; + + if (fIgnoreWildCards) + return (end - start == fLength) && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength); + int segCount = fSegments.length; + if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) // pattern contains only '*'(s) + return true; + if (start == end) + return fLength == 0; + if (fLength == 0) + return start == end; + + int tlen = text.length(); + if (start < 0) + start = 0; + if (end > tlen) + end = tlen; + + int tCurPos = start; + int bound = end - fBound; + if (bound < 0) + return false; + int i = 0; + String current = fSegments[i]; + int segLength = current.length(); + + /* process first segment */ + if (!fHasLeadingStar) { + if (!regExpRegionMatches(text, start, current, 0, segLength)) { + return false; + } + ++i; + tCurPos = tCurPos + segLength; + } + if ((fSegments.length == 1) && (!fHasLeadingStar) && (!fHasTrailingStar)) { + // only one segment to match, no wildcards specified + return tCurPos == end; + } + /* process middle segments */ + while (i < segCount) { + current = fSegments[i]; + int currentMatch; + int k = current.indexOf(fSingleWildCard); + if (k < 0) { + currentMatch = textPosIn(text, tCurPos, end, current); + if (currentMatch < 0) + return false; + } else { + currentMatch = regExpPosIn(text, tCurPos, end, current); + if (currentMatch < 0) + return false; + } + tCurPos = currentMatch + current.length(); + i++; + } + + /* process final segment */ + if (!fHasTrailingStar && tCurPos != end) { + int clen = current.length(); + return regExpRegionMatches(text, end - clen, current, 0, clen); + } + return i == segCount; + } + + /** + * This method parses the given pattern into segments seperated by wildcard '*' characters. + * Since wildcards are not being used in this case, the pattern consists of a single segment. + */ + private void parseNoWildCards() { + fSegments = new String[1]; + fSegments[0] = fPattern; + fBound = fLength; + } + + /** + * Parses the given pattern into segments seperated by wildcard '*' characters. + */ + private void parseWildCards() { + if (fPattern.startsWith("*"))//$NON-NLS-1$ + fHasLeadingStar = true; + if (fPattern.endsWith("*")) {//$NON-NLS-1$ + /* make sure it's not an escaped wildcard */ + if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') { + fHasTrailingStar = true; + } + } + + Vector temp = new Vector<>(); + + int pos = 0; + StringBuilder buf = new StringBuilder(); + while (pos < fLength) { + char c = fPattern.charAt(pos++); + switch (c) { + case '\\' : + if (pos >= fLength) { + buf.append(c); + } else { + char next = fPattern.charAt(pos++); + /* if it's an escape sequence */ + if (next == '*' || next == '?' || next == '\\') { + buf.append(next); + } else { + /* not an escape sequence, just insert literally */ + buf.append(c); + buf.append(next); + } + } + break; + case '*' : + if (buf.length() > 0) { + /* new segment */ + temp.addElement(buf.toString()); + fBound += buf.length(); + buf.setLength(0); + } + break; + case '?' : + /* append special character representing single match wildcard */ + buf.append(fSingleWildCard); + break; + default : + buf.append(c); + } + } + + /* add last buffer to segment list */ + if (buf.length() > 0) { + temp.addElement(buf.toString()); + fBound += buf.length(); + } + + fSegments = new String[temp.size()]; + temp.copyInto(fSegments); + } + + /** + * @param text a string which contains no wildcard + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int posIn(String text, int start, int end) {//no wild card in pattern + int max = end - fLength; + + if (!fIgnoreCase) { + int i = text.indexOf(fPattern, start); + if (i == -1 || i > max) + return -1; + return i; + } + + for (int i = start; i <= max; ++i) { + if (text.regionMatches(true, i, fPattern, 0, fLength)) + return i; + } + + return -1; + } + + /** + * @param text a simple regular expression that may only contain '?'(s) + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @param p a simple regular expression that may contains '?' + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int regExpPosIn(String text, int start, int end, String p) { + int plen = p.length(); + + int max = end - plen; + for (int i = start; i <= max; ++i) { + if (regExpRegionMatches(text, i, p, 0, plen)) + return i; + } + return -1; + } + + protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) { + while (plen-- > 0) { + char tchar = text.charAt(tStart++); + char pchar = p.charAt(pStart++); + + /* process wild cards */ + if (!fIgnoreWildCards) { + /* skip single wild cards */ + if (pchar == fSingleWildCard) { + continue; + } + } + if (pchar == tchar) + continue; + if (fIgnoreCase) { + if (Character.toUpperCase(tchar) == Character.toUpperCase(pchar)) + continue; + // comparing after converting to upper case doesn't handle all cases; + // also compare after converting to lower case + if (Character.toLowerCase(tchar) == Character.toLowerCase(pchar)) + continue; + } + return false; + } + return true; + } + + /** + * @param text the string to match + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @param p a string that has no wildcard + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int textPosIn(String text, int start, int end, String p) { + + int plen = p.length(); + int max = end - plen; + + if (!fIgnoreCase) { + int i = text.indexOf(p, start); + if (i == -1 || i > max) + return -1; + return i; + } + + for (int i = start; i <= max; ++i) { + if (text.regionMatches(true, i, p, 0, plen)) + return i; + } + + return -1; + } +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerFilteredTree.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerFilteredTree.java index 3e203f2e5..d037b6e0e 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerFilteredTree.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerFilteredTree.java @@ -1,61 +1,61 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal; - -import org.eclipse.nebula.widgets.xviewer.XViewerText; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; - -/** - * @author Donald G. Dunne - */ -public class XViewerFilteredTree extends FilteredTreeComposite { - - public XViewerFilteredTree(Composite parent) { - this(parent, SWT.BORDER | SWT.MULTI); - } - - public XViewerFilteredTree(Composite parent, int treeStyle) { - this(parent, treeStyle, new XViewerPatternFilter()); - } - - public XViewerFilteredTree(Composite parent, int treeStyle, PatternFilter filter) { - super(parent, treeStyle, filter); - setInitialText(""); //$NON-NLS-1$ - } - - @Override - protected Composite createFilterControls(Composite parent) { - Composite comp = new Composite(parent, SWT.NONE); - comp.setLayout(XViewerLib.getZeroMarginLayout(3, false)); - comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - (new Label(comp, SWT.NONE)).setText(XViewerText.get("label.filter") + " "); //$NON-NLS-1$//$NON-NLS-2$ - super.createFilterControls(comp); - - return comp; - } - - @Override - protected void createFilterText(Composite parent) { - super.createFilterText(parent); - Listener listener = event -> filterText.setFocus(); - filterText.addListener(SWT.KeyUp, listener); - filterText.addListener(SWT.KeyDown, listener); - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal; + +import org.eclipse.nebula.widgets.xviewer.XViewerText; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; + +/** + * @author Donald G. Dunne + */ +public class XViewerFilteredTree extends FilteredTreeComposite { + + public XViewerFilteredTree(Composite parent) { + this(parent, SWT.BORDER | SWT.MULTI); + } + + public XViewerFilteredTree(Composite parent, int treeStyle) { + this(parent, treeStyle, new XViewerPatternFilter()); + } + + public XViewerFilteredTree(Composite parent, int treeStyle, PatternFilter filter) { + super(parent, treeStyle, filter); + setInitialText(""); //$NON-NLS-1$ + } + + @Override + protected Composite createFilterControls(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + comp.setLayout(XViewerLib.getZeroMarginLayout(3, false)); + comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + (new Label(comp, SWT.NONE)).setText(XViewerText.get("label.filter") + " "); //$NON-NLS-1$//$NON-NLS-2$ + super.createFilterControls(comp); + + return comp; + } + + @Override + protected void createFilterText(Composite parent) { + super.createFilterText(parent); + Listener listener = event -> filterText.setFocus(); + filterText.addListener(SWT.KeyUp, listener); + filterText.addListener(SWT.KeyDown, listener); + } + +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerLib.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerLib.java index dbe5c3db6..53b1886d9 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerLib.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerLib.java @@ -1,207 +1,207 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.logging.Level; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.nebula.widgets.xviewer.Activator; -import org.eclipse.nebula.widgets.xviewer.core.util.XViewerUtil; -import org.eclipse.nebula.widgets.xviewer.util.internal.images.XViewerImageCache; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.PlatformUI; - -/** - * @author Donald G. Dunne - */ -public class XViewerLib { - private static final Date today = new Date(); - public final static int MILLISECS_PER_DAY = (1000 * 60 * 60 * 24); - public final static String MMDDYYHHMM = "MM/dd/yyyy hh:mm a"; - - public static long daysTillToday(Date date) { - return (date.getTime() - today.getTime()) / MILLISECS_PER_DAY; - } - - public static String intern(String str) { - return XViewerUtil.intern(str); - } - - public static String generateGuidStr() { - return XViewerUtil.generateGuidStr(); - } - - public static void writeStringToFile(String str, File outFile) throws IOException { - OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"); - char[] chars = str.toCharArray(); - out.write(chars, 0, chars.length); - out.close(); - } - - public static void popup(final String title, final String message) { - if (!PlatformUI.isWorkbenchRunning()) { - XViewerLog.log(Activator.class, Level.SEVERE, message); - } else { - ensureInDisplayThread(() -> { - MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), title, - message); - }); - } - } - - public static GridLayout getZeroMarginLayout(int numColumns, boolean equalColumnWidth) { - GridLayout layout = new GridLayout(); - layout.numColumns = numColumns; - layout.makeColumnsEqualWidth = equalColumnWidth; - layout.verticalSpacing = 0; - layout.marginWidth = 0; - layout.marginHeight = 0; - return layout; - } - - public static GridLayout getZeroMarginLayout() { - return getZeroMarginLayout(1, false); - } - - public static List readListFromDir(File directory, FilenameFilter filter, boolean keepExtension) { - List list = new ArrayList<>(400); - - if (directory == null) { - XViewerLog.log(Activator.class, Level.SEVERE, "Invalid directory path"); - return list; - } - - File[] files = directory.listFiles(filter); - if (files == null) { - XViewerLog.log(Activator.class, Level.SEVERE, "Invalid path: " + directory); - return list; - } - if (files.length > 0) { - Arrays.sort(files); - } - - if (keepExtension) { - for (int i = 0; i < files.length; i++) { - list.add(files[i].getName()); - } - } else { - for (int i = 0; i < files.length; i++) { - list.add(removeExtension(files[i].getName())); - } - } - - return list; - } - - public static List readListFromDir(String directory, FilenameFilter filter) { - return readListFromDir(new File(directory), filter, false); - } - - /** - * Remove the file extension from the file path - */ - public static String removeExtension(String filepath) { - String ext = getExtension(filepath); - if (ext != null && ext.length() > 0) { - filepath = filepath.substring(0, filepath.length() - (ext.length() + 1)); - } - return filepath; - } - - /** - * Determine is OS is windows - */ - public static boolean isWindows() { - return System.getProperty("os.name").indexOf("indows") != -1; - } - - /** - * Get file extension from the file path - */ - public static String getExtension(String filepath) { - filepath = filepath.trim(); - String separatorRegEx = File.separator; - if (isWindows()) { - separatorRegEx = "\\\\"; - } - String[] pathsArray = filepath.split(separatorRegEx); - - String fileName = pathsArray[0]; - if (pathsArray.length > 0) { - fileName = pathsArray[pathsArray.length - 1]; - } - - int index = fileName.lastIndexOf('.'); - if (index >= 0 && index + 1 < fileName.length()) { - return fileName.substring(index + 1); - } else { - return ""; - } - } - - public static void ensureInDisplayThread(Runnable runnable) { - ensureInDisplayThread(runnable, false); - } - - public static void ensureInDisplayThread(Runnable runnable, boolean forcePend) { - if (isDisplayThread()) { - // No need to check for force since this will always pend - runnable.run(); - } else { - if (forcePend) { - Display.getDefault().syncExec(runnable); - } else { - Display.getDefault().asyncExec(runnable); - } - } - } - - public static boolean isDisplayThread() { - if (Display.getCurrent() == null) { - return false; - } - - return Display.getCurrent().getThread() == Thread.currentThread(); - } - - public static Image getImage(String imageName) { - return XViewerImageCache.getImage(imageName); - } - - public static ImageDescriptor getImageDescriptor(String imageName) { - return XViewerImageCache.getImageDescriptor(imageName); - } - - public static String getDateFromPattern(Date date, String pattern) { - SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); - if (date == null) { - return ""; - } - String result = dateFormat.format(date); - return result; - } -} +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.logging.Level; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.nebula.widgets.xviewer.Activator; +import org.eclipse.nebula.widgets.xviewer.core.util.XViewerUtil; +import org.eclipse.nebula.widgets.xviewer.util.internal.images.XViewerImageCache; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; + +/** + * @author Donald G. Dunne + */ +public class XViewerLib { + private static final Date today = new Date(); + public final static int MILLISECS_PER_DAY = (1000 * 60 * 60 * 24); + public final static String MMDDYYHHMM = "MM/dd/yyyy hh:mm a"; + + public static long daysTillToday(Date date) { + return (date.getTime() - today.getTime()) / MILLISECS_PER_DAY; + } + + public static String intern(String str) { + return XViewerUtil.intern(str); + } + + public static String generateGuidStr() { + return XViewerUtil.generateGuidStr(); + } + + public static void writeStringToFile(String str, File outFile) throws IOException { + OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"); + char[] chars = str.toCharArray(); + out.write(chars, 0, chars.length); + out.close(); + } + + public static void popup(final String title, final String message) { + if (!PlatformUI.isWorkbenchRunning()) { + XViewerLog.log(Activator.class, Level.SEVERE, message); + } else { + ensureInDisplayThread(() -> { + MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), title, + message); + }); + } + } + + public static GridLayout getZeroMarginLayout(int numColumns, boolean equalColumnWidth) { + GridLayout layout = new GridLayout(); + layout.numColumns = numColumns; + layout.makeColumnsEqualWidth = equalColumnWidth; + layout.verticalSpacing = 0; + layout.marginWidth = 0; + layout.marginHeight = 0; + return layout; + } + + public static GridLayout getZeroMarginLayout() { + return getZeroMarginLayout(1, false); + } + + public static List readListFromDir(File directory, FilenameFilter filter, boolean keepExtension) { + List list = new ArrayList<>(400); + + if (directory == null) { + XViewerLog.log(Activator.class, Level.SEVERE, "Invalid directory path"); + return list; + } + + File[] files = directory.listFiles(filter); + if (files == null) { + XViewerLog.log(Activator.class, Level.SEVERE, "Invalid path: " + directory); + return list; + } + if (files.length > 0) { + Arrays.sort(files); + } + + if (keepExtension) { + for (int i = 0; i < files.length; i++) { + list.add(files[i].getName()); + } + } else { + for (int i = 0; i < files.length; i++) { + list.add(removeExtension(files[i].getName())); + } + } + + return list; + } + + public static List readListFromDir(String directory, FilenameFilter filter) { + return readListFromDir(new File(directory), filter, false); + } + + /** + * Remove the file extension from the file path + */ + public static String removeExtension(String filepath) { + String ext = getExtension(filepath); + if (ext != null && ext.length() > 0) { + filepath = filepath.substring(0, filepath.length() - (ext.length() + 1)); + } + return filepath; + } + + /** + * Determine is OS is windows + */ + public static boolean isWindows() { + return System.getProperty("os.name").indexOf("indows") != -1; + } + + /** + * Get file extension from the file path + */ + public static String getExtension(String filepath) { + filepath = filepath.trim(); + String separatorRegEx = File.separator; + if (isWindows()) { + separatorRegEx = "\\\\"; + } + String[] pathsArray = filepath.split(separatorRegEx); + + String fileName = pathsArray[0]; + if (pathsArray.length > 0) { + fileName = pathsArray[pathsArray.length - 1]; + } + + int index = fileName.lastIndexOf('.'); + if (index >= 0 && index + 1 < fileName.length()) { + return fileName.substring(index + 1); + } else { + return ""; + } + } + + public static void ensureInDisplayThread(Runnable runnable) { + ensureInDisplayThread(runnable, false); + } + + public static void ensureInDisplayThread(Runnable runnable, boolean forcePend) { + if (isDisplayThread()) { + // No need to check for force since this will always pend + runnable.run(); + } else { + if (forcePend) { + Display.getDefault().syncExec(runnable); + } else { + Display.getDefault().asyncExec(runnable); + } + } + } + + public static boolean isDisplayThread() { + if (Display.getCurrent() == null) { + return false; + } + + return Display.getCurrent().getThread() == Thread.currentThread(); + } + + public static Image getImage(String imageName) { + return XViewerImageCache.getImage(imageName); + } + + public static ImageDescriptor getImageDescriptor(String imageName) { + return XViewerImageCache.getImageDescriptor(imageName); + } + + public static String getDateFromPattern(Date date, String pattern) { + SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); + if (date == null) { + return ""; + } + String result = dateFormat.format(date); + return result; + } +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerTextWidget.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerTextWidget.java index 74bc2f586..44f5ed6e5 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerTextWidget.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerTextWidget.java @@ -1,528 +1,528 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal; - -import java.util.logging.Level; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.nebula.widgets.xviewer.Activator; -import org.eclipse.nebula.widgets.xviewer.XViewerText; -import org.eclipse.nebula.widgets.xviewer.core.util.XmlUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; - -/** - * Generic label and text field object for use by single entry artifact attributes - * - * @author Donald G. Dunne - */ -public class XViewerTextWidget extends XViewerWidget { - - protected StyledText sText; // Contains visable representation of text - private Composite parent; - protected String text = ""; // Where actual text with xml tags is stored //$NON-NLS-1$ - private int maxTextChars = 0; - - private final static boolean debug = false; - private int width = 0; - private int height = 0; - private Font font; - - public XViewerTextWidget() { - super("AText", "text"); //$NON-NLS-1$//$NON-NLS-2$ - } - - public XViewerTextWidget(String displayLabel) { - this(displayLabel, "text"); //$NON-NLS-1$ - } - - public XViewerTextWidget(String displayLabel, String xmlRoot) { - this(displayLabel, xmlRoot, ""); //$NON-NLS-1$ - } - - public XViewerTextWidget(String displayLabel, String xmlRoot, String xmlSubRoot) { - super(displayLabel, xmlRoot, xmlSubRoot); - } - - public void setEnabled(boolean enabled) { - sText.setEnabled(enabled); - } - - public void setSize(int width, int height) { - this.width = width; - this.height = height; - if (sText != null && !sText.isDisposed()) { - sText.setSize(width, height); - } - } - - public void setHeight(int height) { - this.height = height; - if (sText != null && !sText.isDisposed()) { - sText.setSize(sText.getSize().x, height); - } - } - - @Override - public String toString() { - return label + ": *" + text + "*"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - @Override - public Control getControl() { - return sText; - } - - /** - * Create Text Widgets. Widgets Created: Label: "text entry" horizonatalSpan takes up 2 columns; horizontalSpan must - * be >=2 - */ - @Override - public void createWidgets(Composite parent, int horizontalSpan) { - createWidgets(parent, horizontalSpan, true); - } - - public void createWidgets(Composite parent, int horizontalSpan, boolean fillText) { - - if (!verticalLabel && (horizontalSpan < 2)) { - horizontalSpan = 2; - } - - this.parent = parent; - Composite composite = null; - - composite = createComposite(parent, horizontalSpan); - - createLabelWidget(composite); - - if (fillVertically) { - sText = new StyledText(composite, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.H_SCROLL | SWT.V_SCROLL); - } else { - sText = new StyledText(composite, SWT.BORDER | SWT.SINGLE); - } - GridData gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = verticalLabel ? horizontalSpan : horizontalSpan - 1; - gd.grabExcessHorizontalSpace = true; - gd.horizontalAlignment = GridData.FILL; - - if (fillVertically) { - gd.grabExcessVerticalSpace = true; - gd.verticalAlignment = GridData.FILL; - if (height > 0) { - gd.heightHint = height; - } - } - - sText.setLayoutData(gd); - sText.setMenu(getDefaultMenu()); - - addModificationListener(); - - if (text != null) { - sText.setText(text); - } - if (width != 0 && height != 0) { - sText.setSize(width, height); - } - - if (maxTextChars > 0) { - sText.setTextLimit(maxTextChars); - } - if (fillText) { - updateTextWidget(); - } - setLabelError(); - sText.setEditable(editable); - if (font != null) { - sText.setFont(font); - } - parent.layout(); - } - - private void addModificationListener() { - sText.addListener(SWT.Modify, e -> { - if (sText != null) { - text = sText.getText(); - setLabelError(); - notifyXModifiedListeners(); - } - }); - } - - private void createLabelWidget(Composite composite) { - if (displayLabel && !label.equals("")) { //$NON-NLS-1$ - labelWidget = new Label(composite, SWT.NONE); - labelWidget.setText(label + ":"); //$NON-NLS-1$ - if (toolTip != null) { - labelWidget.setToolTipText(toolTip); - } - } - } - - private Composite createComposite(Composite parent, int horizontalSpan) { - Composite composite; - if (fillVertically) { - composite = new Composite(parent, SWT.NONE); - GridLayout layout = XViewerLib.getZeroMarginLayout(1, false); - layout.verticalSpacing = 4; - composite.setLayout(layout); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - } else { - composite = new Composite(parent, SWT.NONE); - GridLayout layout = XViewerLib.getZeroMarginLayout(2, false); - layout.verticalSpacing = 4; - composite.setLayout(layout); - GridData gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = horizontalSpan; - composite.setLayoutData(gd); - } - return composite; - } - - /** - * @return text including xml tags replaced for references - */ - public String getText() { - return sText.getText(); - } - - public void setText(String text) { - this.text = text; - if (sText != null) { - sText.setText(text); - } - } - - public Menu getDefaultMenu() { - Menu menu = new Menu(sText.getShell()); - MenuItem cut = new MenuItem(menu, SWT.NONE); - cut.setText(XViewerText.get("menu.cut")); //$NON-NLS-1$ - cut.addListener(SWT.Selection, e-> { - sText.cut(); - sText.redraw(); - }); - MenuItem copy = new MenuItem(menu, SWT.NONE); - copy.setText(XViewerText.get("menu.copy")); //$NON-NLS-1$ - copy.addListener(SWT.Selection, e-> sText.copy()); - - MenuItem paste = new MenuItem(menu, SWT.NONE); - paste.setText(XViewerText.get("menu.paste")); //$NON-NLS-1$ - paste.addListener(SWT.Selection, e-> { - sText.paste(); - sText.redraw(); - }); - return menu; - } - - @Override - public void dispose() { - if (font != null) { - font.dispose(); - } - if (labelWidget != null) { - labelWidget.dispose(); - } - if (sText != null) { - sText.dispose(); - sText = null; - } - if (parent != null && !parent.isDisposed()) { - parent.layout(); - } - } - - @Override - public void setFocus() { - if (sText != null) { - sText.setFocus(); - } - } - - @Override - public void setEditable(boolean editable) { - super.setEditable(editable); - if (sText != null && !sText.isDisposed()) { - sText.setEditable(editable); - } - } - - /** - * Set max character limit on text field - * - * @param limit - if 0, then limit is 999, else sets to limit - */ - public void setMaxTextLimit(int limit) { - this.maxTextChars = limit; - if (sText != null) { - if (limit == 0) { - sText.setTextLimit(999); - } else { - sText.setTextLimit(limit); - } - } - } - - public void forceFocus() { - if (sText != null) { - sText.forceFocus(); - } - } - - public boolean isInteger() { - try { - Integer.valueOf(text); - } catch (NumberFormatException e) { - return false; - } - return true; - } - - public boolean isFloat() { - try { - new Float(text); - } catch (NumberFormatException e) { - return false; - } - return true; - } - - public int getInteger() { - Integer num; - try { - num = Integer.valueOf(text); - } catch (NumberFormatException e) { - return 0; - } - return num.intValue(); - } - - public double getFloat() { - Double num; - try { - num = new Double(text); - } catch (NumberFormatException e) { - return 0; - } - return num.doubleValue(); - } - - @Override - public void setRequiredEntry(boolean requiredEntry) { - super.setRequiredEntry(requiredEntry); - setLabelError(); - } - - public boolean requiredEntry() { - return requiredEntry; - } - - public void addModifyListener(ModifyListener modifyListener) { - if (sText != null) { - sText.addModifyListener(modifyListener); - } - } - - public String get() { - if (debug) { - XViewerLog.log(Activator.class, Level.SEVERE, "text set *" + text + "*"); //$NON-NLS-1$//$NON-NLS-2$ - } - return text; - } - - @Override - public String getXmlData() { - if (sText == null || sText.isDisposed()) { - return XmlUtil.textToXml(text); - } else { - try { - return XmlUtil.textToXml(sText.getText()); - } catch (SWTException e) { - return XmlUtil.textToXml(text); - } - } - } - - @Override - public String toXml() { - if (xmlSubRoot.equals("")) { //$NON-NLS-1$ - return toXml(xmlRoot); - } else { - return toXml(xmlRoot, xmlSubRoot); - } - } - - @Override - public String toXml(String xmlRoot) { - return "<" + xmlRoot + ">" + getXmlData() + "\n"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - - @Override - public String toXml(String xmlRoot, String xmlSubRoot) { - return "<" + xmlRoot + ">" + "<" + xmlSubRoot + ">" + getXmlData() + "" + "\n"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ - } - - @Override - public void setXmlData(String str) { - set(str); - if (debug) { - XViewerLog.log(Activator.class, Level.SEVERE, "setFromXml *" + str + "*"); //$NON-NLS-1$//$NON-NLS-2$ - } - } - - @Override - public void setFromXml(String xml) { - Matcher m; - m = Pattern.compile("<" + xmlRoot + ">(.*?)", Pattern.MULTILINE | Pattern.DOTALL).matcher(xml); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - - if (m.find()) { - String xmlStr = m.group(1); - if (debug) { - XViewerLog.log(Activator.class, Level.SEVERE, "xmlStr *" + xmlStr + "*"); //$NON-NLS-1$//$NON-NLS-2$ - } - String str = XmlUtil.xmlToText(xmlStr); - if (debug) { - XViewerLog.log(Activator.class, Level.SEVERE, "str *" + str + "*"); //$NON-NLS-1$//$NON-NLS-2$ - } - setXmlData(str); - } - } - - public int getInt() { - Integer percent = Integer.valueOf(0); - try { - percent = Integer.valueOf(text); - } catch (NumberFormatException e) { - // do nothing - } - return percent.intValue(); - } - - protected void updateTextWidget() { - if (sText == null || sText.isDisposed()) { - return; - } - if (text.equals(sText.getText())) { - return; - } - // Disable Listeners so not to fill Undo List - sText.setText(text); - // Re-enable Listeners - setLabelError(); - } - - public void set(String text) { - if (text == null) { - this.text = ""; //$NON-NLS-1$ - } else { - this.text = text; - } - if (debug) { - XViewerLog.log(Activator.class, Level.SEVERE, "set *" + text + "*"); //$NON-NLS-1$ //$NON-NLS-2$ - } - updateTextWidget(); - } - - public void set(XViewerTextWidget text) { - set(text.get()); - } - - public void append(String text) { - this.text = this.text + text; - updateTextWidget(); - } - - @Override - public void refresh() { - updateTextWidget(); - } - - @Override - public String getReportData() { - StringBuilder sb = new StringBuilder(); - String textStr = text; - if (fillVertically) { - sb.append("\n"); //$NON-NLS-1$ - textStr = textStr.replaceAll("\n", "\n" + " "); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - textStr = " " + textStr; //$NON-NLS-1$ - } - sb.append(textStr); - return sb.toString().replaceAll("\n$", ""); //$NON-NLS-1$//$NON-NLS-2$ - } - - public String toHTML(String labelFont, boolean newLineText) { - String s = HtmlUtil.getLabelStr(labelFont, label + ": "); //$NON-NLS-1$ - if (newLineText) { - s = "
" + s + "
"; //$NON-NLS-1$//$NON-NLS-2$ - } - s += text; - if (newLineText) { - s += "
"; //$NON-NLS-1$ - } - return s; - } - - @Override - public String toHTML(String labelFont) { - return toHTML(labelFont, false); - } - - @Override - public boolean isValid() { - if (isRequiredEntry() && get().equals("")) { //$NON-NLS-1$ - return false; - } - return true; - } - - @Override - public Object getData() { - return sText.getText(); - } - - /** - * @return the sText - */ - public StyledText getStyledText() { - return sText; - } - - /** - * @return the font - */ - public Font getFont() { - return font; - } - - /** - * @param font the font to set - */ - public void setFont(Font font) { - this.font = font; - if (sText != null) { - sText.setFont(font); - } - } - +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal; + +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.nebula.widgets.xviewer.Activator; +import org.eclipse.nebula.widgets.xviewer.XViewerText; +import org.eclipse.nebula.widgets.xviewer.core.util.XmlUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; + +/** + * Generic label and text field object for use by single entry artifact attributes + * + * @author Donald G. Dunne + */ +public class XViewerTextWidget extends XViewerWidget { + + protected StyledText sText; // Contains visable representation of text + private Composite parent; + protected String text = ""; // Where actual text with xml tags is stored //$NON-NLS-1$ + private int maxTextChars = 0; + + private final static boolean debug = false; + private int width = 0; + private int height = 0; + private Font font; + + public XViewerTextWidget() { + super("AText", "text"); //$NON-NLS-1$//$NON-NLS-2$ + } + + public XViewerTextWidget(String displayLabel) { + this(displayLabel, "text"); //$NON-NLS-1$ + } + + public XViewerTextWidget(String displayLabel, String xmlRoot) { + this(displayLabel, xmlRoot, ""); //$NON-NLS-1$ + } + + public XViewerTextWidget(String displayLabel, String xmlRoot, String xmlSubRoot) { + super(displayLabel, xmlRoot, xmlSubRoot); + } + + public void setEnabled(boolean enabled) { + sText.setEnabled(enabled); + } + + public void setSize(int width, int height) { + this.width = width; + this.height = height; + if (sText != null && !sText.isDisposed()) { + sText.setSize(width, height); + } + } + + public void setHeight(int height) { + this.height = height; + if (sText != null && !sText.isDisposed()) { + sText.setSize(sText.getSize().x, height); + } + } + + @Override + public String toString() { + return label + ": *" + text + "*"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + @Override + public Control getControl() { + return sText; + } + + /** + * Create Text Widgets. Widgets Created: Label: "text entry" horizonatalSpan takes up 2 columns; horizontalSpan must + * be >=2 + */ + @Override + public void createWidgets(Composite parent, int horizontalSpan) { + createWidgets(parent, horizontalSpan, true); + } + + public void createWidgets(Composite parent, int horizontalSpan, boolean fillText) { + + if (!verticalLabel && (horizontalSpan < 2)) { + horizontalSpan = 2; + } + + this.parent = parent; + Composite composite = null; + + composite = createComposite(parent, horizontalSpan); + + createLabelWidget(composite); + + if (fillVertically) { + sText = new StyledText(composite, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.H_SCROLL | SWT.V_SCROLL); + } else { + sText = new StyledText(composite, SWT.BORDER | SWT.SINGLE); + } + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = verticalLabel ? horizontalSpan : horizontalSpan - 1; + gd.grabExcessHorizontalSpace = true; + gd.horizontalAlignment = GridData.FILL; + + if (fillVertically) { + gd.grabExcessVerticalSpace = true; + gd.verticalAlignment = GridData.FILL; + if (height > 0) { + gd.heightHint = height; + } + } + + sText.setLayoutData(gd); + sText.setMenu(getDefaultMenu()); + + addModificationListener(); + + if (text != null) { + sText.setText(text); + } + if (width != 0 && height != 0) { + sText.setSize(width, height); + } + + if (maxTextChars > 0) { + sText.setTextLimit(maxTextChars); + } + if (fillText) { + updateTextWidget(); + } + setLabelError(); + sText.setEditable(editable); + if (font != null) { + sText.setFont(font); + } + parent.layout(); + } + + private void addModificationListener() { + sText.addListener(SWT.Modify, e -> { + if (sText != null) { + text = sText.getText(); + setLabelError(); + notifyXModifiedListeners(); + } + }); + } + + private void createLabelWidget(Composite composite) { + if (displayLabel && !label.equals("")) { //$NON-NLS-1$ + labelWidget = new Label(composite, SWT.NONE); + labelWidget.setText(label + ":"); //$NON-NLS-1$ + if (toolTip != null) { + labelWidget.setToolTipText(toolTip); + } + } + } + + private Composite createComposite(Composite parent, int horizontalSpan) { + Composite composite; + if (fillVertically) { + composite = new Composite(parent, SWT.NONE); + GridLayout layout = XViewerLib.getZeroMarginLayout(1, false); + layout.verticalSpacing = 4; + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + } else { + composite = new Composite(parent, SWT.NONE); + GridLayout layout = XViewerLib.getZeroMarginLayout(2, false); + layout.verticalSpacing = 4; + composite.setLayout(layout); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = horizontalSpan; + composite.setLayoutData(gd); + } + return composite; + } + + /** + * @return text including xml tags replaced for references + */ + public String getText() { + return sText.getText(); + } + + public void setText(String text) { + this.text = text; + if (sText != null) { + sText.setText(text); + } + } + + public Menu getDefaultMenu() { + Menu menu = new Menu(sText.getShell()); + MenuItem cut = new MenuItem(menu, SWT.NONE); + cut.setText(XViewerText.get("menu.cut")); //$NON-NLS-1$ + cut.addListener(SWT.Selection, e-> { + sText.cut(); + sText.redraw(); + }); + MenuItem copy = new MenuItem(menu, SWT.NONE); + copy.setText(XViewerText.get("menu.copy")); //$NON-NLS-1$ + copy.addListener(SWT.Selection, e-> sText.copy()); + + MenuItem paste = new MenuItem(menu, SWT.NONE); + paste.setText(XViewerText.get("menu.paste")); //$NON-NLS-1$ + paste.addListener(SWT.Selection, e-> { + sText.paste(); + sText.redraw(); + }); + return menu; + } + + @Override + public void dispose() { + if (font != null) { + font.dispose(); + } + if (labelWidget != null) { + labelWidget.dispose(); + } + if (sText != null) { + sText.dispose(); + sText = null; + } + if (parent != null && !parent.isDisposed()) { + parent.layout(); + } + } + + @Override + public void setFocus() { + if (sText != null) { + sText.setFocus(); + } + } + + @Override + public void setEditable(boolean editable) { + super.setEditable(editable); + if (sText != null && !sText.isDisposed()) { + sText.setEditable(editable); + } + } + + /** + * Set max character limit on text field + * + * @param limit - if 0, then limit is 999, else sets to limit + */ + public void setMaxTextLimit(int limit) { + this.maxTextChars = limit; + if (sText != null) { + if (limit == 0) { + sText.setTextLimit(999); + } else { + sText.setTextLimit(limit); + } + } + } + + public void forceFocus() { + if (sText != null) { + sText.forceFocus(); + } + } + + public boolean isInteger() { + try { + Integer.valueOf(text); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + public boolean isFloat() { + try { + new Float(text); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + public int getInteger() { + Integer num; + try { + num = Integer.valueOf(text); + } catch (NumberFormatException e) { + return 0; + } + return num.intValue(); + } + + public double getFloat() { + Double num; + try { + num = new Double(text); + } catch (NumberFormatException e) { + return 0; + } + return num.doubleValue(); + } + + @Override + public void setRequiredEntry(boolean requiredEntry) { + super.setRequiredEntry(requiredEntry); + setLabelError(); + } + + public boolean requiredEntry() { + return requiredEntry; + } + + public void addModifyListener(ModifyListener modifyListener) { + if (sText != null) { + sText.addModifyListener(modifyListener); + } + } + + public String get() { + if (debug) { + XViewerLog.log(Activator.class, Level.SEVERE, "text set *" + text + "*"); //$NON-NLS-1$//$NON-NLS-2$ + } + return text; + } + + @Override + public String getXmlData() { + if (sText == null || sText.isDisposed()) { + return XmlUtil.textToXml(text); + } else { + try { + return XmlUtil.textToXml(sText.getText()); + } catch (SWTException e) { + return XmlUtil.textToXml(text); + } + } + } + + @Override + public String toXml() { + if (xmlSubRoot.equals("")) { //$NON-NLS-1$ + return toXml(xmlRoot); + } else { + return toXml(xmlRoot, xmlSubRoot); + } + } + + @Override + public String toXml(String xmlRoot) { + return "<" + xmlRoot + ">" + getXmlData() + "\n"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + @Override + public String toXml(String xmlRoot, String xmlSubRoot) { + return "<" + xmlRoot + ">" + "<" + xmlSubRoot + ">" + getXmlData() + "" + "\n"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ + } + + @Override + public void setXmlData(String str) { + set(str); + if (debug) { + XViewerLog.log(Activator.class, Level.SEVERE, "setFromXml *" + str + "*"); //$NON-NLS-1$//$NON-NLS-2$ + } + } + + @Override + public void setFromXml(String xml) { + Matcher m; + m = Pattern.compile("<" + xmlRoot + ">(.*?)", Pattern.MULTILINE | Pattern.DOTALL).matcher(xml); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + + if (m.find()) { + String xmlStr = m.group(1); + if (debug) { + XViewerLog.log(Activator.class, Level.SEVERE, "xmlStr *" + xmlStr + "*"); //$NON-NLS-1$//$NON-NLS-2$ + } + String str = XmlUtil.xmlToText(xmlStr); + if (debug) { + XViewerLog.log(Activator.class, Level.SEVERE, "str *" + str + "*"); //$NON-NLS-1$//$NON-NLS-2$ + } + setXmlData(str); + } + } + + public int getInt() { + Integer percent = Integer.valueOf(0); + try { + percent = Integer.valueOf(text); + } catch (NumberFormatException e) { + // do nothing + } + return percent.intValue(); + } + + protected void updateTextWidget() { + if (sText == null || sText.isDisposed()) { + return; + } + if (text.equals(sText.getText())) { + return; + } + // Disable Listeners so not to fill Undo List + sText.setText(text); + // Re-enable Listeners + setLabelError(); + } + + public void set(String text) { + if (text == null) { + this.text = ""; //$NON-NLS-1$ + } else { + this.text = text; + } + if (debug) { + XViewerLog.log(Activator.class, Level.SEVERE, "set *" + text + "*"); //$NON-NLS-1$ //$NON-NLS-2$ + } + updateTextWidget(); + } + + public void set(XViewerTextWidget text) { + set(text.get()); + } + + public void append(String text) { + this.text = this.text + text; + updateTextWidget(); + } + + @Override + public void refresh() { + updateTextWidget(); + } + + @Override + public String getReportData() { + StringBuilder sb = new StringBuilder(); + String textStr = text; + if (fillVertically) { + sb.append("\n"); //$NON-NLS-1$ + textStr = textStr.replaceAll("\n", "\n" + " "); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + textStr = " " + textStr; //$NON-NLS-1$ + } + sb.append(textStr); + return sb.toString().replaceAll("\n$", ""); //$NON-NLS-1$//$NON-NLS-2$ + } + + public String toHTML(String labelFont, boolean newLineText) { + String s = HtmlUtil.getLabelStr(labelFont, label + ": "); //$NON-NLS-1$ + if (newLineText) { + s = "
" + s + "
"; //$NON-NLS-1$//$NON-NLS-2$ + } + s += text; + if (newLineText) { + s += "
"; //$NON-NLS-1$ + } + return s; + } + + @Override + public String toHTML(String labelFont) { + return toHTML(labelFont, false); + } + + @Override + public boolean isValid() { + if (isRequiredEntry() && get().equals("")) { //$NON-NLS-1$ + return false; + } + return true; + } + + @Override + public Object getData() { + return sText.getText(); + } + + /** + * @return the sText + */ + public StyledText getStyledText() { + return sText; + } + + /** + * @return the font + */ + public Font getFont() { + return font; + } + + /** + * @param font the font to set + */ + public void setFont(Font font) { + this.font = font; + if (sText != null) { + sText.setFont(font); + } + } + } \ No newline at end of file diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerWidget.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerWidget.java index 334b24e12..7a69189dd 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerWidget.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerWidget.java @@ -1,375 +1,375 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.xviewer.util.internal; - -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.logging.Level; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.nebula.widgets.xviewer.Activator; -import org.eclipse.nebula.widgets.xviewer.XViewerText; -import org.eclipse.nebula.widgets.xviewer.core.util.XmlUtil; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.forms.widgets.FormToolkit; - -/** - * Abstract class for all widgets used in Wizards and Editors - * - * @author Donald G. Dunne - */ -public abstract class XViewerWidget { - - protected Label labelWidget = null; - protected String label = ""; //$NON-NLS-1$ - protected String xmlRoot = ""; //$NON-NLS-1$ - protected String xmlSubRoot = ""; //$NON-NLS-1$ - protected String toolTip = null; - protected boolean requiredEntry = false; - protected boolean editable = true; - protected boolean verticalLabel = false; - protected boolean fillVertically = false; - protected boolean fillHorizontally = false; - - public boolean isFillHorizontally() { - return fillHorizontally; - } - - protected boolean displayLabel = true; - private final Set modifiedListeners = - new LinkedHashSet<>(); - private MouseListener mouseLabelListener; - - /** - * Display "label: data" - */ - public final static int RPT_NONE = 0; - /** - * Display "label: data\n\n" Default of AAtribute - */ - public final static int RPT_SINGLE_LINE = 1; - /** - * Display "label:\n data\n\n" - */ - public final static int RPT_MULTI_LINE = 2; - protected int reportType = RPT_SINGLE_LINE; - protected FormToolkit toolkit; - - public XViewerWidget(String label) { - this.label = label; - } - - public XViewerWidget(String label, String xmlRoot) { - this.label = label; - this.xmlRoot = xmlRoot; - } - - public XViewerWidget(String label, String xmlRoot, String xmlSubRoot) { - this.label = label; - this.xmlRoot = xmlRoot; - this.xmlSubRoot = xmlSubRoot; - } - - public void setToolTip(String toolTip) { - this.toolTip = toolTip; - if (this.labelWidget != null && !labelWidget.isDisposed()) { - this.labelWidget.setToolTipText(toolTip); - } - } - - public void addXModifiedListener(XViewerWidgetModifiedListener listener) { - modifiedListeners.add(listener); - } - - public void notifyXModifiedListeners() { - for (XViewerWidgetModifiedListener listener : modifiedListeners) { - listener.widgetModified(this); - } - } - - public void setLabelError() { - if (labelWidget == null || labelWidget.isDisposed()) { - return; - } - if (!isValid()) { - labelWidget.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED)); - } else { - labelWidget.setForeground(null); - } - if (mouseLabelListener == null) { - mouseLabelListener = new MouseListener() { - @Override - public void mouseDoubleClick(MouseEvent e) { - openHelp(); - } - - @Override - public void mouseDown(MouseEvent e) { - // do nothing - } - - @Override - public void mouseUp(MouseEvent e) { - // do nothing - } - }; - labelWidget.addMouseListener(mouseLabelListener); - } - } - - public abstract Control getControl(); - - public void openHelp() { - try { - if (toolTip != null && label != null) { - MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - label + " " + XViewerText.get("tooltip"), toolTip); //$NON-NLS-1$ //$NON-NLS-2$ - } - } catch (Exception ex) { - XViewerLog.log(Activator.class, Level.SEVERE, ex); - } - } - - /** - * Create Widgets used to display label and entry for wizards and editors - */ - public abstract void createWidgets(Composite parent, int horizontalSpan); - - public void createWidgets(FormToolkit toolkit, Composite parent, int horizontalSpan) { - this.toolkit = toolkit; - createWidgets(parent, horizontalSpan); - adaptControls(toolkit); - } - - public void adaptControls(FormToolkit toolkit) { - if (getControl() != null) { - toolkit.adapt(getControl(), true, true); - } - if (labelWidget != null) { - toolkit.adapt(labelWidget, true, true); - toolkit.adapt(labelWidget.getParent(), true, true); - } - } - - /** - * Create Widgets used to display label and entry for wizards and editors - */ - public abstract void dispose(); - - /** - * Set focus to the entry widget - */ - public abstract void setFocus(); - - /** - * Refresh the entry widget - */ - public abstract void refresh(); - - /** - * Return true if entry is valid - * - * @return Return boolean validity indication. - */ - public abstract boolean isValid(); - - /** - * Called with string found between xml tags Used by setFromXml() String will be sent through AXml.xmlToText() before - * being sent to setXmlData implementation. Used by: setFromXml - */ - public abstract void setXmlData(String str); - - /** - * Return string to save off between xml tags Used by call to toXml() String returned will be sent through - * AXml.textToXml() before being saved Used by: toXml - */ - public abstract String getXmlData(); - - public abstract String toHTML(String labelFont); - - public String toXml() throws Exception { - if (xmlSubRoot.equals("")) { //$NON-NLS-1$ - return toXml(xmlRoot); - } else { - return toXml(xmlRoot, xmlSubRoot); - } - } - - public String toXml(String xmlRoot) throws Exception { - return "<" + xmlRoot + ">" + XmlUtil.textToXml(getXmlData()) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - - public String toXml(String xmlRoot, String xmlSubRoot) throws Exception { - return "<" + xmlRoot + ">" + "<" + xmlSubRoot + ">" + XmlUtil.textToXml( //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ - getXmlData()) + "" + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - - public void setFromXml(String xml) throws IllegalStateException { - Matcher m; - m = Pattern.compile("<" + xmlRoot + ">(.*?)", Pattern.MULTILINE | Pattern.DOTALL).matcher(xml); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (m.find()) { - setXmlData(XmlUtil.xmlToText(m.group(1))); - } - } - - public List getDisplayLabels() { - List l = new ArrayList<>(); - l.add(label); - return l; - } - - public void setDisplayLabel(String displayLabel) { - this.label = displayLabel; - } - - public boolean isEditable() { - return editable; - } - - public void setEditable(boolean editable) { - this.editable = editable; - } - - public boolean isVerticalLabel() { - return verticalLabel; - } - - public void setVerticalLabel(boolean verticalLabel) { - this.verticalLabel = verticalLabel; - } - - public String getXmlRoot() { - return xmlRoot; - } - - public void setXmlRoot(String xmlRoot) { - this.xmlRoot = xmlRoot; - } - - public String getXmlSubRoot() { - return xmlSubRoot; - } - - public void setXmlSubRoot(String xmlSubRoot) { - this.xmlSubRoot = xmlSubRoot; - } - - public String getToolTip() { - return toolTip; - } - - public boolean isFillVertically() { - return fillVertically; - } - - public void setFillVertically(boolean fillVertically) { - this.fillVertically = fillVertically; - } - - public String getLabel() { - return label; - } - - public void setLabel(String label) { - this.label = label; - } - - public Label getLabelWidget() { - return labelWidget; - } - - public void setLabelWidget(Label labelWidget) { - this.labelWidget = labelWidget; - } - - public boolean isRequiredEntry() { - return requiredEntry; - } - - public void setRequiredEntry(boolean requiredEntry) { - this.requiredEntry = requiredEntry; - } - - public int getReportType() { - return reportType; - } - - public void setReportType(int reportType) { - this.reportType = reportType; - } - - /** - * Return data for display in Report (without label) NOTE: There should be no newlines at end of String - */ - public abstract String getReportData(); - - @Override - public String toString() { - return toReport(); - } - - public String toReport() { - return toReport(reportType); - } - - /** - * RPT_NONE (label: data), RPT_SINGLE_LINE (label: data\n\n), RPT_MULTI_LINE (label:\n data\n\n) - */ - public String toReport(int rptType) { - String s = label + ": "; //$NON-NLS-1$ - switch (rptType) { - case RPT_SINGLE_LINE: - s += getReportData() + "\n\n"; //$NON-NLS-1$ - break; - case RPT_MULTI_LINE: - String data = getReportData(); - data = data.replaceAll("\n", "\n "); //$NON-NLS-1$ //$NON-NLS-2$ - s += "\n" + data + "\n\n"; //$NON-NLS-1$ //$NON-NLS-2$ - break; - default: - s += getReportData(); - break; - } - return s; - } - - /** - * If set, label will be displayed with entry widget. - */ - public void setDisplayLabel(boolean displayLabel) { - this.displayLabel = displayLabel; - } - - public void setFillHorizontally(boolean fillHorizontally) { - this.fillHorizontally = fillHorizontally; - } - - public abstract Object getData(); - - public boolean isDisplayLabel() { - return displayLabel; - } +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.xviewer.util.internal; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.nebula.widgets.xviewer.Activator; +import org.eclipse.nebula.widgets.xviewer.XViewerText; +import org.eclipse.nebula.widgets.xviewer.core.util.XmlUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * Abstract class for all widgets used in Wizards and Editors + * + * @author Donald G. Dunne + */ +public abstract class XViewerWidget { + + protected Label labelWidget = null; + protected String label = ""; //$NON-NLS-1$ + protected String xmlRoot = ""; //$NON-NLS-1$ + protected String xmlSubRoot = ""; //$NON-NLS-1$ + protected String toolTip = null; + protected boolean requiredEntry = false; + protected boolean editable = true; + protected boolean verticalLabel = false; + protected boolean fillVertically = false; + protected boolean fillHorizontally = false; + + public boolean isFillHorizontally() { + return fillHorizontally; + } + + protected boolean displayLabel = true; + private final Set modifiedListeners = + new LinkedHashSet<>(); + private MouseListener mouseLabelListener; + + /** + * Display "label: data" + */ + public final static int RPT_NONE = 0; + /** + * Display "label: data\n\n" Default of AAtribute + */ + public final static int RPT_SINGLE_LINE = 1; + /** + * Display "label:\n data\n\n" + */ + public final static int RPT_MULTI_LINE = 2; + protected int reportType = RPT_SINGLE_LINE; + protected FormToolkit toolkit; + + public XViewerWidget(String label) { + this.label = label; + } + + public XViewerWidget(String label, String xmlRoot) { + this.label = label; + this.xmlRoot = xmlRoot; + } + + public XViewerWidget(String label, String xmlRoot, String xmlSubRoot) { + this.label = label; + this.xmlRoot = xmlRoot; + this.xmlSubRoot = xmlSubRoot; + } + + public void setToolTip(String toolTip) { + this.toolTip = toolTip; + if (this.labelWidget != null && !labelWidget.isDisposed()) { + this.labelWidget.setToolTipText(toolTip); + } + } + + public void addXModifiedListener(XViewerWidgetModifiedListener listener) { + modifiedListeners.add(listener); + } + + public void notifyXModifiedListeners() { + for (XViewerWidgetModifiedListener listener : modifiedListeners) { + listener.widgetModified(this); + } + } + + public void setLabelError() { + if (labelWidget == null || labelWidget.isDisposed()) { + return; + } + if (!isValid()) { + labelWidget.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED)); + } else { + labelWidget.setForeground(null); + } + if (mouseLabelListener == null) { + mouseLabelListener = new MouseListener() { + @Override + public void mouseDoubleClick(MouseEvent e) { + openHelp(); + } + + @Override + public void mouseDown(MouseEvent e) { + // do nothing + } + + @Override + public void mouseUp(MouseEvent e) { + // do nothing + } + }; + labelWidget.addMouseListener(mouseLabelListener); + } + } + + public abstract Control getControl(); + + public void openHelp() { + try { + if (toolTip != null && label != null) { + MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), + label + " " + XViewerText.get("tooltip"), toolTip); //$NON-NLS-1$ //$NON-NLS-2$ + } + } catch (Exception ex) { + XViewerLog.log(Activator.class, Level.SEVERE, ex); + } + } + + /** + * Create Widgets used to display label and entry for wizards and editors + */ + public abstract void createWidgets(Composite parent, int horizontalSpan); + + public void createWidgets(FormToolkit toolkit, Composite parent, int horizontalSpan) { + this.toolkit = toolkit; + createWidgets(parent, horizontalSpan); + adaptControls(toolkit); + } + + public void adaptControls(FormToolkit toolkit) { + if (getControl() != null) { + toolkit.adapt(getControl(), true, true); + } + if (labelWidget != null) { + toolkit.adapt(labelWidget, true, true); + toolkit.adapt(labelWidget.getParent(), true, true); + } + } + + /** + * Create Widgets used to display label and entry for wizards and editors + */ + public abstract void dispose(); + + /** + * Set focus to the entry widget + */ + public abstract void setFocus(); + + /** + * Refresh the entry widget + */ + public abstract void refresh(); + + /** + * Return true if entry is valid + * + * @return Return boolean validity indication. + */ + public abstract boolean isValid(); + + /** + * Called with string found between xml tags Used by setFromXml() String will be sent through AXml.xmlToText() before + * being sent to setXmlData implementation. Used by: setFromXml + */ + public abstract void setXmlData(String str); + + /** + * Return string to save off between xml tags Used by call to toXml() String returned will be sent through + * AXml.textToXml() before being saved Used by: toXml + */ + public abstract String getXmlData(); + + public abstract String toHTML(String labelFont); + + public String toXml() throws Exception { + if (xmlSubRoot.equals("")) { //$NON-NLS-1$ + return toXml(xmlRoot); + } else { + return toXml(xmlRoot, xmlSubRoot); + } + } + + public String toXml(String xmlRoot) throws Exception { + return "<" + xmlRoot + ">" + XmlUtil.textToXml(getXmlData()) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + public String toXml(String xmlRoot, String xmlSubRoot) throws Exception { + return "<" + xmlRoot + ">" + "<" + xmlSubRoot + ">" + XmlUtil.textToXml( //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ + getXmlData()) + "" + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + + public void setFromXml(String xml) throws IllegalStateException { + Matcher m; + m = Pattern.compile("<" + xmlRoot + ">(.*?)", Pattern.MULTILINE | Pattern.DOTALL).matcher(xml); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (m.find()) { + setXmlData(XmlUtil.xmlToText(m.group(1))); + } + } + + public List getDisplayLabels() { + List l = new ArrayList<>(); + l.add(label); + return l; + } + + public void setDisplayLabel(String displayLabel) { + this.label = displayLabel; + } + + public boolean isEditable() { + return editable; + } + + public void setEditable(boolean editable) { + this.editable = editable; + } + + public boolean isVerticalLabel() { + return verticalLabel; + } + + public void setVerticalLabel(boolean verticalLabel) { + this.verticalLabel = verticalLabel; + } + + public String getXmlRoot() { + return xmlRoot; + } + + public void setXmlRoot(String xmlRoot) { + this.xmlRoot = xmlRoot; + } + + public String getXmlSubRoot() { + return xmlSubRoot; + } + + public void setXmlSubRoot(String xmlSubRoot) { + this.xmlSubRoot = xmlSubRoot; + } + + public String getToolTip() { + return toolTip; + } + + public boolean isFillVertically() { + return fillVertically; + } + + public void setFillVertically(boolean fillVertically) { + this.fillVertically = fillVertically; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public Label getLabelWidget() { + return labelWidget; + } + + public void setLabelWidget(Label labelWidget) { + this.labelWidget = labelWidget; + } + + public boolean isRequiredEntry() { + return requiredEntry; + } + + public void setRequiredEntry(boolean requiredEntry) { + this.requiredEntry = requiredEntry; + } + + public int getReportType() { + return reportType; + } + + public void setReportType(int reportType) { + this.reportType = reportType; + } + + /** + * Return data for display in Report (without label) NOTE: There should be no newlines at end of String + */ + public abstract String getReportData(); + + @Override + public String toString() { + return toReport(); + } + + public String toReport() { + return toReport(reportType); + } + + /** + * RPT_NONE (label: data), RPT_SINGLE_LINE (label: data\n\n), RPT_MULTI_LINE (label:\n data\n\n) + */ + public String toReport(int rptType) { + String s = label + ": "; //$NON-NLS-1$ + switch (rptType) { + case RPT_SINGLE_LINE: + s += getReportData() + "\n\n"; //$NON-NLS-1$ + break; + case RPT_MULTI_LINE: + String data = getReportData(); + data = data.replaceAll("\n", "\n "); //$NON-NLS-1$ //$NON-NLS-2$ + s += "\n" + data + "\n\n"; //$NON-NLS-1$ //$NON-NLS-2$ + break; + default: + s += getReportData(); + break; + } + return s; + } + + /** + * If set, label will be displayed with entry widget. + */ + public void setDisplayLabel(boolean displayLabel) { + this.displayLabel = displayLabel; + } + + public void setFillHorizontally(boolean fillHorizontally) { + this.fillHorizontally = fillHorizontally; + } + + public abstract Object getData(); + + public boolean isDisplayLabel() { + return displayLabel; + } } \ No newline at end of file diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerWorkbenchJob.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerWorkbenchJob.java index 7307b23d1..0830dbb2a 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerWorkbenchJob.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/XViewerWorkbenchJob.java @@ -1,94 +1,94 @@ -package org.eclipse.nebula.widgets.xviewer.util.internal; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.JobChangeAdapter; -import org.eclipse.nebula.widgets.xviewer.util.XViewerDisplay; -import org.eclipse.swt.widgets.Display; - -/** - * WorkbenchJob is a type of job that implements a done listener and does the shutdown checks before scheduling. This is - * used if a job is not meant to run when the Workbench is shutdown. - * - * @since 3.0 - */ -public abstract class XViewerWorkbenchJob extends XViewerUIJob { - - /** - * Create a new instance of the receiver with the supplied display and name. Normally this constructor would not be - * used as it is best to let the job find the display from the workbench - * - * @param jobDisplay Display. The display to run the job with. - * @param name String - */ - public XViewerWorkbenchJob(Display jobDisplay, String name) { - super(jobDisplay, name); - addDefaultJobChangeListener(); - } - - /** - * Add a new instance of the reciever with the supplied name. - * - * @param name String - */ - public XViewerWorkbenchJob(String name) { - super(name); - addDefaultJobChangeListener(); - } - - /** - * Add a job change listeners that handles a done event if the result was IStatus.OK. - */ - private void addDefaultJobChangeListener() { - addJobChangeListener(new JobChangeAdapter() { - /** - * (non-Javadoc) - * @see org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse.core.runtime.jobs.IJobChangeEvent) - */ - @Override - public void done(IJobChangeEvent event) { - - //Abort if it is not running - if (!XViewerDisplay.isStandaloneXViewer() && !XViewerDisplay.isWorkbenchRunning()) { - return; - } - - if (event.getResult().getCode() == IStatus.OK) { - performDone(event); - } - } - }); - } - - /** - * Perform done with the supplied event. This will only occur if the returned status was OK. This is called only if - * the job is finished with an IStatus.OK result and the workbench is still running. - * - * @param event IJobChangeEvent - */ - public void performDone(IJobChangeEvent event) { - //Do nothing by default. - } - - - /** - * @see org.eclipse.core.runtime.jobs.Job#shouldSchedule() - */ - @Override - public boolean shouldSchedule() { - boolean result = - super.shouldSchedule() && (XViewerDisplay.isStandaloneXViewer() || XViewerDisplay.isWorkbenchRunning()); - return result; - } - - /** - * (non-Javadoc) - * @see org.eclipse.core.runtime.jobs.Job#shouldRun() - */ - @Override - public boolean shouldRun() { - boolean result = super.shouldRun() && (XViewerDisplay.isStandaloneXViewer() || XViewerDisplay.isWorkbenchRunning()); - return result; - } - -} +package org.eclipse.nebula.widgets.xviewer.util.internal; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.nebula.widgets.xviewer.util.XViewerDisplay; +import org.eclipse.swt.widgets.Display; + +/** + * WorkbenchJob is a type of job that implements a done listener and does the shutdown checks before scheduling. This is + * used if a job is not meant to run when the Workbench is shutdown. + * + * @since 3.0 + */ +public abstract class XViewerWorkbenchJob extends XViewerUIJob { + + /** + * Create a new instance of the receiver with the supplied display and name. Normally this constructor would not be + * used as it is best to let the job find the display from the workbench + * + * @param jobDisplay Display. The display to run the job with. + * @param name String + */ + public XViewerWorkbenchJob(Display jobDisplay, String name) { + super(jobDisplay, name); + addDefaultJobChangeListener(); + } + + /** + * Add a new instance of the reciever with the supplied name. + * + * @param name String + */ + public XViewerWorkbenchJob(String name) { + super(name); + addDefaultJobChangeListener(); + } + + /** + * Add a job change listeners that handles a done event if the result was IStatus.OK. + */ + private void addDefaultJobChangeListener() { + addJobChangeListener(new JobChangeAdapter() { + /** + * (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse.core.runtime.jobs.IJobChangeEvent) + */ + @Override + public void done(IJobChangeEvent event) { + + //Abort if it is not running + if (!XViewerDisplay.isStandaloneXViewer() && !XViewerDisplay.isWorkbenchRunning()) { + return; + } + + if (event.getResult().getCode() == IStatus.OK) { + performDone(event); + } + } + }); + } + + /** + * Perform done with the supplied event. This will only occur if the returned status was OK. This is called only if + * the job is finished with an IStatus.OK result and the workbench is still running. + * + * @param event IJobChangeEvent + */ + public void performDone(IJobChangeEvent event) { + //Do nothing by default. + } + + + /** + * @see org.eclipse.core.runtime.jobs.Job#shouldSchedule() + */ + @Override + public boolean shouldSchedule() { + boolean result = + super.shouldSchedule() && (XViewerDisplay.isStandaloneXViewer() || XViewerDisplay.isWorkbenchRunning()); + return result; + } + + /** + * (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#shouldRun() + */ + @Override + public boolean shouldRun() { + boolean result = super.shouldRun() && (XViewerDisplay.isStandaloneXViewer() || XViewerDisplay.isWorkbenchRunning()); + return result; + } + +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/ColumnFilterDialog.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/ColumnFilterDialog.java index debf3371a..1bd8591a0 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/ColumnFilterDialog.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/ColumnFilterDialog.java @@ -1,174 +1,174 @@ -/******************************************************************************* - * Copyright (c) 2015 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; - -import java.util.Calendar; -import java.util.Date; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.ComboViewer; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.nebula.widgets.xviewer.core.model.DateRangeType; -import org.eclipse.nebula.widgets.xviewer.core.model.SortDataType; -import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.DateTime; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * @author Donald G. Dunne - */ -public class ColumnFilterDialog extends DialogWithEntry { - - private final XViewerColumn column; - private ComboViewer dateRangeTypeCombo; - private DateTime date1Widget; - private Date date1, date2; - private DateRangeType dateRangeType = null; - private DateTime date2Widget; - private DateTime time1Widget; - private DateTime time2Widget; - private Composite widgetComp; - - public ColumnFilterDialog(Shell shell, String dialogTitle, String dialogMessage, int question, String[] strings, int i, XViewerColumn column) { - super(shell, dialogTitle, null, dialogMessage, MessageDialog.QUESTION, strings, 0); - this.column = column; - } - - @Override - protected void createExtendedArea(Composite parent) { - super.createExtendedArea(parent); - if (column.getSortDataType() == SortDataType.Date) { - - widgetComp = new Composite(parent, SWT.NONE); - widgetComp.setLayout(new GridLayout(6, false)); - GridData gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 2; - widgetComp.setLayoutData(gd); - - Label label = new Label(widgetComp, SWT.NONE); - label.setText("Date Match: "); - - dateRangeTypeCombo = new ComboViewer(widgetComp, SWT.NONE); - dateRangeTypeCombo.setContentProvider(new ArrayContentProvider()); - dateRangeTypeCombo.setLabelProvider(new LabelProvider() { - - @Override - public String getText(Object element) { - return ((DateRangeType) element).getDisplayName(); - } - - }); - dateRangeTypeCombo.setInput(DateRangeType.values()); - dateRangeTypeCombo.addSelectionChangedListener(event -> { - String text2 = dateRangeTypeCombo.getCombo().getText(); - dateRangeType = DateRangeType.get(text2); - updateDate2Composite(); - }); - - date1Widget = new DateTime(widgetComp, SWT.CALENDAR); - date1Widget.addListener(SWT.Selection, e-> setDate1Selection()); - - // set initial date - Calendar cal = Calendar.getInstance(); - cal.set(date1Widget.getYear(), date1Widget.getMonth(), date1Widget.getDay(), 0, 0); - date1 = cal.getTime(); - - time1Widget = new DateTime(widgetComp, SWT.TIME); - time1Widget.addListener(SWT.Selection, e-> setDate1Selection()); - time1Widget.setHours(0); - time1Widget.setMinutes(0); - time1Widget.setSeconds(0); - - } - } - - private boolean isBetweenDates() { - dateRangeType = DateRangeType.get(dateRangeTypeCombo.getCombo().getText()); - return dateRangeType == DateRangeType.Between_Dates; - } - - public void updateDate2Composite() { - if (isBetweenDates()) { - - date2Widget = new DateTime(widgetComp, SWT.CALENDAR); - date2Widget.addListener(SWT.Selection, e-> setDate2Selection()); - - time2Widget = new DateTime(widgetComp, SWT.TIME); - time2Widget.addListener(SWT.Selection, e-> setDate2Selection()); - time2Widget.setHours(0); - time2Widget.setMinutes(0); - time2Widget.setSeconds(0); - } else { - if (date2Widget != null) { - date2Widget.dispose(); - date2Widget = null; - time2Widget.dispose(); - time2Widget = null; - } - } - widgetComp.layout(true, true); - final Point newSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); - getShell().setSize(newSize); - } - - private void setDate1Selection() { - Calendar cal = Calendar.getInstance(); - cal.set(date1Widget.getYear(), date1Widget.getMonth(), date1Widget.getDay(), time1Widget.getHours(), - time1Widget.getMinutes()); - date1 = cal.getTime(); - } - - private void setDate2Selection() { - if (date2Widget.isEnabled()) { - Calendar cal = Calendar.getInstance(); - cal.set(date2Widget.getYear(), date2Widget.getMonth(), date2Widget.getDay(), date2Widget.getHours(), - date2Widget.getMinutes()); - date2 = cal.getTime(); - } else { - date2 = null; - } - } - - public Date getDate1() { - return date1; - } - - public void setDate1(Date date1) { - this.date1 = date1; - } - - public Date getDate2() { - return date2; - } - - public void setDate2(Date date2) { - this.date2 = date2; - } - - public DateRangeType getDateRangeType() { - return dateRangeType; - } - - public void setDateRangeType(DateRangeType dateRangeType) { - this.dateRangeType = dateRangeType; - } - -} +/******************************************************************************* + * Copyright (c) 2015 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; + +import java.util.Calendar; +import java.util.Date; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.nebula.widgets.xviewer.core.model.DateRangeType; +import org.eclipse.nebula.widgets.xviewer.core.model.SortDataType; +import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.DateTime; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * @author Donald G. Dunne + */ +public class ColumnFilterDialog extends DialogWithEntry { + + private final XViewerColumn column; + private ComboViewer dateRangeTypeCombo; + private DateTime date1Widget; + private Date date1, date2; + private DateRangeType dateRangeType = null; + private DateTime date2Widget; + private DateTime time1Widget; + private DateTime time2Widget; + private Composite widgetComp; + + public ColumnFilterDialog(Shell shell, String dialogTitle, String dialogMessage, int question, String[] strings, int i, XViewerColumn column) { + super(shell, dialogTitle, null, dialogMessage, MessageDialog.QUESTION, strings, 0); + this.column = column; + } + + @Override + protected void createExtendedArea(Composite parent) { + super.createExtendedArea(parent); + if (column.getSortDataType() == SortDataType.Date) { + + widgetComp = new Composite(parent, SWT.NONE); + widgetComp.setLayout(new GridLayout(6, false)); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + widgetComp.setLayoutData(gd); + + Label label = new Label(widgetComp, SWT.NONE); + label.setText("Date Match: "); + + dateRangeTypeCombo = new ComboViewer(widgetComp, SWT.NONE); + dateRangeTypeCombo.setContentProvider(new ArrayContentProvider()); + dateRangeTypeCombo.setLabelProvider(new LabelProvider() { + + @Override + public String getText(Object element) { + return ((DateRangeType) element).getDisplayName(); + } + + }); + dateRangeTypeCombo.setInput(DateRangeType.values()); + dateRangeTypeCombo.addSelectionChangedListener(event -> { + String text2 = dateRangeTypeCombo.getCombo().getText(); + dateRangeType = DateRangeType.get(text2); + updateDate2Composite(); + }); + + date1Widget = new DateTime(widgetComp, SWT.CALENDAR); + date1Widget.addListener(SWT.Selection, e-> setDate1Selection()); + + // set initial date + Calendar cal = Calendar.getInstance(); + cal.set(date1Widget.getYear(), date1Widget.getMonth(), date1Widget.getDay(), 0, 0); + date1 = cal.getTime(); + + time1Widget = new DateTime(widgetComp, SWT.TIME); + time1Widget.addListener(SWT.Selection, e-> setDate1Selection()); + time1Widget.setHours(0); + time1Widget.setMinutes(0); + time1Widget.setSeconds(0); + + } + } + + private boolean isBetweenDates() { + dateRangeType = DateRangeType.get(dateRangeTypeCombo.getCombo().getText()); + return dateRangeType == DateRangeType.Between_Dates; + } + + public void updateDate2Composite() { + if (isBetweenDates()) { + + date2Widget = new DateTime(widgetComp, SWT.CALENDAR); + date2Widget.addListener(SWT.Selection, e-> setDate2Selection()); + + time2Widget = new DateTime(widgetComp, SWT.TIME); + time2Widget.addListener(SWT.Selection, e-> setDate2Selection()); + time2Widget.setHours(0); + time2Widget.setMinutes(0); + time2Widget.setSeconds(0); + } else { + if (date2Widget != null) { + date2Widget.dispose(); + date2Widget = null; + time2Widget.dispose(); + time2Widget = null; + } + } + widgetComp.layout(true, true); + final Point newSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + getShell().setSize(newSize); + } + + private void setDate1Selection() { + Calendar cal = Calendar.getInstance(); + cal.set(date1Widget.getYear(), date1Widget.getMonth(), date1Widget.getDay(), time1Widget.getHours(), + time1Widget.getMinutes()); + date1 = cal.getTime(); + } + + private void setDate2Selection() { + if (date2Widget.isEnabled()) { + Calendar cal = Calendar.getInstance(); + cal.set(date2Widget.getYear(), date2Widget.getMonth(), date2Widget.getDay(), date2Widget.getHours(), + date2Widget.getMinutes()); + date2 = cal.getTime(); + } else { + date2 = null; + } + } + + public Date getDate1() { + return date1; + } + + public void setDate1(Date date1) { + this.date1 = date1; + } + + public Date getDate2() { + return date2; + } + + public void setDate2(Date date2) { + this.date2 = date2; + } + + public DateRangeType getDateRangeType() { + return dateRangeType; + } + + public void setDateRangeType(DateRangeType dateRangeType) { + this.dateRangeType = dateRangeType; + } + +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/DateSelectionDialog.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/DateSelectionDialog.java index 2c93a324b..26f041094 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/DateSelectionDialog.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/DateSelectionDialog.java @@ -1,107 +1,107 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; - -import java.util.Calendar; -import java.util.Date; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.nebula.widgets.xviewer.XViewerText; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.DateTime; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -public class DateSelectionDialog extends MessageDialog { - - private Date initialDate, selectedDate; - - private final String dialogMessage; - - public DateSelectionDialog(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage, int dialogImageType, String[] dialogButtonLabels, int defaultIndex, Date selectedDate) { - super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, dialogButtonLabels, - defaultIndex); - this.initialDate = selectedDate; - this.dialogMessage = dialogMessage; - } - - public DateSelectionDialog(String dialogTitle, String dialogMessage, Date selectedDate) { - this(Display.getCurrent().getActiveShell(), dialogTitle, null, dialogMessage, MessageDialog.NONE, new String[] { - XViewerText.get("button.ok"), XViewerText.get("button.cancel")}, 0, selectedDate); //$NON-NLS-1$ //$NON-NLS-2$ - } - - @Override - protected Control createDialogArea(Composite container) { - - Composite filterComp = new Composite(container, SWT.NONE); - - filterComp.setLayout(new GridLayout(1, false)); - filterComp.setLayoutData(new GridData(GridData.FILL_BOTH)); - - new Label(filterComp, SWT.None).setText(dialogMessage); - - final DateTime dp = new DateTime(filterComp, SWT.CALENDAR); - dp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - if (initialDate != null) { - Calendar cal = Calendar.getInstance(); - cal.setTime(initialDate); - - dp.setYear(cal.get(Calendar.YEAR)); - dp.setMonth(cal.get(Calendar.MONTH)); - dp.setDay(cal.get(Calendar.DAY_OF_YEAR)); - } - dp.addListener(SWT.Selection, e-> { - Calendar cal = Calendar.getInstance(); - cal.set(dp.getYear(), dp.getMonth(), dp.getDay()); - selectedDate = cal.getTime(); - }); - - Button clearButton = new Button(filterComp, SWT.PUSH); - clearButton.setText(XViewerText.get("button.clear")); //$NON-NLS-1$ - clearButton.addListener(SWT.Selection, e-> selectedDate = null); - - // set selected date if != null - return filterComp; - } - - /** - * @return the selectedDate - */ - public Date getSelectedDate() { - return selectedDate; - } - - /** - * @param selectedDate the selectedDate to set - */ - public void setSelectedDate(Date initialDate) { - this.initialDate = initialDate; - } - - /** - * @return the noneSelected - */ - public boolean isNoneSelected() { - return selectedDate == null; - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; + +import java.util.Calendar; +import java.util.Date; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.nebula.widgets.xviewer.XViewerText; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.DateTime; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +public class DateSelectionDialog extends MessageDialog { + + private Date initialDate, selectedDate; + + private final String dialogMessage; + + public DateSelectionDialog(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage, int dialogImageType, String[] dialogButtonLabels, int defaultIndex, Date selectedDate) { + super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, dialogButtonLabels, + defaultIndex); + this.initialDate = selectedDate; + this.dialogMessage = dialogMessage; + } + + public DateSelectionDialog(String dialogTitle, String dialogMessage, Date selectedDate) { + this(Display.getCurrent().getActiveShell(), dialogTitle, null, dialogMessage, MessageDialog.NONE, new String[] { + XViewerText.get("button.ok"), XViewerText.get("button.cancel")}, 0, selectedDate); //$NON-NLS-1$ //$NON-NLS-2$ + } + + @Override + protected Control createDialogArea(Composite container) { + + Composite filterComp = new Composite(container, SWT.NONE); + + filterComp.setLayout(new GridLayout(1, false)); + filterComp.setLayoutData(new GridData(GridData.FILL_BOTH)); + + new Label(filterComp, SWT.None).setText(dialogMessage); + + final DateTime dp = new DateTime(filterComp, SWT.CALENDAR); + dp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + if (initialDate != null) { + Calendar cal = Calendar.getInstance(); + cal.setTime(initialDate); + + dp.setYear(cal.get(Calendar.YEAR)); + dp.setMonth(cal.get(Calendar.MONTH)); + dp.setDay(cal.get(Calendar.DAY_OF_YEAR)); + } + dp.addListener(SWT.Selection, e-> { + Calendar cal = Calendar.getInstance(); + cal.set(dp.getYear(), dp.getMonth(), dp.getDay()); + selectedDate = cal.getTime(); + }); + + Button clearButton = new Button(filterComp, SWT.PUSH); + clearButton.setText(XViewerText.get("button.clear")); //$NON-NLS-1$ + clearButton.addListener(SWT.Selection, e-> selectedDate = null); + + // set selected date if != null + return filterComp; + } + + /** + * @return the selectedDate + */ + public Date getSelectedDate() { + return selectedDate; + } + + /** + * @param selectedDate the selectedDate to set + */ + public void setSelectedDate(Date initialDate) { + this.initialDate = initialDate; + } + + /** + * @return the noneSelected + */ + public boolean isNoneSelected() { + return selectedDate == null; + } + +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/DialogWithEntry.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/DialogWithEntry.java index f44ed85ae..5b28dc191 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/DialogWithEntry.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/DialogWithEntry.java @@ -1,247 +1,247 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.nebula.widgets.xviewer.XViewerText; -import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerTextWidget; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * @author Donald G. Dunne - */ -public class DialogWithEntry extends MessageDialog { - - XViewerTextWidget text; - Composite comp; - String entryText = ""; //$NON-NLS-1$ - String validationRegularExpression = null; - String validationErrorString = ""; //$NON-NLS-1$ - Button ok; - MouseMoveListener listener; - Label errorLabel; - boolean fillVertically = false; - private static Font font = null; - private Button fontButton; - - public DialogWithEntry(String dialogTitle, String dialogMessage) { - super(Display.getCurrent().getActiveShell(), dialogTitle, null, dialogMessage, MessageDialog.QUESTION, - new String[] {XViewerText.get("button.ok"), XViewerText.get("button.cancel")}, 0); //$NON-NLS-1$ //$NON-NLS-2$ - } - - public DialogWithEntry(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage, int dialogImageType, String[] dialogButtonLabels, int defaultIndex) { - super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, dialogButtonLabels, - defaultIndex); - } - - @Override - protected Control createCustomArea(Composite parent) { - - comp = new Composite(parent, SWT.NONE); - comp.setLayout(new GridLayout(2, false)); - comp.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); - - listener = new MouseMoveListener() { - - @Override - public void mouseMove(MouseEvent e) { - setInitialButtonState(); - } - }; - comp.addMouseMoveListener(listener); - - Composite headerComp = new Composite(comp, SWT.NONE); - headerComp.setLayout(new GridLayout(3, false)); - GridData gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 2; - headerComp.setLayoutData(gd); - - if (fillVertically) { // Create error label - Button button = new Button(headerComp, SWT.PUSH); - button.setText(XViewerText.get("button.clear")); //$NON-NLS-1$ - button.addListener(SWT.Selection, e-> text.setText("")); - // Create error label - fontButton = new Button(headerComp, SWT.CHECK); - fontButton.setText(XViewerText.get("DialogWithEntry.button.font")); //$NON-NLS-1$ - fontButton.addListener(SWT.Selection, e-> { - if (fontButton.getSelection()) { - if (font == null) { - font = new Font(Display.getCurrent(), "Courier New", 8, SWT.NORMAL); //$NON-NLS-1$ - } - text.setFont(font); - } else { - text.setFont(null); - } - }); - } - - // Create error label - errorLabel = new Label(headerComp, SWT.NONE); - errorLabel.setSize(errorLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - errorLabel.setText(""); //$NON-NLS-1$ - if (!fillVertically) { - gd = new GridData(); - gd.horizontalSpan = 3; - errorLabel.setLayoutData(gd); - } - - createExtendedAreaPre(comp); - - text = new XViewerTextWidget(); - text.setFillHorizontally(true); - text.setFocus(); - text.setDisplayLabel(false); - if (fillVertically) { - text.setFillVertically(true); - text.setHeight(200); - text.setFont(font); - } - text.createWidgets(comp, 2); - if (!entryText.equals("")) { //$NON-NLS-1$ - text.set(entryText); - } - - ModifyListener modifyListener = new ModifyListener() { - - @Override - public void modifyText(ModifyEvent e) { - handleModified(); - } - }; - text.addModifyListener(modifyListener); - createExtendedArea(comp); - comp.layout(); - parent.layout(); - return comp; - } - - /** - * Override to provide other widgets before entry - */ - protected void createExtendedAreaPre(Composite parent) { - // provided for subclass implementation - } - - @Override - protected boolean isResizable() { - return true; - } - - /** - * Override to provide other widgets - */ - protected void createExtendedArea(Composite parent) { - // provided for subclass implementation - } - - public void setInitialButtonState() { - if (ok == null) { - ok = getButton(0); - handleModified(); - } - comp.removeMouseMoveListener(listener); - } - - public void handleModified() { - if (text != null) { - entryText = text.get(); - if (!isEntryValid()) { - getButton(getDefaultButtonIndex()).setEnabled(false); - errorLabel.setText(validationErrorString); - errorLabel.update(); - comp.layout(); - } else { - getButton(getDefaultButtonIndex()).setEnabled(true); - errorLabel.setText(""); //$NON-NLS-1$ - errorLabel.update(); - comp.layout(); - } - } - } - - public String getEntry() { - return entryText; - } - - public void setEntry(String entry) { - if (text != null) { - text.set(entry); - } - this.entryText = entry; - } - - /** - * override this method to make own checks on entry this will be called with every keystroke - * - * @return true if entry is valid - */ - public boolean isEntryValid() { - if (validationRegularExpression == null) { - return true; - } - // verify title is alpha-numeric with spaces and dashes - Matcher m = Pattern.compile(validationRegularExpression).matcher(text.get()); - return m.find(); - } - - public void setValidationRegularExpression(String regExp) { - validationRegularExpression = regExp; - } - - public void setValidationErrorString(String errorText) { - validationErrorString = errorText; - } - - /** - * Calling will enable dialog to loose focus - */ - public void setModeless() { - setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS); - setBlockOnOpen(false); - } - - public void setSelectionListener(SelectionListener listener) { - for (int i = 0; i < getButtonLabels().length; i++) { - Button button = getButton(i); - button.addSelectionListener(listener); - } - } - - public boolean isFillVertically() { - return fillVertically; - } - - public void setFillVertically(boolean fillVertically) { - this.fillVertically = fillVertically; - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.nebula.widgets.xviewer.XViewerText; +import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerTextWidget; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * @author Donald G. Dunne + */ +public class DialogWithEntry extends MessageDialog { + + XViewerTextWidget text; + Composite comp; + String entryText = ""; //$NON-NLS-1$ + String validationRegularExpression = null; + String validationErrorString = ""; //$NON-NLS-1$ + Button ok; + MouseMoveListener listener; + Label errorLabel; + boolean fillVertically = false; + private static Font font = null; + private Button fontButton; + + public DialogWithEntry(String dialogTitle, String dialogMessage) { + super(Display.getCurrent().getActiveShell(), dialogTitle, null, dialogMessage, MessageDialog.QUESTION, + new String[] {XViewerText.get("button.ok"), XViewerText.get("button.cancel")}, 0); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public DialogWithEntry(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage, int dialogImageType, String[] dialogButtonLabels, int defaultIndex) { + super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, dialogButtonLabels, + defaultIndex); + } + + @Override + protected Control createCustomArea(Composite parent) { + + comp = new Composite(parent, SWT.NONE); + comp.setLayout(new GridLayout(2, false)); + comp.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); + + listener = new MouseMoveListener() { + + @Override + public void mouseMove(MouseEvent e) { + setInitialButtonState(); + } + }; + comp.addMouseMoveListener(listener); + + Composite headerComp = new Composite(comp, SWT.NONE); + headerComp.setLayout(new GridLayout(3, false)); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + headerComp.setLayoutData(gd); + + if (fillVertically) { // Create error label + Button button = new Button(headerComp, SWT.PUSH); + button.setText(XViewerText.get("button.clear")); //$NON-NLS-1$ + button.addListener(SWT.Selection, e-> text.setText("")); + // Create error label + fontButton = new Button(headerComp, SWT.CHECK); + fontButton.setText(XViewerText.get("DialogWithEntry.button.font")); //$NON-NLS-1$ + fontButton.addListener(SWT.Selection, e-> { + if (fontButton.getSelection()) { + if (font == null) { + font = new Font(Display.getCurrent(), "Courier New", 8, SWT.NORMAL); //$NON-NLS-1$ + } + text.setFont(font); + } else { + text.setFont(null); + } + }); + } + + // Create error label + errorLabel = new Label(headerComp, SWT.NONE); + errorLabel.setSize(errorLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + errorLabel.setText(""); //$NON-NLS-1$ + if (!fillVertically) { + gd = new GridData(); + gd.horizontalSpan = 3; + errorLabel.setLayoutData(gd); + } + + createExtendedAreaPre(comp); + + text = new XViewerTextWidget(); + text.setFillHorizontally(true); + text.setFocus(); + text.setDisplayLabel(false); + if (fillVertically) { + text.setFillVertically(true); + text.setHeight(200); + text.setFont(font); + } + text.createWidgets(comp, 2); + if (!entryText.equals("")) { //$NON-NLS-1$ + text.set(entryText); + } + + ModifyListener modifyListener = new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + handleModified(); + } + }; + text.addModifyListener(modifyListener); + createExtendedArea(comp); + comp.layout(); + parent.layout(); + return comp; + } + + /** + * Override to provide other widgets before entry + */ + protected void createExtendedAreaPre(Composite parent) { + // provided for subclass implementation + } + + @Override + protected boolean isResizable() { + return true; + } + + /** + * Override to provide other widgets + */ + protected void createExtendedArea(Composite parent) { + // provided for subclass implementation + } + + public void setInitialButtonState() { + if (ok == null) { + ok = getButton(0); + handleModified(); + } + comp.removeMouseMoveListener(listener); + } + + public void handleModified() { + if (text != null) { + entryText = text.get(); + if (!isEntryValid()) { + getButton(getDefaultButtonIndex()).setEnabled(false); + errorLabel.setText(validationErrorString); + errorLabel.update(); + comp.layout(); + } else { + getButton(getDefaultButtonIndex()).setEnabled(true); + errorLabel.setText(""); //$NON-NLS-1$ + errorLabel.update(); + comp.layout(); + } + } + } + + public String getEntry() { + return entryText; + } + + public void setEntry(String entry) { + if (text != null) { + text.set(entry); + } + this.entryText = entry; + } + + /** + * override this method to make own checks on entry this will be called with every keystroke + * + * @return true if entry is valid + */ + public boolean isEntryValid() { + if (validationRegularExpression == null) { + return true; + } + // verify title is alpha-numeric with spaces and dashes + Matcher m = Pattern.compile(validationRegularExpression).matcher(text.get()); + return m.find(); + } + + public void setValidationRegularExpression(String regExp) { + validationRegularExpression = regExp; + } + + public void setValidationErrorString(String errorText) { + validationErrorString = errorText; + } + + /** + * Calling will enable dialog to loose focus + */ + public void setModeless() { + setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS); + setBlockOnOpen(false); + } + + public void setSelectionListener(SelectionListener listener) { + for (int i = 0; i < getButtonLabels().length; i++) { + Button button = getButton(i); + button.addSelectionListener(listener); + } + } + + public boolean isFillVertically() { + return fillVertically; + } + + public void setFillVertically(boolean fillVertically) { + this.fillVertically = fillVertically; + } + +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/HtmlDialog.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/HtmlDialog.java index fd2895e29..390e97aa8 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/HtmlDialog.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/HtmlDialog.java @@ -1,94 +1,94 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ - -package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; - -import java.io.File; -import java.io.IOException; -import java.util.logging.Level; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.nebula.widgets.xviewer.Activator; -import org.eclipse.nebula.widgets.xviewer.XViewerText; -import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerLib; -import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerLog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.browser.LocationListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; - -/** - * @author Donald G. Dunne - */ -public class HtmlDialog extends MessageDialog { - protected Browser b; - private LocationListener listener; - private final String html; - - public HtmlDialog(String title, String message, String html) { - super(Display.getCurrent().getActiveShell(), title, null, message, SWT.NONE, new String[] {XViewerText.get("button.ok"), XViewerText.get("button.cancel")}, 0); //$NON-NLS-1$ //$NON-NLS-2$ - this.html = html; - } - - /** - * Add listener to browser widget. - */ - public void addLocationListener(LocationListener listener) { - this.listener = listener; - } - - @Override - protected boolean isResizable() { - return true; - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite c = (Composite) super.createDialogArea(parent); - b = new Browser(c, SWT.BORDER); - GridData gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL); - b.setLayoutData(gd); - b.setText(html); - b.setSize(500, 500); - if (listener != null) { - b.addLocationListener(listener); - } - b.setMenu(pageOverviewGetPopup()); - - return c; - } - - public Menu pageOverviewGetPopup() { - Menu menu = new Menu(b.getShell()); - MenuItem item = new MenuItem(menu, SWT.NONE); - item.setText(XViewerText.get("HtmlDialog.menu.view_source")); //$NON-NLS-1$ - item.addListener(SWT.Selection, e-> { - String file = System.getProperty("user.home") + File.separator + "out.html"; //$NON-NLS-1$ //$NON-NLS-2$ - try { - XViewerLib.writeStringToFile(html, new File(file)); - } catch (IOException ex) { - XViewerLog.logAndPopup(Activator.class, Level.SEVERE, ex); - } - Program.launch(file); - }); - return menu; - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ + +package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.nebula.widgets.xviewer.Activator; +import org.eclipse.nebula.widgets.xviewer.XViewerText; +import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerLib; +import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerLog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.browser.LocationListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; + +/** + * @author Donald G. Dunne + */ +public class HtmlDialog extends MessageDialog { + protected Browser b; + private LocationListener listener; + private final String html; + + public HtmlDialog(String title, String message, String html) { + super(Display.getCurrent().getActiveShell(), title, null, message, SWT.NONE, new String[] {XViewerText.get("button.ok"), XViewerText.get("button.cancel")}, 0); //$NON-NLS-1$ //$NON-NLS-2$ + this.html = html; + } + + /** + * Add listener to browser widget. + */ + public void addLocationListener(LocationListener listener) { + this.listener = listener; + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite c = (Composite) super.createDialogArea(parent); + b = new Browser(c, SWT.BORDER); + GridData gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL); + b.setLayoutData(gd); + b.setText(html); + b.setSize(500, 500); + if (listener != null) { + b.addLocationListener(listener); + } + b.setMenu(pageOverviewGetPopup()); + + return c; + } + + public Menu pageOverviewGetPopup() { + Menu menu = new Menu(b.getShell()); + MenuItem item = new MenuItem(menu, SWT.NONE); + item.setText(XViewerText.get("HtmlDialog.menu.view_source")); //$NON-NLS-1$ + item.addListener(SWT.Selection, e-> { + String file = System.getProperty("user.home") + File.separator + "out.html"; //$NON-NLS-1$ //$NON-NLS-2$ + try { + XViewerLib.writeStringToFile(html, new File(file)); + } catch (IOException ex) { + XViewerLog.logAndPopup(Activator.class, Level.SEVERE, ex); + } + Program.launch(file); + }); + return menu; + } + +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XCheckFilteredTreeDialog.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XCheckFilteredTreeDialog.java index d0fd3e314..7a29f7cf0 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XCheckFilteredTreeDialog.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XCheckFilteredTreeDialog.java @@ -1,162 +1,162 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; - -import java.util.Collection; -import java.util.Collections; -import java.util.Set; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.jface.viewers.IContentProvider; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.nebula.widgets.xviewer.XViewerText; -import org.eclipse.nebula.widgets.xviewer.util.internal.PatternFilter; -import org.eclipse.nebula.widgets.xviewer.util.internal.Result; -import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerLib; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; - -public class XCheckFilteredTreeDialog extends MessageDialog { - - protected Label statusLabel; - private Button okButton; - private XCheckedFilteredTree treeViewer; - private final PatternFilter patternFilter; - private Object input; - private final IContentProvider contentProvider; - private final IBaseLabelProvider labelProvider; - private Collection initialSelections; - private final ViewerSorter viewerSorter; - - public XCheckFilteredTreeDialog(String dialogTitle, String dialogMessage, PatternFilter patternFilter, IContentProvider contentProvider, IBaseLabelProvider labelProvider, ViewerSorter viewerSorter) { - super(Display.getCurrent().getActiveShell(), dialogTitle, null, dialogMessage, MessageDialog.NONE, new String[] { - XViewerText.get("button.ok"), XViewerText.get("button.cancel")}, 0); //$NON-NLS-1$ //$NON-NLS-2$ - this.contentProvider = contentProvider; - this.labelProvider = labelProvider; - this.patternFilter = patternFilter; - this.viewerSorter = viewerSorter; - setShellStyle(getShellStyle() | SWT.RESIZE); - } - - protected void createPreCustomArea(Composite parent) { - // provided for subclass implementation - } - - public Set getChecked() { - if (getTreeViewer() == null) { - return Collections.emptySet(); - } - return getTreeViewer().getChecked(); - } - - /** - * Sets the input. Convenience method. - */ - public final void setInput(Object input) { - this.input = input; - if (treeViewer != null) { - treeViewer.getViewer().setInput(input); - } - } - - /** - * Sets the initial selection. Convenience method. - */ - public void setInitialSelections(Collection initialSelections) { - this.initialSelections = initialSelections; - if (treeViewer != null) { - treeViewer.setInitalChecked(initialSelections); - } - } - - public Object[] getResult() { - if (treeViewer == null) { - return new Object[] {}; - } - return treeViewer.getResult(); - } - - @Override - protected Control createCustomArea(Composite parent) { - - statusLabel = new Label(parent, SWT.NONE); - statusLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED)); - updateStatusLabel(); - - createPreCustomArea(parent); - - Composite aiComp = new Composite(parent, SWT.NONE); - aiComp.setLayout(XViewerLib.getZeroMarginLayout()); - aiComp.setLayoutData(new GridData(GridData.FILL_BOTH)); - - treeViewer = - new XCheckedFilteredTree(aiComp, - SWT.MULTI | SWT.CHECK | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, patternFilter); - treeViewer.getViewer().getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - treeViewer.getViewer().setContentProvider(contentProvider); - treeViewer.getViewer().setLabelProvider(labelProvider); - treeViewer.getViewer().setSorter(viewerSorter); - GridData gd = new GridData(GridData.FILL_BOTH); - gd.heightHint = 400; - treeViewer.getViewer().getTree().setLayoutData(gd); - treeViewer.getViewer().addSelectionChangedListener(event -> updateStatusLabel()); - if (input != null) { - treeViewer.getViewer().setInput(input); - } - if (initialSelections != null) { - treeViewer.setInitalChecked(initialSelections); - } - return parent; - } - - protected void updateStatusLabel() { - Result result = isComplete(); - if (result.isFalse()) { - statusLabel.setText(result.getText()); - } else { - statusLabel.setText(""); //$NON-NLS-1$ - } - statusLabel.getParent().layout(); - updateButtons(); - } - - @Override - protected Control createButtonBar(Composite parent) { - Control c = super.createButtonBar(parent); - okButton = getButton(0); - okButton.setEnabled(false); - return c; - } - - protected Result isComplete() { - return Result.TrueResult; - } - - private void updateButtons() { - if (okButton != null) { - okButton.setEnabled(isComplete().isTrue()); - } - } - - public XCheckedFilteredTree getTreeViewer() { - return treeViewer; - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.nebula.widgets.xviewer.XViewerText; +import org.eclipse.nebula.widgets.xviewer.util.internal.PatternFilter; +import org.eclipse.nebula.widgets.xviewer.util.internal.Result; +import org.eclipse.nebula.widgets.xviewer.util.internal.XViewerLib; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; + +public class XCheckFilteredTreeDialog extends MessageDialog { + + protected Label statusLabel; + private Button okButton; + private XCheckedFilteredTree treeViewer; + private final PatternFilter patternFilter; + private Object input; + private final IContentProvider contentProvider; + private final IBaseLabelProvider labelProvider; + private Collection initialSelections; + private final ViewerSorter viewerSorter; + + public XCheckFilteredTreeDialog(String dialogTitle, String dialogMessage, PatternFilter patternFilter, IContentProvider contentProvider, IBaseLabelProvider labelProvider, ViewerSorter viewerSorter) { + super(Display.getCurrent().getActiveShell(), dialogTitle, null, dialogMessage, MessageDialog.NONE, new String[] { + XViewerText.get("button.ok"), XViewerText.get("button.cancel")}, 0); //$NON-NLS-1$ //$NON-NLS-2$ + this.contentProvider = contentProvider; + this.labelProvider = labelProvider; + this.patternFilter = patternFilter; + this.viewerSorter = viewerSorter; + setShellStyle(getShellStyle() | SWT.RESIZE); + } + + protected void createPreCustomArea(Composite parent) { + // provided for subclass implementation + } + + public Set getChecked() { + if (getTreeViewer() == null) { + return Collections.emptySet(); + } + return getTreeViewer().getChecked(); + } + + /** + * Sets the input. Convenience method. + */ + public final void setInput(Object input) { + this.input = input; + if (treeViewer != null) { + treeViewer.getViewer().setInput(input); + } + } + + /** + * Sets the initial selection. Convenience method. + */ + public void setInitialSelections(Collection initialSelections) { + this.initialSelections = initialSelections; + if (treeViewer != null) { + treeViewer.setInitalChecked(initialSelections); + } + } + + public Object[] getResult() { + if (treeViewer == null) { + return new Object[] {}; + } + return treeViewer.getResult(); + } + + @Override + protected Control createCustomArea(Composite parent) { + + statusLabel = new Label(parent, SWT.NONE); + statusLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED)); + updateStatusLabel(); + + createPreCustomArea(parent); + + Composite aiComp = new Composite(parent, SWT.NONE); + aiComp.setLayout(XViewerLib.getZeroMarginLayout()); + aiComp.setLayoutData(new GridData(GridData.FILL_BOTH)); + + treeViewer = + new XCheckedFilteredTree(aiComp, + SWT.MULTI | SWT.CHECK | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, patternFilter); + treeViewer.getViewer().getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + treeViewer.getViewer().setContentProvider(contentProvider); + treeViewer.getViewer().setLabelProvider(labelProvider); + treeViewer.getViewer().setSorter(viewerSorter); + GridData gd = new GridData(GridData.FILL_BOTH); + gd.heightHint = 400; + treeViewer.getViewer().getTree().setLayoutData(gd); + treeViewer.getViewer().addSelectionChangedListener(event -> updateStatusLabel()); + if (input != null) { + treeViewer.getViewer().setInput(input); + } + if (initialSelections != null) { + treeViewer.setInitalChecked(initialSelections); + } + return parent; + } + + protected void updateStatusLabel() { + Result result = isComplete(); + if (result.isFalse()) { + statusLabel.setText(result.getText()); + } else { + statusLabel.setText(""); //$NON-NLS-1$ + } + statusLabel.getParent().layout(); + updateButtons(); + } + + @Override + protected Control createButtonBar(Composite parent) { + Control c = super.createButtonBar(parent); + okButton = getButton(0); + okButton.setEnabled(false); + return c; + } + + protected Result isComplete() { + return Result.TrueResult; + } + + private void updateButtons() { + if (okButton != null) { + okButton.setEnabled(isComplete().isTrue()); + } + } + + public XCheckedFilteredTree getTreeViewer() { + return treeViewer; + } + +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XCheckedFilteredTree.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XCheckedFilteredTree.java index b81cfe37b..864e045f4 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XCheckedFilteredTree.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XCheckedFilteredTree.java @@ -1,92 +1,92 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.nebula.widgets.xviewer.util.internal.PatternFilter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.TreeItem; - -/** - * @author Donald G. Dunne - */ -public class XCheckedFilteredTree extends XFilteredTree { - - private final Set checked = new HashSet<>(); - - public XCheckedFilteredTree(Composite parent, int treeStyle, PatternFilter filter) { - super(parent, treeStyle, filter, true); - setInitialText(""); //$NON-NLS-1$ - } - - @Override - protected Control createTreeControl(Composite parent, int style) { - Control control = super.createTreeControl(parent, style); - getViewer().addSelectionChangedListener(even -> storeResults(treeViewer.getTree().getItems())); - - getFilterControl().addListener(SWT.Modify, e -> restoreChecked(treeViewer.getTree().getItems())); - - getViewer().getTree().addListener(SWT.Paint, e-> restoreChecked(treeViewer.getTree().getItems())); - return control; - } - - public void setInitalChecked(Collection checked) { - this.checked.addAll(checked); - restoreChecked(treeViewer.getTree().getItems()); - for (Object obj : checked) { - treeViewer.reveal(obj); - } - } - - public void clearChecked() { - this.checked.clear(); - restoreChecked(treeViewer.getTree().getItems()); - } - - private void restoreChecked(TreeItem treeItems[]) { - for (TreeItem treeItem : treeItems) { - if (treeItem.getChecked() && !checked.contains(treeItem.getData())) { - treeItem.setChecked(false); - } else if (!treeItem.getChecked() && checked.contains(treeItem.getData())) { - treeItem.setChecked(true); - } - restoreChecked(treeItem.getItems()); - } - } - - public Object[] getResult() { - return getChecked().toArray(new Object[getChecked().size()]); - } - - private void storeResults(TreeItem treeItems[]) { - for (TreeItem treeItem : treeItems) { - if (treeItem.getChecked() && !checked.contains(treeItem.getData())) { - checked.add(treeItem.getData()); - } else if (!treeItem.getChecked() && checked.contains(treeItem.getData())) { - checked.remove(treeItem.getData()); - } - storeResults(treeItem.getItems()); - } - } - - public Set getChecked() { - return checked; - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.nebula.widgets.xviewer.util.internal.PatternFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.TreeItem; + +/** + * @author Donald G. Dunne + */ +public class XCheckedFilteredTree extends XFilteredTree { + + private final Set checked = new HashSet<>(); + + public XCheckedFilteredTree(Composite parent, int treeStyle, PatternFilter filter) { + super(parent, treeStyle, filter, true); + setInitialText(""); //$NON-NLS-1$ + } + + @Override + protected Control createTreeControl(Composite parent, int style) { + Control control = super.createTreeControl(parent, style); + getViewer().addSelectionChangedListener(even -> storeResults(treeViewer.getTree().getItems())); + + getFilterControl().addListener(SWT.Modify, e -> restoreChecked(treeViewer.getTree().getItems())); + + getViewer().getTree().addListener(SWT.Paint, e-> restoreChecked(treeViewer.getTree().getItems())); + return control; + } + + public void setInitalChecked(Collection checked) { + this.checked.addAll(checked); + restoreChecked(treeViewer.getTree().getItems()); + for (Object obj : checked) { + treeViewer.reveal(obj); + } + } + + public void clearChecked() { + this.checked.clear(); + restoreChecked(treeViewer.getTree().getItems()); + } + + private void restoreChecked(TreeItem treeItems[]) { + for (TreeItem treeItem : treeItems) { + if (treeItem.getChecked() && !checked.contains(treeItem.getData())) { + treeItem.setChecked(false); + } else if (!treeItem.getChecked() && checked.contains(treeItem.getData())) { + treeItem.setChecked(true); + } + restoreChecked(treeItem.getItems()); + } + } + + public Object[] getResult() { + return getChecked().toArray(new Object[getChecked().size()]); + } + + private void storeResults(TreeItem treeItems[]) { + for (TreeItem treeItem : treeItems) { + if (treeItem.getChecked() && !checked.contains(treeItem.getData())) { + checked.add(treeItem.getData()); + } else if (!treeItem.getChecked() && checked.contains(treeItem.getData())) { + checked.remove(treeItem.getData()); + } + storeResults(treeItem.getItems()); + } + } + + public Set getChecked() { + return checked; + } + +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XFilteredTree.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XFilteredTree.java index 3d97f6fd8..640de5429 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XFilteredTree.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/dialog/XFilteredTree.java @@ -1,1073 +1,1073 @@ -package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.viewers.IContentProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.nebula.widgets.xviewer.XViewerText; -import org.eclipse.nebula.widgets.xviewer.util.internal.PatternFilter; -import org.eclipse.nebula.widgets.xviewer.util.internal.images.XViewerImageCache; -import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; -import org.eclipse.swt.accessibility.ACC; -import org.eclipse.swt.accessibility.AccessibleAdapter; -import org.eclipse.swt.accessibility.AccessibleControlAdapter; -import org.eclipse.swt.accessibility.AccessibleControlEvent; -import org.eclipse.swt.accessibility.AccessibleEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseMoveListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeItem; -import org.eclipse.ui.progress.WorkbenchJob; - -/** - * A simple control that provides a text widget and a tree viewer. The contents of the text widget are used to drive a - * PatternFilter that is on the viewer. - * - * @see org.eclipse.ui.dialogs.PatternFilter - * @since 3.2 - */ -public class XFilteredTree extends Composite { - - /** - * The filter text widget to be used by this tree. This value may be null if there is no filter widget, - * or if the controls have not yet been created. - */ - protected Text filterText; - - /** - * The control representing the clear button for the filter text entry. This value may be null if no - * such button exists, or if the controls have not yet been created. - *

- * Note: As of 3.5, this is not used if the new look is chosen. - *

- */ - protected ToolBarManager filterToolBar; - - /** - * The control representing the clear button for the filter text entry. This value may be null if no - * such button exists, or if the controls have not yet been created. - *

- * Note: This is only used if the new look is chosen. - *

- * - * @since 3.5 - */ - protected Control clearButtonControl; - - /** - * The viewer for the filtered tree. This value should never be null after the widget creation methods - * are complete. - */ - protected TreeViewer treeViewer; - - /** - * The Composite on which the filter controls are created. This is used to set the background color of the filter - * controls to match the surrounding controls. - */ - protected Composite filterComposite; - - /** - * The pattern filter for the tree. This value must not be null. - */ - private PatternFilter patternFilter; - - /** - * The text to initially show in the filter text control. - */ - protected String initialText = ""; //$NON-NLS-1$ - - /** - * The job used to refresh the tree. - */ - private Job refreshJob; - - /** - * The parent composite of the filtered tree. - * - * @since 3.3 - */ - protected Composite parent; - - /** - * Whether or not to show the filter controls (text and clear button). The default is to show these controls. This - * can be overridden by providing a setting in the product configuration file. The setting to add to not show these - * controls is: org.eclipse.ui/SHOW_FILTERED_TEXTS=false - */ - protected boolean showFilterControls; - - /** - * @since 3.3 - */ - protected Composite treeComposite; - - /** - * Tells whether to use the pre 3.5 or the new look. - * - * @since 3.5 - */ - private boolean useNewLook = false; - - /** - * Image descriptor for enabled clear button. - */ - private static final String CLEAR_ICON = "org.eclipse.ui.internal.dialogs.CLEAR_ICON"; //$NON-NLS-1$ - - /** - * Image descriptor for disabled clear button. - */ - private static final String DISABLED_CLEAR_ICON = "org.eclipse.ui.internal.dialogs.DCLEAR_ICON"; //$NON-NLS-1$ - - /** - * Maximum time spent expanding the tree after the filter text has been updated (this is only used if we were able to - * at least expand the visible nodes) - */ - private static final long SOFT_MAX_EXPAND_TIME = 200; - - /** - * Get image descriptors for the clear button. - */ - static { - ImageDescriptor descriptor = null; - JFaceResources.getImageRegistry().put(DISABLED_CLEAR_ICON, descriptor); - } - - /** - * Create a new instance of the receiver. - * - * @param parent the parent Composite - * @param treeStyle the style bits for the Tree - * @param filter the filter to be used - * @deprecated As of 3.5, replaced by {@link #FilteredTree(Composite, int, PatternFilter, boolean)} where using the - * new look is encouraged - */ - @Deprecated - public XFilteredTree(Composite parent, int treeStyle, PatternFilter filter) { - super(parent, SWT.NONE); - this.parent = parent; - init(treeStyle, filter); - } - - /** - * Create a new instance of the receiver. - * - * @param parent the parent Composite - * @param treeStyle the style bits for the Tree - * @param filter the filter to be used - * @param useNewLook true if the new 3.5 look should be used - * @since 3.5 - */ - public XFilteredTree(Composite parent, int treeStyle, PatternFilter filter, boolean useNewLook) { - super(parent, SWT.NONE); - this.parent = parent; - this.useNewLook = useNewLook; - init(treeStyle, filter); - } - - /** - * Create a new instance of the receiver. Subclasses that wish to override the default creation behavior may use this - * constructor, but must ensure that the init(composite, int, PatternFilter) method is called in the - * overriding constructor. - * - * @param parent the parent Composite - * @see #init(int, PatternFilter) - * @since 3.3 - * @deprecated As of 3.5, replaced by {@link #FilteredTree(Composite, boolean)} where using the look is encouraged - */ - @Deprecated - protected XFilteredTree(Composite parent) { - super(parent, SWT.NONE); - this.parent = parent; - } - - /** - * Create a new instance of the receiver. Subclasses that wish to override the default creation behavior may use this - * constructor, but must ensure that the init(composite, int, PatternFilter) method is called in the - * overriding constructor. - * - * @param parent the parent Composite - * @param useNewLook true if the new 3.5 look should be used - * @see #init(int, PatternFilter) - * @since 3.5 - */ - protected XFilteredTree(Composite parent, boolean useNewLook) { - super(parent, SWT.NONE); - this.parent = parent; - this.useNewLook = useNewLook; - } - - /** - * Create the filtered tree. - * - * @param treeStyle the style bits for the Tree - * @param filter the filter to be used - * @since 3.3 - */ - protected void init(int treeStyle, PatternFilter filter) { - patternFilter = filter; - showFilterControls = true; - createControl(parent, treeStyle); - createRefreshJob(); - setInitialText(XViewerText.get("XFilteredTree.filter")); //$NON-NLS-1$ - setFont(parent.getFont()); - - } - - /** - * Create the filtered tree's controls. Subclasses should override. - * - * @param parent - * @param treeStyle - */ - protected void createControl(Composite parent, int treeStyle) { - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - setLayout(layout); - setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - if (showFilterControls) { - if (!useNewLook || useNativeSearchField(parent)) { - filterComposite = new Composite(this, SWT.NONE); - } else { - filterComposite = new Composite(this, SWT.BORDER); - filterComposite.setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - } - GridLayout filterLayout = new GridLayout(2, false); - filterLayout.marginHeight = 0; - filterLayout.marginWidth = 0; - filterComposite.setLayout(filterLayout); - filterComposite.setFont(parent.getFont()); - - createFilterControls(filterComposite); - filterComposite.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); - } - - treeComposite = new Composite(this, SWT.NONE); - GridLayout treeCompositeLayout = new GridLayout(); - treeCompositeLayout.marginHeight = 0; - treeCompositeLayout.marginWidth = 0; - treeComposite.setLayout(treeCompositeLayout); - GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); - treeComposite.setLayoutData(data); - createTreeControl(treeComposite, treeStyle); - } - - private static Boolean useNativeSearchField; - - private static boolean useNativeSearchField(Composite composite) { - if (useNativeSearchField == null) { - useNativeSearchField = Boolean.FALSE; - Text testText = null; - try { - testText = new Text(composite, SWT.SEARCH | SWT.ICON_CANCEL); - useNativeSearchField = new Boolean((testText.getStyle() & SWT.ICON_CANCEL) != 0); - } finally { - if (testText != null) { - testText.dispose(); - } - } - - } - return useNativeSearchField.booleanValue(); - } - - /** - * Create the filter controls. By default, a text and corresponding tool bar button that clears the contents of the - * text is created. Subclasses may override. - * - * @param parent parent Composite of the filter controls - * @return the Composite that contains the filter controls - */ - protected Composite createFilterControls(Composite parent) { - createFilterText(parent); - if (useNewLook) { - createClearTextNew(parent); - } else { - createClearTextOld(parent); - } - if (clearButtonControl != null) { - // initially there is no text to clear - clearButtonControl.setVisible(false); - } - if (filterToolBar != null) { - filterToolBar.update(false); - // initially there is no text to clear - filterToolBar.getControl().setVisible(false); - } - return parent; - } - - /** - * Creates and set up the tree and tree viewer. This method calls {@link #doCreateTreeViewer(Composite, int)} to - * create the tree viewer. Subclasses should override {@link #doCreateTreeViewer(Composite, int)} instead of - * overriding this method. - * - * @param parent parent Composite - * @param style SWT style bits used to create the tree - * @return the tree - */ - protected Control createTreeControl(Composite parent, int style) { - treeViewer = doCreateTreeViewer(parent, style); - GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); - treeViewer.getControl().setLayoutData(data); - treeViewer.getControl().addListener(SWT.Dispose, e-> refreshJob.cancel()); - if (treeViewer instanceof NotifyingTreeViewer) { - patternFilter.setUseCache(true); - } - treeViewer.addFilter(patternFilter); - return treeViewer.getControl(); - } - - /** - * Creates the tree viewer. Subclasses may override. - * - * @param parent the parent composite - * @param style SWT style bits used to create the tree viewer - * @return the tree viewer - * @since 3.3 - */ - protected TreeViewer doCreateTreeViewer(Composite parent, int style) { - return new NotifyingTreeViewer(parent, style); - } - - /** - * Return the first item in the tree that matches the filter pattern. - * - * @param items - * @return the first matching TreeItem - */ - private TreeItem getFirstMatchingItem(TreeItem[] items) { - for (int i = 0; i < items.length; i++) { - if (patternFilter.isLeafMatch(treeViewer, items[i].getData()) && patternFilter.isElementSelectable(items[i].getData())) { - return items[i]; - } - TreeItem treeItem = getFirstMatchingItem(items[i].getItems()); - if (treeItem != null) { - return treeItem; - } - } - return null; - } - - /** - * Create the refresh job for the receiver. - */ - private void createRefreshJob() { - refreshJob = doCreateRefreshJob(); - refreshJob.setSystem(true); - } - - /** - * Creates a workbench job that will refresh the tree based on the current filter text. Subclasses may override. - * - * @return a workbench job that can be scheduled to refresh the tree - * @since 3.4 - */ - protected WorkbenchJob doCreateRefreshJob() { - return new WorkbenchJob("Refresh Filter") {//$NON-NLS-1$ - @Override - public IStatus runInUIThread(IProgressMonitor monitor) { - if (treeViewer.getControl().isDisposed()) { - return Status.CANCEL_STATUS; - } - - String text = getFilterString(); - if (text == null) { - return Status.OK_STATUS; - } - - boolean initial = initialText != null && initialText.equals(text); - if (initial) { - patternFilter.setPattern(null); - } else { - patternFilter.setPattern(text); - } - - Control redrawFalseControl = treeComposite != null ? treeComposite : treeViewer.getControl(); - try { - // don't want the user to see updates that will be made to - // the tree - // we are setting redraw(false) on the composite to avoid - // dancing scrollbar - redrawFalseControl.setRedraw(false); - if (!narrowingDown) { - // collapse all - TreeItem[] is = treeViewer.getTree().getItems(); - for (int i = 0; i < is.length; i++) { - TreeItem item = is[i]; - if (item.getExpanded()) { - treeViewer.setExpandedState(item.getData(), false); - } - } - } - treeViewer.refresh(true); - - if (text.length() > 0 && !initial) { - /* - * Expand elements one at a time. After each is expanded, check to see if the filter text has been - * modified. If it has, then cancel the refresh job so the user doesn't have to endure expansion of - * all the nodes. - */ - TreeItem[] items = getViewer().getTree().getItems(); - int treeHeight = getViewer().getTree().getBounds().height; - int numVisibleItems = treeHeight / getViewer().getTree().getItemHeight(); - long stopTime = SOFT_MAX_EXPAND_TIME + System.currentTimeMillis(); - boolean cancel = false; - if (items.length > 0 && recursiveExpand(items, monitor, stopTime, new int[] {numVisibleItems})) { - cancel = true; - } - - // enabled toolbar - there is text to clear - // and the list is currently being filtered - updateToolbar(true); - - if (cancel) { - return Status.CANCEL_STATUS; - } - } else { - // disabled toolbar - there is no text to clear - // and the list is currently not filtered - updateToolbar(false); - } - } finally { - // done updating the tree - set redraw back to true - TreeItem[] items = getViewer().getTree().getItems(); - if (items.length > 0 && getViewer().getTree().getSelectionCount() == 0) { - treeViewer.getTree().setTopItem(items[0]); - } - redrawFalseControl.setRedraw(true); - } - return Status.OK_STATUS; - } - - /** - * Returns true if the job should be canceled (because of timeout or actual cancellation). - * - * @param items - * @param monitor - * @param cancelTime - * @param numItemsLeft - * @return true if canceled - */ - private boolean recursiveExpand(TreeItem[] items, IProgressMonitor monitor, long cancelTime, int[] numItemsLeft) { - boolean canceled = false; - for (int i = 0; !canceled && i < items.length; i++) { - TreeItem item = items[i]; - boolean visible = numItemsLeft[0]-- >= 0; - if (monitor.isCanceled() || (!visible && System.currentTimeMillis() > cancelTime)) { - canceled = true; - } else { - Object itemData = item.getData(); - if (itemData != null) { - if (!item.getExpanded()) { - // do the expansion through the viewer so that - // it can refresh children appropriately. - treeViewer.setExpandedState(itemData, true); - } - TreeItem[] children = item.getItems(); - if (items.length > 0) { - canceled = recursiveExpand(children, monitor, cancelTime, numItemsLeft); - } - } - } - } - return canceled; - } - - }; - } - - protected void updateToolbar(boolean visible) { - if (clearButtonControl != null) { - clearButtonControl.setVisible(visible); - } - if (filterToolBar != null) { - filterToolBar.getControl().setVisible(visible); - } - } - - /** - * Creates the filter text and adds listeners. This method calls {@link #doCreateFilterText(Composite)} to create the - * text control. Subclasses should override {@link #doCreateFilterText(Composite)} instead of overriding this method. - * - * @param parent Composite of the filter text - */ - protected void createFilterText(Composite parent) { - filterText = doCreateFilterText(parent); - filterText.getAccessible().addAccessibleListener(new AccessibleAdapter() { - /** - * @see org.eclipse.swt.accessibility.AccessibleListener#getName(org.eclipse.swt.accessibility.AccessibleEvent) - */ - @Override - public void getName(AccessibleEvent e) { - String filterTextString = filterText.getText(); - if (filterTextString.length() == 0 || filterTextString.equals(initialText)) { - e.result = initialText; - } else { - e.result = - NLS.bind( - XViewerText.get("XFilteredTree.matches"), new String[] {filterTextString, String.valueOf(getFilteredItemsCount())}); //$NON-NLS-1$ - } - } - - /** - * Return the number of filtered items - * - * @return int - */ - private int getFilteredItemsCount() { - int total = 0; - TreeItem[] items = getViewer().getTree().getItems(); - for (int i = 0; i < items.length; i++) { - total += itemCount(items[i]); - - } - return total; - } - - /** - * Return the count of treeItem and it's children to infinite depth. - * - * @param treeItem - * @return int - */ - private int itemCount(TreeItem treeItem) { - int count = 1; - TreeItem[] children = treeItem.getItems(); - for (int i = 0; i < children.length; i++) { - count += itemCount(children[i]); - - } - return count; - } - }); - - filterText.addListener(SWT.FocusIn, e -> { - if (!useNewLook) { - /* - * Running in an asyncExec because the selectAll() does not appear to work when - * using mouse to give focus to text. - */ - Display display = filterText.getDisplay(); - display.asyncExec(() -> { - if (!filterText.isDisposed()) { - if (getInitialText().equals(filterText.getText().trim())) { - filterText.selectAll(); - } - } - }); - return; - } - }); - - filterText.addListener(SWT.FocusOut, e -> { - if (!useNewLook) { - return; - } - if (filterText.getText().equals(initialText)) { - setFilterText(""); //$NON-NLS-1$ - textChanged(); - } - }); - - if (useNewLook) { - filterText.addListener(SWT.MouseDown, e -> { - if (filterText.getText().equals(initialText)) { - // XXX: We cannot call clearText() due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=260664 - setFilterText(""); //$NON-NLS-1$ - textChanged(); - } - }); - } - - filterText.addListener(SWT.KeyDown, e-> { - // on a CR we want to transfer focus to the list - boolean hasItems = getViewer().getTree().getItemCount() > 0; - if (hasItems && e.keyCode == SWT.ARROW_DOWN) { - treeViewer.getTree().setFocus(); - return; - } - }); - - // enter key set focus to tree - filterText.addListener(SWT.Traverse, e-> { - if (e.detail == SWT.TRAVERSE_RETURN) { - e.doit = false; - if (getViewer().getTree().getItemCount() == 0) { - Display.getCurrent().beep(); - } else { - // if the initial filter text hasn't changed, do not try - // to match - boolean hasFocus = getViewer().getTree().setFocus(); - boolean textChanged = !getInitialText().equals(filterText.getText().trim()); - if (hasFocus && textChanged && filterText.getText().trim().length() > 0) { - Tree tree = getViewer().getTree(); - TreeItem item; - if (tree.getSelectionCount() > 0) { - item = getFirstMatchingItem(tree.getSelection()); - } else { - item = getFirstMatchingItem(tree.getItems()); - } - if (item != null) { - tree.setSelection(new TreeItem[] {item}); - ISelection sel = getViewer().getSelection(); - getViewer().setSelection(sel, true); - } - } - } - } - }); - - filterText.addListener(SWT.Modify, e-> textChanged()); - - // if we're using a field with built in cancel we need to listen for - // default selection changes (which tell us the cancel button has been - // pressed) - if ((filterText.getStyle() & SWT.ICON_CANCEL) != 0) { - filterText.addListener(SWT.DefaultSelection, e-> { - if (e.detail == SWT.ICON_CANCEL) { - clearText(); - } - }); - } - - GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); - // if the text widget supported cancel then it will have it's own - // integrated button. We can take all of the space. - if ((filterText.getStyle() & SWT.ICON_CANCEL) != 0) { - gridData.horizontalSpan = 2; - } - filterText.setLayoutData(gridData); - } - - /** - * Creates the text control for entering the filter text. Subclasses may override. - * - * @param parent the parent composite - * @return the text widget - * @since 3.3 - */ - protected Text doCreateFilterText(Composite parent) { - if (!useNewLook || useNativeSearchField(parent)) { - return new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL); - } - return new Text(parent, SWT.SINGLE); - } - - private String previousFilterText; - - private boolean narrowingDown; - - /** - * Update the receiver after the text has changed. - */ - protected void textChanged() { - narrowingDown = - previousFilterText == null || previousFilterText.equals(XViewerText.get("XFilteredTree.filter")) || getFilterString().startsWith( //$NON-NLS-1$ - previousFilterText); - previousFilterText = getFilterString(); - // cancel currently running job first, to prevent unnecessary redraw - refreshJob.cancel(); - refreshJob.schedule(getRefreshJobDelay()); - } - - /** - * Return the time delay that should be used when scheduling the filter refresh job. Subclasses may override. - * - * @return a time delay in milliseconds before the job should run - * @since 3.5 - */ - protected long getRefreshJobDelay() { - return 200; - } - - /** - * Set the background for the widgets that support the filter text area. - * - * @param background background Color to set - */ - @Override - public void setBackground(Color background) { - super.setBackground(background); - if (filterComposite != null && (!useNewLook || useNativeSearchField(filterComposite))) { - filterComposite.setBackground(background); - } - if (filterToolBar != null && filterToolBar.getControl() != null) { - filterToolBar.getControl().setBackground(background); - } - } - - /** - * Create the button that clears the text. - * - * @param parent parent Composite of toolbar button - */ - private void createClearTextOld(Composite parent) { - // only create the button if the text widget doesn't support one - // natively - if ((filterText.getStyle() & SWT.ICON_CANCEL) == 0) { - filterToolBar = new ToolBarManager(SWT.FLAT | SWT.HORIZONTAL); - filterToolBar.createControl(parent); - - IAction clearTextAction = new Action("", IAction.AS_PUSH_BUTTON) {//$NON-NLS-1$ - /** - * @see org.eclipse.jface.action.Action#run() - */ - @Override - public void run() { - clearText(); - } - }; - - clearTextAction.setToolTipText(XViewerText.get("button.clear")); //$NON-NLS-1$ - clearTextAction.setImageDescriptor(JFaceResources.getImageRegistry().getDescriptor(CLEAR_ICON)); - clearTextAction.setDisabledImageDescriptor(JFaceResources.getImageRegistry().getDescriptor(DISABLED_CLEAR_ICON)); - - filterToolBar.add(clearTextAction); - } - } - - /** - * Create the button that clears the text. - * - * @param parent parent Composite of toolbar button - */ - private void createClearTextNew(Composite parent) { - // only create the button if the text widget doesn't support one - // natively - if ((filterText.getStyle() & SWT.ICON_CANCEL) == 0) { - final Image inactiveImage = XViewerImageCache.getImage("clear.gif"); //$NON-NLS-1$ - final Image activeImage = inactiveImage; - final Image pressedImage = inactiveImage; - - final Label clearButton = new Label(parent, SWT.NONE); - clearButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); - clearButton.setImage(inactiveImage); - clearButton.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); - clearButton.setToolTipText(XViewerText.get("button.clear")); //$NON-NLS-1$ - clearButton.addMouseListener(new MouseAdapter() { - private MouseMoveListener fMoveListener; - - @Override - public void mouseDown(MouseEvent e) { - clearButton.setImage(pressedImage); - fMoveListener = new MouseMoveListener() { - private boolean fMouseInButton = true; - - @Override - public void mouseMove(MouseEvent e) { - boolean mouseInButton = isMouseInButton(e); - if (mouseInButton != fMouseInButton) { - fMouseInButton = mouseInButton; - clearButton.setImage(mouseInButton ? pressedImage : inactiveImage); - } - } - }; - clearButton.addMouseMoveListener(fMoveListener); - } - - @Override - public void mouseUp(MouseEvent e) { - if (fMoveListener != null) { - clearButton.removeMouseMoveListener(fMoveListener); - fMoveListener = null; - boolean mouseInButton = isMouseInButton(e); - clearButton.setImage(mouseInButton ? activeImage : inactiveImage); - if (mouseInButton) { - clearText(); - filterText.setFocus(); - } - } - } - - private boolean isMouseInButton(MouseEvent e) { - Point buttonSize = clearButton.getSize(); - return 0 <= e.x && e.x < buttonSize.x && 0 <= e.y && e.y < buttonSize.y; - } - }); - - clearButton.addListener(SWT.MouseEnter, e-> clearButton.setImage(activeImage)); - - clearButton.addListener(SWT.MouseExit, e-> clearButton.setImage(inactiveImage)); - - clearButton.getAccessible().addAccessibleListener(new AccessibleAdapter() { - @Override - public void getName(AccessibleEvent e) { - e.result = XViewerText.get("XFilteredTree.filter.clear"); //$NON-NLS-1$ - } - }); - clearButton.getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() { - @Override - public void getRole(AccessibleControlEvent e) { - e.detail = ACC.ROLE_PUSHBUTTON; - } - }); - this.clearButtonControl = clearButton; - } - } - - /** - * Clears the text in the filter text widget. - */ - protected void clearText() { - setFilterText(""); //$NON-NLS-1$ - textChanged(); - } - - /** - * Set the text in the filter control. - * - * @param string - */ - protected void setFilterText(String string) { - if (filterText != null) { - filterText.setText(string); - selectAll(); - } - } - - /** - * Returns the pattern filter used by this tree. - * - * @return The pattern filter; never null. - */ - public final PatternFilter getPatternFilter() { - return patternFilter; - } - - /** - * Get the tree viewer of the receiver. - * - * @return the tree viewer - */ - public TreeViewer getViewer() { - return treeViewer; - } - - /** - * Get the filter text for the receiver, if it was created. Otherwise return null. - * - * @return the filter Text, or null if it was not created - */ - public Text getFilterControl() { - return filterText; - } - - /** - * Convenience method to return the text of the filter control. If the text widget is not created, then null is - * returned. - * - * @return String in the text, or null if the text does not exist - */ - protected String getFilterString() { - return filterText != null ? filterText.getText() : null; - } - - /** - * Set the text that will be shown until the first focus. A default value is provided, so this method only need be - * called if overriding the default initial text is desired. - * - * @param text initial text to appear in text field - */ - public void setInitialText(String text) { - initialText = text; - if (useNewLook && filterText != null) { - filterText.setMessage(text); - if (filterText.isFocusControl()) { - setFilterText(initialText); - textChanged(); - } else { - getDisplay().asyncExec(() -> { - if (!filterText.isDisposed() && filterText.isFocusControl()) { - setFilterText(initialText); - textChanged(); - } - }); - } - } else { - setFilterText(initialText); - textChanged(); - } - } - - /** - * Select all text in the filter text field. - */ - protected void selectAll() { - if (filterText != null) { - filterText.selectAll(); - } - } - - /** - * Get the initial text for the receiver. - * - * @return String - */ - protected String getInitialText() { - return initialText; - } - - /** - * Return a bold font if the given element matches the given pattern. Clients can opt to call this method from a - * Viewer's label provider to get a bold font for which to highlight the given element in the tree. - * - * @param element element for which a match should be determined - * @param tree FilteredTree in which the element resides - * @param filter PatternFilter which determines a match - * @return bold font - */ - public static Font getBoldFont(Object element, XFilteredTree tree, PatternFilter filter) { - String filterText = tree.getFilterString(); - - if (filterText == null) { - return null; - } - - // Do nothing if it's empty string - String initialText = tree.getInitialText(); - if (!filterText.equals("") && !filterText.equals(initialText)) {//$NON-NLS-1$ - if (tree.getPatternFilter() != filter) { - boolean initial = initialText != null && initialText.equals(filterText); - if (initial) { - filter.setPattern(null); - } else { - filter.setPattern(filterText); - } - } - if (filter.isElementVisible(tree.getViewer(), element) && filter.isLeafMatch(tree.getViewer(), element)) { - return JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT); - } - } - return null; - } - - /** - * Custom tree viewer subclass that clears the caches in patternFilter on any change to the tree. See bug 187200. - * - * @since 3.3 - */ - class NotifyingTreeViewer extends TreeViewer { - - /** - * @param parent - * @param style - */ - public NotifyingTreeViewer(Composite parent, int style) { - super(parent, style); - } - - @Override - public void add(Object parentElementOrTreePath, Object childElement) { - getPatternFilter().clearCaches(); - super.add(parentElementOrTreePath, childElement); - } - - @Override - public void add(Object parentElementOrTreePath, Object... childElements) { - getPatternFilter().clearCaches(); - super.add(parentElementOrTreePath, childElements); - } - - @Override - protected void inputChanged(Object input, Object oldInput) { - getPatternFilter().clearCaches(); - super.inputChanged(input, oldInput); - } - - @Override - public void insert(Object parentElementOrTreePath, Object element, int position) { - getPatternFilter().clearCaches(); - super.insert(parentElementOrTreePath, element, position); - } - - @Override - public void refresh() { - getPatternFilter().clearCaches(); - super.refresh(); - } - - @Override - public void refresh(boolean updateLabels) { - getPatternFilter().clearCaches(); - super.refresh(updateLabels); - } - - @Override - public void refresh(Object element) { - getPatternFilter().clearCaches(); - super.refresh(element); - } - - @Override - public void refresh(Object element, boolean updateLabels) { - getPatternFilter().clearCaches(); - super.refresh(element, updateLabels); - } - - @Override - public void remove(Object elementsOrTreePaths) { - getPatternFilter().clearCaches(); - super.remove(elementsOrTreePaths); - } - - @Override - public void remove(Object parent, Object... elements) { - getPatternFilter().clearCaches(); - super.remove(parent, elements); - } - - @Override - public void remove(Object... elementsOrTreePaths) { - getPatternFilter().clearCaches(); - super.remove(elementsOrTreePaths); - } - - @Override - public void replace(Object parentElementOrTreePath, int index, Object element) { - getPatternFilter().clearCaches(); - super.replace(parentElementOrTreePath, index, element); - } - - @Override - public void setChildCount(Object elementOrTreePath, int count) { - getPatternFilter().clearCaches(); - super.setChildCount(elementOrTreePath, count); - } - - @Override - public void setContentProvider(IContentProvider provider) { - getPatternFilter().clearCaches(); - super.setContentProvider(provider); - } - - @Override - public void setHasChildren(Object elementOrTreePath, boolean hasChildren) { - getPatternFilter().clearCaches(); - super.setHasChildren(elementOrTreePath, hasChildren); - } - - } - -} +package org.eclipse.nebula.widgets.xviewer.util.internal.dialog; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.nebula.widgets.xviewer.XViewerText; +import org.eclipse.nebula.widgets.xviewer.util.internal.PatternFilter; +import org.eclipse.nebula.widgets.xviewer.util.internal.images.XViewerImageCache; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleControlAdapter; +import org.eclipse.swt.accessibility.AccessibleControlEvent; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.progress.WorkbenchJob; + +/** + * A simple control that provides a text widget and a tree viewer. The contents of the text widget are used to drive a + * PatternFilter that is on the viewer. + * + * @see org.eclipse.ui.dialogs.PatternFilter + * @since 3.2 + */ +public class XFilteredTree extends Composite { + + /** + * The filter text widget to be used by this tree. This value may be null if there is no filter widget, + * or if the controls have not yet been created. + */ + protected Text filterText; + + /** + * The control representing the clear button for the filter text entry. This value may be null if no + * such button exists, or if the controls have not yet been created. + *

+ * Note: As of 3.5, this is not used if the new look is chosen. + *

+ */ + protected ToolBarManager filterToolBar; + + /** + * The control representing the clear button for the filter text entry. This value may be null if no + * such button exists, or if the controls have not yet been created. + *

+ * Note: This is only used if the new look is chosen. + *

+ * + * @since 3.5 + */ + protected Control clearButtonControl; + + /** + * The viewer for the filtered tree. This value should never be null after the widget creation methods + * are complete. + */ + protected TreeViewer treeViewer; + + /** + * The Composite on which the filter controls are created. This is used to set the background color of the filter + * controls to match the surrounding controls. + */ + protected Composite filterComposite; + + /** + * The pattern filter for the tree. This value must not be null. + */ + private PatternFilter patternFilter; + + /** + * The text to initially show in the filter text control. + */ + protected String initialText = ""; //$NON-NLS-1$ + + /** + * The job used to refresh the tree. + */ + private Job refreshJob; + + /** + * The parent composite of the filtered tree. + * + * @since 3.3 + */ + protected Composite parent; + + /** + * Whether or not to show the filter controls (text and clear button). The default is to show these controls. This + * can be overridden by providing a setting in the product configuration file. The setting to add to not show these + * controls is: org.eclipse.ui/SHOW_FILTERED_TEXTS=false + */ + protected boolean showFilterControls; + + /** + * @since 3.3 + */ + protected Composite treeComposite; + + /** + * Tells whether to use the pre 3.5 or the new look. + * + * @since 3.5 + */ + private boolean useNewLook = false; + + /** + * Image descriptor for enabled clear button. + */ + private static final String CLEAR_ICON = "org.eclipse.ui.internal.dialogs.CLEAR_ICON"; //$NON-NLS-1$ + + /** + * Image descriptor for disabled clear button. + */ + private static final String DISABLED_CLEAR_ICON = "org.eclipse.ui.internal.dialogs.DCLEAR_ICON"; //$NON-NLS-1$ + + /** + * Maximum time spent expanding the tree after the filter text has been updated (this is only used if we were able to + * at least expand the visible nodes) + */ + private static final long SOFT_MAX_EXPAND_TIME = 200; + + /** + * Get image descriptors for the clear button. + */ + static { + ImageDescriptor descriptor = null; + JFaceResources.getImageRegistry().put(DISABLED_CLEAR_ICON, descriptor); + } + + /** + * Create a new instance of the receiver. + * + * @param parent the parent Composite + * @param treeStyle the style bits for the Tree + * @param filter the filter to be used + * @deprecated As of 3.5, replaced by {@link #FilteredTree(Composite, int, PatternFilter, boolean)} where using the + * new look is encouraged + */ + @Deprecated + public XFilteredTree(Composite parent, int treeStyle, PatternFilter filter) { + super(parent, SWT.NONE); + this.parent = parent; + init(treeStyle, filter); + } + + /** + * Create a new instance of the receiver. + * + * @param parent the parent Composite + * @param treeStyle the style bits for the Tree + * @param filter the filter to be used + * @param useNewLook true if the new 3.5 look should be used + * @since 3.5 + */ + public XFilteredTree(Composite parent, int treeStyle, PatternFilter filter, boolean useNewLook) { + super(parent, SWT.NONE); + this.parent = parent; + this.useNewLook = useNewLook; + init(treeStyle, filter); + } + + /** + * Create a new instance of the receiver. Subclasses that wish to override the default creation behavior may use this + * constructor, but must ensure that the init(composite, int, PatternFilter) method is called in the + * overriding constructor. + * + * @param parent the parent Composite + * @see #init(int, PatternFilter) + * @since 3.3 + * @deprecated As of 3.5, replaced by {@link #FilteredTree(Composite, boolean)} where using the look is encouraged + */ + @Deprecated + protected XFilteredTree(Composite parent) { + super(parent, SWT.NONE); + this.parent = parent; + } + + /** + * Create a new instance of the receiver. Subclasses that wish to override the default creation behavior may use this + * constructor, but must ensure that the init(composite, int, PatternFilter) method is called in the + * overriding constructor. + * + * @param parent the parent Composite + * @param useNewLook true if the new 3.5 look should be used + * @see #init(int, PatternFilter) + * @since 3.5 + */ + protected XFilteredTree(Composite parent, boolean useNewLook) { + super(parent, SWT.NONE); + this.parent = parent; + this.useNewLook = useNewLook; + } + + /** + * Create the filtered tree. + * + * @param treeStyle the style bits for the Tree + * @param filter the filter to be used + * @since 3.3 + */ + protected void init(int treeStyle, PatternFilter filter) { + patternFilter = filter; + showFilterControls = true; + createControl(parent, treeStyle); + createRefreshJob(); + setInitialText(XViewerText.get("XFilteredTree.filter")); //$NON-NLS-1$ + setFont(parent.getFont()); + + } + + /** + * Create the filtered tree's controls. Subclasses should override. + * + * @param parent + * @param treeStyle + */ + protected void createControl(Composite parent, int treeStyle) { + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + setLayout(layout); + setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + if (showFilterControls) { + if (!useNewLook || useNativeSearchField(parent)) { + filterComposite = new Composite(this, SWT.NONE); + } else { + filterComposite = new Composite(this, SWT.BORDER); + filterComposite.setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + } + GridLayout filterLayout = new GridLayout(2, false); + filterLayout.marginHeight = 0; + filterLayout.marginWidth = 0; + filterComposite.setLayout(filterLayout); + filterComposite.setFont(parent.getFont()); + + createFilterControls(filterComposite); + filterComposite.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + } + + treeComposite = new Composite(this, SWT.NONE); + GridLayout treeCompositeLayout = new GridLayout(); + treeCompositeLayout.marginHeight = 0; + treeCompositeLayout.marginWidth = 0; + treeComposite.setLayout(treeCompositeLayout); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + treeComposite.setLayoutData(data); + createTreeControl(treeComposite, treeStyle); + } + + private static Boolean useNativeSearchField; + + private static boolean useNativeSearchField(Composite composite) { + if (useNativeSearchField == null) { + useNativeSearchField = Boolean.FALSE; + Text testText = null; + try { + testText = new Text(composite, SWT.SEARCH | SWT.ICON_CANCEL); + useNativeSearchField = new Boolean((testText.getStyle() & SWT.ICON_CANCEL) != 0); + } finally { + if (testText != null) { + testText.dispose(); + } + } + + } + return useNativeSearchField.booleanValue(); + } + + /** + * Create the filter controls. By default, a text and corresponding tool bar button that clears the contents of the + * text is created. Subclasses may override. + * + * @param parent parent Composite of the filter controls + * @return the Composite that contains the filter controls + */ + protected Composite createFilterControls(Composite parent) { + createFilterText(parent); + if (useNewLook) { + createClearTextNew(parent); + } else { + createClearTextOld(parent); + } + if (clearButtonControl != null) { + // initially there is no text to clear + clearButtonControl.setVisible(false); + } + if (filterToolBar != null) { + filterToolBar.update(false); + // initially there is no text to clear + filterToolBar.getControl().setVisible(false); + } + return parent; + } + + /** + * Creates and set up the tree and tree viewer. This method calls {@link #doCreateTreeViewer(Composite, int)} to + * create the tree viewer. Subclasses should override {@link #doCreateTreeViewer(Composite, int)} instead of + * overriding this method. + * + * @param parent parent Composite + * @param style SWT style bits used to create the tree + * @return the tree + */ + protected Control createTreeControl(Composite parent, int style) { + treeViewer = doCreateTreeViewer(parent, style); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + treeViewer.getControl().setLayoutData(data); + treeViewer.getControl().addListener(SWT.Dispose, e-> refreshJob.cancel()); + if (treeViewer instanceof NotifyingTreeViewer) { + patternFilter.setUseCache(true); + } + treeViewer.addFilter(patternFilter); + return treeViewer.getControl(); + } + + /** + * Creates the tree viewer. Subclasses may override. + * + * @param parent the parent composite + * @param style SWT style bits used to create the tree viewer + * @return the tree viewer + * @since 3.3 + */ + protected TreeViewer doCreateTreeViewer(Composite parent, int style) { + return new NotifyingTreeViewer(parent, style); + } + + /** + * Return the first item in the tree that matches the filter pattern. + * + * @param items + * @return the first matching TreeItem + */ + private TreeItem getFirstMatchingItem(TreeItem[] items) { + for (int i = 0; i < items.length; i++) { + if (patternFilter.isLeafMatch(treeViewer, items[i].getData()) && patternFilter.isElementSelectable(items[i].getData())) { + return items[i]; + } + TreeItem treeItem = getFirstMatchingItem(items[i].getItems()); + if (treeItem != null) { + return treeItem; + } + } + return null; + } + + /** + * Create the refresh job for the receiver. + */ + private void createRefreshJob() { + refreshJob = doCreateRefreshJob(); + refreshJob.setSystem(true); + } + + /** + * Creates a workbench job that will refresh the tree based on the current filter text. Subclasses may override. + * + * @return a workbench job that can be scheduled to refresh the tree + * @since 3.4 + */ + protected WorkbenchJob doCreateRefreshJob() { + return new WorkbenchJob("Refresh Filter") {//$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + if (treeViewer.getControl().isDisposed()) { + return Status.CANCEL_STATUS; + } + + String text = getFilterString(); + if (text == null) { + return Status.OK_STATUS; + } + + boolean initial = initialText != null && initialText.equals(text); + if (initial) { + patternFilter.setPattern(null); + } else { + patternFilter.setPattern(text); + } + + Control redrawFalseControl = treeComposite != null ? treeComposite : treeViewer.getControl(); + try { + // don't want the user to see updates that will be made to + // the tree + // we are setting redraw(false) on the composite to avoid + // dancing scrollbar + redrawFalseControl.setRedraw(false); + if (!narrowingDown) { + // collapse all + TreeItem[] is = treeViewer.getTree().getItems(); + for (int i = 0; i < is.length; i++) { + TreeItem item = is[i]; + if (item.getExpanded()) { + treeViewer.setExpandedState(item.getData(), false); + } + } + } + treeViewer.refresh(true); + + if (text.length() > 0 && !initial) { + /* + * Expand elements one at a time. After each is expanded, check to see if the filter text has been + * modified. If it has, then cancel the refresh job so the user doesn't have to endure expansion of + * all the nodes. + */ + TreeItem[] items = getViewer().getTree().getItems(); + int treeHeight = getViewer().getTree().getBounds().height; + int numVisibleItems = treeHeight / getViewer().getTree().getItemHeight(); + long stopTime = SOFT_MAX_EXPAND_TIME + System.currentTimeMillis(); + boolean cancel = false; + if (items.length > 0 && recursiveExpand(items, monitor, stopTime, new int[] {numVisibleItems})) { + cancel = true; + } + + // enabled toolbar - there is text to clear + // and the list is currently being filtered + updateToolbar(true); + + if (cancel) { + return Status.CANCEL_STATUS; + } + } else { + // disabled toolbar - there is no text to clear + // and the list is currently not filtered + updateToolbar(false); + } + } finally { + // done updating the tree - set redraw back to true + TreeItem[] items = getViewer().getTree().getItems(); + if (items.length > 0 && getViewer().getTree().getSelectionCount() == 0) { + treeViewer.getTree().setTopItem(items[0]); + } + redrawFalseControl.setRedraw(true); + } + return Status.OK_STATUS; + } + + /** + * Returns true if the job should be canceled (because of timeout or actual cancellation). + * + * @param items + * @param monitor + * @param cancelTime + * @param numItemsLeft + * @return true if canceled + */ + private boolean recursiveExpand(TreeItem[] items, IProgressMonitor monitor, long cancelTime, int[] numItemsLeft) { + boolean canceled = false; + for (int i = 0; !canceled && i < items.length; i++) { + TreeItem item = items[i]; + boolean visible = numItemsLeft[0]-- >= 0; + if (monitor.isCanceled() || (!visible && System.currentTimeMillis() > cancelTime)) { + canceled = true; + } else { + Object itemData = item.getData(); + if (itemData != null) { + if (!item.getExpanded()) { + // do the expansion through the viewer so that + // it can refresh children appropriately. + treeViewer.setExpandedState(itemData, true); + } + TreeItem[] children = item.getItems(); + if (items.length > 0) { + canceled = recursiveExpand(children, monitor, cancelTime, numItemsLeft); + } + } + } + } + return canceled; + } + + }; + } + + protected void updateToolbar(boolean visible) { + if (clearButtonControl != null) { + clearButtonControl.setVisible(visible); + } + if (filterToolBar != null) { + filterToolBar.getControl().setVisible(visible); + } + } + + /** + * Creates the filter text and adds listeners. This method calls {@link #doCreateFilterText(Composite)} to create the + * text control. Subclasses should override {@link #doCreateFilterText(Composite)} instead of overriding this method. + * + * @param parent Composite of the filter text + */ + protected void createFilterText(Composite parent) { + filterText = doCreateFilterText(parent); + filterText.getAccessible().addAccessibleListener(new AccessibleAdapter() { + /** + * @see org.eclipse.swt.accessibility.AccessibleListener#getName(org.eclipse.swt.accessibility.AccessibleEvent) + */ + @Override + public void getName(AccessibleEvent e) { + String filterTextString = filterText.getText(); + if (filterTextString.length() == 0 || filterTextString.equals(initialText)) { + e.result = initialText; + } else { + e.result = + NLS.bind( + XViewerText.get("XFilteredTree.matches"), new String[] {filterTextString, String.valueOf(getFilteredItemsCount())}); //$NON-NLS-1$ + } + } + + /** + * Return the number of filtered items + * + * @return int + */ + private int getFilteredItemsCount() { + int total = 0; + TreeItem[] items = getViewer().getTree().getItems(); + for (int i = 0; i < items.length; i++) { + total += itemCount(items[i]); + + } + return total; + } + + /** + * Return the count of treeItem and it's children to infinite depth. + * + * @param treeItem + * @return int + */ + private int itemCount(TreeItem treeItem) { + int count = 1; + TreeItem[] children = treeItem.getItems(); + for (int i = 0; i < children.length; i++) { + count += itemCount(children[i]); + + } + return count; + } + }); + + filterText.addListener(SWT.FocusIn, e -> { + if (!useNewLook) { + /* + * Running in an asyncExec because the selectAll() does not appear to work when + * using mouse to give focus to text. + */ + Display display = filterText.getDisplay(); + display.asyncExec(() -> { + if (!filterText.isDisposed()) { + if (getInitialText().equals(filterText.getText().trim())) { + filterText.selectAll(); + } + } + }); + return; + } + }); + + filterText.addListener(SWT.FocusOut, e -> { + if (!useNewLook) { + return; + } + if (filterText.getText().equals(initialText)) { + setFilterText(""); //$NON-NLS-1$ + textChanged(); + } + }); + + if (useNewLook) { + filterText.addListener(SWT.MouseDown, e -> { + if (filterText.getText().equals(initialText)) { + // XXX: We cannot call clearText() due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=260664 + setFilterText(""); //$NON-NLS-1$ + textChanged(); + } + }); + } + + filterText.addListener(SWT.KeyDown, e-> { + // on a CR we want to transfer focus to the list + boolean hasItems = getViewer().getTree().getItemCount() > 0; + if (hasItems && e.keyCode == SWT.ARROW_DOWN) { + treeViewer.getTree().setFocus(); + return; + } + }); + + // enter key set focus to tree + filterText.addListener(SWT.Traverse, e-> { + if (e.detail == SWT.TRAVERSE_RETURN) { + e.doit = false; + if (getViewer().getTree().getItemCount() == 0) { + Display.getCurrent().beep(); + } else { + // if the initial filter text hasn't changed, do not try + // to match + boolean hasFocus = getViewer().getTree().setFocus(); + boolean textChanged = !getInitialText().equals(filterText.getText().trim()); + if (hasFocus && textChanged && filterText.getText().trim().length() > 0) { + Tree tree = getViewer().getTree(); + TreeItem item; + if (tree.getSelectionCount() > 0) { + item = getFirstMatchingItem(tree.getSelection()); + } else { + item = getFirstMatchingItem(tree.getItems()); + } + if (item != null) { + tree.setSelection(new TreeItem[] {item}); + ISelection sel = getViewer().getSelection(); + getViewer().setSelection(sel, true); + } + } + } + } + }); + + filterText.addListener(SWT.Modify, e-> textChanged()); + + // if we're using a field with built in cancel we need to listen for + // default selection changes (which tell us the cancel button has been + // pressed) + if ((filterText.getStyle() & SWT.ICON_CANCEL) != 0) { + filterText.addListener(SWT.DefaultSelection, e-> { + if (e.detail == SWT.ICON_CANCEL) { + clearText(); + } + }); + } + + GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); + // if the text widget supported cancel then it will have it's own + // integrated button. We can take all of the space. + if ((filterText.getStyle() & SWT.ICON_CANCEL) != 0) { + gridData.horizontalSpan = 2; + } + filterText.setLayoutData(gridData); + } + + /** + * Creates the text control for entering the filter text. Subclasses may override. + * + * @param parent the parent composite + * @return the text widget + * @since 3.3 + */ + protected Text doCreateFilterText(Composite parent) { + if (!useNewLook || useNativeSearchField(parent)) { + return new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL); + } + return new Text(parent, SWT.SINGLE); + } + + private String previousFilterText; + + private boolean narrowingDown; + + /** + * Update the receiver after the text has changed. + */ + protected void textChanged() { + narrowingDown = + previousFilterText == null || previousFilterText.equals(XViewerText.get("XFilteredTree.filter")) || getFilterString().startsWith( //$NON-NLS-1$ + previousFilterText); + previousFilterText = getFilterString(); + // cancel currently running job first, to prevent unnecessary redraw + refreshJob.cancel(); + refreshJob.schedule(getRefreshJobDelay()); + } + + /** + * Return the time delay that should be used when scheduling the filter refresh job. Subclasses may override. + * + * @return a time delay in milliseconds before the job should run + * @since 3.5 + */ + protected long getRefreshJobDelay() { + return 200; + } + + /** + * Set the background for the widgets that support the filter text area. + * + * @param background background Color to set + */ + @Override + public void setBackground(Color background) { + super.setBackground(background); + if (filterComposite != null && (!useNewLook || useNativeSearchField(filterComposite))) { + filterComposite.setBackground(background); + } + if (filterToolBar != null && filterToolBar.getControl() != null) { + filterToolBar.getControl().setBackground(background); + } + } + + /** + * Create the button that clears the text. + * + * @param parent parent Composite of toolbar button + */ + private void createClearTextOld(Composite parent) { + // only create the button if the text widget doesn't support one + // natively + if ((filterText.getStyle() & SWT.ICON_CANCEL) == 0) { + filterToolBar = new ToolBarManager(SWT.FLAT | SWT.HORIZONTAL); + filterToolBar.createControl(parent); + + IAction clearTextAction = new Action("", IAction.AS_PUSH_BUTTON) {//$NON-NLS-1$ + /** + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + clearText(); + } + }; + + clearTextAction.setToolTipText(XViewerText.get("button.clear")); //$NON-NLS-1$ + clearTextAction.setImageDescriptor(JFaceResources.getImageRegistry().getDescriptor(CLEAR_ICON)); + clearTextAction.setDisabledImageDescriptor(JFaceResources.getImageRegistry().getDescriptor(DISABLED_CLEAR_ICON)); + + filterToolBar.add(clearTextAction); + } + } + + /** + * Create the button that clears the text. + * + * @param parent parent Composite of toolbar button + */ + private void createClearTextNew(Composite parent) { + // only create the button if the text widget doesn't support one + // natively + if ((filterText.getStyle() & SWT.ICON_CANCEL) == 0) { + final Image inactiveImage = XViewerImageCache.getImage("clear.gif"); //$NON-NLS-1$ + final Image activeImage = inactiveImage; + final Image pressedImage = inactiveImage; + + final Label clearButton = new Label(parent, SWT.NONE); + clearButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + clearButton.setImage(inactiveImage); + clearButton.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + clearButton.setToolTipText(XViewerText.get("button.clear")); //$NON-NLS-1$ + clearButton.addMouseListener(new MouseAdapter() { + private MouseMoveListener fMoveListener; + + @Override + public void mouseDown(MouseEvent e) { + clearButton.setImage(pressedImage); + fMoveListener = new MouseMoveListener() { + private boolean fMouseInButton = true; + + @Override + public void mouseMove(MouseEvent e) { + boolean mouseInButton = isMouseInButton(e); + if (mouseInButton != fMouseInButton) { + fMouseInButton = mouseInButton; + clearButton.setImage(mouseInButton ? pressedImage : inactiveImage); + } + } + }; + clearButton.addMouseMoveListener(fMoveListener); + } + + @Override + public void mouseUp(MouseEvent e) { + if (fMoveListener != null) { + clearButton.removeMouseMoveListener(fMoveListener); + fMoveListener = null; + boolean mouseInButton = isMouseInButton(e); + clearButton.setImage(mouseInButton ? activeImage : inactiveImage); + if (mouseInButton) { + clearText(); + filterText.setFocus(); + } + } + } + + private boolean isMouseInButton(MouseEvent e) { + Point buttonSize = clearButton.getSize(); + return 0 <= e.x && e.x < buttonSize.x && 0 <= e.y && e.y < buttonSize.y; + } + }); + + clearButton.addListener(SWT.MouseEnter, e-> clearButton.setImage(activeImage)); + + clearButton.addListener(SWT.MouseExit, e-> clearButton.setImage(inactiveImage)); + + clearButton.getAccessible().addAccessibleListener(new AccessibleAdapter() { + @Override + public void getName(AccessibleEvent e) { + e.result = XViewerText.get("XFilteredTree.filter.clear"); //$NON-NLS-1$ + } + }); + clearButton.getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() { + @Override + public void getRole(AccessibleControlEvent e) { + e.detail = ACC.ROLE_PUSHBUTTON; + } + }); + this.clearButtonControl = clearButton; + } + } + + /** + * Clears the text in the filter text widget. + */ + protected void clearText() { + setFilterText(""); //$NON-NLS-1$ + textChanged(); + } + + /** + * Set the text in the filter control. + * + * @param string + */ + protected void setFilterText(String string) { + if (filterText != null) { + filterText.setText(string); + selectAll(); + } + } + + /** + * Returns the pattern filter used by this tree. + * + * @return The pattern filter; never null. + */ + public final PatternFilter getPatternFilter() { + return patternFilter; + } + + /** + * Get the tree viewer of the receiver. + * + * @return the tree viewer + */ + public TreeViewer getViewer() { + return treeViewer; + } + + /** + * Get the filter text for the receiver, if it was created. Otherwise return null. + * + * @return the filter Text, or null if it was not created + */ + public Text getFilterControl() { + return filterText; + } + + /** + * Convenience method to return the text of the filter control. If the text widget is not created, then null is + * returned. + * + * @return String in the text, or null if the text does not exist + */ + protected String getFilterString() { + return filterText != null ? filterText.getText() : null; + } + + /** + * Set the text that will be shown until the first focus. A default value is provided, so this method only need be + * called if overriding the default initial text is desired. + * + * @param text initial text to appear in text field + */ + public void setInitialText(String text) { + initialText = text; + if (useNewLook && filterText != null) { + filterText.setMessage(text); + if (filterText.isFocusControl()) { + setFilterText(initialText); + textChanged(); + } else { + getDisplay().asyncExec(() -> { + if (!filterText.isDisposed() && filterText.isFocusControl()) { + setFilterText(initialText); + textChanged(); + } + }); + } + } else { + setFilterText(initialText); + textChanged(); + } + } + + /** + * Select all text in the filter text field. + */ + protected void selectAll() { + if (filterText != null) { + filterText.selectAll(); + } + } + + /** + * Get the initial text for the receiver. + * + * @return String + */ + protected String getInitialText() { + return initialText; + } + + /** + * Return a bold font if the given element matches the given pattern. Clients can opt to call this method from a + * Viewer's label provider to get a bold font for which to highlight the given element in the tree. + * + * @param element element for which a match should be determined + * @param tree FilteredTree in which the element resides + * @param filter PatternFilter which determines a match + * @return bold font + */ + public static Font getBoldFont(Object element, XFilteredTree tree, PatternFilter filter) { + String filterText = tree.getFilterString(); + + if (filterText == null) { + return null; + } + + // Do nothing if it's empty string + String initialText = tree.getInitialText(); + if (!filterText.equals("") && !filterText.equals(initialText)) {//$NON-NLS-1$ + if (tree.getPatternFilter() != filter) { + boolean initial = initialText != null && initialText.equals(filterText); + if (initial) { + filter.setPattern(null); + } else { + filter.setPattern(filterText); + } + } + if (filter.isElementVisible(tree.getViewer(), element) && filter.isLeafMatch(tree.getViewer(), element)) { + return JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT); + } + } + return null; + } + + /** + * Custom tree viewer subclass that clears the caches in patternFilter on any change to the tree. See bug 187200. + * + * @since 3.3 + */ + class NotifyingTreeViewer extends TreeViewer { + + /** + * @param parent + * @param style + */ + public NotifyingTreeViewer(Composite parent, int style) { + super(parent, style); + } + + @Override + public void add(Object parentElementOrTreePath, Object childElement) { + getPatternFilter().clearCaches(); + super.add(parentElementOrTreePath, childElement); + } + + @Override + public void add(Object parentElementOrTreePath, Object... childElements) { + getPatternFilter().clearCaches(); + super.add(parentElementOrTreePath, childElements); + } + + @Override + protected void inputChanged(Object input, Object oldInput) { + getPatternFilter().clearCaches(); + super.inputChanged(input, oldInput); + } + + @Override + public void insert(Object parentElementOrTreePath, Object element, int position) { + getPatternFilter().clearCaches(); + super.insert(parentElementOrTreePath, element, position); + } + + @Override + public void refresh() { + getPatternFilter().clearCaches(); + super.refresh(); + } + + @Override + public void refresh(boolean updateLabels) { + getPatternFilter().clearCaches(); + super.refresh(updateLabels); + } + + @Override + public void refresh(Object element) { + getPatternFilter().clearCaches(); + super.refresh(element); + } + + @Override + public void refresh(Object element, boolean updateLabels) { + getPatternFilter().clearCaches(); + super.refresh(element, updateLabels); + } + + @Override + public void remove(Object elementsOrTreePaths) { + getPatternFilter().clearCaches(); + super.remove(elementsOrTreePaths); + } + + @Override + public void remove(Object parent, Object... elements) { + getPatternFilter().clearCaches(); + super.remove(parent, elements); + } + + @Override + public void remove(Object... elementsOrTreePaths) { + getPatternFilter().clearCaches(); + super.remove(elementsOrTreePaths); + } + + @Override + public void replace(Object parentElementOrTreePath, int index, Object element) { + getPatternFilter().clearCaches(); + super.replace(parentElementOrTreePath, index, element); + } + + @Override + public void setChildCount(Object elementOrTreePath, int count) { + getPatternFilter().clearCaches(); + super.setChildCount(elementOrTreePath, count); + } + + @Override + public void setContentProvider(IContentProvider provider) { + getPatternFilter().clearCaches(); + super.setContentProvider(provider); + } + + @Override + public void setHasChildren(Object elementOrTreePath, boolean hasChildren) { + getPatternFilter().clearCaches(); + super.setHasChildren(elementOrTreePath, hasChildren); + } + + } + +} diff --git a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/images/XViewerImageCache.java b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/images/XViewerImageCache.java index aef246e83..d1201d1f8 100644 --- a/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/images/XViewerImageCache.java +++ b/widgets/xviewer/org.eclipse.nebula.widgets.xviewer/src/org/eclipse/nebula/widgets/xviewer/util/internal/images/XViewerImageCache.java @@ -1,46 +1,46 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.nebula.widgets.xviewer.util.internal.images; - -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.Image; - -/** - * @author Donald G. Dunne - */ -public class XViewerImageCache { - - static Map imageCache = new HashMap<>(); - static Map imageDescriptorCache = new HashMap<>(); - - public static Image getImage(String imageName) { - if (!imageCache.containsKey(imageName)) { - imageCache.put(imageName, getImageDescriptor(imageName).createImage()); - } - return imageCache.get(imageName); - } - - public static ImageDescriptor getImageDescriptor(String imageName) { - if (!imageDescriptorCache.containsKey(imageName)) { - URL url = XViewerImageCache.class.getResource(imageName); - imageDescriptorCache.put(imageName, ImageDescriptor.createFromURL(url)); - } - return imageDescriptorCache.get(imageName); - } - -} +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.nebula.widgets.xviewer.util.internal.images; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; + +/** + * @author Donald G. Dunne + */ +public class XViewerImageCache { + + static Map imageCache = new HashMap<>(); + static Map imageDescriptorCache = new HashMap<>(); + + public static Image getImage(String imageName) { + if (!imageCache.containsKey(imageName)) { + imageCache.put(imageName, getImageDescriptor(imageName).createImage()); + } + return imageCache.get(imageName); + } + + public static ImageDescriptor getImageDescriptor(String imageName) { + if (!imageDescriptorCache.containsKey(imageName)) { + URL url = XViewerImageCache.class.getResource(imageName); + imageDescriptorCache.put(imageName, ImageDescriptor.createFromURL(url)); + } + return imageDescriptorCache.get(imageName); + } + +}