001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.core.text.bundle;
011:
012: import org.eclipse.jface.text.BadLocationException;
013: import org.eclipse.jface.text.IDocument;
014: import org.eclipse.osgi.util.NLS;
015: import org.eclipse.pde.core.IModelChangedEvent;
016: import org.eclipse.pde.internal.core.PDECoreMessages;
017: import org.eclipse.pde.internal.core.text.AbstractKeyValueTextChangeListener;
018: import org.eclipse.pde.internal.core.text.IDocumentKey;
019: import org.eclipse.pde.internal.core.util.PropertiesUtil;
020: import org.eclipse.text.edits.InsertEdit;
021: import org.eclipse.text.edits.TextEdit;
022:
023: public class BundleTextChangeListener extends
024: AbstractKeyValueTextChangeListener {
025:
026: public BundleTextChangeListener(IDocument document) {
027: super (document, false);
028: }
029:
030: public BundleTextChangeListener(IDocument document,
031: boolean generateReadableNames) {
032: super (document, generateReadableNames);
033: }
034:
035: public TextEdit[] getTextOperations() {
036: TextEdit[] ops = super .getTextOperations();
037: try {
038: if (ops.length == 0
039: || !PropertiesUtil.isNewlineNeeded(fDocument))
040: return ops;
041: } catch (BadLocationException e) {
042: }
043:
044: TextEdit[] result = new TextEdit[ops.length + 1];
045: result[ops.length] = new InsertEdit(PropertiesUtil
046: .getInsertOffset(fDocument), fSep);
047: if (fReadableNames != null)
048: fReadableNames
049: .put(
050: result[ops.length],
051: PDECoreMessages.BundleTextChangeListener_editNames_newLine);
052: System.arraycopy(ops, 0, result, 0, ops.length);
053: return result;
054: }
055:
056: /*
057: * (non-Javadoc)
058: *
059: * This method is overwritten in the BundleTextChangeListener so that newly inserted headers
060: * will have their separator inserted at the start of the change rather than the end when there
061: * is not already a new line at the end of the manifest. This allows the "Add a new line at the
062: * end of the file" change to go at the bottom of the preview as the user would expect. Previously
063: * it was added before all inserts so the new headers would appear on new lines.
064: *
065: * @see org.eclipse.pde.internal.core.text.AbstractKeyValueTextChangeListener#insertKey(org.eclipse.pde.internal.core.text.IDocumentKey, java.lang.String)
066: */
067: protected void insertKey(IDocumentKey key, String name) {
068: int offset = PropertiesUtil.getInsertOffset(fDocument);
069: StringBuffer buffer = new StringBuffer(key.write());
070: try {
071: // if the file does not end in a new line and the key to insert does, move the new line
072: // to the start of the key.
073: if (PropertiesUtil.isNewlineNeeded(fDocument)
074: && buffer
075: .substring(buffer.length() - fSep.length())
076: .equals(fSep)) {
077: buffer.insert(0, fSep);
078: buffer.setLength(buffer.length() - fSep.length());
079: }
080: } catch (BadLocationException e) {
081: }
082: InsertEdit edit = new InsertEdit(offset, buffer.toString());
083: fOperationTable.put(key, edit);
084: if (fReadableNames != null)
085: fReadableNames.put(edit, name);
086: }
087:
088: public void modelChanged(IModelChangedEvent event) {
089: Object[] objects = event.getChangedObjects();
090: for (int i = 0; i < objects.length; i++) {
091: Object object = objects[i];
092: if (object instanceof PDEManifestElement)
093: object = ((PDEManifestElement) object).getHeader();
094: else if (object instanceof PackageFriend)
095: object = ((PackageFriend) object).getHeader();
096:
097: if (object instanceof ManifestHeader) {
098: ManifestHeader header = (ManifestHeader) object;
099: Object op = fOperationTable.remove(header);
100: if (fReadableNames != null)
101: fReadableNames.remove(op);
102:
103: if (header.getValue() == null
104: || header.getValue().trim().length() == 0) {
105: String name = fReadableNames == null ? null
106: : NLS
107: .bind(
108: PDECoreMessages.BundleTextChangeListener_editNames_remove,
109: header.fName);
110: deleteKey(header, name);
111: } else {
112: String name = fReadableNames == null ? null
113: : NLS
114: .bind(
115: header.getOffset() == -1 ? PDECoreMessages.BundleTextChangeListener_editNames_insert
116: : PDECoreMessages.BundleTextChangeListener_editNames_modify,
117: header.fName);
118: modifyKey(header, name);
119: }
120: }
121: }
122: }
123:
124: }
|