Skip to content

Commit

Permalink
Repair combo-box in layout preference page #640
Browse files Browse the repository at this point in the history
Selecting any element in the default layout manager combo box always
reverts back to the implicit layout. But this should only happen, if the
element is unchecked in the table below.

The input of the combo is adapted whenever the checked state of the
table changes, to ensure that the user is only allowed to set those
layouts as default, which are checked.

This change also converts the raw SWT widgets into their matching JFace
viewers, to allow us to work directly on the LayoutDescription objects,
rather than on e.g. Strings.
  • Loading branch information
ptziegler committed Nov 24, 2023
1 parent 3c7faeb commit b6a03f5
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,25 @@
import org.eclipse.wb.internal.core.utils.ui.GridLayoutFactory;
import org.eclipse.wb.internal.core.utils.ui.UiUtils;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ICheckStateProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;

import org.apache.commons.lang.StringUtils;
import org.osgi.service.prefs.BackingStoreException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
Expand All @@ -52,13 +56,15 @@
* @coverage core.preferences.ui
*/
public abstract class LayoutsPreferencePage extends AbstractBindingPreferencesPage {
private final IEclipsePreferences m_layoutPreferences;
////////////////////////////////////////////////////////////////////////////
//
// Constructor
//
////////////////////////////////////////////////////////////////////////////
public LayoutsPreferencePage(ToolkitDescription toolkit) {
super(toolkit);
m_layoutPreferences = InstanceScope.INSTANCE.getNode(IEditorPreferenceConstants.P_AVAILABLE_LAYOUTS_NODE);
}

////////////////////////////////////////////////////////////////////////////
Expand All @@ -74,7 +80,7 @@ protected AbstractBindingComposite createBindingComposite(Composite parent) {
@Override
public boolean performOk() {
try {
InstanceScope.INSTANCE.getNode(IEditorPreferenceConstants.P_AVAILABLE_LAYOUTS_NODE).flush();
m_layoutPreferences.flush();
} catch (BackingStoreException e) {
e.printStackTrace();
}
Expand All @@ -87,6 +93,8 @@ public boolean performOk() {
//
////////////////////////////////////////////////////////////////////////////
protected class ContentsComposite extends AbstractBindingComposite {
private final CheckboxTableViewer m_table;

public ContentsComposite(Composite parent,
DataBindManager bindManager,
IPreferenceStore preferences) {
Expand All @@ -96,9 +104,18 @@ public ContentsComposite(Composite parent,
// default layout
{
new Label(this, SWT.NONE).setText(UiMessages.LayoutsPreferencePage_defaultLayout);
final Combo layoutCombo = new Combo(this, SWT.READ_ONLY);
GridDataFactory.create(layoutCombo).grabH().fillH();
UiUtils.setVisibleItemCount(layoutCombo, 15);
final ISelection implicitLayoutSelection = new StructuredSelection(
UiMessages.LayoutsPreferencePage_implicitLayout);
final ComboViewer layoutCombo = new ComboViewer(this, SWT.READ_ONLY);
layoutCombo.setContentProvider(ArrayContentProvider.getInstance());
layoutCombo.setLabelProvider(ColumnLabelProvider.createTextProvider(o -> {
if (o instanceof LayoutDescription layout) {
return layout.getName();
}
return (String) o;
}));
GridDataFactory.create(layoutCombo.getCombo()).grabH().fillH();
UiUtils.setVisibleItemCount(layoutCombo.getCombo(), 15);
// prepare layouts
final List<LayoutDescription> layouts = LayoutDescriptionHelper.get(m_toolkit);
Collections.sort(layouts, new Comparator<LayoutDescription>() {
Expand All @@ -114,91 +131,66 @@ public int compare(LayoutDescription layout_1, LayoutDescription layout_2) {
layoutCombo.add(layoutDescription.getName());
}
}

layoutCombo.addSelectionListener(new SelectionListener() {

@Override
public void widgetSelected(SelectionEvent e) {
// If a layout is specified as a default layout but the layout is not specified
// to be available in the table
// the default layout is set back to implicit layout
int index = layoutCombo.getSelectionIndex();
LayoutDescription layout = layouts.get(index - 1);
if (!isLayoutAvailable(layout)) {
layoutCombo.select(0);
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {

}

});
// bind
m_bindManager.bind(new IDataEditor() {
@Override
public void setValue(Object value) {
String id = (String) value;
// implicit layout
if (StringUtils.isEmpty(id)) {
layoutCombo.select(0);
layoutCombo.setSelection(implicitLayoutSelection);
return;
}
// find layout by id
for (int index = 0; index < layouts.size(); index++) {
LayoutDescription layout = layouts.get(index);
if (layout.getId().equals(id)) {
layoutCombo.select(1 + index);
layoutCombo.setSelection(new StructuredSelection(layout));
}
}
}

@Override
public Object getValue() {
int index = layoutCombo.getSelectionIndex();
if (index <= 0) {
// implicit layout
return null;
} else {
LayoutDescription layout = layouts.get(index - 1);
if (isLayoutAvailable(layout)) {
return layout.getId();
}
return null;

if (layoutCombo.getStructuredSelection()
.getFirstElement() instanceof LayoutDescription layout) {
return layout.getId();
}
// implicit layout
return null;
}
},
new StringPreferenceProvider(m_preferences, IPreferenceConstants.P_LAYOUT_DEFAULT), true);
new Label(this, SWT.NONE).setText(UiMessages.LayoutsPreferencePage_availableLayouts);
Table table = new Table(this, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
for (LayoutDescription layout : layouts) {
TableItem checkItem = new TableItem(table, SWT.NONE);
checkItem.setText(layout.getName());
checkItem.setData(layout);
checkItem.setChecked(
InstanceScope.INSTANCE.getNode(
IEditorPreferenceConstants.P_AVAILABLE_LAYOUTS_NODE).getBoolean(
layout.getLayoutClassName(),
true));
}
table.addListener(SWT.Selection, event -> {
if (event.detail == SWT.CHECK) {
InstanceScope.INSTANCE.getNode(
IEditorPreferenceConstants.P_AVAILABLE_LAYOUTS_NODE).putBoolean(
((LayoutDescription) ((TableItem) event.item).getData()).getLayoutClassName(),
((TableItem) event.item).getChecked());
m_table = CheckboxTableViewer.newCheckList(this, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
m_table.setContentProvider(ArrayContentProvider.getInstance());
m_table.setLabelProvider(ColumnLabelProvider.createTextProvider(o -> ((LayoutDescription)o).getName()));
m_table.setCheckStateProvider(new ICheckStateProvider() {
@Override
public boolean isChecked(Object element) {
return m_layoutPreferences.getBoolean(((LayoutDescription) element).getLayoutClassName(), true);
}
// If default was set to a layoiut that is deselcted from available layouts. The
// default layout is set back to implicit layout
if (!((TableItem) event.item).getChecked()
&& ((LayoutDescription) ((TableItem) event.item).getData()).getName()
.contentEquals(layoutCombo.getText())) {
layoutCombo.select(0);

@Override
public boolean isGrayed(Object element) {
return false;
}
});
GridDataFactory.create(table).fillH().spanH(gridLayoutColumns);
m_table.setInput(layouts);
m_table.addCheckStateListener(event -> {
LayoutDescription layout = (LayoutDescription) event.getElement();
m_layoutPreferences.putBoolean(layout.getLayoutClassName(), event.getChecked());
// If default was set to a layout that is de-selected from available layouts.
// The default layout is set back to implicit layout
List<Object> layoutItems = new ArrayList<>();
layoutItems.add(UiMessages.LayoutsPreferencePage_implicitLayout);
layoutItems.addAll(List.of(m_table.getCheckedElements()));
layoutCombo.setInput(layoutItems.toArray());
if (layoutCombo.getStructuredSelection().isEmpty()) {
layoutCombo.setSelection(implicitLayoutSelection);
}
});
GridDataFactory.create(m_table.getTable()).fillH().spanH(gridLayoutColumns);
}
// boolean preferences
checkButton(
Expand All @@ -208,10 +200,4 @@ public Object getValue() {
IPreferenceConstants.P_LAYOUT_OF_PARENT);
}
}

private static boolean isLayoutAvailable(LayoutDescription layout) {
return InstanceScope.INSTANCE.getNode(IEditorPreferenceConstants.P_AVAILABLE_LAYOUTS_NODE)
.getBoolean(layout.getLayoutClassName(), false);

}
}
2 changes: 1 addition & 1 deletion org.eclipse.wb.rcp.doc.user/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.wb.rcp.doc.user;singleton:=true
Bundle-Version: 1.9.3.qualifier
Bundle-Version: 1.9.400.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-ActivationPolicy: lazy
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ <h2>Default layout manager</h2>
<p>This preference controls the default layout manager that <b>SWT Designer</b> uses
for any new frame or panel. The default is to use the implicit layout
manager already in effect for each container (e.g., BorderLayout for JFrames
and FlowLayout for JPanels).<h2>Containers automatically use layout
manager type of parent</h2>
and FlowLayout for JPanels).
<h2>Layouts to use</h2>
<p>This preference controls the layouts which can be selected in the
default layout manager and also which layouts are available in the
Design editor page.<br> If a layout is unchecked that is currently set
as default layout, the selection in the default layout manager control
is cleared, with the implict layout being used as default again.
<h2>Containers automatically use layout manager type of parent</h2>
<p>This preference determines whether new panels will use the layout
manager of their parent's by default.<h2>Create variable for Layout
using pattern</h2>
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.wb.swing.doc.user/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.wb.swing.doc.user;singleton:=true
Bundle-Version: 1.9.3.qualifier
Bundle-Version: 1.9.400.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-17
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ <h2>Default layout manager</h2>
<p>This preference controls the default layout manager that <b>Swing Designer</b> uses
for any new frame or panel. The default is to use the implicit layout
manager already in effect for each container (e.g., BorderLayout for JFrames
and FlowLayout for JPanels).<h2>Containers automatically use layout
manager type of parent</h2>
and FlowLayout for JPanels).
<h2>Layouts to use</h2>
<p>This preference controls the layouts which can be selected in the
default layout manager and also which layouts are available in the
Design editor page.<br> If a layout is unchecked that is currently set
as default layout, the selection in the default layout manager control
is cleared, with the implict layout being used as default again.
<h2>Containers automatically use layout manager type of parent</h2>
<p>This preference determines whether new panels will use the layout
manager of their parent's by default.<h2>Create variable for Layout
using pattern</h2>
Expand Down

0 comments on commit b6a03f5

Please sign in to comment.