0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2006 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.jdt.internal.ui.refactoring.nls;
0011:
0012: import java.io.InputStream;
0013: import java.util.ArrayList;
0014: import java.util.Collections;
0015: import java.util.Iterator;
0016: import java.util.List;
0017: import java.util.Properties;
0018:
0019: import org.eclipse.core.runtime.Assert;
0020: import org.eclipse.core.runtime.IStatus;
0021:
0022: import org.eclipse.core.resources.IFile;
0023:
0024: import org.eclipse.swt.SWT;
0025: import org.eclipse.swt.custom.SashForm;
0026: import org.eclipse.swt.events.ModifyEvent;
0027: import org.eclipse.swt.events.ModifyListener;
0028: import org.eclipse.swt.events.MouseAdapter;
0029: import org.eclipse.swt.events.MouseEvent;
0030: import org.eclipse.swt.events.SelectionAdapter;
0031: import org.eclipse.swt.events.SelectionEvent;
0032: import org.eclipse.swt.events.SelectionListener;
0033: import org.eclipse.swt.graphics.Font;
0034: import org.eclipse.swt.graphics.Image;
0035: import org.eclipse.swt.layout.FormAttachment;
0036: import org.eclipse.swt.layout.FormData;
0037: import org.eclipse.swt.layout.FormLayout;
0038: import org.eclipse.swt.layout.GridData;
0039: import org.eclipse.swt.layout.GridLayout;
0040: import org.eclipse.swt.widgets.Button;
0041: import org.eclipse.swt.widgets.Combo;
0042: import org.eclipse.swt.widgets.Composite;
0043: import org.eclipse.swt.widgets.Control;
0044: import org.eclipse.swt.widgets.Label;
0045: import org.eclipse.swt.widgets.Shell;
0046: import org.eclipse.swt.widgets.Table;
0047: import org.eclipse.swt.widgets.TableColumn;
0048: import org.eclipse.swt.widgets.TableItem;
0049: import org.eclipse.swt.widgets.Text;
0050: import org.eclipse.swt.widgets.Widget;
0051:
0052: import org.eclipse.jface.dialogs.Dialog;
0053: import org.eclipse.jface.dialogs.IDialogSettings;
0054: import org.eclipse.jface.dialogs.StatusDialog;
0055: import org.eclipse.jface.preference.IPreferenceStore;
0056: import org.eclipse.jface.resource.FontRegistry;
0057: import org.eclipse.jface.resource.ImageDescriptor;
0058: import org.eclipse.jface.resource.JFaceResources;
0059: import org.eclipse.jface.viewers.CellEditor;
0060: import org.eclipse.jface.viewers.ColumnLayoutData;
0061: import org.eclipse.jface.viewers.ColumnPixelData;
0062: import org.eclipse.jface.viewers.ColumnWeightData;
0063: import org.eclipse.jface.viewers.ICellModifier;
0064: import org.eclipse.jface.viewers.IFontProvider;
0065: import org.eclipse.jface.viewers.ISelection;
0066: import org.eclipse.jface.viewers.ISelectionChangedListener;
0067: import org.eclipse.jface.viewers.IStructuredContentProvider;
0068: import org.eclipse.jface.viewers.IStructuredSelection;
0069: import org.eclipse.jface.viewers.ITableLabelProvider;
0070: import org.eclipse.jface.viewers.LabelProvider;
0071: import org.eclipse.jface.viewers.SelectionChangedEvent;
0072: import org.eclipse.jface.viewers.StructuredSelection;
0073: import org.eclipse.jface.viewers.TableLayout;
0074: import org.eclipse.jface.viewers.TableViewer;
0075: import org.eclipse.jface.viewers.TextCellEditor;
0076: import org.eclipse.jface.viewers.Viewer;
0077: import org.eclipse.jface.viewers.ViewerFilter;
0078: import org.eclipse.jface.window.Window;
0079: import org.eclipse.jface.wizard.IWizardPage;
0080:
0081: import org.eclipse.jface.text.Document;
0082: import org.eclipse.jface.text.IDocument;
0083: import org.eclipse.jface.text.Region;
0084: import org.eclipse.jface.text.source.SourceViewer;
0085:
0086: import org.eclipse.ui.PlatformUI;
0087:
0088: import org.eclipse.ltk.core.refactoring.RefactoringStatus;
0089: import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
0090:
0091: import org.eclipse.jdt.core.ICompilationUnit;
0092: import org.eclipse.jdt.core.IJavaProject;
0093: import org.eclipse.jdt.core.JavaModelException;
0094:
0095: import org.eclipse.jdt.internal.corext.refactoring.nls.KeyValuePair;
0096: import org.eclipse.jdt.internal.corext.refactoring.nls.NLSRefactoring;
0097: import org.eclipse.jdt.internal.corext.refactoring.nls.NLSSubstitution;
0098:
0099: import org.eclipse.jdt.ui.JavaElementImageDescriptor;
0100: import org.eclipse.jdt.ui.PreferenceConstants;
0101: import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;
0102: import org.eclipse.jdt.ui.text.JavaTextTools;
0103:
0104: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
0105: import org.eclipse.jdt.internal.ui.JavaPlugin;
0106: import org.eclipse.jdt.internal.ui.JavaPluginImages;
0107: import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
0108: import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
0109: import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
0110: import org.eclipse.jdt.internal.ui.util.SWTUtil;
0111: import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
0112: import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
0113: import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
0114: import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
0115: import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField;
0116:
0117: class ExternalizeWizardPage extends UserInputWizardPage {
0118:
0119: private static final String[] PROPERTIES;
0120: private static final String[] fgTitles;
0121: private static final int STATE_PROP = 0;
0122: private static final int VAL_PROP = 1;
0123: private static final int KEY_PROP = 2;
0124: private static final int SIZE = 3; //column counter
0125: private static final int ROW_COUNT = 5;
0126:
0127: public static final String PAGE_NAME = "NLSWizardPage1"; //$NON-NLS-1$
0128: static {
0129: PROPERTIES = new String[SIZE];
0130: PROPERTIES[STATE_PROP] = "task"; //$NON-NLS-1$
0131: PROPERTIES[KEY_PROP] = "key"; //$NON-NLS-1$
0132: PROPERTIES[VAL_PROP] = "value"; //$NON-NLS-1$
0133:
0134: fgTitles = new String[SIZE];
0135: fgTitles[STATE_PROP] = ""; //$NON-NLS-1$
0136: fgTitles[KEY_PROP] = NLSUIMessages.ExternalizeWizardPage_key;
0137: fgTitles[VAL_PROP] = NLSUIMessages.ExternalizeWizardPage_value;
0138: }
0139:
0140: private class CellModifier implements ICellModifier {
0141:
0142: /**
0143: * @see ICellModifier#canModify(Object, String)
0144: */
0145: public boolean canModify(Object element, String property) {
0146: if (property == null)
0147: return false;
0148:
0149: if (!(element instanceof NLSSubstitution))
0150: return false;
0151:
0152: NLSSubstitution subst = (NLSSubstitution) element;
0153: if (PROPERTIES[KEY_PROP].equals(property)
0154: && subst.getState() != NLSSubstitution.EXTERNALIZED) {
0155: return false;
0156: }
0157:
0158: return true;
0159: }
0160:
0161: /**
0162: * @see ICellModifier#getValue(Object, String)
0163: */
0164: public Object getValue(Object element, String property) {
0165: if (element instanceof NLSSubstitution) {
0166: NLSSubstitution substitution = (NLSSubstitution) element;
0167: String res = null;
0168: if (PROPERTIES[KEY_PROP].equals(property)) {
0169: res = substitution.getKeyWithoutPrefix();
0170: } else if (PROPERTIES[VAL_PROP].equals(property)) {
0171: res = substitution.getValue();
0172: } else if (PROPERTIES[STATE_PROP].equals(property)) {
0173: return new Integer(substitution.getState());
0174: }
0175: if (res != null) {
0176: return unwindEscapeChars(res);
0177: }
0178: return ""; //$NON-NLS-1$
0179: }
0180: return ""; //$NON-NLS-1$
0181: }
0182:
0183: /**
0184: * @see ICellModifier#modify(Object, String, Object)
0185: */
0186: public void modify(Object element, String property, Object value) {
0187: if (element instanceof TableItem) {
0188: Object data = ((TableItem) element).getData();
0189: if (data instanceof NLSSubstitution) {
0190: NLSSubstitution substitution = (NLSSubstitution) data;
0191: if (PROPERTIES[KEY_PROP].equals(property)) {
0192: String string = (String) value;
0193: string = windEscapeChars(string);
0194: substitution.setKey(string);
0195: }
0196: if (PROPERTIES[VAL_PROP].equals(property)) {
0197: String string = (String) value;
0198: string = windEscapeChars(string);
0199: substitution.setValue(string);
0200: }
0201: if (PROPERTIES[STATE_PROP].equals(property)) {
0202: substitution.setState(((Integer) value)
0203: .intValue());
0204: if ((substitution.getState() == NLSSubstitution.EXTERNALIZED)
0205: && substitution.hasStateChanged()) {
0206: substitution.generateKey(fSubstitutions);
0207: }
0208: }
0209: }
0210: validateKeys(false);
0211: fTableViewer.update(data, null);
0212: }
0213: }
0214: }
0215:
0216: private class NLSSubstitutionLabelProvider extends LabelProvider
0217: implements ITableLabelProvider, IFontProvider {
0218:
0219: private FontRegistry fFontRegistry;
0220:
0221: public NLSSubstitutionLabelProvider() {
0222: fFontRegistry = JFaceResources.getFontRegistry();
0223: }
0224:
0225: public String getColumnText(Object element, int columnIndex) {
0226: String columnText = ""; //$NON-NLS-1$
0227: if (element instanceof NLSSubstitution) {
0228: NLSSubstitution substitution = (NLSSubstitution) element;
0229: if (columnIndex == KEY_PROP) {
0230: if (substitution.getState() == NLSSubstitution.EXTERNALIZED) {
0231: columnText = substitution.getKey();
0232: }
0233: } else if ((columnIndex == VAL_PROP)
0234: && (substitution.getValue() != null)) {
0235: columnText = substitution.getValue();
0236: }
0237: }
0238: return unwindEscapeChars(columnText);
0239: }
0240:
0241: public Image getColumnImage(Object element, int columnIndex) {
0242: if ((columnIndex == STATE_PROP)
0243: && (element instanceof NLSSubstitution)) {
0244: return getNLSImage((NLSSubstitution) element);
0245: }
0246:
0247: return null;
0248: }
0249:
0250: public Font getFont(Object element) {
0251: if (element instanceof NLSSubstitution) {
0252: NLSSubstitution substitution = (NLSSubstitution) element;
0253: if (substitution.hasPropertyFileChange()
0254: || substitution.hasSourceChange()) {
0255: return fFontRegistry
0256: .getBold(JFaceResources.DIALOG_FONT);
0257: }
0258: }
0259: return null;
0260: }
0261:
0262: private Image getNLSImage(NLSSubstitution sub) {
0263: if ((sub.getValue() == null) && (sub.getKey() != null)) {
0264: // Missing keys
0265: JavaElementImageDescriptor imageDescriptor = new JavaElementImageDescriptor(
0266: getNLSImageDescriptor(sub.getState()),
0267: JavaElementImageDescriptor.WARNING,
0268: JavaElementImageProvider.SMALL_SIZE);
0269: return JavaPlugin.getImageDescriptorRegistry().get(
0270: imageDescriptor);
0271: } else if (sub.isConflicting(fSubstitutions)
0272: || !isKeyValid(sub, null)) {
0273: JavaElementImageDescriptor imageDescriptor = new JavaElementImageDescriptor(
0274: getNLSImageDescriptor(sub.getState()),
0275: JavaElementImageDescriptor.ERROR,
0276: JavaElementImageProvider.SMALL_SIZE);
0277: return JavaPlugin.getImageDescriptorRegistry().get(
0278: imageDescriptor);
0279: } else {
0280: return getNLSImage(sub.getState());
0281: }
0282: }
0283:
0284: private Image getNLSImage(int task) {
0285: switch (task) {
0286: case NLSSubstitution.EXTERNALIZED:
0287: return JavaPluginImages
0288: .get(JavaPluginImages.IMG_OBJS_NLS_TRANSLATE);
0289: case NLSSubstitution.IGNORED:
0290: return JavaPluginImages
0291: .get(JavaPluginImages.IMG_OBJS_NLS_NEVER_TRANSLATE);
0292: case NLSSubstitution.INTERNALIZED:
0293: return JavaPluginImages
0294: .get(JavaPluginImages.IMG_OBJS_NLS_SKIP);
0295: default:
0296: Assert.isTrue(false);
0297: return null;
0298: }
0299: }
0300:
0301: private ImageDescriptor getNLSImageDescriptor(int task) {
0302: switch (task) {
0303: case NLSSubstitution.EXTERNALIZED:
0304: return JavaPluginImages.DESC_OBJS_NLS_TRANSLATE;
0305: case NLSSubstitution.IGNORED:
0306: return JavaPluginImages.DESC_OBJS_NLS_NEVER_TRANSLATE;
0307: case NLSSubstitution.INTERNALIZED:
0308: return JavaPluginImages.DESC_OBJS_NLS_SKIP;
0309: default:
0310: Assert.isTrue(false);
0311: return null;
0312: }
0313: }
0314: }
0315:
0316: private static String unwindEscapeChars(String s) {
0317: if (s != null) {
0318: StringBuffer sb = new StringBuffer(s.length());
0319: int length = s.length();
0320: for (int i = 0; i < length; i++) {
0321: char c = s.charAt(i);
0322: sb.append(getUnwoundString(c));
0323: }
0324: return sb.toString();
0325: }
0326: return null;
0327: }
0328:
0329: private static String getUnwoundString(char c) {
0330: switch (c) {
0331: case '\b':
0332: return "\\b";//$NON-NLS-1$
0333: case '\t':
0334: return "\\t";//$NON-NLS-1$
0335: case '\n':
0336: return "\\n";//$NON-NLS-1$
0337: case '\f':
0338: return "\\f";//$NON-NLS-1$
0339: case '\r':
0340: return "\\r";//$NON-NLS-1$
0341: case '\\':
0342: return "\\\\";//$NON-NLS-1$
0343: }
0344: return String.valueOf(c);
0345: }
0346:
0347: private static String windEscapeChars(String s) {
0348: if (s == null)
0349: return null;
0350:
0351: char aChar;
0352: int len = s.length();
0353: StringBuffer outBuffer = new StringBuffer(len);
0354:
0355: for (int x = 0; x < len;) {
0356: aChar = s.charAt(x++);
0357: if (aChar == '\\') {
0358: aChar = s.charAt(x++);
0359: if (aChar == 'u') {
0360: // Read the xxxx
0361: int value = 0;
0362: for (int i = 0; i < 4; i++) {
0363: aChar = s.charAt(x++);
0364: switch (aChar) {
0365: case '0':
0366: case '1':
0367: case '2':
0368: case '3':
0369: case '4':
0370: case '5':
0371: case '6':
0372: case '7':
0373: case '8':
0374: case '9':
0375: value = (value << 4) + aChar - '0';
0376: break;
0377: case 'a':
0378: case 'b':
0379: case 'c':
0380: case 'd':
0381: case 'e':
0382: case 'f':
0383: value = (value << 4) + 10 + aChar - 'a';
0384: break;
0385: case 'A':
0386: case 'B':
0387: case 'C':
0388: case 'D':
0389: case 'E':
0390: case 'F':
0391: value = (value << 4) + 10 + aChar - 'A';
0392: break;
0393: default:
0394: throw new IllegalArgumentException(
0395: "Malformed \\uxxxx encoding."); //$NON-NLS-1$
0396: }
0397: }
0398: outBuffer.append((char) value);
0399: } else {
0400: if (aChar == 't') {
0401: outBuffer.append('\t');
0402: } else {
0403: if (aChar == 'r') {
0404: outBuffer.append('\r');
0405: } else {
0406: if (aChar == 'n') {
0407: outBuffer.append('\n');
0408: } else {
0409: if (aChar == 'f') {
0410: outBuffer.append('\f');
0411: } else {
0412: outBuffer.append(aChar);
0413: }
0414: }
0415: }
0416: }
0417: }
0418: } else
0419: outBuffer.append(aChar);
0420: }
0421: return outBuffer.toString();
0422: }
0423:
0424: private class NLSInputDialog extends StatusDialog implements
0425: IDialogFieldListener {
0426: private StringDialogField fKeyField;
0427: private StringDialogField fValueField;
0428: private DialogField fMessageField;
0429: private NLSSubstitution fSubstitution;
0430:
0431: public NLSInputDialog(Shell parent, NLSSubstitution substitution) {
0432: super (parent);
0433:
0434: setTitle(NLSUIMessages.ExternalizeWizardPage_NLSInputDialog_Title);
0435:
0436: fSubstitution = substitution;
0437:
0438: fMessageField = new DialogField();
0439: if (substitution.getState() == NLSSubstitution.EXTERNALIZED) {
0440: fMessageField
0441: .setLabelText(NLSUIMessages.ExternalizeWizardPage_NLSInputDialog_ext_Label);
0442: } else {
0443: fMessageField
0444: .setLabelText(NLSUIMessages.ExternalizeWizardPage_NLSInputDialog_Label);
0445: }
0446:
0447: fKeyField = new StringDialogField();
0448: fKeyField
0449: .setLabelText(NLSUIMessages.ExternalizeWizardPage_NLSInputDialog_Enter_key);
0450: fKeyField.setDialogFieldListener(this );
0451:
0452: fValueField = new StringDialogField();
0453: fValueField
0454: .setLabelText(NLSUIMessages.ExternalizeWizardPage_NLSInputDialog_Enter_value);
0455: fValueField.setDialogFieldListener(this );
0456:
0457: if (substitution.getState() == NLSSubstitution.EXTERNALIZED) {
0458: fKeyField.setText(substitution.getKeyWithoutPrefix());
0459: } else {
0460: fKeyField.setText(""); //$NON-NLS-1$
0461: }
0462:
0463: fValueField.setText(substitution.getValueNonEmpty());
0464: }
0465:
0466: public KeyValuePair getResult() {
0467: KeyValuePair res = new KeyValuePair(fKeyField.getText(),
0468: fValueField.getText());
0469: return res;
0470: }
0471:
0472: protected Control createDialogArea(Composite parent) {
0473: Composite composite = (Composite) super
0474: .createDialogArea(parent);
0475:
0476: Composite inner = new Composite(composite, SWT.NONE);
0477: inner.setFont(composite.getFont());
0478:
0479: GridLayout layout = new GridLayout();
0480: layout.marginHeight = 0;
0481: layout.marginWidth = 0;
0482: layout.numColumns = 2;
0483: inner.setLayout(layout);
0484:
0485: fMessageField.doFillIntoGrid(inner, 2);
0486:
0487: if (fSubstitution.getState() == NLSSubstitution.EXTERNALIZED) {
0488: fKeyField.doFillIntoGrid(inner, 2);
0489: LayoutUtil.setWidthHint(fKeyField.getTextControl(null),
0490: convertWidthInCharsToPixels(45));
0491: }
0492:
0493: fValueField.doFillIntoGrid(inner, 2);
0494: LayoutUtil.setWidthHint(fValueField.getTextControl(null),
0495: convertWidthInCharsToPixels(45));
0496: LayoutUtil.setHorizontalGrabbing(fValueField
0497: .getTextControl(null));
0498:
0499: fValueField.postSetFocusOnDialogField(parent.getDisplay());
0500:
0501: applyDialogFont(composite);
0502: return composite;
0503: }
0504:
0505: /* (non-Javadoc)
0506: * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener#dialogFieldChanged(org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField)
0507: */
0508: public void dialogFieldChanged(DialogField field) {
0509: IStatus keyStatus = validateKey(fKeyField.getText());
0510: //IStatus valueStatus= StatusInfo.OK_STATUS; // no validation yet
0511:
0512: //updateStatus(StatusUtil.getMoreSevere(valueStatus, keyStatus));
0513: updateStatus(keyStatus);
0514: }
0515:
0516: private IStatus validateKey(String val) {
0517: if (fSubstitution.getState() != NLSSubstitution.EXTERNALIZED) {
0518: return StatusInfo.OK_STATUS;
0519: }
0520:
0521: if (val == null || val.length() == 0) {
0522: return new StatusInfo(
0523: IStatus.ERROR,
0524: NLSUIMessages.ExternalizeWizardPage_NLSInputDialog_Error_empty_key);
0525: }
0526:
0527: if (fNLSRefactoring.isEclipseNLS()) {
0528: if (!Character.isJavaIdentifierStart(val.charAt(0)))
0529: return new StatusInfo(
0530: IStatus.ERROR,
0531: NLSUIMessages.ExternalizeWizardPage_NLSInputDialog_Error_invalid_EclipseNLS_key);
0532:
0533: for (int i = 1, length = val.length(); i < length; i++) {
0534: if (!Character.isJavaIdentifierPart(val.charAt(i)))
0535: return new StatusInfo(
0536: IStatus.ERROR,
0537: NLSUIMessages.ExternalizeWizardPage_NLSInputDialog_Error_invalid_EclipseNLS_key);
0538: }
0539: } else {
0540: // validation so keys don't contain spaces
0541: for (int i = 0; i < val.length(); i++) {
0542: if (Character.isWhitespace(val.charAt(i))) {
0543: return new StatusInfo(
0544: IStatus.ERROR,
0545: NLSUIMessages.ExternalizeWizardPage_NLSInputDialog_Error_invalid_key);
0546: }
0547: }
0548: }
0549: return StatusInfo.OK_STATUS;
0550: }
0551: }
0552:
0553: private static final String SETTINGS_NLS_ACCESSORS = "nls_accessor_history"; //$NON-NLS-1$
0554: private static final int SETTINGS_MAX_ENTRIES = 5;
0555:
0556: private Text fPrefixField;
0557: private Button fIsEclipseNLS;
0558: private Table fTable;
0559: private TableViewer fTableViewer;
0560: private SourceViewer fSourceViewer;
0561:
0562: private final ICompilationUnit fCu;
0563: private NLSSubstitution[] fSubstitutions;
0564: private Button fExternalizeButton;
0565: private Button fIgnoreButton;
0566: private Button fInternalizeButton;
0567: private Button fRevertButton;
0568: private Button fEditButton;
0569: private NLSRefactoring fNLSRefactoring;
0570: private Button fRenameButton;
0571: private Combo fAccessorClassField;
0572:
0573: private AccessorDescription[] fAccessorChoices;
0574: private Button fFilterCheckBox;
0575:
0576: public ExternalizeWizardPage(NLSRefactoring nlsRefactoring) {
0577: super (PAGE_NAME);
0578: fCu = nlsRefactoring.getCu();
0579: fSubstitutions = nlsRefactoring.getSubstitutions();
0580: fNLSRefactoring = nlsRefactoring;
0581: fAccessorChoices = null;
0582:
0583: setDescription(NLSUIMessages.ExternalizeWizardPage_description);
0584: createDefaultExternalization(fSubstitutions, nlsRefactoring
0585: .getPrefix());
0586: }
0587:
0588: /*
0589: * @see IDialogPage#createControl(Composite)
0590: */
0591: public void createControl(Composite parent) {
0592: initializeDialogUnits(parent);
0593:
0594: Composite super composite = new Composite(parent, SWT.NONE);
0595: super composite.setFont(parent.getFont());
0596: super composite.setLayout(new GridLayout());
0597:
0598: createIsEclipseNLSCheckbox(super composite);
0599:
0600: createKeyPrefixField(super composite);
0601:
0602: SashForm composite = new SashForm(super composite, SWT.VERTICAL);
0603: composite.setFont(super composite.getFont());
0604:
0605: GridData data = new GridData(GridData.FILL_BOTH);
0606: composite.setLayoutData(data);
0607:
0608: createTableViewer(composite);
0609: createSourceViewer(composite);
0610:
0611: createAccessorInfoComposite(super composite);
0612:
0613: composite.setWeights(new int[] { 65, 45 });
0614:
0615: validateKeys(false);
0616: updateButtonStates(StructuredSelection.EMPTY);
0617:
0618: // promote control
0619: setControl(super composite);
0620: Dialog.applyDialogFont(super composite);
0621: PlatformUI.getWorkbench().getHelpSystem().setHelp(
0622: super composite,
0623: IJavaHelpContextIds.EXTERNALIZE_WIZARD_KEYVALUE_PAGE);
0624: }
0625:
0626: /**
0627: * @param supercomposite
0628: */
0629: private void createAccessorInfoComposite(Composite super composite) {
0630: Composite accessorComposite = new Composite(super composite,
0631: SWT.NONE);
0632: accessorComposite.setLayoutData(new GridData(
0633: GridData.FILL_HORIZONTAL));
0634: GridLayout layout = new GridLayout(2, false);
0635: layout.marginHeight = 0;
0636: layout.marginWidth = 0;
0637: accessorComposite.setLayout(layout);
0638:
0639: Composite composite = new Composite(accessorComposite, SWT.NONE);
0640: composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
0641:
0642: layout = new GridLayout(1, true);
0643: layout.marginHeight = 0;
0644: layout.marginWidth = 0;
0645: composite.setLayout(layout);
0646:
0647: Label accessorClassLabel = new Label(composite, SWT.NONE);
0648: accessorClassLabel
0649: .setText(NLSUIMessages.ExternalizeWizardPage_accessorclass_label);
0650: accessorClassLabel.setLayoutData(new GridData());
0651:
0652: SelectionListener listener = new SelectionAdapter() {
0653: public void widgetSelected(SelectionEvent e) {
0654: if (e.widget instanceof Button) {
0655: doConfigureButtonPressed();
0656: } else {
0657: doAccessorSelectionChanged();
0658: }
0659: }
0660: };
0661:
0662: GridData data = new GridData(GridData.FILL_HORIZONTAL);
0663: data.widthHint = convertWidthInCharsToPixels(30);
0664: fAccessorClassField = new Combo(composite, SWT.READ_ONLY);
0665: fAccessorClassField.setLayoutData(data);
0666: fAccessorClassField.addSelectionListener(listener);
0667:
0668: //new Label(composite, SWT.NONE); // placeholder
0669:
0670: Button configure = new Button(accessorComposite, SWT.PUSH);
0671: configure
0672: .setText(NLSUIMessages.ExternalizeWizardPage_configure_button);
0673: data = new GridData(GridData.HORIZONTAL_ALIGN_END
0674: | GridData.VERTICAL_ALIGN_END);
0675: data.widthHint = SWTUtil.getButtonWidthHint(configure);
0676: configure.setLayoutData(data);
0677:
0678: configure.addSelectionListener(listener);
0679:
0680: updateAccessorChoices();
0681:
0682: }
0683:
0684: protected void doAccessorSelectionChanged() {
0685: int selectionIndex = fAccessorClassField.getSelectionIndex();
0686: if (fAccessorChoices != null
0687: && selectionIndex < fAccessorChoices.length) {
0688: AccessorDescription selected = fAccessorChoices[selectionIndex];
0689: fNLSRefactoring.setAccessorClassName(selected
0690: .getAccessorClassName());
0691: fNLSRefactoring.setAccessorClassPackage(selected
0692: .getAccessorClassPackage());
0693: fNLSRefactoring.setResourceBundleName(selected
0694: .getResourceBundleName());
0695: fNLSRefactoring.setResourceBundlePackage(selected
0696: .getResourceBundlePackage());
0697: fNLSRefactoring.setIsEclipseNLS(fNLSRefactoring
0698: .detectIsEclipseNLS());
0699:
0700: NLSSubstitution.updateSubtitutions(fSubstitutions,
0701: getProperties(fNLSRefactoring
0702: .getPropertyFileHandle()), fNLSRefactoring
0703: .getAccessorClassName());
0704: if (fIsEclipseNLS != null) {
0705: fIsEclipseNLS.setSelection(fNLSRefactoring
0706: .isEclipseNLS());
0707: fIsEclipseNLS.setEnabled(willCreateAccessorClass());
0708: }
0709: validateKeys(true);
0710: }
0711: }
0712:
0713: private boolean willCreateAccessorClass() {
0714: try {
0715: return fNLSRefactoring.willCreateAccessorClass();
0716: } catch (JavaModelException e) {
0717: return false;
0718: }
0719: }
0720:
0721: private void updateAccessorChoices() {
0722:
0723: AccessorDescription configured = new AccessorDescription(
0724: fNLSRefactoring.getAccessorClassName(), fNLSRefactoring
0725: .getAccessorClassPackage(), fNLSRefactoring
0726: .getResourceBundleName(), fNLSRefactoring
0727: .getResourceBundlePackage());
0728:
0729: ArrayList currChoices = new ArrayList();
0730: ArrayList currLabels = new ArrayList();
0731:
0732: currChoices.add(configured);
0733: currLabels.add(configured.getLabel());
0734:
0735: AccessorDescription[] choices = fAccessorChoices;
0736: if (choices == null) {
0737: choices = loadAccessorDescriptions();
0738: }
0739:
0740: for (int i = 0; i < choices.length; i++) {
0741: AccessorDescription curr = choices[i];
0742: if (!curr.equals(configured)) {
0743: currChoices.add(curr);
0744: currLabels.add(curr.getLabel());
0745: }
0746: }
0747:
0748: String[] labels = (String[]) currLabels
0749: .toArray(new String[currLabels.size()]);
0750: fAccessorChoices = (AccessorDescription[]) currChoices
0751: .toArray(new AccessorDescription[currChoices.size()]);
0752:
0753: fAccessorClassField.setItems(labels);
0754: fAccessorClassField.select(0);
0755: }
0756:
0757: private AccessorDescription[] loadAccessorDescriptions() {
0758: IDialogSettings section = JavaPlugin.getDefault()
0759: .getDialogSettings().getSection(SETTINGS_NLS_ACCESSORS);
0760: if (section == null) {
0761: return new AccessorDescription[0];
0762: }
0763: ArrayList res = new ArrayList();
0764: for (int i = 0; i < SETTINGS_MAX_ENTRIES; i++) {
0765: IDialogSettings serializedDesc = section.getSection(String
0766: .valueOf(i));
0767: if (serializedDesc != null) {
0768: AccessorDescription accessor = AccessorDescription
0769: .deserialize(serializedDesc);
0770: if (accessor != null) {
0771: res.add(accessor);
0772: }
0773: }
0774: }
0775: return (AccessorDescription[]) res
0776: .toArray(new AccessorDescription[res.size()]);
0777: }
0778:
0779: private void storeAccessorDescriptions() {
0780: if (fAccessorChoices == null) {
0781: return;
0782: }
0783: IDialogSettings dialogSettings = JavaPlugin.getDefault()
0784: .getDialogSettings();
0785: IDialogSettings nlsSection = dialogSettings
0786: .getSection(SETTINGS_NLS_ACCESSORS);
0787: if (nlsSection == null) {
0788: nlsSection = dialogSettings
0789: .addNewSection(SETTINGS_NLS_ACCESSORS);
0790: }
0791: int nEntries = Math.min(SETTINGS_MAX_ENTRIES,
0792: fAccessorChoices.length);
0793: for (int i = 0; i < nEntries; i++) {
0794: IDialogSettings serializedDesc = nlsSection
0795: .addNewSection(String.valueOf(i));
0796: fAccessorChoices[i].serialize(serializedDesc);
0797: }
0798: }
0799:
0800: private void doConfigureButtonPressed() {
0801: NLSAccessorConfigurationDialog dialog = new NLSAccessorConfigurationDialog(
0802: getShell(), fNLSRefactoring);
0803: if (dialog.open() == Window.OK) {
0804: NLSSubstitution.updateSubtitutions(fSubstitutions,
0805: getProperties(fNLSRefactoring
0806: .getPropertyFileHandle()), fNLSRefactoring
0807: .getAccessorClassName());
0808: if (fIsEclipseNLS != null) {
0809: fIsEclipseNLS.setSelection(fNLSRefactoring
0810: .isEclipseNLS());
0811: fIsEclipseNLS.setEnabled(willCreateAccessorClass());
0812: }
0813: validateKeys(true);
0814: updateAccessorChoices();
0815: }
0816: }
0817:
0818: private Properties getProperties(IFile propertyFile) {
0819: Properties props = new Properties();
0820: try {
0821: if (propertyFile.exists()) {
0822: InputStream is = propertyFile.getContents();
0823: props.load(is);
0824: is.close();
0825: }
0826: } catch (Exception e) {
0827: // sorry no property
0828: }
0829: return props;
0830: }
0831:
0832: private void createTableViewer(Composite composite) {
0833: createTableComposite(composite);
0834:
0835: /*
0836: * Feature of CellEditors - double click is ignored.
0837: * The workaround is to register my own listener and force the desired
0838: * behavior.
0839: */
0840: fTableViewer = new TableViewer(fTable) {
0841: protected void hookControl(Control control) {
0842: super .hookControl(control);
0843: ((Table) control).addMouseListener(new MouseAdapter() {
0844: public void mouseDoubleClick(MouseEvent e) {
0845: if (getTable().getSelection().length == 0)
0846: return;
0847: TableItem item = getTable().getSelection()[0];
0848: if (item.getBounds(STATE_PROP).contains(e.x,
0849: e.y)) {
0850: List widgetSel = getSelectionFromWidget();
0851: if (widgetSel == null
0852: || widgetSel.size() != 1)
0853: return;
0854: NLSSubstitution substitution = (NLSSubstitution) widgetSel
0855: .get(0);
0856: Integer value = (Integer) getCellModifier()
0857: .getValue(substitution,
0858: PROPERTIES[STATE_PROP]);
0859: int newValue = MultiStateCellEditor
0860: .getNextValue(
0861: NLSSubstitution.STATE_COUNT,
0862: value.intValue());
0863: getCellModifier().modify(item,
0864: PROPERTIES[STATE_PROP],
0865: new Integer(newValue));
0866: }
0867: }
0868: });
0869: }
0870: };
0871:
0872: fTableViewer.setUseHashlookup(true);
0873:
0874: final CellEditor[] editors = createCellEditors();
0875: fTableViewer.setCellEditors(editors);
0876: fTableViewer.setColumnProperties(PROPERTIES);
0877: fTableViewer.setCellModifier(new CellModifier());
0878:
0879: fTableViewer
0880: .setContentProvider(new IStructuredContentProvider() {
0881: public Object[] getElements(Object inputElement) {
0882: return fSubstitutions;
0883: }
0884:
0885: public void dispose() {
0886: }
0887:
0888: public void inputChanged(Viewer viewer,
0889: Object oldInput, Object newInput) {
0890: }
0891: });
0892: fTableViewer.addFilter(new ViewerFilter() {
0893: public boolean select(Viewer viewer, Object parentElement,
0894: Object element) {
0895: if (!fFilterCheckBox.getSelection()) {
0896: return true;
0897: }
0898: NLSSubstitution curr = (NLSSubstitution) element;
0899: return (curr.getInitialState() == NLSSubstitution.INTERNALIZED)
0900: || (curr.getInitialState() == NLSSubstitution.EXTERNALIZED && curr
0901: .getInitialValue() == null);
0902: }
0903: });
0904:
0905: fTableViewer
0906: .setLabelProvider(new NLSSubstitutionLabelProvider());
0907: fTableViewer.setInput(new Object());
0908:
0909: fTableViewer
0910: .addSelectionChangedListener(new ISelectionChangedListener() {
0911: public void selectionChanged(
0912: SelectionChangedEvent event) {
0913: ExternalizeWizardPage.this
0914: .selectionChanged(event);
0915: }
0916: });
0917: }
0918:
0919: private void createDefaultExternalization(
0920: NLSSubstitution[] substitutions, String defaultPrefix) {
0921: for (int i = 0; i < substitutions.length; i++) {
0922: NLSSubstitution substitution = substitutions[i];
0923: if (substitution.getState() == NLSSubstitution.INTERNALIZED) {
0924: substitution.setState(NLSSubstitution.EXTERNALIZED);
0925: substitution.generateKey(substitutions);
0926: }
0927: }
0928: }
0929:
0930: private CellEditor[] createCellEditors() {
0931: final CellEditor editors[] = new CellEditor[SIZE];
0932: editors[STATE_PROP] = new MultiStateCellEditor(fTable,
0933: NLSSubstitution.STATE_COUNT, NLSSubstitution.DEFAULT);
0934: editors[KEY_PROP] = new TextCellEditor(fTable);
0935: editors[VAL_PROP] = new TextCellEditor(fTable);
0936: return editors;
0937: }
0938:
0939: private void createSourceViewer(Composite parent) {
0940: Composite c = new Composite(parent, SWT.NONE);
0941: c.setLayoutData(new GridData(GridData.FILL_BOTH));
0942: GridLayout gl = new GridLayout();
0943: gl.marginHeight = 0;
0944: gl.marginWidth = 0;
0945: c.setLayout(gl);
0946:
0947: Label l = new Label(c, SWT.NONE);
0948: l.setText(NLSUIMessages.ExternalizeWizardPage_context);
0949: l.setLayoutData(new GridData());
0950:
0951: // source viewer
0952: JavaTextTools tools = JavaPlugin.getDefault()
0953: .getJavaTextTools();
0954: int styles = SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI
0955: | SWT.BORDER | SWT.FULL_SELECTION;
0956: IPreferenceStore store = JavaPlugin.getDefault()
0957: .getCombinedPreferenceStore();
0958: fSourceViewer = new JavaSourceViewer(c, null, null, false,
0959: styles, store);
0960: fSourceViewer.configure(new JavaSourceViewerConfiguration(tools
0961: .getColorManager(), store, null, null));
0962: fSourceViewer.getControl().setFont(
0963: JFaceResources
0964: .getFont(PreferenceConstants.EDITOR_TEXT_FONT));
0965:
0966: try {
0967:
0968: String contents = fCu.getBuffer().getContents();
0969: IDocument document = new Document(contents);
0970: tools.setupJavaDocumentPartitioner(document);
0971:
0972: fSourceViewer.setDocument(document);
0973: fSourceViewer.setEditable(false);
0974:
0975: GridData gd = new GridData(GridData.FILL_BOTH);
0976: gd.heightHint = convertHeightInCharsToPixels(10);
0977: gd.widthHint = convertWidthInCharsToPixels(40);
0978: fSourceViewer.getControl().setLayoutData(gd);
0979:
0980: } catch (JavaModelException e) {
0981: ExceptionHandler
0982: .handle(
0983: e,
0984: NLSUIMessages.ExternalizeWizardPage_exception_title,
0985: NLSUIMessages.ExternalizeWizardPage_exception_message);
0986: }
0987: }
0988:
0989: private void createKeyPrefixField(Composite parent) {
0990: Composite composite = new Composite(parent, SWT.NONE);
0991: composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
0992: GridLayout gl = new GridLayout();
0993: gl.numColumns = 2;
0994: gl.marginWidth = 0;
0995: composite.setLayout(gl);
0996:
0997: Label l = new Label(composite, SWT.NONE);
0998: l.setText(NLSUIMessages.ExternalizeWizardPage_common_prefix);
0999: l.setLayoutData(new GridData());
1000:
1001: fPrefixField = new Text(composite, SWT.SINGLE | SWT.BORDER);
1002: fPrefixField.setLayoutData(new GridData(
1003: GridData.FILL_HORIZONTAL));
1004: fPrefixField.setText(fNLSRefactoring.getPrefix());
1005: fPrefixField.selectAll();
1006:
1007: fPrefixField.addModifyListener(new ModifyListener() {
1008: public void modifyText(ModifyEvent e) {
1009: fNLSRefactoring.setPrefix(fPrefixField.getText());
1010: validateKeys(true);
1011: }
1012: });
1013: }
1014:
1015: private boolean isEclipseNLSAvailable() {
1016: if (fNLSRefactoring == null || fNLSRefactoring.getCu() == null)
1017: return false;
1018:
1019: IJavaProject jp = fNLSRefactoring.getCu().getJavaProject();
1020: if (jp == null || !jp.exists())
1021: return false;
1022:
1023: try {
1024: return jp.findType("org.eclipse.osgi.util.NLS") != null; //$NON-NLS-1$
1025: } catch (JavaModelException e) {
1026: return false;
1027: }
1028: }
1029:
1030: private void createIsEclipseNLSCheckbox(Composite parent) {
1031: if (fNLSRefactoring.isEclipseNLS() || isEclipseNLSAvailable()) {
1032: fIsEclipseNLS = new Button(parent, SWT.CHECK);
1033: fIsEclipseNLS.setLayoutData(new GridData(
1034: GridData.FILL_HORIZONTAL));
1035: fIsEclipseNLS
1036: .setText(NLSUIMessages.ExternalizeWizardPage_isEclipseNLSCheckbox);
1037: fIsEclipseNLS.setSelection(fNLSRefactoring.isEclipseNLS());
1038: fIsEclipseNLS.setEnabled(willCreateAccessorClass());
1039: fIsEclipseNLS.addSelectionListener(new SelectionAdapter() {
1040: public void widgetSelected(SelectionEvent e) {
1041: super .widgetDefaultSelected(e);
1042: boolean isEclipseNLS = fIsEclipseNLS.getSelection();
1043: fNLSRefactoring.setIsEclipseNLS(isEclipseNLS);
1044: if (isEclipseNLS) {
1045: fNLSRefactoring.setPrefix(fNLSRefactoring
1046: .getPrefix().replace('.', '_'));
1047: } else {
1048: fNLSRefactoring.setPrefix(fNLSRefactoring
1049: .getPrefix().replace('_', '.'));
1050: }
1051: fPrefixField.setText(fNLSRefactoring.getPrefix());
1052: validateKeys(true);
1053: }
1054: });
1055: }
1056: }
1057:
1058: private void validateKeys(boolean refreshTable) {
1059: RefactoringStatus status = new RefactoringStatus();
1060: checkInvalidKeys(status);
1061: checkDuplicateKeys(status);
1062: checkMissingKeys(status);
1063: setPageComplete(status);
1064: if (refreshTable)
1065: fTableViewer.refresh(true);
1066: }
1067:
1068: private void checkInvalidKeys(RefactoringStatus status) {
1069: for (int i = 0; i < fSubstitutions.length; i++) {
1070: if (!isKeyValid(fSubstitutions[i], status))
1071: return;
1072: }
1073: }
1074:
1075: private boolean isKeyValid(NLSSubstitution substitution,
1076: RefactoringStatus status) {
1077: if (substitution == null)
1078: return false;
1079:
1080: if (substitution.getState() != NLSSubstitution.EXTERNALIZED)
1081: return true;
1082:
1083: String key = substitution.getKey();
1084:
1085: if (fNLSRefactoring.isEclipseNLS()) {
1086: if (key == null || key.length() == 0
1087: || !Character.isJavaIdentifierStart(key.charAt(0))) {
1088: if (status != null)
1089: status
1090: .addFatalError(NLSUIMessages.ExternalizeWizardPage_warning_EclipseNLS_keyInvalid);
1091: return false;
1092: }
1093: for (int i = 1, length = key.length(); i < length; i++) {
1094: if (!Character.isJavaIdentifierPart(key.charAt(i))) {
1095: if (status != null)
1096: status
1097: .addFatalError(NLSUIMessages.ExternalizeWizardPage_warning_EclipseNLS_keyInvalid);
1098: return false;
1099: }
1100: }
1101: } else {
1102: if (key == null || key.length() == 0) {
1103: if (status != null)
1104: status
1105: .addFatalError(NLSUIMessages.ExternalizeWizardPage_warning_keyInvalid);
1106: return false;
1107: }
1108: // validation so keys don't contain spaces
1109: for (int i = 0; i < key.length(); i++) {
1110: if (Character.isWhitespace(key.charAt(i))) {
1111: if (status != null)
1112: status
1113: .addFatalError(NLSUIMessages.ExternalizeWizardPage_warning_keyInvalid);
1114: return false;
1115: }
1116: }
1117: }
1118:
1119: return true;
1120: }
1121:
1122: private void checkDuplicateKeys(RefactoringStatus status) {
1123: for (int i = 0; i < fSubstitutions.length; i++) {
1124: NLSSubstitution substitution = fSubstitutions[i];
1125: if (conflictingKeys(substitution)) {
1126: status
1127: .addFatalError(NLSUIMessages.ExternalizeWizardPage_warning_conflicting);
1128: return;
1129: }
1130: }
1131: }
1132:
1133: private void checkMissingKeys(RefactoringStatus status) {
1134: for (int i = 0; i < fSubstitutions.length; i++) {
1135: NLSSubstitution substitution = fSubstitutions[i];
1136: if ((substitution.getValue() == null)
1137: && (substitution.getKey() != null)) {
1138: status
1139: .addWarning(NLSUIMessages.ExternalizeWizardPage_warning_keymissing);
1140: return;
1141: }
1142: }
1143: }
1144:
1145: private boolean conflictingKeys(NLSSubstitution substitution) {
1146: if (substitution.getState() == NLSSubstitution.EXTERNALIZED) {
1147: return substitution.isConflicting(fSubstitutions);
1148: }
1149: return false;
1150: }
1151:
1152: private void createTableComposite(Composite parent) {
1153: Composite comp = new Composite(parent, SWT.NONE);
1154: comp.setFont(parent.getFont());
1155:
1156: comp.setLayoutData(new GridData(GridData.FILL_BOTH));
1157:
1158: FormLayout fl = new FormLayout();
1159: fl.marginWidth = 0;
1160: fl.marginHeight = 0;
1161: comp.setLayout(fl);
1162:
1163: Label l = new Label(comp, SWT.NONE);
1164: l
1165: .setText(NLSUIMessages.ExternalizeWizardPage_strings_to_externalize);
1166: FormData formData = new FormData();
1167: formData.left = new FormAttachment(0, 0);
1168: l.setLayoutData(formData);
1169:
1170: Control tableControl = createTable(comp);
1171: formData = new FormData();
1172: formData.top = new FormAttachment(l, 5);
1173: formData.left = new FormAttachment(0, 0);
1174: formData.right = new FormAttachment(100, 0);
1175: formData.bottom = new FormAttachment(100, 0);
1176: tableControl.setLayoutData(formData);
1177:
1178: fFilterCheckBox = new Button(comp, SWT.CHECK);
1179: fFilterCheckBox
1180: .setText(NLSUIMessages.ExternalizeWizardPage_filter_label);
1181: formData = new FormData();
1182: formData.right = new FormAttachment(100, 0);
1183: fFilterCheckBox.setLayoutData(formData);
1184: fFilterCheckBox.addSelectionListener(new SelectionListener() {
1185: public void widgetSelected(SelectionEvent e) {
1186: doFilterCheckBoxPressed();
1187: }
1188:
1189: public void widgetDefaultSelected(SelectionEvent e) {
1190: }
1191: });
1192: fFilterCheckBox.setSelection(hasNewOrMissingSubstitutions());
1193: }
1194:
1195: private boolean hasNewOrMissingSubstitutions() {
1196: for (int i = 0; i < fSubstitutions.length; i++) {
1197: NLSSubstitution curr = fSubstitutions[i];
1198: if (curr.getInitialState() == NLSSubstitution.INTERNALIZED) {
1199: return true;
1200: }
1201: if (curr.getInitialState() == NLSSubstitution.EXTERNALIZED
1202: && curr.getInitialValue() == null) {
1203: return true;
1204: }
1205: }
1206: return false;
1207: }
1208:
1209: /**
1210: *
1211: */
1212: protected void doFilterCheckBoxPressed() {
1213: fTableViewer.refresh();
1214: }
1215:
1216: private Control createTable(Composite parent) {
1217: Composite c = new Composite(parent, SWT.NONE);
1218: GridLayout gl = new GridLayout();
1219: gl.numColumns = 2;
1220: gl.marginWidth = 0;
1221: gl.marginHeight = 0;
1222: c.setLayout(gl);
1223:
1224: fTable = new Table(c, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
1225: | SWT.FULL_SELECTION | SWT.HIDE_SELECTION | SWT.BORDER);
1226: fTable.setFont(parent.getFont());
1227:
1228: GridData tableGD = new GridData(GridData.FILL_BOTH);
1229: tableGD.heightHint = SWTUtil.getTableHeightHint(fTable,
1230: ROW_COUNT);
1231: //tableGD.widthHint= 40;
1232: fTable.setLayoutData(tableGD);
1233:
1234: fTable.setLinesVisible(true);
1235:
1236: TableLayout layout = new TableLayout();
1237: fTable.setLayout(layout);
1238: fTable.setHeaderVisible(true);
1239:
1240: ColumnLayoutData[] columnLayoutData = new ColumnLayoutData[SIZE];
1241: columnLayoutData[STATE_PROP] = new ColumnPixelData(18, false,
1242: true);
1243: columnLayoutData[KEY_PROP] = new ColumnWeightData(40, true);
1244: columnLayoutData[VAL_PROP] = new ColumnWeightData(40, true);
1245:
1246: for (int i = 0; i < fgTitles.length; i++) {
1247: TableColumn tc = new TableColumn(fTable, SWT.NONE, i);
1248: tc.setText(fgTitles[i]);
1249: layout.addColumnData(columnLayoutData[i]);
1250: tc.setResizable(columnLayoutData[i].resizable);
1251: }
1252:
1253: createButtonComposite(c);
1254: return c;
1255: }
1256:
1257: private void createButtonComposite(Composite parent) {
1258: Composite buttonComp = new Composite(parent, SWT.NONE);
1259: GridLayout gl = new GridLayout();
1260: gl.marginHeight = 0;
1261: gl.marginWidth = 0;
1262: buttonComp.setLayout(gl);
1263: buttonComp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
1264:
1265: SelectionAdapter adapter = new SelectionAdapter() {
1266: public void widgetSelected(SelectionEvent e) {
1267: handleButtonPressed(e.widget);
1268: }
1269: };
1270:
1271: fExternalizeButton = createTaskButton(
1272: buttonComp,
1273: NLSUIMessages.ExternalizeWizardPage_Externalize_Selected,
1274: adapter);
1275: fIgnoreButton = createTaskButton(buttonComp,
1276: NLSUIMessages.ExternalizeWizardPage_Ignore_Selected,
1277: adapter);
1278: fInternalizeButton = createTaskButton(
1279: buttonComp,
1280: NLSUIMessages.ExternalizeWizardPage_Internalize_Selected,
1281: adapter);
1282:
1283: new Label(buttonComp, SWT.NONE); // separator
1284:
1285: fEditButton = createTaskButton(buttonComp,
1286: NLSUIMessages.ExternalizeWizardPage_Edit_key_and_value,
1287: adapter);
1288: fRevertButton = createTaskButton(buttonComp,
1289: NLSUIMessages.ExternalizeWizardPage_Revert_Selected,
1290: adapter);
1291: fRenameButton = createTaskButton(buttonComp,
1292: NLSUIMessages.ExternalizeWizardPage_Rename_Keys,
1293: adapter);
1294:
1295: fEditButton.setEnabled(false);
1296: fRenameButton.setEnabled(false);
1297: buttonComp.pack();
1298: }
1299:
1300: /**
1301: * @param widget
1302: */
1303: protected void handleButtonPressed(Widget widget) {
1304: if (widget == fExternalizeButton) {
1305: setSelectedTasks(NLSSubstitution.EXTERNALIZED);
1306: } else if (widget == fIgnoreButton) {
1307: setSelectedTasks(NLSSubstitution.IGNORED);
1308: } else if (widget == fInternalizeButton) {
1309: setSelectedTasks(NLSSubstitution.INTERNALIZED);
1310: } else if (widget == fEditButton) {
1311: openEditButton(fTableViewer.getSelection());
1312: } else if (widget == fRevertButton) {
1313: revertStateOfSelection();
1314: } else if (widget == fRenameButton) {
1315: openRenameDialog();
1316: }
1317: }
1318:
1319: /**
1320: *
1321: */
1322: private void openRenameDialog() {
1323: IStructuredSelection sel = (IStructuredSelection) fTableViewer
1324: .getSelection();
1325: List elementsToRename = getExternalizedElements(sel);
1326: RenameKeysDialog dialog = new RenameKeysDialog(getShell(),
1327: elementsToRename);
1328: if (dialog.open() == Window.OK) {
1329: fTableViewer.refresh();
1330: updateButtonStates((IStructuredSelection) fTableViewer
1331: .getSelection());
1332: }
1333: }
1334:
1335: private void revertStateOfSelection() {
1336: List selection = getSelectedTableEntries();
1337: for (Iterator iter = selection.iterator(); iter.hasNext();) {
1338: NLSSubstitution substitution = (NLSSubstitution) iter
1339: .next();
1340: substitution.revert();
1341: }
1342: fTableViewer.refresh();
1343: updateButtonStates((IStructuredSelection) fTableViewer
1344: .getSelection());
1345: }
1346:
1347: private Button createTaskButton(Composite parent, String label,
1348: SelectionAdapter adapter) {
1349: Button button = new Button(parent, SWT.PUSH);
1350: button.setText(label);
1351: button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1352: SWTUtil.setButtonDimensionHint(button);
1353: button.addSelectionListener(adapter);
1354: return button;
1355: }
1356:
1357: private void openEditButton(ISelection selection) {
1358: try {
1359: IStructuredSelection sel = (IStructuredSelection) fTableViewer
1360: .getSelection();
1361: NLSSubstitution substitution = (NLSSubstitution) sel
1362: .getFirstElement();
1363: if (substitution == null) {
1364: return;
1365: }
1366:
1367: NLSInputDialog dialog = new NLSInputDialog(getShell(),
1368: substitution);
1369: if (dialog.open() == Window.CANCEL)
1370: return;
1371: KeyValuePair kvPair = dialog.getResult();
1372: if (substitution.getState() == NLSSubstitution.EXTERNALIZED) {
1373: substitution.setKey(kvPair.getKey());
1374: }
1375: substitution.setValue(kvPair.getValue());
1376: validateKeys(false);
1377: } finally {
1378: fTableViewer.refresh();
1379: fTableViewer.getControl().setFocus();
1380: fTableViewer.setSelection(selection);
1381: }
1382: }
1383:
1384: private List getSelectedTableEntries() {
1385: ISelection sel = fTableViewer.getSelection();
1386: if (sel instanceof IStructuredSelection)
1387: return ((IStructuredSelection) sel).toList();
1388: else
1389: return Collections.EMPTY_LIST;
1390: }
1391:
1392: private void setSelectedTasks(int state) {
1393: Assert.isTrue(state == NLSSubstitution.EXTERNALIZED
1394: || state == NLSSubstitution.IGNORED
1395: || state == NLSSubstitution.INTERNALIZED);
1396: List selected = getSelectedTableEntries();
1397: String[] props = new String[] { PROPERTIES[STATE_PROP] };
1398: for (Iterator iter = selected.iterator(); iter.hasNext();) {
1399: NLSSubstitution substitution = (NLSSubstitution) iter
1400: .next();
1401: substitution.setState(state);
1402: if ((substitution.getState() == NLSSubstitution.EXTERNALIZED)
1403: && substitution.hasStateChanged()) {
1404: substitution.generateKey(fSubstitutions);
1405: }
1406: }
1407: fTableViewer.update(selected.toArray(), props);
1408: fTableViewer.getControl().setFocus();
1409: updateButtonStates((IStructuredSelection) fTableViewer
1410: .getSelection());
1411: }
1412:
1413: private void selectionChanged(SelectionChangedEvent event) {
1414: IStructuredSelection selection = (IStructuredSelection) event
1415: .getSelection();
1416: updateButtonStates(selection);
1417: updateSourceView(selection);
1418: }
1419:
1420: private void updateSourceView(IStructuredSelection selection) {
1421: NLSSubstitution first = (NLSSubstitution) selection
1422: .getFirstElement();
1423: if (first != null) {
1424: Region region = first.getNLSElement().getPosition();
1425: fSourceViewer.setSelectedRange(region.getOffset(), region
1426: .getLength());
1427: fSourceViewer.revealRange(region.getOffset(), region
1428: .getLength());
1429: }
1430: }
1431:
1432: private void updateButtonStates(IStructuredSelection selection) {
1433: fExternalizeButton.setEnabled(true);
1434: fIgnoreButton.setEnabled(true);
1435: fInternalizeButton.setEnabled(true);
1436: fRevertButton.setEnabled(true);
1437:
1438: if (containsOnlyElementsOfSameState(
1439: NLSSubstitution.EXTERNALIZED, selection)) {
1440: fExternalizeButton.setEnabled(false);
1441: }
1442:
1443: if (containsOnlyElementsOfSameState(NLSSubstitution.IGNORED,
1444: selection)) {
1445: fIgnoreButton.setEnabled(false);
1446: }
1447:
1448: if (containsOnlyElementsOfSameState(
1449: NLSSubstitution.INTERNALIZED, selection)) {
1450: fInternalizeButton.setEnabled(false);
1451: }
1452:
1453: if (!containsElementsWithChange(selection)) {
1454: fRevertButton.setEnabled(false);
1455: }
1456:
1457: fRenameButton.setEnabled(getExternalizedElements(selection)
1458: .size() > 1);
1459: fEditButton.setEnabled(selection.size() == 1);
1460: }
1461:
1462: private boolean containsElementsWithChange(
1463: IStructuredSelection selection) {
1464: for (Iterator iter = selection.iterator(); iter.hasNext();) {
1465: NLSSubstitution substitution = (NLSSubstitution) iter
1466: .next();
1467: if (substitution.hasPropertyFileChange()
1468: || substitution.hasSourceChange()) {
1469: return true;
1470: }
1471: }
1472: return false;
1473: }
1474:
1475: private List getExternalizedElements(IStructuredSelection selection) {
1476: ArrayList res = new ArrayList();
1477: for (Iterator iter = selection.iterator(); iter.hasNext();) {
1478: NLSSubstitution substitution = (NLSSubstitution) iter
1479: .next();
1480: if (substitution.getState() == NLSSubstitution.EXTERNALIZED
1481: && !substitution.hasStateChanged()) {
1482: res.add(substitution);
1483: }
1484: }
1485: return res;
1486: }
1487:
1488: private boolean containsOnlyElementsOfSameState(int state,
1489: IStructuredSelection selection) {
1490: for (Iterator iter = selection.iterator(); iter.hasNext();) {
1491: NLSSubstitution substitution = (NLSSubstitution) iter
1492: .next();
1493: if (substitution.getState() != state) {
1494: return false;
1495: }
1496: }
1497: return true;
1498: }
1499:
1500: public boolean performFinish() {
1501: return super .performFinish();
1502: }
1503:
1504: public IWizardPage getNextPage() {
1505: return super .getNextPage();
1506: }
1507:
1508: public void dispose() {
1509: storeAccessorDescriptions();
1510: //widgets will be disposed. only need to null'em
1511: fPrefixField = null;
1512: fSourceViewer = null;
1513: fTable = null;
1514: fTableViewer = null;
1515: fEditButton = null;
1516: super.dispose();
1517: }
1518: }
|