Allowing changing encoding on per-file.
diff --git a/openide.loaders/src/org/netbeans/modules/openide/loaders/PerFileEncodingQueryImplementation.java b/openide.loaders/src/org/netbeans/modules/openide/loaders/PerFileEncodingQueryImplementation.java
new file mode 100644
--- /dev/null
+++ b/openide.loaders/src/org/netbeans/modules/openide/loaders/PerFileEncodingQueryImplementation.java
@@ -0,0 +1,78 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.openide.loaders;
+
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.logging.Logger;
+import org.netbeans.spi.queries.FileEncodingQueryImplementation;
+import org.openide.filesystems.FileObject;
+
+/**
+ * This provides a higher priority query on text encoding.
+ *
+ *
In order to keep it work, make sure other service implementation has a lower
+ * position than this one.
+ *
+ * @author LAO Zhongcheng
+ */
+@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.queries.FileEncodingQueryImplementation.class, position=10)
+public class PerFileEncodingQueryImplementation extends FileEncodingQueryImplementation {
+
+ private static final Logger LOG = Logger.getLogger(PerFileEncodingQueryImplementation.class.getName());
+
+ /** Name of text encoding property. Allows to change per-file text encoding. */
+ private static final String PROP_TEXT_ENCODING = "textEncoding"; // NOI18N
+
+ @Override
+ public Charset getEncoding(FileObject file) {
+ String overridenEncoding = (String) file.getAttribute(PROP_TEXT_ENCODING);
+ if (overridenEncoding != null) {
+ try {
+ return Charset.forName(overridenEncoding);
+ } catch (UnsupportedCharsetException ex) {
+ LOG.warning("Invalid charset: " + overridenEncoding);
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/openide.loaders/src/org/openide/loaders/Bundle.properties b/openide.loaders/src/org/openide/loaders/Bundle.properties
--- a/openide.loaders/src/org/openide/loaders/Bundle.properties
+++ b/openide.loaders/src/org/openide/loaders/Bundle.properties
@@ -90,6 +90,9 @@
PROP_extension=Extension
HINT_extension=Primary file extension.
ERROR_extension=Cannot change extension. File is modified.
+PROP_textEncoding=Text Encoding
+HINT_textEncoding=Text encoding of the primary file. (Only applies to the text editor. This will not effect the build.)
+ERROR_textEncoding=Cannot change text encoding. The specified encoding {0} is invalid on current Java platform.
# name of set with sorting options
PROP_sorting=Sorting
diff --git a/openide.loaders/src/org/openide/loaders/DataNode.java b/openide.loaders/src/org/openide/loaders/DataNode.java
--- a/openide.loaders/src/org/openide/loaders/DataNode.java
+++ b/openide.loaders/src/org/openide/loaders/DataNode.java
@@ -46,13 +46,18 @@
import java.beans.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import java.text.MessageFormat;
import java.util.*;
import javax.swing.Action;
+import org.netbeans.api.queries.FileEncodingQuery;
import org.netbeans.modules.openide.loaders.UIException;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.filesystems.*;
import org.openide.nodes.*;
+import org.openide.text.DataEditorSupport;
import org.openide.util.*;
import org.openide.util.actions.SystemAction;
import org.openide.util.datatransfer.ExTransferable;
@@ -78,6 +83,9 @@
/** Name of extension property. Allows to change extension. */
private static final String PROP_EXTENSION = "extension"; // NOI18N
+ /** Name of text encoding property. Allows to change per-file text encoding. */
+ private static final String PROP_TEXT_ENCODING = "textEncoding"; // NOI18N
+
/** Create a data node with the given children set for the given data object.
* @param obj object to work with
* @param ch children container for the node
@@ -468,6 +476,7 @@
ss.put(new AllFilesProperty());
ss.put(new SizeProperty());
ss.put(new LastModifiedProperty());
+ ss.put(new TextEncodingProperty());
}
// Fix for IZ#120560 - Refactor of resources node in project view throws ISE exception
if ( fo.isFolder() ){
@@ -602,6 +611,69 @@
}
}
+ /**
+ * A property with text encoding of this object. It allows to change the per-file text encoding (#27444).
+ */
+ private final class TextEncodingProperty extends PropertySupport.ReadWrite {
+
+ public TextEncodingProperty() {
+ super(PROP_TEXT_ENCODING, String.class,
+ DataObject.getString("PROP_textEncoding"), DataObject.getString("HINT_textEncoding")); //NOI18N
+ }
+
+ @Override
+ public boolean canWrite() {
+ return obj.isRenameAllowed();
+ }
+
+ @Override
+ public String getValue() throws IllegalAccessException, InvocationTargetException {
+ Charset charset = FileEncodingQuery.getEncoding(obj.getPrimaryFile());
+ return charset.name();
+ }
+
+ @Override
+ public void setValue(String newEncoding) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ try {
+ Charset newCharset = Charset.forName(newEncoding);
+ newEncoding = newCharset.name();
+ if (getValue().equals(newEncoding)) {
+ return;
+ }
+ } catch (UnsupportedCharsetException ex) {
+ String message = DataObject.getString("ERROR_textEncoding"); //NOI18N
+ DialogDisplayer.getDefault().notify(
+ new NotifyDescriptor.Message(MessageFormat.format(message, new Object[]{newEncoding})));
+ return;
+ }
+ try {
+ DataEditorSupport editor = obj.getLookup().lookup(DataEditorSupport.class);
+ FileObject prim = obj.getPrimaryFile();
+
+ if (obj.isModified() && editor.close() == false) {
+ return;
+ }
+
+ FileLock lock = prim.lock();
+ try {
+ prim.setAttribute(PROP_TEXT_ENCODING, newEncoding);
+
+ } finally {
+ lock.releaseLock();
+ }
+
+ if (editor.isDocumentLoaded()) {
+ editor.reload();
+ } else {
+ editor.open();
+ }
+
+ } catch (IOException ioe) {
+ Exceptions.printStackTrace(ioe);
+ }
+ }
+ }
+
/** Copy this node to the clipboard.
*
* @return {@link org.openide.util.datatransfer.ExTransferable.Single} with one copy flavor
@@ -1176,6 +1248,4 @@
}
}
-
-
}
diff --git a/openide.loaders/src/org/openide/text/DataEditorSupport.java b/openide.loaders/src/org/openide/text/DataEditorSupport.java
--- a/openide.loaders/src/org/openide/text/DataEditorSupport.java
+++ b/openide.loaders/src/org/openide/text/DataEditorSupport.java
@@ -95,6 +95,7 @@
import org.openide.util.Mutex;
import org.openide.util.NbBundle;
import org.openide.util.Parameters;
+import org.openide.util.Task;
import org.openide.util.WeakListeners;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
@@ -1204,5 +1205,12 @@
return obj != null && getClass() == obj.getClass();
}
}
+
+ /**
+ * Reloads the document synchronously.
+ */
+ public void reload() {
+ super.reloadDocument().waitFinished();
+ }
}