| /******************************************************************************* |
| * Copyright (c) 2001, 2005 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| * Jens Lukowski/Innoopract - initial renaming/restructuring |
| * |
| *******************************************************************************/ |
| package org.eclipse.wst.sse.ui.internal.preferences.ui; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.preference.PreferencePage; |
| import org.eclipse.jface.text.Assert; |
| import org.eclipse.jface.viewers.ArrayContentProvider; |
| import org.eclipse.jface.viewers.CheckStateChangedEvent; |
| import org.eclipse.jface.viewers.CheckboxTableViewer; |
| import org.eclipse.jface.viewers.ColumnWeightData; |
| import org.eclipse.jface.viewers.ICheckStateListener; |
| import org.eclipse.jface.viewers.ITableLabelProvider; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TableLayout; |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.events.KeyListener; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.events.ModifyListener; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.graphics.FontMetrics; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.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.Table; |
| import org.eclipse.swt.widgets.TableColumn; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.wst.sse.ui.internal.SSEUIMessages; |
| import org.eclipse.wst.sse.ui.internal.SSEUIPlugin; |
| import org.eclipse.wst.sse.ui.internal.editor.IHelpContextIds; |
| import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames; |
| import org.eclipse.wst.sse.ui.internal.preferences.OverlayPreferenceStore; |
| import org.eclipse.wst.sse.ui.internal.taginfo.TextHoverManager; |
| import org.eclipse.wst.sse.ui.internal.taginfo.TextHoverManager.TextHoverDescriptor; |
| import org.eclipse.wst.sse.ui.internal.util.EditorUtility; |
| |
| /** |
| * Preference tab for Structured text editor hover help preferences |
| * |
| * @author amywu |
| */ |
| public class TextHoverPreferenceTab extends AbstractPreferenceTab { |
| |
| private class InternalTableLabelProvider extends LabelProvider implements ITableLabelProvider { |
| public InternalTableLabelProvider() { |
| super(); |
| } |
| |
| public Image getColumnImage(Object element, int columnIndex) { |
| return null; |
| } |
| |
| public String getColumnText(Object element, int columnIndex) { |
| switch (columnIndex) { |
| case 0 : // text hover label |
| return ((TextHoverManager.TextHoverDescriptor) element).getLabel(); |
| |
| case 1 : // text hover state mask |
| return ((TextHoverManager.TextHoverDescriptor) element).getModifierString(); |
| |
| default : |
| break; |
| } |
| |
| return null; |
| } |
| } |
| |
| private static final String DELIMITER = SSEUIMessages.TextHoverPreferenceTab_delimiter; //$NON-NLS-1$ |
| private Text fDescription; |
| private Table fHoverTable; |
| private TableViewer fHoverTableViewer; |
| private TableColumn fModifierColumn; |
| // for this preference page |
| private Text fModifierEditor; |
| private TableColumn fNameColumn; |
| |
| private TextHoverDescriptor[] fTextHovers; // current list of text hovers |
| |
| public TextHoverPreferenceTab(PreferencePage mainPreferencePage, OverlayPreferenceStore store) { |
| Assert.isNotNull(mainPreferencePage); |
| Assert.isNotNull(store); |
| setMainPreferencePage(mainPreferencePage); |
| setOverlayStore(store); |
| getOverlayStore().addKeys(createOverlayStoreKeys()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.sse.ui.preferences.ui.IPreferenceTab#createContents(org.eclipse.swt.widgets.Composite) |
| */ |
| public Control createContents(Composite tabFolder) { |
| Composite hoverComposite = new Composite(tabFolder, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| hoverComposite.setLayout(layout); |
| GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
| hoverComposite.setLayoutData(gd); |
| |
| // commented out until these preferences are actually handled in some |
| // way |
| // String rollOverLabel= |
| // ResourceHandler.getString("TextHoverPreferenceTab.annotationRollover"); |
| // //$NON-NLS-1$ |
| // addCheckBox(hoverComposite, rollOverLabel, |
| // CommonEditorPreferenceNames.EDITOR_ANNOTATION_ROLL_OVER, 0); |
| // |
| // // Affordance checkbox |
| // String showAffordanceLabel = |
| // ResourceHandler.getString("TextHoverPreferenceTab.showAffordance"); |
| // //$NON-NLS-1$ |
| // addCheckBox(hoverComposite, showAffordanceLabel, |
| // CommonEditorPreferenceNames.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE, 0); |
| |
| Label label = new Label(hoverComposite, SWT.NONE); |
| label.setText(SSEUIMessages.TextHoverPreferenceTab_hoverPreferences); //$NON-NLS-1$ |
| gd = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); |
| gd.horizontalAlignment = GridData.BEGINNING; |
| label.setLayoutData(gd); |
| |
| fHoverTableViewer = CheckboxTableViewer.newCheckList(hoverComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION); |
| // Hover table |
| fHoverTable = fHoverTableViewer.getTable(); |
| fHoverTable.setHeaderVisible(true); |
| fHoverTable.setLinesVisible(true); |
| |
| gd = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=104507 |
| GC gc = new GC(fHoverTable); |
| gc.setFont(fHoverTable.getFont()); |
| FontMetrics fontMetrics = gc.getFontMetrics(); |
| gc.dispose(); |
| int heightHint = Dialog.convertHeightInCharsToPixels(fontMetrics, 7); |
| gd.heightHint = heightHint; |
| |
| fHoverTable.setLayoutData(gd); |
| |
| TableLayout tableLayout = new TableLayout(); |
| tableLayout.addColumnData(new ColumnWeightData(1, 140, true)); |
| tableLayout.addColumnData(new ColumnWeightData(1, 140, true)); |
| fHoverTable.setLayout(tableLayout); |
| |
| fHoverTable.addSelectionListener(new SelectionListener() { |
| |
| public void widgetDefaultSelected(SelectionEvent e) { |
| } |
| |
| public void widgetSelected(SelectionEvent e) { |
| handleHoverListSelection(); |
| } |
| }); |
| |
| fNameColumn = new TableColumn(fHoverTable, SWT.NONE); |
| fNameColumn.setText(SSEUIMessages.TextHoverPreferenceTab_nameColumnTitle); //$NON-NLS-1$ |
| fNameColumn.setResizable(true); |
| |
| fModifierColumn = new TableColumn(fHoverTable, SWT.NONE); |
| fModifierColumn.setText(SSEUIMessages.TextHoverPreferenceTab_modifierColumnTitle); //$NON-NLS-1$ |
| fModifierColumn.setResizable(true); |
| |
| fHoverTableViewer.setUseHashlookup(true); |
| fHoverTableViewer.setContentProvider(new ArrayContentProvider()); |
| fHoverTableViewer.setLabelProvider(new InternalTableLabelProvider()); |
| ((CheckboxTableViewer) fHoverTableViewer).addCheckStateListener(new ICheckStateListener() { |
| /* |
| * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent) |
| */ |
| public void checkStateChanged(CheckStateChangedEvent event) { |
| String id = ((TextHoverDescriptor) event.getElement()).getId(); |
| if (id == null) |
| return; |
| |
| TextHoverManager.TextHoverDescriptor[] descriptors = getTextHoverManager().getTextHovers(); |
| TextHoverManager.TextHoverDescriptor hoverConfig = null; |
| int i = 0, length = fTextHovers.length; |
| while (i < length) { |
| if (id.equals(descriptors[i].getId())) { |
| hoverConfig = fTextHovers[i]; |
| hoverConfig.setEnabled(event.getChecked()); |
| fModifierEditor.setEnabled(event.getChecked()); |
| fHoverTableViewer.setSelection(new StructuredSelection(descriptors[i])); |
| } |
| i++; |
| } |
| |
| handleHoverListSelection(); |
| updateStatus(hoverConfig); |
| } |
| }); |
| |
| // Text field for modifier string |
| label = new Label(hoverComposite, SWT.LEFT); |
| label.setText(SSEUIMessages.TextHoverPreferenceTab_keyModifier); //$NON-NLS-1$ |
| fModifierEditor = new Text(hoverComposite, SWT.BORDER); |
| gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); |
| fModifierEditor.setLayoutData(gd); |
| |
| fModifierEditor.addKeyListener(new KeyListener() { |
| private boolean isModifierCandidate; |
| |
| public void keyPressed(KeyEvent e) { |
| isModifierCandidate = e.keyCode > 0 && e.character == 0 && e.stateMask == 0; |
| } |
| |
| public void keyReleased(KeyEvent e) { |
| if (isModifierCandidate && e.stateMask > 0 && e.stateMask == e.stateMask && e.character == 0) {// && |
| // e.time |
| // -time |
| // < |
| // 1000) |
| // { |
| String text = fModifierEditor.getText(); |
| Point selection = fModifierEditor.getSelection(); |
| int i = selection.x - 1; |
| while (i > -1 && Character.isWhitespace(text.charAt(i))) { |
| i--; |
| } |
| boolean needsPrefixDelimiter = i > -1 && !String.valueOf(text.charAt(i)).equals(DELIMITER); |
| |
| i = selection.y; |
| while (i < text.length() && Character.isWhitespace(text.charAt(i))) { |
| i++; |
| } |
| boolean needsPostfixDelimiter = i < text.length() && !String.valueOf(text.charAt(i)).equals(DELIMITER); |
| |
| String insertString; |
| |
| if (needsPrefixDelimiter && needsPostfixDelimiter) |
| insertString = NLS.bind(SSEUIMessages.TextHoverPreferenceTab_insertDelimiterAndModifierAndDelimiter, new String[]{Action.findModifierString(e.stateMask)}); |
| else if (needsPrefixDelimiter) |
| insertString = NLS.bind(SSEUIMessages.TextHoverPreferenceTab_insertDelimiterAndModifier, new String[]{Action.findModifierString(e.stateMask)}); |
| else if (needsPostfixDelimiter) |
| insertString = NLS.bind(SSEUIMessages.TextHoverPreferenceTab_insertModifierAndDelimiter, new String[]{Action.findModifierString(e.stateMask)}); |
| else |
| insertString = Action.findModifierString(e.stateMask); |
| |
| if (insertString != null) |
| fModifierEditor.insert(insertString); |
| } |
| } |
| }); |
| |
| fModifierEditor.addModifyListener(new ModifyListener() { |
| public void modifyText(ModifyEvent e) { |
| handleModifierModified(); |
| } |
| }); |
| |
| // Description |
| Label descriptionLabel = new Label(hoverComposite, SWT.LEFT); |
| descriptionLabel.setText(SSEUIMessages.TextHoverPreferenceTab_description); //$NON-NLS-1$ |
| gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); |
| gd.horizontalSpan = 2; |
| descriptionLabel.setLayoutData(gd); |
| fDescription = new Text(hoverComposite, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER); |
| gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1); |
| gd.horizontalSpan = 2; |
| fDescription.setLayoutData(gd); |
| |
| initialize(); |
| |
| Dialog.applyDialogFont(hoverComposite); |
| |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(hoverComposite, IHelpContextIds.PREFSTE_HOVERS_HELPID); |
| return hoverComposite; |
| } |
| |
| private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() { |
| ArrayList overlayKeys = new ArrayList(); |
| |
| overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, EditorPreferenceNames.EDITOR_TEXT_HOVER_MODIFIERS)); |
| |
| OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; |
| overlayKeys.toArray(keys); |
| return keys; |
| } |
| |
| private String generateTextHoverString() { |
| StringBuffer buf = new StringBuffer(); |
| |
| for (int i = 0; i < fTextHovers.length; i++) { |
| buf.append(fTextHovers[i].getId()); |
| buf.append(TextHoverManager.HOVER_ATTRIBUTE_SEPARATOR); |
| buf.append(Boolean.toString(fTextHovers[i].isEnabled())); |
| buf.append(TextHoverManager.HOVER_ATTRIBUTE_SEPARATOR); |
| String modifier = fTextHovers[i].getModifierString(); |
| if (modifier == null || modifier.length() == 0) |
| modifier = TextHoverManager.NO_MODIFIER; |
| buf.append(modifier); |
| buf.append(TextHoverManager.HOVER_SEPARATOR); |
| } |
| return buf.toString(); |
| } |
| |
| private TextHoverManager getTextHoverManager() { |
| return SSEUIPlugin.getDefault().getTextHoverManager(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.sse.ui.preferences.ui.IPreferenceTab#getTitle() |
| */ |
| public String getTitle() { |
| return SSEUIMessages.TextHoverPreferenceTab_title; //$NON-NLS-1$ |
| } |
| |
| void handleHoverListSelection() { |
| int i = fHoverTable.getSelectionIndex(); |
| |
| if (i == -1) { |
| if (fHoverTable.getSelectionCount() == 0) |
| fModifierEditor.setEnabled(false); |
| return; |
| } |
| |
| boolean enabled = fTextHovers[i].isEnabled(); |
| fModifierEditor.setEnabled(enabled); |
| fModifierEditor.setText(fTextHovers[i].getModifierString()); |
| String description = fTextHovers[i].getDescription(); |
| if (description == null) |
| description = ""; //$NON-NLS-1$ |
| fDescription.setText(description); |
| } |
| |
| private void handleModifierModified() { |
| int i = fHoverTable.getSelectionIndex(); |
| if (i == -1) |
| return; |
| |
| String modifiers = fModifierEditor.getText(); |
| fTextHovers[i].setModifierString(modifiers); |
| |
| // update table |
| fHoverTableViewer.refresh(fTextHovers[i]); |
| |
| updateStatus(fTextHovers[i]); |
| } |
| |
| private void initialize() { |
| restoreFromOverlay(); |
| fHoverTableViewer.setInput(fTextHovers); |
| |
| initializeFields(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.sse.ui.preferences.ui.AbstractPreferenceTab#initializeFields() |
| */ |
| protected void initializeFields() { |
| super.initializeFields(); |
| |
| fModifierEditor.setEnabled(false); |
| // initialize checkboxes in hover table |
| for (int i = 0; i < fTextHovers.length; i++) |
| fHoverTable.getItem(i).setChecked(fTextHovers[i].isEnabled()); |
| fHoverTableViewer.refresh(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.sse.ui.preferences.ui.IPreferenceTab#performApply() |
| */ |
| public void performApply() { |
| performOk(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.sse.ui.preferences.ui.IPreferenceTab#performDefaults() |
| */ |
| public void performDefaults() { |
| initialize(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.sse.ui.preferences.ui.IPreferenceTab#performOk() |
| */ |
| public void performOk() { |
| String textHoverString = generateTextHoverString(); |
| getOverlayStore().setValue(EditorPreferenceNames.EDITOR_TEXT_HOVER_MODIFIERS, textHoverString); |
| getTextHoverManager().resetTextHovers(); // notify text hover manager |
| // it should reset to get |
| // latest preferences |
| } |
| |
| /** |
| * Populates fTextHovers with text hover description from the overlay |
| * store (which is the preferences) |
| */ |
| private void restoreFromOverlay() { |
| String descriptorsString = getOverlayStore().getString(EditorPreferenceNames.EDITOR_TEXT_HOVER_MODIFIERS); |
| fTextHovers = getTextHoverManager().generateTextHoverDescriptors(descriptorsString); |
| } |
| |
| void updateStatus(TextHoverManager.TextHoverDescriptor hoverConfig) { |
| IStatus status = new StatusInfo(); |
| |
| if (hoverConfig != null && hoverConfig.isEnabled() && EditorUtility.computeStateMask(hoverConfig.getModifierString()) == -1) |
| status = new StatusInfo(IStatus.ERROR, NLS.bind(SSEUIMessages.TextHoverPreferenceTab_modifierIsNotValid, new String[]{hoverConfig.getModifierString()})); |
| |
| int i = 0; |
| HashMap stateMasks = new HashMap(fTextHovers.length); |
| while (status.isOK() && i < fTextHovers.length) { |
| if (fTextHovers[i].isEnabled()) { |
| String label = fTextHovers[i].getLabel(); |
| Integer stateMask = new Integer(EditorUtility.computeStateMask(fTextHovers[i].getModifierString())); |
| if (stateMask.intValue() == -1) |
| status = new StatusInfo(IStatus.ERROR, NLS.bind(SSEUIMessages.TextHoverPreferenceTab_modifierIsNotValidForHover, new String[]{fTextHovers[i].getModifierString(), label})); |
| else if (stateMasks.containsKey(stateMask)) |
| status = new StatusInfo(IStatus.ERROR, NLS.bind(SSEUIMessages.TextHoverPreferenceTab_duplicateModifier, new String[]{label, (String) stateMasks.get(stateMask)})); |
| else |
| stateMasks.put(stateMask, label); |
| } |
| i++; |
| } |
| |
| updateStatus(status); |
| } |
| } |