/*******************************************************************************
* Copyright (c) 2010, SAP AG.
* 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:
* Mathias Kinzler (SAP AG) - initial implementation
*******************************************************************************/
package org.eclipse.egit.ui.internal.preferences;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.Path;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.BaseLabelProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.SameShellProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
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;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.ide.FileStoreEditorInput;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.model.WorkbenchAdapter;
import org.eclipse.ui.model.WorkbenchContentProvider;
/**
* A reusable UI component to display and edit a Git configuration.
* <p>
* Concrete subclasses that are interested in displaying error messages should
* override {@link #setErrorMessage(String)}
* <p>
* TODO: do the changes in memory and offer methods to obtain dirty state, to
* save, and something like setDirty(boolean) to be implemented by subclasses so
* that proper save/revert can be implemented; we could also offer this for
* non-stored configurations
*/
public class ConfigurationEditorComponent {
private final static String DOT = "."; //$NON-NLS-1$
private StoredConfig editableConfig;
private final IShellProvider shellProvider;
private final Composite parent;
private final boolean useDialogFont;
private Composite contents;
private Button newValue;
private Button remove;
private TreeViewer tv;
private Text location;
private boolean editable;
/**
* @param parent
* the parent
* @param config
* to be used instead of the user configuration
* @param useDialogFont
* if <code>true</code>, the current dialog font is used
*/
public ConfigurationEditorComponent(Composite parent, StoredConfig config,
boolean useDialogFont) {
editableConfig = config;
this.shellProvider = new SameShellProvider(parent);
this.parent = parent;
this.useDialogFont = useDialogFont;
}
void setConfig(FileBasedConfig config) throws IOException {
editableConfig = config;
try {
editableConfig.clear();
editableConfig.load();
} catch (ConfigInvalidException e) {
throw new IOException(e.getMessage());
}
initControlsFromConfig();
}
/**
* Saves and (in case of success) reloads the current configuration
*
* @throws IOException
*/
public void save() throws IOException {
editableConfig.save();
setDirty(false);
initControlsFromConfig();
}
/**
* Restores and (in case of success) reloads the current configuration
*
* @throws IOException
*/
public void restore() throws IOException {
try {
editableConfig.clear();
editableConfig.load();
} catch (ConfigInvalidException e) {
throw new IOException(e.getMessage());
}
initControlsFromConfig();
}
/**
* @return the control being created
*/
public Control createContents() {
final Composite main = new Composite(parent, SWT.NONE);
main.setLayout(new GridLayout(2, false));
GridDataFactory.fillDefaults().grab(true, true).applyTo(main);
if (editableConfig instanceof FileBasedConfig) {
Composite locationPanel = new Composite(main, SWT.NONE);
locationPanel.setLayout(new GridLayout(4, false));
GridDataFactory.fillDefaults().grab(true, false).span(2, 1)
.applyTo(locationPanel);
Label locationLabel = new Label(locationPanel, SWT.NONE);
locationLabel
.setText(UIText.ConfigurationEditorComponent_ConfigLocationLabel);
// GridDataFactory.fillDefaults().applyTo(locationLabel);
int locationStyle = SWT.BORDER|SWT.READ_ONLY;
location = new Text(locationPanel, locationStyle);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).applyTo(location);
Button openEditor = new Button(locationPanel, SWT.PUSH);
openEditor
.setText(UIText.ConfigurationEditorComponent_OpenEditorButton);
openEditor
.setToolTipText(UIText.ConfigurationEditorComponent_OpenEditorTooltip);
openEditor.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
IFileStore store = EFS.getLocalFileSystem().getStore(
new Path(((FileBasedConfig) editableConfig)
.getFile().getAbsolutePath()));
try {
IDE.openEditor(PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage(),
new FileStoreEditorInput(store),
EditorsUI.DEFAULT_TEXT_EDITOR_ID);
} catch (PartInitException ex) {
Activator.handleError(ex.getMessage(), ex, true);
}
}
});
openEditor
.setEnabled(((FileBasedConfig) editableConfig).getFile() != null);
}
tv = new TreeViewer(main, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER);
Tree tree = tv.getTree();
GridDataFactory.fillDefaults().hint(100, 60).grab(true, true)
.applyTo(tree);
TreeColumn key = new TreeColumn(tree, SWT.NONE);
key.setText(UIText.ConfigurationEditorComponent_KeyColumnHeader);
key.setWidth(150);
final TextCellEditor editor = new TextCellEditor(tree);
editor.setValidator(new ICellEditorValidator() {
@Override
public String isValid(Object value) {
String editedValue = value.toString();
return editedValue.length() > 0 ? null
: UIText.ConfigurationEditorComponent_EmptyStringNotAllowed;
}
});
editor.addListener(new ICellEditorListener() {
@Override
public void editorValueChanged(boolean oldValidState,
boolean newValidState) {
setErrorMessage(editor.getErrorMessage());
}
@Override
public void cancelEditor() {
setErrorMessage(null);
}
@Override
public void applyEditorValue() {
setErrorMessage(null);
}
});
TreeColumn value = new TreeColumn(tree, SWT.NONE);
value.setText(UIText.ConfigurationEditorComponent_ValueColumnHeader);
value.setWidth(250);
new TreeViewerColumn(tv, value)
.setEditingSupport(new EditingSupport(tv) {
@Override
protected void setValue(Object element, Object newValue) {
Entry entry = (Entry) element;
if (!entry.value.equals(newValue)) {
entry.changeValue(newValue.toString());
markDirty();
}
}
@Override
protected Object getValue(Object element) {
return ((Entry) element).value;
}
@Override
protected CellEditor getCellEditor(Object element) {
return editor;
}
@Override
protected boolean canEdit(Object element) {
return editable && element instanceof Entry;
}
});
tv.setContentProvider(new WorkbenchContentProvider());
Font defaultFont;
if (useDialogFont)
defaultFont = JFaceResources.getDialogFont();
else
defaultFont = JFaceResources.getDefaultFont();
tv.setLabelProvider(new ConfigEditorLabelProvider(defaultFont));
tree.setHeaderVisible(true);
tree.setLinesVisible(true);
Composite buttonPanel = new Composite(main, SWT.NONE);
GridLayoutFactory.fillDefaults().applyTo(buttonPanel);
GridDataFactory.fillDefaults().grab(false, false).applyTo(buttonPanel);
newValue = new Button(buttonPanel, SWT.PUSH);
GridDataFactory.fillDefaults().applyTo(newValue);
newValue.setText(UIText.ConfigurationEditorComponent_AddButton);
newValue.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String suggestedKey;
IStructuredSelection sel = (IStructuredSelection) tv
.getSelection();
Object first = sel.getFirstElement();
if (first instanceof Section)
suggestedKey = ((Section) first).name + DOT;
else if (first instanceof SubSection) {
SubSection sub = (SubSection) first;
suggestedKey = sub.parent.name + DOT + sub.name + DOT;
} else if (first instanceof Entry) {
Entry entry = (Entry) first;
if (entry.sectionparent != null)
suggestedKey = entry.sectionparent.name + DOT;
else
suggestedKey = entry.subsectionparent.parent.name + DOT
+ entry.subsectionparent.name + DOT;
} else
suggestedKey = null;
AddConfigEntryDialog dlg = new AddConfigEntryDialog(getShell(),
suggestedKey);
if (dlg.open() == Window.OK) {
String result = dlg.getKey();
if (result == null) {
// bug in swt bot, see
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=472110
return;
}
StringTokenizer st = new StringTokenizer(result, DOT);
if (st.countTokens() == 2) {
String sectionName = st.nextToken();
String entryName = st.nextToken();
Entry entry = ((GitConfig) tv.getInput()).getEntry(
sectionName, null, entryName);
if (entry == null)
editableConfig.setString(sectionName, null,
entryName, dlg.getValue());
else
entry.addValue(dlg.getValue());
markDirty();
} else if (st.countTokens() > 2) {
int n = st.countTokens();
String sectionName = st.nextToken();
StringBuilder b = new StringBuilder(st.nextToken());
for (int i = 0; i < n - 3; i++) {
b.append(DOT);
b.append(st.nextToken());
}
String subSectionName = b.toString();
String entryName = st.nextToken();
Entry entry = ((GitConfig) tv.getInput()).getEntry(
sectionName, subSectionName, entryName);
if (entry == null)
editableConfig.setString(sectionName,
subSectionName, entryName, dlg.getValue());
else
entry.addValue(dlg.getValue());
markDirty();
} else
Activator
.handleError(
UIText.ConfigurationEditorComponent_WrongNumberOfTokensMessage,
null, true);
}
}
});
remove = new Button(buttonPanel, SWT.PUSH);
GridDataFactory.fillDefaults().applyTo(remove);
remove.setText(UIText.ConfigurationEditorComponent_RemoveButton);
remove.setToolTipText(UIText.ConfigurationEditorComponent_RemoveTooltip);
remove.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
IStructuredSelection sel = (IStructuredSelection) tv
.getSelection();
Object first = sel.getFirstElement();
if (first instanceof Section) {
Section section = (Section) first;
if (MessageDialog
.openConfirm(
getShell(),
UIText.ConfigurationEditorComponent_RemoveSectionTitle,
NLS.bind(
UIText.ConfigurationEditorComponent_RemoveSectionMessage,
section.name))) {
editableConfig.unsetSection(section.name, null);
markDirty();
}
} else if (first instanceof SubSection) {
SubSection section = (SubSection) first;
if (MessageDialog
.openConfirm(
getShell(),
UIText.ConfigurationEditorComponent_RemoveSubsectionTitle,
NLS.bind(
UIText.ConfigurationEditorComponent_RemoveSubsectionMessage,
section.parent.name + DOT
+ section.name))) {
editableConfig.unsetSection(section.parent.name,
section.name);
markDirty();
}
} else if (first instanceof Entry) {
((Entry) first).removeValue();
markDirty();
} else
Activator
.handleError(
UIText.ConfigurationEditorComponent_NoSectionSubsectionMessage,
null, true);
super.widgetSelected(e);
}
});
tv.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
updateEnablement();
}
});
initControlsFromConfig();
contents = main;
return contents;
}
/**
* @return the composite containing all the controls
*/
public Composite getContents() {
return contents;
}
private boolean isWriteable(final File f) {
if (f.exists())
if (f.isFile())
if (f.canWrite())
return true;
else
return false;
else
return false;
// no file, can we create one
for (File d = f.getParentFile(); d != null; d = d.getParentFile())
if (d.isDirectory())
if (d.canWrite())
return true;
else
return false;
else if (d.exists())
return false;
// else continue
return false;
}
private void initControlsFromConfig() {
try {
editableConfig.load();
tv.setInput(new GitConfig(editableConfig));
editable = true;
if (editableConfig instanceof FileBasedConfig) {
FileBasedConfig fileConfig = (FileBasedConfig) editableConfig;
File configFile = fileConfig.getFile();
if (configFile != null)
if (isWriteable(configFile))
location.setText(configFile.getPath());
else {
location.setText(NLS
.bind(UIText.ConfigurationEditorComponent_ReadOnlyLocationFormat,
configFile.getPath()));
editable = false;
}
else {
location.setText(UIText.ConfigurationEditorComponent_NoConfigLocationKnown);
editable = false;
}
}
} catch (IOException e) {
Activator.handleError(e.getMessage(), e, true);
} catch (ConfigInvalidException e) {
Activator.handleError(e.getMessage(), e, true);
}
tv.expandAll();
updateEnablement();
}
/**
* @param message
* the error message to display
*/
protected void setErrorMessage(String message) {
// the default implementation does nothing
}
/**
* @param dirty
* the dirty flag
*/
protected void setDirty(boolean dirty) {
// the default implementation does nothing
}
private void updateEnablement() {
remove.setEnabled(editable);
newValue.setEnabled(editable);
}
private void markDirty() {
setDirty(true);
((GitConfig) tv.getInput()).refresh();
tv.refresh();
}
private final static class GitConfig extends WorkbenchAdapter {
private final Config config;
private Section[] children;
GitConfig(Config config) {
this.config = config;
}
GitConfig refresh() {
children = null;
return this;
}
@Override
public Object[] getChildren(Object o) {
if (children == null)
if (config != null) {
List<Section> sections = new ArrayList<>();
Set<String> sectionNames = config.getSections();
for (String sectionName : sectionNames)
sections.add(new Section(this, sectionName));
Collections.sort(sections, new Comparator<Section>() {
@Override
public int compare(Section o1, Section o2) {
return o1.name.compareTo(o2.name);
}
});
children = sections.toArray(new Section[sections.size()]);
} else
children = new Section[0];
return children;
}
public Entry getEntry(String sectionName, String subsectionName,
String entryName) {
for (Object child : getChildren(this)) {
Section section = (Section) child;
if (sectionName.equals(section.name))
return section.getEntry(subsectionName, entryName);
}
return null;
}
}
private final static class Section extends WorkbenchAdapter {
private final String name;
private final GitConfig parent;
private Object[] children;
Section(GitConfig parent, String name) {
this.parent = parent;
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + 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;
Section other = (Section) obj;
if (!name.equals(other.name))
return false;
return true;
}
@Override
public Object getParent(Object object) {
return parent;
}
@Override
public Object[] getChildren(Object o) {
if (children == null) {
List<Object> allChildren = new ArrayList<>();
Set<String> subSectionNames = parent.config
.getSubsections(name);
for (String subSectionName : subSectionNames)
allChildren.add(new SubSection(parent.config, this,
subSectionName));
Set<String> entryNames = parent.config.getNames(name);
for (String entryName : entryNames) {
String[] values = parent.config.getStringList(name, null,
entryName);
if (values.length == 1)
allChildren.add(new Entry(this, entryName, values[0],
-1));
else {
int index = 0;
for (String value : values)
allChildren.add(new Entry(this, entryName, value,
index++));
}
}
children = allChildren.toArray();
}
return children;
}
@Override
public String getLabel(Object o) {
return name;
}
public Entry getEntry(String subsectionName, String entryName) {
if (subsectionName != null) {
for (Object child : getChildren(this))
if (child instanceof SubSection
&& ((SubSection) child).name.equals(subsectionName))
return ((SubSection) child).getEntry(entryName);
} else
for (Object child : getChildren(this))
if (child instanceof Entry
&& ((Entry) child).name.equals(entryName))
return (Entry) child;
return null;
}
}
private final static class SubSection extends WorkbenchAdapter {
private final Config config;
private final Section parent;
private final String name;
private Entry[] children;
SubSection(Config config, Section parent, String name) {
this.config = config;
this.parent = parent;
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + name.hashCode();
result = prime * result + parent.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;
SubSection other = (SubSection) obj;
if (!name.equals(other.name))
return false;
if (!parent.equals(other.parent))
return false;
return true;
}
@Override
public Object[] getChildren(Object o) {
if (children == null) {
List<Entry> entries = new ArrayList<>();
Set<String> entryNames = config.getNames(parent.name, name);
for (String entryName : entryNames) {
String[] values = config.getStringList(parent.name, name,
entryName);
if (values.length == 1)
entries.add(new Entry(this, entryName, values[0], -1));
else {
int index = 0;
for (String value : values)
entries.add(new Entry(this, entryName, value,
index++));
}
}
children = entries.toArray(new Entry[entries.size()]);
}
return children;
}
@Override
public String getLabel(Object o) {
return name;
}
@Override
public Object getParent(Object object) {
return parent;
}
public Entry getEntry(String entryName) {
for (Object child : getChildren(this))
if (entryName.equals(((Entry) child).name))
return (Entry) child;
return null;
}
}
private final static class Entry extends WorkbenchAdapter {
private final Section sectionparent;
private final SubSection subsectionparent;
private final String name;
private final String value;
private final int index;
Entry(Section parent, String name, String value, int index) {
this.sectionparent = parent;
this.subsectionparent = null;
this.name = name;
this.value = value;
this.index = index;
}
public void addValue(String newValue) {
if (newValue.length() == 0)
throw new IllegalArgumentException(
UIText.ConfigurationEditorComponent_EmptyStringNotAllowed);
Config config = getConfig();
List<String> entries;
if (sectionparent != null) {
// Arrays.asList returns a fixed-size list, so we need to copy
// over to a mutable list
entries = new ArrayList<>(Arrays.asList(config
.getStringList(sectionparent.name, null, name)));
entries.add(Math.max(index, 0), newValue);
config.setStringList(sectionparent.name, null, name, entries);
} else {
// Arrays.asList returns a fixed-size list, so we need to copy
// over to a mutable list
entries = new ArrayList<>(Arrays.asList(config
.getStringList(subsectionparent.parent.name,
subsectionparent.name, name)));
entries.add(Math.max(index, 0), newValue);
config.setStringList(subsectionparent.parent.name,
subsectionparent.name, name, entries);
}
}
Entry(SubSection parent, String name, String value, int index) {
this.sectionparent = null;
this.subsectionparent = parent;
this.name = name;
this.value = value;
this.index = index;
}
public void changeValue(String newValue)
throws IllegalArgumentException {
if (newValue.length() == 0)
throw new IllegalArgumentException(
UIText.ConfigurationEditorComponent_EmptyStringNotAllowed);
Config config = getConfig();
if (index < 0) {
if (sectionparent != null)
config.setString(sectionparent.name, null, name, newValue);
else
config.setString(subsectionparent.parent.name,
subsectionparent.name, name, newValue);
} else {
String[] entries;
if (sectionparent != null) {
entries = config.getStringList(sectionparent.name, null,
name);
entries[index] = newValue;
config.setStringList(sectionparent.name, null, name,
Arrays.asList(entries));
} else {
entries = config.getStringList(
subsectionparent.parent.name,
subsectionparent.name, name);
entries[index] = newValue;
config.setStringList(subsectionparent.parent.name,
subsectionparent.name, name, Arrays.asList(entries));
}
}
}
private Config getConfig() {
Config config;
if (sectionparent != null)
config = sectionparent.parent.config;
else
config = subsectionparent.parent.parent.config;
return config;
}
public void removeValue() {
Config config = getConfig();
if (index < 0) {
if (sectionparent != null)
config.unset(sectionparent.name, null, name);
else
config.unset(subsectionparent.parent.name,
subsectionparent.name, name);
} else {
List<String> entries;
if (sectionparent != null) {
// Arrays.asList returns a fixed-size list, so we need to
// copy over to a mutable list
entries = new ArrayList<>(Arrays.asList(config
.getStringList(sectionparent.name, null, name)));
entries.remove(index);
config.setStringList(sectionparent.name, null, name,
entries);
} else {
// Arrays.asList returns a fixed-size list, so we need to
// copy over to a mutable list
entries = new ArrayList<>(Arrays.asList(config
.getStringList(subsectionparent.parent.name,
subsectionparent.name, name)));
// the list is fixed-size, so we have to copy over
entries.remove(index);
config.setStringList(subsectionparent.parent.name,
subsectionparent.name, name, entries);
}
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + index;
result = prime * result + name.hashCode();
result = prime * result
+ ((sectionparent == null) ? 0 : sectionparent.hashCode());
result = prime
* result
+ ((subsectionparent == null) ? 0 : subsectionparent
.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;
Entry other = (Entry) obj;
// the index may change between 0 and -1 when values are added
if (index != other.index && (index > 0 || other.index > 0))
return false;
if (!name.equals(other.name))
return false;
if (sectionparent == null) {
if (other.sectionparent != null)
return false;
} else if (!sectionparent.equals(other.sectionparent))
return false;
if (subsectionparent == null) {
if (other.subsectionparent != null)
return false;
} else if (!subsectionparent.equals(other.subsectionparent))
return false;
return true;
}
}
private static final class ConfigEditorLabelProvider extends
BaseLabelProvider implements ITableLabelProvider, IFontProvider {
private Font boldFont = null;
private final Font defaultFont;
public ConfigEditorLabelProvider(Font defaultFont) {
this.defaultFont = defaultFont;
}
@Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
switch (columnIndex) {
case 0:
if (element instanceof Section)
return ((Section) element).name;
if (element instanceof SubSection)
return ((SubSection) element).name;
if (element instanceof Entry) {
Entry entry = (Entry) element;
if (entry.index < 0)
return entry.name;
return entry.name + "[" + entry.index + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
return null;
case 1:
if (element instanceof Entry)
return ((Entry) element).value;
return null;
default:
return null;
}
}
@Override
public Font getFont(Object element) {
if (element instanceof Section || element instanceof SubSection)
return getBoldFont();
else
return null;
}
private Font getBoldFont() {
if (boldFont != null)
return boldFont;
FontData[] data = defaultFont.getFontData();
for (int i = 0; i < data.length; i++)
data[i].setStyle(data[i].getStyle() | SWT.BOLD);
boldFont = new Font(Display.getDefault(), data);
return boldFont;
}
@Override
public void dispose() {
if (boldFont != null)
boldFont.dispose();
super.dispose();
}
}
private Shell getShell() {
return shellProvider.getShell();
}
}