org.eclipse.pde.internal.ui.nls.ExternalizeStringsWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.pde.internal.ui.nls.ExternalizeStringsWizardPage.java

Source

/*******************************************************************************
 *  Copyright (c) 2005, 2013 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
 *******************************************************************************/
package org.eclipse.pde.internal.ui.nls;

import java.util.Properties;
import org.eclipse.core.filebuffers.*;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.*;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.internal.ui.*;
import org.eclipse.pde.internal.ui.editor.context.ManifestDocumentSetupParticipant;
import org.eclipse.pde.internal.ui.editor.context.XMLDocumentSetupParticpant;
import org.eclipse.pde.internal.ui.editor.text.*;
import org.eclipse.pde.internal.ui.refactoring.PDERefactor;
import org.eclipse.pde.internal.ui.wizards.ListUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;

public class ExternalizeStringsWizardPage extends UserInputWizardPage {

    public static final String PAGE_NAME = "ExternalizeStringsWizardPage"; //$NON-NLS-1$

    public static final int EXTERN = 0;
    public static final int VALUE = 1;
    public static final int KEY = 2;
    private static final int SIZE = 3; // column counter
    private static final String[] TABLE_PROPERTIES = new String[SIZE];
    private static final String[] TABLE_COLUMNS = new String[SIZE];

    static {
        TABLE_PROPERTIES[EXTERN] = "extern"; //$NON-NLS-1$
        TABLE_PROPERTIES[VALUE] = "value"; //$NON-NLS-1$
        TABLE_PROPERTIES[KEY] = "key"; //$NON-NLS-1$
        TABLE_COLUMNS[EXTERN] = ""; //$NON-NLS-1$
        TABLE_COLUMNS[VALUE] = PDEUIMessages.ExternalizeStringsWizardPage_value;
        TABLE_COLUMNS[KEY] = PDEUIMessages.ExternalizeStringsWizardPage_subKey;
    }

    private class ModelChangeContentProvider implements ITreeContentProvider {

        public Object[] getElements(Object parent) {
            return fModelChangeTable.getAllModelChanges().toArray();
        }

        public Object[] getChildren(Object parentElement) {
            if (!(parentElement instanceof ModelChange))
                return new Object[0];
            return ((ModelChange) parentElement).getModelChangeFiles();
        }

        public Object getParent(Object element) {
            if (element instanceof ModelChangeFile) {
                return ((ModelChangeFile) element).getModel();
            }
            return null;
        }

        public boolean hasChildren(Object element) {
            return element instanceof ModelChange;
        }

        public void dispose() {
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }
    }

    private class ExternalizeStringsCellModifier implements ICellModifier {

        public boolean canModify(Object element, String property) {
            return (property != null && (element instanceof ModelChangeElement)
                    && !TABLE_PROPERTIES[VALUE].equals(property)
                    && (isPageComplete() || element.equals(fErrorElement))
                    && (TABLE_PROPERTIES[KEY].equals(property) && ((ModelChangeElement) element).isExternalized()));

        }

        public Object getValue(Object element, String property) {
            if (element instanceof ModelChangeElement) {
                ModelChangeElement changeElement = (ModelChangeElement) element;
                if (TABLE_PROPERTIES[KEY].equals(property)) {
                    return StringHelper.unwindEscapeChars(changeElement.getKey());
                }
            }
            return ""; //$NON-NLS-1$
        }

        public void modify(Object element, String property, Object value) {
            if (element instanceof TableItem) {
                Object data = ((TableItem) element).getData();
                if (data instanceof ModelChangeElement) {
                    ModelChangeElement changeElement = (ModelChangeElement) data;
                    if (TABLE_PROPERTIES[KEY].equals(property)) {
                        String newKey = StringHelper.windEscapeChars((String) value);
                        validateKey(newKey, changeElement);
                        changeElement.setKey(newKey);
                        fPropertiesViewer.update(data, null);
                    }
                }
            }
        }
    }

    private ModelChangeTable fModelChangeTable;

    private ContainerCheckedTreeViewer fInputViewer;
    private Button fSelectAll;
    private Button fDeselectAll;
    private Label fProjectLabel;
    private Text fLocalizationText;
    private CheckboxTableViewer fPropertiesViewer;
    private Table fTable;
    private SourceViewer fSourceViewer;

    private ViewerFilter fErrorElementFilter;
    private ModifyListener fModifyListener;

    private Object fCurrSelection;
    private ModelChangeElement fErrorElement;
    private String fPreErrorKey;

    private IDocument fEmptyDoc;
    private IColorManager fColorManager;
    private XMLConfiguration fXMLConfig;
    private XMLDocumentSetupParticpant fXMLSetupParticipant;
    private ManifestDocumentSetupParticipant fManifestSetupParticipant;

    private ManifestConfiguration fManifestConfig;

    protected ExternalizeStringsWizardPage(ModelChangeTable changeTable) {
        super(PAGE_NAME);
        setTitle(PDEUIMessages.ExternalizeStringsWizardPage_pageTitle);
        setDescription(PDEUIMessages.ExternalizeStringsWizardPage_pageDescription);
        fModelChangeTable = changeTable;
        fErrorElementFilter = new ViewerFilter() {
            @Override
            public boolean select(Viewer viewer, Object parentElement, Object element) {
                if (!(element instanceof ModelChangeElement))
                    return false;
                ModelChangeElement change = (ModelChangeElement) element;
                return change.equals(fErrorElement);
            }
        };
        fModifyListener = new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                String localization = fLocalizationText.getText();
                if (StringHelper.isValidLocalization(localization)) {
                    setEnabled(fLocalizationText, true);
                    setPageComplete(hasCheckedElements());
                    setErrorMessage(null);
                    if (fCurrSelection instanceof ModelChange) {
                        ((ModelChange) fCurrSelection).setBundleLocalization(fLocalizationText.getText());
                    } else if (fCurrSelection instanceof ModelChangeFile) {
                        ((ModelChangeFile) fCurrSelection).getModel()
                                .setBundleLocalization(fLocalizationText.getText());
                    }
                } else {
                    setEnabled(fLocalizationText, false);
                    fLocalizationText.setEditable(true);
                    setPageComplete(false);
                    setErrorMessage(PDEUIMessages.ExternalizeStringsWizardPage_badLocalizationError);
                }
            }
        };
        fColorManager = ColorManager.getDefault();
        fXMLConfig = new XMLConfiguration(fColorManager);
        fXMLSetupParticipant = new XMLDocumentSetupParticpant();
        fManifestConfig = new ManifestConfiguration(fColorManager);
        fManifestSetupParticipant = new ManifestDocumentSetupParticipant();
    }

    @Override
    public void dispose() {
        fColorManager.dispose();
        super.dispose();
    }

    public void createControl(Composite parent) {

        SashForm superSash = new SashForm(parent, SWT.HORIZONTAL);
        superSash.setFont(parent.getFont());
        superSash.setLayoutData(new GridData(GridData.FILL_BOTH));

        createInputContents(superSash);

        SashForm sash = new SashForm(superSash, SWT.VERTICAL);
        sash.setFont(superSash.getFont());
        sash.setLayoutData(new GridData(GridData.FILL_BOTH));

        createTableViewer(sash);
        createSourceViewer(sash);
        initialize();

        setPageComplete(hasCheckedElements());

        superSash.setWeights(new int[] { 4, 7 });
        setControl(superSash);
        Dialog.applyDialogFont(superSash);

        PlatformUI.getWorkbench().getHelpSystem().setHelp(superSash, IHelpContextIds.EXTERNALIZE_STRINGS_PAGE);
    }

    private void createInputContents(Composite composite) {
        Composite fileComposite = new Composite(composite, SWT.NONE);
        fileComposite.setLayout(new GridLayout());
        fileComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

        Label label = new Label(fileComposite, SWT.NONE);
        label.setText(PDEUIMessages.ExternalizeStringsWizardPage_resourcelabel);
        fInputViewer = new ContainerCheckedTreeViewer(fileComposite,
                SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE | SWT.BORDER);
        fInputViewer.setContentProvider(new ModelChangeContentProvider());
        fInputViewer.setLabelProvider(new ModelChangeLabelProvider());
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.heightHint = 250;
        fInputViewer.getTree().setLayoutData(gd);
        fInputViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                handleSelectionChanged(event);
            }
        });
        fInputViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                setPageComplete(hasCheckedElements());
            }
        });
        fInputViewer.setComparator(ListUtil.PLUGIN_COMPARATOR);

        Composite buttonComposite = new Composite(fileComposite, SWT.NONE);
        GridLayout layout = new GridLayout(2, true);
        layout.marginHeight = layout.marginWidth = 0;
        buttonComposite.setLayout(layout);
        buttonComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        fSelectAll = new Button(buttonComposite, SWT.PUSH);
        fSelectAll.setText(PDEUIMessages.ExternalizeStringsWizardPage_selectAllButton);
        fSelectAll.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        fSelectAll.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                fInputViewer.setCheckedElements(fModelChangeTable.getAllModelChanges().toArray());
                setPageComplete(hasCheckedElements());
            }
        });
        fDeselectAll = new Button(buttonComposite, SWT.PUSH);
        fDeselectAll.setText(PDEUIMessages.ExternalizeStringsWizardPage_deselectAllButton);
        fDeselectAll.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        fDeselectAll.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                fInputViewer.setCheckedElements(new Object[0]);
                setPageComplete(hasCheckedElements());
            }
        });

        Composite infoComposite = new Composite(fileComposite, SWT.NONE);
        layout = new GridLayout();
        layout.marginHeight = 0;
        infoComposite.setLayout(layout);
        infoComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        Label project = new Label(infoComposite, SWT.NONE);
        project.setText(PDEUIMessages.ExternalizeStringsWizardPage_projectLabel);
        fProjectLabel = new Label(infoComposite, SWT.NONE);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalIndent = 10;
        fProjectLabel.setLayoutData(gd);
        fProjectLabel.setText(PDEUIMessages.ExternalizeStringsWizardPage_noUnderlyingResource);

        Label properties = new Label(infoComposite, SWT.NONE);
        properties.setText(PDEUIMessages.ExternalizeStringsWizardPage_localizationLabel);
        fLocalizationText = new Text(infoComposite, SWT.BORDER);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalIndent = 10;
        fLocalizationText.setLayoutData(gd);
        fLocalizationText.setText(PDEUIMessages.ExternalizeStringsWizardPage_noUnderlyingResource);
        fLocalizationText.addModifyListener(fModifyListener);

        fInputViewer.setInput(PDEPlugin.getDefault());
    }

    private void createTableViewer(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setFont(parent.getFont());
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setLayout(new GridLayout());

        Label label = new Label(composite, SWT.NONE);
        label.setText(PDEUIMessages.ExternalizeStringsWizardPage_propertiesLabel);
        label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        fPropertiesViewer = CheckboxTableViewer.newCheckList(composite,
                SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.HIDE_SELECTION | SWT.BORDER);
        fTable = fPropertiesViewer.getTable();
        fTable.setFont(composite.getFont());
        fTable.setLayoutData(new GridData(GridData.FILL_BOTH));
        fTable.setLayout(new GridLayout());
        fTable.setLinesVisible(true);
        fTable.setHeaderVisible(true);

        for (int i = 0; i < TABLE_COLUMNS.length; i++) {
            TableColumn tc = new TableColumn(fTable, SWT.NONE);
            tc.setText(TABLE_COLUMNS[i]);
            tc.setResizable(i != 0);
            tc.setWidth(i == 0 ? 20 : 200);
        }

        fPropertiesViewer.setUseHashlookup(true);
        fPropertiesViewer.setCellEditors(createCellEditors());
        fPropertiesViewer.setColumnProperties(TABLE_PROPERTIES);
        fPropertiesViewer.setCellModifier(new ExternalizeStringsCellModifier());
        fPropertiesViewer.setContentProvider(new IStructuredContentProvider() {
            public Object[] getElements(Object inputElement) {
                if (fInputViewer.getSelection() instanceof IStructuredSelection) {
                    Object selection = ((IStructuredSelection) fInputViewer.getSelection()).getFirstElement();
                    if (selection instanceof ModelChangeFile) {
                        ModelChangeFile cf = (ModelChangeFile) selection;
                        return (cf).getModel().getChangesInFile(cf.getFile()).toArray();
                    }
                }
                return new Object[0];
            }

            public void dispose() {
            }

            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            }
        });
        fPropertiesViewer.setLabelProvider(new ExternalizeStringsLabelProvider());
        fPropertiesViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                handlePropertySelection();
            }
        });
        fPropertiesViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                Object element = event.getElement();
                if (element instanceof ModelChangeElement) {
                    ((ModelChangeElement) element).setExternalized(event.getChecked());
                    fPropertiesViewer.update(element, null);
                }
            }
        });
        fPropertiesViewer.setInput(new Object());
    }

    private void createSourceViewer(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setLayout(new GridLayout());

        Label label = new Label(composite, SWT.NONE);
        label.setText(PDEUIMessages.ExternalizeStringsWizardPage_sourceLabel);
        label.setLayoutData(new GridData());

        fSourceViewer = new SourceViewer(composite, null, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
        fSourceViewer.setEditable(false);
        fSourceViewer.getTextWidget().setFont(JFaceResources.getTextFont());
        fSourceViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));

        fEmptyDoc = new Document();
        fSourceViewer.setDocument(fEmptyDoc);
    }

    // must set selection after source viewer is created, otherwise you get an NPE.
    private void initialize() {
        Object[] preSelect = fModelChangeTable.getPreSelected();
        fInputViewer.setSelection(new StructuredSelection(preSelect));
        fInputViewer.setCheckedElements(fModelChangeTable.getPreSelected());
    }

    private void handleSelectionChanged(SelectionChangedEvent event) {
        if (!(event.getSelection() instanceof IStructuredSelection))
            return;
        Object selection = (((IStructuredSelection) event.getSelection()).getFirstElement());
        if (selection == null) {
            fCurrSelection = null;
            fSourceViewer.setDocument(fEmptyDoc);
        } else if (selection.equals(fCurrSelection)) {
            return;
        } else if (selection instanceof ModelChangeFile) {
            fCurrSelection = selection;
            IFile file = ((ModelChangeFile) fCurrSelection).getFile();
            NullProgressMonitor monitor = new NullProgressMonitor();
            ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
            try {
                try {
                    manager.connect(file.getFullPath(), LocationKind.IFILE, monitor);
                    updateSourceViewer(manager, file);
                } catch (MalformedTreeException e) {
                } finally {
                    manager.disconnect(file.getFullPath(), LocationKind.IFILE, monitor);
                }
            } catch (CoreException e) {
            }
        } else if (selection instanceof ModelChange) {
            fCurrSelection = selection;
            fSourceViewer.setDocument(fEmptyDoc);
            updatePropertiesLabel(((ModelChange) fCurrSelection).getParentModel());
        }
        refreshPropertiesViewer(false);
    }

    private void refreshPropertiesViewer(boolean updateLabels) {
        fPropertiesViewer.refresh(updateLabels);
        TableItem[] items = fTable.getItems();
        for (int i = 0; i < items.length; i++) {
            if (!(items[i].getData() instanceof ModelChangeElement))
                continue;
            ModelChangeElement element = (ModelChangeElement) items[i].getData();
            fPropertiesViewer.setChecked(element, element.isExternalized());
        }
    }

    private void updateSourceViewer(ITextFileBufferManager manager, IFile sourceFile) {
        IDocument document = manager.getTextFileBuffer(sourceFile.getFullPath(), LocationKind.IFILE).getDocument();
        TreeItem item = fInputViewer.getTree().getSelection()[0];
        IPluginModelBase model = ((ModelChange) item.getParentItem().getData()).getParentModel();

        if (fSourceViewer.getDocument() != null)
            fSourceViewer.unconfigure();
        if (sourceFile.getFileExtension().equalsIgnoreCase("xml")) { //$NON-NLS-1$
            fSourceViewer.configure(fXMLConfig);
            fXMLSetupParticipant.setup(document);
        } else {
            fSourceViewer.configure(fManifestConfig);
            fManifestSetupParticipant.setup(document);
        }

        fSourceViewer.setDocument(document);
        updatePropertiesLabel(model);
    }

    private void updatePropertiesLabel(IPluginModelBase model) {
        ModelChange modelChange = fModelChangeTable.getModelChange(model);
        fProjectLabel.setText(model.getUnderlyingResource().getProject().getName());
        fLocalizationText.setEditable(!modelChange.localizationSet());
        fLocalizationText.setText(modelChange.getBundleLocalization());
    }

    private void handlePropertySelection() {
        if (!(fPropertiesViewer.getSelection() instanceof IStructuredSelection))
            return;
        Object selection = (((IStructuredSelection) fPropertiesViewer.getSelection()).getFirstElement());
        if (selection instanceof ModelChangeElement && fSourceViewer.getDocument() != null) {
            ModelChangeElement element = (ModelChangeElement) selection;
            int offset = element.getOffset();
            int length = element.getLength();
            fSourceViewer.setSelectedRange(offset, length);
            fSourceViewer.revealRange(offset, length);
        }
    }

    private CellEditor[] createCellEditors() {
        final CellEditor editors[] = new CellEditor[SIZE];
        editors[EXTERN] = null;
        editors[VALUE] = null;
        editors[KEY] = new TextCellEditor(fTable);
        return editors;
    }

    private void validateKey(String key, ModelChangeElement element) {
        ModelChange modelChange = ((ModelChangeFile) fCurrSelection).getModel();
        Properties properties = modelChange.getProperties();
        String error = null;
        String oldKey = (fPreErrorKey != null) ? fPreErrorKey : element.getKey();
        if (key.equals(fPreErrorKey)) {
            //         error = null;
        } else if (key.trim().length() < 1) {
            error = getErrorMessage(PDEUIMessages.ExternalizeStringsWizardPage_keyEmptyError, oldKey);
        } else if (key.charAt(0) == '#' || key.charAt(0) == '!' || key.charAt(0) == '%') {
            error = getErrorMessage(PDEUIMessages.ExternalizeStringsWizardPage_keyCommentError, oldKey);
        } else if (key.indexOf(':') != -1 || key.indexOf('=') != -1 || key.indexOf(' ') != -1) {
            error = getErrorMessage(PDEUIMessages.ExternalizeStringsWizardPage_keyError, oldKey);
        } else if ((!key.equals(oldKey) || fPreErrorKey != null) && properties.containsKey(key)) {
            error = getErrorMessage(PDEUIMessages.ExternalizeStringsWizardPage_keyDuplicateError, oldKey);
        }

        setErrorMessage(error);
        setPageComplete(error == null && hasCheckedElements());
        if (error == null) {
            fErrorElement = null;
            fPreErrorKey = null;
            setEnabled(fPropertiesViewer.getControl(), true);
            fPropertiesViewer.removeFilter(fErrorElementFilter);
            refreshPropertiesViewer(true);
            properties.setProperty(key, element.getValue());
        } else if (fPreErrorKey == null) {
            fErrorElement = element;
            fPreErrorKey = oldKey;
            setEnabled(fPropertiesViewer.getControl(), false);
            fPropertiesViewer.addFilter(fErrorElementFilter);
        }
    }

    private String getErrorMessage(String error, String suggestion) {
        StringBuffer sb = new StringBuffer(error);
        if (suggestion != null) {
            sb.append(PDEUIMessages.ExternalizeStringsWizardPage_keySuggested);
            sb.append(suggestion);
        }
        return sb.toString();
    }

    public Object[] getChangeFiles() {
        return fInputViewer.getCheckedElements();
    }

    private boolean hasCheckedElements() {
        return fInputViewer.getCheckedElements().length > 0;
    }

    private void setEnabled(Control exception, boolean enabled) {
        if (!exception.equals(fInputViewer.getControl()))
            fInputViewer.getControl().setEnabled(enabled);
        if (!exception.equals(fPropertiesViewer.getControl()))
            fPropertiesViewer.getControl().setEnabled(enabled);
        if (!exception.equals(fLocalizationText))
            fLocalizationText.setEnabled(enabled);
        if (!exception.equals(fSelectAll))
            fSelectAll.setEnabled(enabled);
        if (!exception.equals(fDeselectAll))
            fDeselectAll.setEnabled(enabled);
    }

    @Override
    public void setPageComplete(boolean complete) {
        super.setPageComplete(complete);
        // if the page is ready to be completed set the selection on the processor so it knows
        // what work needs to be done
        if (complete)
            ((ExternalizeStringsProcessor) ((PDERefactor) getRefactoring()).getProcessor())
                    .setChangeFiles(fInputViewer.getCheckedElements());
    }
}