package org.erlide.ui.prefs; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; 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.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.erlide.ui.editors.erl.folding.IErlangFoldingPreferenceBlock; import org.erlide.ui.internal.ErlideUIPlugin; import org.erlide.ui.internal.folding.ErlangFoldingStructureProviderDescriptor; import org.erlide.ui.internal.folding.ErlangFoldingStructureProviderRegistry; import org.erlide.ui.prefs.plugin.PreferencesMessages; import org.erlide.ui.util.OverlayPreferenceStore; import org.erlide.ui.util.PixelConverter; public class FoldingConfigurationBlock implements IPreferenceConfigurationBlock { private static class ErrorPreferences implements IErlangFoldingPreferenceBlock { private final String fMessage; protected ErrorPreferences(final String message) { fMessage = message; } /* * @see org.eclipse.jdt.internal.ui.text.folding.IErlangFoldingPreferences# * createControl(org.eclipse.swt.widgets.Group) */ @Override public Control createControl(final Composite composite) { final Composite inner = new Composite(composite, SWT.NONE); inner.setLayout(new FillLayout(SWT.VERTICAL)); final Label label = new Label(inner, SWT.CENTER); label.setText(fMessage); return inner; } @Override public void initialize() { } @Override public void performOk() { } @Override public void performDefaults() { } @Override public void dispose() { } } /** The overlay preference store. */ final OverlayPreferenceStore fStore; /* The controls */ private Combo fProviderCombo; Button fFoldingCheckbox; private ComboViewer fProviderViewer; private Composite fGroup; private StackLayout fStackLayout; /* the model */ final Map<String, ErlangFoldingStructureProviderDescriptor> fProviderDescriptors; private final Map<String, IErlangFoldingPreferenceBlock> fProviderPreferences; private final Map<String, Control> fProviderControls; public FoldingConfigurationBlock(final OverlayPreferenceStore store) { fStore = store; fStore.addKeys(createOverlayStoreKeys()); fProviderDescriptors = createListModel(); fProviderPreferences = new HashMap<>(); fProviderControls = new HashMap<>(); } private Map<String, ErlangFoldingStructureProviderDescriptor> createListModel() { final ErlangFoldingStructureProviderRegistry reg = ErlideUIPlugin.getDefault() .getFoldingStructureProviderRegistry(); reg.reloadExtensions(); final ErlangFoldingStructureProviderDescriptor[] descs = reg .getFoldingProviderDescriptors(); final Map<String, ErlangFoldingStructureProviderDescriptor> map = new HashMap<>(); for (final ErlangFoldingStructureProviderDescriptor element : descs) { map.put(element.getId(), element); } return map; } private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() { final ArrayList<OverlayPreferenceStore.OverlayKey> overlayKeys = new ArrayList<>(); overlayKeys.add(new OverlayPreferenceStore.OverlayKey( OverlayPreferenceStore.TypeDescriptor.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_ENABLED)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey( OverlayPreferenceStore.TypeDescriptor.STRING, PreferenceConstants.EDITOR_FOLDING_PROVIDER)); return overlayKeys .toArray(new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]); } /** * Creates page for folding preferences. * * @param parent * the parent composite * @return the control for the preference page */ @Override public Control createControl(final Composite parent) { final Composite composite = new Composite(parent, SWT.NULL); // assume parent page uses griddata GridData gd = new GridData( GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL); composite.setLayoutData(gd); final GridLayout layout = new GridLayout(); layout.numColumns = 2; final PixelConverter pc = new PixelConverter(composite); layout.verticalSpacing = pc.convertHeightInCharsToPixels(1) / 2; composite.setLayout(layout); /* check box for new editors */ fFoldingCheckbox = new Button(composite, SWT.CHECK); fFoldingCheckbox.setText(PreferencesMessages.FoldingConfigurationBlock_enable); gd = new GridData( GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); fFoldingCheckbox.setLayoutData(gd); fFoldingCheckbox.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(final SelectionEvent e) { final boolean enabled = fFoldingCheckbox.getSelection(); fStore.setValue(PreferenceConstants.EDITOR_FOLDING_ENABLED, enabled); updateCheckboxDependencies(); } @Override public void widgetDefaultSelected(final SelectionEvent e) { } }); Label label = new Label(composite, SWT.CENTER); gd = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); label.setLayoutData(gd); if (fProviderDescriptors.size() > 1) { /* list */ final Composite comboComp = new Composite(composite, SWT.NONE); gd = new GridData( GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); final GridLayout gridLayout = new GridLayout(2, false); gridLayout.marginWidth = 0; comboComp.setLayout(gridLayout); final Label comboLabel = new Label(comboComp, SWT.CENTER); gd = new GridData( GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER); comboLabel.setLayoutData(gd); comboLabel .setText(PreferencesMessages.FoldingConfigurationBlock_combo_caption); label = new Label(composite, SWT.CENTER); gd = new GridData( GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); label.setLayoutData(gd); fProviderCombo = new Combo(comboComp, SWT.READ_ONLY | SWT.DROP_DOWN); gd = new GridData( GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); fProviderCombo.setLayoutData(gd); fProviderViewer = createProviderViewer(); } final Composite groupComp = new Composite(composite, SWT.NONE); gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 2; groupComp.setLayoutData(gd); final GridLayout gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 0; groupComp.setLayout(gridLayout); /* contributed provider preferences. */ fGroup = new Composite(groupComp, SWT.NONE); gd = new GridData( GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); fGroup.setLayoutData(gd); fStackLayout = new StackLayout(); fGroup.setLayout(fStackLayout); return composite; } private ComboViewer createProviderViewer() { /* list viewer */ final ComboViewer viewer = new ComboViewer(fProviderCombo); viewer.setContentProvider(new IStructuredContentProvider() { /* * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ @Override public void dispose() { } /* * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse * .jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ @Override public void inputChanged(final Viewer v, final Object oldInput, final Object newInput) { } /* * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements * (java.lang.Object) */ @Override public Object[] getElements(final Object inputElement) { return fProviderDescriptors.values().toArray(); } }); viewer.setLabelProvider(new LabelProvider() { /* * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object ) */ @Override public Image getImage(final Object element) { return null; } /* * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) */ @Override public String getText(final Object element) { return ((ErlangFoldingStructureProviderDescriptor) element).getName(); } }); viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(final SelectionChangedEvent event) { final IStructuredSelection sel = (IStructuredSelection) event .getSelection(); if (!sel.isEmpty()) { fStore.setValue(PreferenceConstants.EDITOR_FOLDING_PROVIDER, ((ErlangFoldingStructureProviderDescriptor) sel .getFirstElement()).getId()); updateListDependencies(); } } }); viewer.setInput(fProviderDescriptors); viewer.refresh(); return viewer; } void updateCheckboxDependencies() { } void updateListDependencies() { final String id = fStore.getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER); final ErlangFoldingStructureProviderDescriptor desc = fProviderDescriptors .get(id); IErlangFoldingPreferenceBlock prefs; if (desc == null) { // safety in case there is no such descriptor final String message = PreferencesMessages.FoldingConfigurationBlock_error_not_exist; ErlideUIPlugin.log(new Status(IStatus.WARNING, ErlideUIPlugin.PLUGIN_ID, IStatus.OK, message, null)); prefs = new ErrorPreferences(message); } else { prefs = fProviderPreferences.get(id); if (prefs == null) { try { prefs = desc.createPreferences(); fProviderPreferences.put(id, prefs); } catch (final CoreException e) { ErlideUIPlugin.log(e); prefs = new ErrorPreferences(e.getLocalizedMessage()); } } } Control control = fProviderControls.get(id); if (control == null) { control = prefs.createControl(fGroup); if (control == null) { final String message = PreferencesMessages.FoldingConfigurationBlock_info_no_preferences; control = new ErrorPreferences(message).createControl(fGroup); } else { fProviderControls.put(id, control); } } Dialog.applyDialogFont(control); fStackLayout.topControl = control; control.pack(); fGroup.layout(); fGroup.getParent().layout(); prefs.initialize(); } @Override public void initialize() { restoreFromPreferences(); } @Override public void performOk() { for (final Object element : fProviderPreferences.values()) { final IErlangFoldingPreferenceBlock prefs = (IErlangFoldingPreferenceBlock) element; prefs.performOk(); } } @Override public void performDefaults() { restoreFromPreferences(); for (final Object element : fProviderPreferences.values()) { final IErlangFoldingPreferenceBlock prefs = (IErlangFoldingPreferenceBlock) element; prefs.performDefaults(); } } @Override public void dispose() { for (final Object element : fProviderPreferences.values()) { final IErlangFoldingPreferenceBlock prefs = (IErlangFoldingPreferenceBlock) element; prefs.dispose(); } } private void restoreFromPreferences() { final boolean enabled = fStore .getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); fFoldingCheckbox.setSelection(enabled); updateCheckboxDependencies(); final String id = fStore.getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER); final Object provider = fProviderDescriptors.get(id); if (provider != null) { if (fProviderViewer == null) { updateListDependencies(); } else { fProviderViewer.setSelection(new StructuredSelection(provider), true); } } } }