diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/export/AbstractPropertiesFieldsPart.java')
-rwxr-xr-x | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/export/AbstractPropertiesFieldsPart.java | 356 |
1 files changed, 0 insertions, 356 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/export/AbstractPropertiesFieldsPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/export/AbstractPropertiesFieldsPart.java deleted file mode 100755 index bc3051e88..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/export/AbstractPropertiesFieldsPart.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.editors.export; - -import com.android.SdkConstants; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper.ManifestSectionPart; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.DocumentEvent; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.Section; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; - -/** - * Section part for editing fields of a properties file in an Export editor. - * <p/> - * This base class is intended to be derived and customized. - */ -abstract class AbstractPropertiesFieldsPart extends ManifestSectionPart { - - private final HashMap<String, Control> mNameToField = new HashMap<String, Control>(); - - private ExportEditor mEditor; - - private boolean mInternalTextUpdate = false; - - public AbstractPropertiesFieldsPart(Composite body, FormToolkit toolkit, ExportEditor editor) { - super(body, toolkit, Section.TWISTIE | Section.EXPANDED, true /* description */); - mEditor = editor; - } - - protected HashMap<String, Control> getNameToField() { - return mNameToField; - } - - protected ExportEditor getEditor() { - return mEditor; - } - - protected void setInternalTextUpdate(boolean internalTextUpdate) { - mInternalTextUpdate = internalTextUpdate; - } - - protected boolean isInternalTextUpdate() { - return mInternalTextUpdate; - } - - /** - * Adds a modify listener to every text field that will mark the part as dirty. - * - * CONTRACT: Derived classes MUST call this at the end of their constructor. - * - * @see #setFieldModifyListener(Control, ModifyListener) - */ - protected void addModifyListenerToFields() { - ModifyListener markDirtyListener = new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - // Mark the part as dirty if a field has been changed. - // This will force a commit() operation to store the data in the model. - if (!mInternalTextUpdate) { - markDirty(); - } - } - }; - - for (Control field : mNameToField.values()) { - setFieldModifyListener(field, markDirtyListener); - } - } - - /** - * Sets a listener that will mark the part as dirty when the control is modified. - * The base method only handles {@link Text} fields. - * - * CONTRACT: Derived classes CAN use this to add a listener to their own controls. - * The listener must call {@link #markDirty()} when the control is modified by the user. - * - * @param field A control previously registered with {@link #getNameToField()}. - * @param markDirtyListener A {@link ModifyListener} that invokes {@link #markDirty()}. - * - * @see #isInternalTextUpdate() - */ - protected void setFieldModifyListener(Control field, ModifyListener markDirtyListener) { - if (field instanceof Text) { - ((Text) field).addModifyListener(markDirtyListener); - } - } - - /** - * Updates the model based on the content of fields. This is invoked when a field - * has marked the document as dirty. - * - * CONTRACT: Derived classes do not need to override this. - */ - @Override - public void commit(boolean onSave) { - - // We didn't store any information indicating which field was dirty (we could). - // Since there are not many fields, just update all the document lines that - // match our field keywords. - - if (isDirty()) { - mEditor.wrapRewriteSession(new Runnable() { - @Override - public void run() { - saveFieldsToModel(); - } - }); - } - - super.commit(onSave); - } - - private void saveFieldsToModel() { - // Get a list of all keywords to process. Go thru the document, replacing in-place - // the ones we can find and remove them from this set. This will leave the list - // of new keywords to add at the end of the document. - HashSet<String> allKeywords = new HashSet<String>(mNameToField.keySet()); - - IDocument doc = mEditor.getDocument(); - int numLines = doc.getNumberOfLines(); - - String delim = null; - try { - delim = numLines > 0 ? doc.getLineDelimiter(0) : null; - } catch (BadLocationException e1) { - // ignore - } - if (delim == null || delim.length() == 0) { - delim = SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS ? - "\r\n" : "\n"; //$NON-NLS-1$ //$NON-NLS-2# - } - - for (int i = 0; i < numLines; i++) { - try { - IRegion info = doc.getLineInformation(i); - String line = doc.get(info.getOffset(), info.getLength()); - line = line.trim(); - if (line.startsWith("#")) { //$NON-NLS-1$ - continue; - } - - int pos = line.indexOf('='); - if (pos > 0 && pos < line.length() - 1) { - String key = line.substring(0, pos).trim(); - - Control field = mNameToField.get(key); - if (field != null) { - - // This is the new line to inject - line = key + "=" + getFieldText(field); - - try { - // replace old line by new one. This doesn't change the - // line delimiter. - mInternalTextUpdate = true; - doc.replace(info.getOffset(), info.getLength(), line); - allKeywords.remove(key); - } finally { - mInternalTextUpdate = false; - } - } - } - - } catch (BadLocationException e) { - // TODO log it - AdtPlugin.log(e, "Failed to replace in export.properties"); - } - } - - for (String key : allKeywords) { - Control field = mNameToField.get(key); - if (field != null) { - // This is the new line to inject - String line = key + "=" + getFieldText(field); - - try { - // replace old line by new one - mInternalTextUpdate = true; - - numLines = doc.getNumberOfLines(); - - IRegion info = numLines > 0 ? doc.getLineInformation(numLines - 1) : null; - if (info != null && info.getLength() == 0) { - // last line is empty. Insert right before there. - doc.replace(info.getOffset(), info.getLength(), line); - } else { - if (numLines > 0) { - String eofDelim = doc.getLineDelimiter(numLines - 1); - if (eofDelim == null || eofDelim.length() == 0) { - // The document doesn't end with a line delimiter, so add - // one to the line to be written. - line = delim + line; - } - } - - int len = doc.getLength(); - doc.replace(len, 0, line); - } - - allKeywords.remove(key); - } catch (BadLocationException e) { - // TODO log it - AdtPlugin.log(e, "Failed to append to export.properties: %s", line); - } finally { - mInternalTextUpdate = false; - } - } - } - } - - /** - * Used when committing fields values to the model to retrieve the text - * associated with a field. - * <p/> - * The base method only handles {@link Text} controls. - * - * CONTRACT: Derived classes CAN use this to support their own controls. - * - * @param field A control previously registered with {@link #getNameToField()}. - * @return A non-null string to write to the properties files. - */ - protected String getFieldText(Control field) { - if (field instanceof Text) { - return ((Text) field).getText(); - } - return ""; - } - - /** - * Called after all pages have been created, to let the parts initialize their - * content based on the document's model. - * <p/> - * The model should be acceded via the {@link ExportEditor}. - * - * @param editor The {@link ExportEditor} instance. - */ - public void onModelInit(ExportEditor editor) { - - // Start with a set of all the possible keywords and remove those we - // found in the document as we read the lines. - HashSet<String> allKeywords = new HashSet<String>(mNameToField.keySet()); - - // Parse the lines in the document for patterns "keyword=value", - // trimming all whitespace and discarding lines that start with # (comments) - // then affect to the internal fields as appropriate. - IDocument doc = editor.getDocument(); - int numLines = doc.getNumberOfLines(); - for (int i = 0; i < numLines; i++) { - try { - IRegion info = doc.getLineInformation(i); - String line = doc.get(info.getOffset(), info.getLength()); - line = line.trim(); - if (line.startsWith("#")) { //$NON-NLS-1$ - continue; - } - - int pos = line.indexOf('='); - if (pos > 0 && pos < line.length() - 1) { - String key = line.substring(0, pos).trim(); - - Control field = mNameToField.get(key); - if (field != null) { - String value = line.substring(pos + 1).trim(); - try { - mInternalTextUpdate = true; - setFieldText(field, value); - allKeywords.remove(key); - } finally { - mInternalTextUpdate = false; - } - } - } - - } catch (BadLocationException e) { - // TODO log it - AdtPlugin.log(e, "Failed to set field to export.properties value"); - } - } - - // Clear the text of any keyword we didn't find in the document - Iterator<String> iterator = allKeywords.iterator(); - while (iterator.hasNext()) { - String key = iterator.next(); - Control field = mNameToField.get(key); - if (field != null) { - try { - mInternalTextUpdate = true; - setFieldText(field, ""); - iterator.remove(); - } finally { - mInternalTextUpdate = false; - } - } - } - } - - /** - * Used when reading the model to set the field values. - * <p/> - * The base method only handles {@link Text} controls. - * - * CONTRACT: Derived classes CAN use this to support their own controls. - * - * @param field A control previously registered with {@link #getNameToField()}. - * @param value A non-null string to that was read from the properties files. - * The value is an empty string if the property line is missing. - */ - protected void setFieldText(Control field, String value) { - if (field instanceof Text) { - ((Text) field).setText(value); - } - } - - /** - * Called after the document model has been changed. The model should be acceded via - * the {@link ExportEditor} (e.g. getDocument, wrapRewriteSession) - * - * @param editor The {@link ExportEditor} instance. - * @param event Specification of changes applied to document. - */ - public void onModelChanged(ExportEditor editor, DocumentEvent event) { - // To simplify and since we don't have many fields, just reload all the values. - // A better way would to be to look at DocumentEvent which gives us the offset/length - // and text that has changed. - if (!mInternalTextUpdate) { - onModelInit(editor); - } - } -} |