├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── README_es.md ├── build.xml ├── manifest.mf ├── nbproject ├── build-impl.xml ├── genfiles.properties ├── platform.properties ├── project.properties └── project.xml ├── pom.xml ├── screenshots └── nb-encoding-statusline.png ├── src └── com │ └── junichi11 │ └── netbeans │ └── modules │ └── encoding │ ├── Bundle.properties │ ├── Bundle_es.properties │ ├── Bundle_fr.properties │ ├── Bundle_it.properties │ ├── OpenInEncodingQueryImpl.java │ ├── actions │ ├── Bundle.properties │ ├── Bundle_es.properties │ ├── Bundle_fr.properties │ ├── Bundle_it.properties │ ├── EncodingAccessories.form │ ├── EncodingAccessories.java │ ├── OpenInEncoding.java │ └── SaveInEncoding.java │ ├── options │ └── EncodingOptions.java │ ├── resources │ ├── encoding_16.png │ ├── layer.xml │ └── license.txt │ └── ui │ ├── Bundle.properties │ ├── EncodingFileChooser.java │ ├── EncodingMetalFileChooserUI.java │ ├── EncodingPanel.form │ ├── EncodingPanel.java │ ├── EncodingStatusLineElementProvider.java │ └── UiUtils.java └── test └── unit └── src └── com └── junichi11 └── netbeans └── modules └── encoding └── OpenInEncodingQueryImplTest.java /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: junichi11 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | nbproject/private 3 | lib 4 | pom.xml.asc 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetBeans Encoding Plugin 2 | 3 | This plugin opens/saves a file with a specified encoding. 4 | 5 | ## Requirements 6 | 7 | - NetBeans8.2+ 8 | 9 | ## Open/Save in Encoding 10 | 11 | File > Open/Save in Encoding... 12 | 13 | ## Show encoding on the status line 14 | 15 | Current file encoding will be shown on the status line. If you want to change encoding, Please click the encoding label. 16 | (Note: Then, file is closed once and opened again. i.e. File is reopened.) 17 | 18 | ![screenshot](screenshots/nb-encoding-statusline.png) 19 | 20 | ## Search encodings 21 | 22 | To search encodings, you can type something when the encoding list is shown. 23 | You can use and key to change the selected encoding. 24 | You can use Enter key to decide the encoding. 25 | 26 | ## Hide the encoding list 27 | 28 | Just type ESC key or click other than the encoding list. 29 | 30 | ## Downloads 31 | 32 | - https://github.com/junichi11/netbeans-encoding-plugin/releases 33 | - https://plugins.netbeans.apache.org/catalogue/?id=32 34 | 35 | ## Donation 36 | 37 | - https://github.com/sponsors/junichi11 38 | 39 | ## Translations 40 | 41 | - [README_es.md](README_es.md) - Español ([@javatlacati](https://github.com/javatlacati)) 42 | 43 | ## License 44 | 45 | [Common Development and Distribution License (CDDL) v1.0 and GNU General Public License (GPL) v2](http://netbeans.org/cddl-gplv2.html) 46 | 47 | ---- 48 | Cloned from `encoding module` of `main/contrib` repository. ([Tomas Zezula](https://github.com/tzezula)) 49 | 50 | Also see [https://netbeans.org/bugzilla/show_bug.cgi?id=114123](https://netbeans.org/bugzilla/show_bug.cgi?id=114123) 51 | -------------------------------------------------------------------------------- /README_es.md: -------------------------------------------------------------------------------- 1 | # NetBeans Encoding Plugin 2 | Este plugin abre/guarda un archivo con una codificación especificada 3 | 4 | ## Requerimientos 5 | 6 | - NetBeans7.4+ 7 | ## Abrior/Guardar en la Codificación 8 | File > Open/Save in Encoding... 9 | 10 | La codificación actual se mostrará en la Barra de Herramientas. Si desea cambiar la codificación, por favor seleccione la codificación específica. 11 | ( Nota:Entonces, el archivo se cierra y se vuelve a abrir.) 12 | 13 | Si no desea que se muestre deseleccione la casilla `View > Toolbar > Encoding`. 14 | 15 | ## Licencia 16 | [Common Development and Distribution License (CDDL) v1.0 and GNU General Public License (GPL) v2](http://netbeans.org/cddl-gplv2.html) 17 | 18 | ---- 19 | Clonado de `encoding module` del repositorio `main/contrib`. (Tomas Zezula) 20 | También vea https://netbeans.org/bugzilla/show_bug.cgi?id=114123 21 | 22 | Traductor : [@javatlacati](https://github.com/javatlacati) (scherzo16@gmail.com) 23 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Builds, tests, and runs the project com.junichi11.netbeans.modules.encoding. 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | OpenIDE-Module: com.junichi11.netbeans.modules.encoding 3 | OpenIDE-Module-Layer: com/junichi11/netbeans/modules/encoding/resources/layer.xml 4 | OpenIDE-Module-Localizing-Bundle: com/junichi11/netbeans/modules/encoding/Bundle.properties 5 | OpenIDE-Module-Specification-Version: 1.9.1 6 | 7 | -------------------------------------------------------------------------------- /nbproject/build-impl.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /nbproject/genfiles.properties: -------------------------------------------------------------------------------- 1 | build.xml.data.CRC32=e12ca191 2 | build.xml.script.CRC32=6c7bb501 3 | build.xml.stylesheet.CRC32=15ca8a54@2.75.1 4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. 5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. 6 | nbproject/build-impl.xml.data.CRC32=e12ca191 7 | nbproject/build-impl.xml.script.CRC32=3d1bfa64 8 | nbproject/build-impl.xml.stylesheet.CRC32=49aa68b0@2.75.1 9 | -------------------------------------------------------------------------------- /nbproject/platform.properties: -------------------------------------------------------------------------------- 1 | cluster.path=\ 2 | ${nbplatform.active.dir}/nb:\ 3 | ${nbplatform.active.dir}/platform:\ 4 | ${nbplatform.active.dir}/apisupport:\ 5 | ${nbplatform.active.dir}/ide:\ 6 | ${nbplatform.active.dir}/java:\ 7 | ${nbplatform.active.dir}/profiler:\ 8 | ${nbplatform.active.dir}/harness 9 | nbplatform.active=default 10 | -------------------------------------------------------------------------------- /nbproject/project.properties: -------------------------------------------------------------------------------- 1 | javac.source=1.8 2 | javac.compilerargs=-Xlint -Xlint:-serial 3 | license.file=src/com/junichi11/netbeans/modules/encoding/resources/license.txt 4 | nbm.homepage=https://github.com/junichi11/netbeans-encoding-plugin 5 | nbm.module.author=Tomas Zezula, Junichi Yamamoto 6 | project.license=cddl-netbeans-sun 7 | keystore=nbproject/private/keystore 8 | nbm_alias=encoding 9 | -------------------------------------------------------------------------------- /nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.apisupport.project 4 | 5 | 6 | com.junichi11.netbeans.modules.encoding 7 | 8 | 9 | 10 | org.netbeans.api.annotations.common 11 | 12 | 13 | 14 | 1 15 | 1.27.1 16 | 17 | 18 | 19 | org.netbeans.api.templates 20 | 21 | 22 | 23 | 1.6.1 24 | 25 | 26 | 27 | org.netbeans.modules.editor 28 | 29 | 30 | 31 | 3 32 | 1.75.1.5.22.43 33 | 34 | 35 | 36 | org.netbeans.modules.editor.document 37 | 38 | 39 | 40 | 1.5.1.1 41 | 42 | 43 | 44 | org.netbeans.modules.editor.lib2 45 | 46 | 47 | 48 | 1 49 | 1.81.1.43 50 | 51 | 52 | 53 | org.netbeans.modules.projectapi 54 | 55 | 56 | 57 | 1 58 | 1.66.1 59 | 60 | 61 | 62 | org.netbeans.modules.queries 63 | 64 | 65 | 66 | 1 67 | 1.36.1 68 | 69 | 70 | 71 | org.openide.awt 72 | 73 | 74 | 75 | 7.59.1 76 | 77 | 78 | 79 | org.openide.dialogs 80 | 81 | 82 | 83 | 7.42.1 84 | 85 | 86 | 87 | org.openide.filesystems 88 | 89 | 90 | 91 | 9.8.1 92 | 93 | 94 | 95 | org.openide.loaders 96 | 97 | 98 | 99 | 7.51.1 100 | 101 | 102 | 103 | org.openide.nodes 104 | 105 | 106 | 107 | 7.36.1 108 | 109 | 110 | 111 | org.openide.text 112 | 113 | 114 | 115 | 6.58.1 116 | 117 | 118 | 119 | org.openide.util 120 | 121 | 122 | 123 | 8.33.1 124 | 125 | 126 | 127 | org.openide.util.lookup 128 | 129 | 130 | 131 | 8.22.1 132 | 133 | 134 | 135 | org.openide.util.ui 136 | 137 | 138 | 139 | 9.4.1 140 | 141 | 142 | 143 | org.openide.windows 144 | 145 | 146 | 147 | 6.65.1 148 | 149 | 150 | 151 | 152 | 153 | unit 154 | 155 | org.netbeans.insane 156 | 157 | 158 | 159 | org.netbeans.libs.junit4 160 | 161 | 162 | 163 | org.netbeans.modules.masterfs 164 | 165 | 166 | 167 | org.netbeans.modules.nbjunit 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.junichi11.netbeans.modules 5 | netbeans-encoding 6 | 7 | 1.9.1 8 | nbm 9 | NetBeans Encoding Plugin 10 | https://github.com/junichi11/netbeans-encoding-plugin 11 | This plugin opens/saves a file with a specified encoding. 12 | 13 | 14 | junichi11 15 | Junichi Yamamoto 16 | https://github.com/junichi11 17 | 18 | 19 | 20 | scm:git:https://github.com/junichi11/netbeans-encoding-plugin.git 21 | scm:git:https://github.com/junichi11/netbeans-encoding-plugin.git 22 | https://github.com/junichi11/netbeans-encoding-plugin 23 | HEAD 24 | 25 | 26 | 27 | Common Development and Distribution License (CDDL) v1.0 and GNU General Public License (GPL) v2 28 | http://netbeans.org/cddl-gplv2.html 29 | 30 | 31 | 32 | 33 | ossrh 34 | https://oss.sonatype.org/content/repositories/snapshots 35 | 36 | 37 | ossrh 38 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-deploy-plugin 46 | 3.0.0-M1 47 | 48 | 49 | org.sonatype.plugins 50 | nexus-staging-maven-plugin 51 | 1.6.7 52 | true 53 | 54 | ossrh 55 | https://oss.sonatype.org/ 56 | true 57 | 58 | 59 | 60 | org.apache.maven.plugins 61 | maven-compiler-plugin 62 | 3.8.1 63 | 64 | 1.8 65 | 1.8 66 | 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-jar-plugin 71 | 3.1.2 72 | 73 | 74 | ${project.build.outputDirectory}/META-INF/MANIFEST.MF 75 | 76 | 77 | 78 | 79 | org.apache.maven.plugins 80 | maven-gpg-plugin 81 | 1.6 82 | 83 | 84 | sign-artifacts 85 | verify 86 | 87 | sign 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /screenshots/nb-encoding-statusline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junichi11/netbeans-encoding-plugin/9cdbe72d25424cfac9f14fc54d79332c11bb6f45/screenshots/nb-encoding-statusline.png -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/Bundle.properties: -------------------------------------------------------------------------------- 1 | OpenIDE-Module-Display-Category=Utilities 2 | OpenIDE-Module-Long-Description=\ 3 | This modules provides actions to open or save a file in a user given encoding. \ 4 | This actions can be used on convert file to different encodings. 5 | OpenIDE-Module-Name=Encoding Support 6 | OpenIDE-Module-Short-Description=Provides utilities for handling files in various encodings -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/Bundle_es.properties: -------------------------------------------------------------------------------- 1 | OpenIDE-Module-Display-Category=Utilities 2 | OpenIDE-Module-Long-Description=\ 3 | Este m\u00f3dulo provee acciones para abrir o guardar un archivo en una codificaci\u00f3n propuesta por el usuario. \ 4 | Estas acciones pueden ser usadas para convertir un archivo a diferentes codificaciones. 5 | OpenIDE-Module-Name=Encoding Support 6 | OpenIDE-Module-Short-Description=Provee utilidades para la administraci\u00f3n de archivosen varias codificaciones. -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/Bundle_fr.properties: -------------------------------------------------------------------------------- 1 | OpenIDE-Module-Display-Category=Utilitaires 2 | OpenIDE-Module-Long-Description=\ 3 | Le présent module fournit des actes pour ouvrir ou enregistrer un fichier dans un encodage d'utilisateur donné. \ 4 | Ces actes peuvent être utilisés sur le fichier converti à différents encodages. 5 | OpenIDE-Module-Name=Encoding Support 6 | OpenIDE-Module-Short-Description=Fournit des utilitaires pour gérer des fichiers dans différents encodages 7 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/Bundle_it.properties: -------------------------------------------------------------------------------- 1 | OpenIDE-Module-Display-Category=Utilit\u00e0 2 | OpenIDE-Module-Long-Description=\ 3 | Questo modulo fornisce le azioni per aprire o salvare un file in una codifica determinata di utente. \ 4 | This actions can be used per convertire il file in differenti codifiche. 5 | OpenIDE-Module-Name=Supporto Codifica 6 | OpenIDE-Module-Short-Description=Provide utilit\u00e0 per manipolare files in codifiche vari 7 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/OpenInEncodingQueryImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 | * 4 | * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. 5 | * 6 | * The contents of this file are subject to the terms of either the GNU 7 | * General Public License Version 2 only ("GPL") or the Common 8 | * Development and Distribution License("CDDL") (collectively, the 9 | * "License"). You may not use this file except in compliance with the 10 | * License. You can obtain a copy of the License at 11 | * http://www.netbeans.org/cddl-gplv2.html 12 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the 13 | * specific language governing permissions and limitations under the 14 | * License. When distributing the software, include this License Header 15 | * Notice in each file and include the License file at 16 | * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this 17 | * particular file as subject to the "Classpath" exception as provided 18 | * by Sun in the GPL Version 2 section of the License file that 19 | * accompanied this code. If applicable, add the following below the 20 | * License Header, with the fields enclosed by brackets [] replaced by 21 | * your own identifying information: 22 | * "Portions Copyrighted [year] [name of copyright owner]" 23 | * 24 | * Contributor(s): 25 | * 26 | * Portions Copyrighted 2007 Sun Microsystems, Inc. 27 | */ 28 | package com.junichi11.netbeans.modules.encoding; 29 | 30 | import java.nio.charset.Charset; 31 | import java.nio.charset.IllegalCharsetNameException; 32 | import org.netbeans.spi.queries.FileEncodingQueryImplementation; 33 | import org.openide.filesystems.FileObject; 34 | import org.openide.util.lookup.ServiceProvider; 35 | 36 | /** 37 | * 38 | * @author Tomas Zezula 39 | */ 40 | @ServiceProvider(service = FileEncodingQueryImplementation.class, position = 10) 41 | public final class OpenInEncodingQueryImpl extends FileEncodingQueryImplementation { 42 | 43 | public static final String ENCODING = "encoding"; // NOI18N 44 | 45 | @Override 46 | public Charset getEncoding(FileObject file) { 47 | assert file != null; 48 | final Object encodingName = file.getAttribute(ENCODING); 49 | try { 50 | return encodingName instanceof String ? Charset.forName((String) encodingName) : null; 51 | } catch (IllegalCharsetNameException e) { 52 | return null; 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/actions/Bundle.properties: -------------------------------------------------------------------------------- 1 | CTL_OpenInEncoding=Open in Encoding ... 2 | CTL_SaveInEncoding=Save In Encoding... 3 | EncodingAccessories.encodingLabel.text=&Encoding: 4 | TXT_OpenFile=Open File 5 | CTL_Open=Open 6 | MNE_Open=O 7 | TXT_SaveFile=Save File 8 | CTL_Save=Save 9 | MNE_Save=S 10 | TXT_Default=Default Encoding 11 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/actions/Bundle_es.properties: -------------------------------------------------------------------------------- 1 | CTL_OpenInEncoding=Abrir en la codificaci\u00f3n ... 2 | CTL_SaveInEncoding=Guardar en la codificaci\u00f3n... 3 | EncodingAccessories.encodingLabel.text=&Codificaci\u00f3n: 4 | TXT_OpenFile=Abrir Archivo 5 | CTL_Open=Abrir 6 | MNE_Open=A 7 | TXT_SaveFile=Guardar Archivo 8 | CTL_Save=Guardar 9 | MNE_Save=G 10 | TXT_Default=Codificaci\u00f3n por Defecto 11 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/actions/Bundle_fr.properties: -------------------------------------------------------------------------------- 1 | CTL_OpenInEncoding=Ouvrir dans le encodage... 2 | CTL_SaveInEncoding=Enregistrer dans Encodage... 3 | EncodingAccessories.encodingLabel.text=&Encodage: 4 | TXT_OpenFile=Ouvrir Fichier 5 | CTL_Open=Ouvrir 6 | MNE_Open=O 7 | TXT_SaveFile=Enregistrer Fichier 8 | CTL_Save=Enregistrer 9 | MNE_Save=E 10 | TXT_Default=Encodage par D\u00e9faut 11 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/actions/Bundle_it.properties: -------------------------------------------------------------------------------- 1 | CTL_OpenInEncoding=Apri in Codifica ... 2 | CTL_SaveInEncoding=Salva In Codifica... 3 | EncodingAccessories.encodingLabel.text=&Codifica: 4 | TXT_OpenFile=Apri File 5 | CTL_Open=Apri 6 | MNE_Open=A 7 | TXT_SaveFile=Salva il File 8 | CTL_Save=Salva 9 | MNE_Save=S 10 | TXT_Default=CODIFICA PREDEFINITA 11 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/actions/EncodingAccessories.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/actions/EncodingAccessories.java: -------------------------------------------------------------------------------- 1 | /* 2 | * EncodingAccessories.java 3 | * 4 | * Created on October 12, 2007, 3:22 PM 5 | */ 6 | package com.junichi11.netbeans.modules.encoding.actions; 7 | 8 | import com.junichi11.netbeans.modules.encoding.options.EncodingOptions; 9 | import java.awt.Component; 10 | import java.awt.Dimension; 11 | import java.nio.charset.Charset; 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | import java.util.Collections; 15 | import java.util.List; 16 | import javax.swing.ComboBoxModel; 17 | import javax.swing.DefaultListCellRenderer; 18 | import javax.swing.JList; 19 | import javax.swing.event.ListDataListener; 20 | import org.openide.util.NbBundle; 21 | 22 | /** 23 | * 24 | * @author Tomas Zezula 25 | */ 26 | public class EncodingAccessories extends javax.swing.JPanel { 27 | 28 | private static final long serialVersionUID = 9119652225263260409L; 29 | 30 | /** 31 | * Creates new form EncodingAccessories 32 | */ 33 | public EncodingAccessories() { 34 | initComponents(); 35 | this.encoding.setModel(new EncodingModel()); 36 | this.encoding.setRenderer(new EncodingRenderer()); 37 | } 38 | 39 | public EncodingAccessories(Dimension dimension) { 40 | this(); 41 | encodingLabel.setPreferredSize(dimension); 42 | } 43 | 44 | /** 45 | * This method is called from within the constructor to initialize the form. 46 | * WARNING: Do NOT modify this code. The content of this method is always 47 | * regenerated by the Form Editor. 48 | */ 49 | // //GEN-BEGIN:initComponents 50 | private void initComponents() { 51 | 52 | encodingLabel = new javax.swing.JLabel(); 53 | encoding = new javax.swing.JComboBox(); 54 | 55 | setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.LINE_AXIS)); 56 | 57 | encodingLabel.setLabelFor(encoding); 58 | org.openide.awt.Mnemonics.setLocalizedText(encodingLabel, org.openide.util.NbBundle.getMessage(EncodingAccessories.class, "EncodingAccessories.encodingLabel.text")); // NOI18N 59 | add(encodingLabel); 60 | 61 | add(encoding); 62 | }// //GEN-END:initComponents 63 | 64 | public Charset getEncoding() { 65 | return ((EncodingKey) this.encoding.getSelectedItem()).getCharset(); 66 | } 67 | 68 | public void setEncoding(final Charset encoding) { 69 | EncodingKey key = (encoding == null ? EncodingKey.DEFAULT : new EncodingKey(encoding)); 70 | this.encoding.setSelectedItem(key); 71 | } 72 | 73 | private static class EncodingModel implements ComboBoxModel { 74 | 75 | private Object selected; 76 | private List data; 77 | 78 | public EncodingModel() { 79 | final Collection acs = Charset.availableCharsets().values(); 80 | final List _data = new ArrayList<>(acs.size() + 1); 81 | _data.add(EncodingKey.DEFAULT); 82 | List lastSelectedEncodings = EncodingOptions.getInstance().getLastSelectedEncodings(); 83 | lastSelectedEncodings.forEach(encoding -> { 84 | if (Charset.isSupported(encoding)) { 85 | EncodingKey encodingKey = new EncodingKey(Charset.forName(encoding)); 86 | _data.add(encodingKey); 87 | } 88 | }); 89 | acs.forEach(charset -> { 90 | if (!lastSelectedEncodings.contains(charset.name())) { 91 | _data.add(new EncodingKey(charset)); 92 | } 93 | }); 94 | data = Collections.unmodifiableList(_data); 95 | } 96 | 97 | @Override 98 | public void setSelectedItem(Object anItem) { 99 | this.selected = anItem; 100 | } 101 | 102 | @Override 103 | public Object getSelectedItem() { 104 | return this.selected; 105 | } 106 | 107 | @Override 108 | public int getSize() { 109 | return this.data.size(); 110 | } 111 | 112 | @Override 113 | public Object getElementAt(int index) { 114 | assert index >= 0 && index < this.data.size(); 115 | return this.data.get(index); 116 | } 117 | 118 | @Override 119 | public void addListDataListener(ListDataListener l) { 120 | //Non mutable 121 | } 122 | 123 | @Override 124 | public void removeListDataListener(ListDataListener l) { 125 | //Non mutable 126 | } 127 | 128 | } 129 | 130 | private final static class EncodingKey { 131 | 132 | public static final EncodingKey DEFAULT = new EncodingKey(); 133 | 134 | private final Charset cs; 135 | 136 | public EncodingKey(final Charset cs) { 137 | assert cs != null; 138 | this.cs = cs; 139 | } 140 | 141 | private EncodingKey() { 142 | this.cs = null; 143 | } 144 | 145 | public String getDisplayName() { 146 | return this.cs == null ? NbBundle.getMessage(EncodingAccessories.class, "TXT_Default") : this.cs.displayName(); 147 | } 148 | 149 | public Charset getCharset() { 150 | return this.cs; 151 | } 152 | 153 | @Override 154 | public int hashCode() { 155 | return this.cs == null ? 0 : this.cs.hashCode(); 156 | } 157 | 158 | @Override 159 | public boolean equals(Object obj) { 160 | if (obj instanceof EncodingKey) { 161 | EncodingKey ok = (EncodingKey) obj; 162 | return this.cs == null ? ok.cs == null : this.cs.equals(ok.cs); 163 | } 164 | return false; 165 | } 166 | 167 | @Override 168 | public String toString() { 169 | return this.cs == null ? "" : cs.toString(); // NOI18N 170 | } 171 | 172 | } 173 | 174 | private static class EncodingRenderer extends DefaultListCellRenderer { 175 | 176 | private static final long serialVersionUID = -1262247864555519110L; 177 | 178 | @Override 179 | public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 180 | if (value == null) { 181 | return super.getListCellRendererComponent(list, "", index, isSelected, cellHasFocus); // NOI18N 182 | } else { 183 | assert value instanceof EncodingKey; 184 | return super.getListCellRendererComponent(list, ((EncodingKey) value).getDisplayName(), index, isSelected, cellHasFocus); 185 | } 186 | } 187 | 188 | } 189 | 190 | // Variables declaration - do not modify//GEN-BEGIN:variables 191 | private javax.swing.JComboBox encoding; 192 | private javax.swing.JLabel encodingLabel; 193 | // End of variables declaration//GEN-END:variables 194 | 195 | } 196 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/actions/OpenInEncoding.java: -------------------------------------------------------------------------------- 1 | package com.junichi11.netbeans.modules.encoding.actions; 2 | 3 | import com.junichi11.netbeans.modules.encoding.ui.EncodingFileChooser; 4 | import com.junichi11.netbeans.modules.encoding.OpenInEncodingQueryImpl; 5 | import com.junichi11.netbeans.modules.encoding.options.EncodingOptions; 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.nio.charset.Charset; 9 | import javax.swing.JFileChooser; 10 | import org.openide.awt.ActionID; 11 | import org.openide.awt.ActionReference; 12 | import org.openide.awt.ActionRegistration; 13 | import org.openide.cookies.OpenCookie; 14 | import org.openide.filesystems.FileObject; 15 | import org.openide.filesystems.FileUtil; 16 | import org.openide.loaders.DataObject; 17 | import org.openide.loaders.DataObjectNotFoundException; 18 | import org.openide.util.Exceptions; 19 | import org.openide.util.HelpCtx; 20 | import org.openide.util.NbBundle; 21 | import org.openide.util.actions.CallableSystemAction; 22 | import org.openide.windows.WindowManager; 23 | 24 | @ActionID(id = "com.junichi11.netbeans.modules.encoding.actions.OpenInEncoding", category = "File") 25 | @ActionRegistration(lazy = false, displayName = "Open in Encoding ...") 26 | @ActionReference(path = "Menu/File", position = 950) 27 | public final class OpenInEncoding extends CallableSystemAction { 28 | 29 | static File lastFolder = new File(System.getProperty("user.home")); //NOI18N 30 | static Charset lastEncoding = null; 31 | private static final long serialVersionUID = 3891880406655022866L; 32 | 33 | @Override 34 | public void performAction() { 35 | final EncodingFileChooser chooser = new EncodingFileChooser(lastEncoding); 36 | chooser.setCurrentDirectory(null); 37 | chooser.setDialogTitle(NbBundle.getMessage(OpenInEncoding.class, "TXT_OpenFile")); 38 | chooser.setApproveButtonText(NbBundle.getMessage(OpenInEncoding.class, "CTL_Open")); 39 | chooser.setApproveButtonMnemonic(NbBundle.getMessage(OpenInEncoding.class, "MNE_Open").charAt(0)); 40 | chooser.setCurrentDirectory(lastFolder); 41 | if (chooser.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) { 42 | final Charset charset = chooser.getEncoding(); 43 | if (charset != null) { 44 | EncodingOptions.getInstance().setLastSelectedEncodings(charset.name()); 45 | } 46 | lastEncoding = charset; 47 | lastFolder = chooser.getCurrentDirectory(); 48 | final File file = FileUtil.normalizeFile(chooser.getSelectedFile()); 49 | final FileObject fo = FileUtil.toFileObject(file); 50 | try { 51 | final String encodingName = (charset == null ? null : charset.name()); 52 | fo.setAttribute(OpenInEncodingQueryImpl.ENCODING, encodingName); 53 | final DataObject dobj = DataObject.find(fo); 54 | OpenCookie oc = dobj.getLookup().lookup(OpenCookie.class); 55 | if (oc != null) { 56 | oc.open(); 57 | } 58 | } catch (DataObjectNotFoundException ex) { 59 | Exceptions.printStackTrace(ex); 60 | } catch (IOException ioe) { 61 | Exceptions.printStackTrace(ioe); 62 | } 63 | } 64 | } 65 | 66 | @Override 67 | public String getName() { 68 | return NbBundle.getMessage(OpenInEncoding.class, "CTL_OpenInEncoding"); 69 | } 70 | 71 | @Override 72 | protected void initialize() { 73 | super.initialize(); 74 | // see org.openide.util.actions.SystemAction.iconResource() javadoc for more details 75 | putValue("noIconInMenu", Boolean.TRUE); 76 | } 77 | 78 | @Override 79 | public HelpCtx getHelpCtx() { 80 | return HelpCtx.DEFAULT_HELP; 81 | } 82 | 83 | @Override 84 | protected boolean asynchronous() { 85 | return false; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/actions/SaveInEncoding.java: -------------------------------------------------------------------------------- 1 | package com.junichi11.netbeans.modules.encoding.actions; 2 | 3 | import com.junichi11.netbeans.modules.encoding.ui.EncodingFileChooser; 4 | import com.junichi11.netbeans.modules.encoding.OpenInEncodingQueryImpl; 5 | import com.junichi11.netbeans.modules.encoding.ui.UiUtils; 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.io.InputStreamReader; 9 | import java.io.OutputStreamWriter; 10 | import java.io.Reader; 11 | import java.io.Writer; 12 | import java.nio.charset.Charset; 13 | import javax.swing.JFileChooser; 14 | import org.netbeans.api.project.FileOwnerQuery; 15 | import org.netbeans.api.project.Project; 16 | import org.netbeans.api.queries.FileEncodingQuery; 17 | import org.openide.awt.ActionID; 18 | import org.openide.awt.ActionReference; 19 | import org.openide.awt.ActionRegistration; 20 | import org.openide.cookies.EditorCookie; 21 | import org.openide.cookies.OpenCookie; 22 | import org.openide.cookies.SaveCookie; 23 | import org.openide.filesystems.FileLock; 24 | import org.openide.filesystems.FileObject; 25 | import org.openide.filesystems.FileUtil; 26 | import org.openide.loaders.DataObject; 27 | import org.openide.nodes.Node; 28 | import org.openide.util.Exceptions; 29 | import org.openide.util.HelpCtx; 30 | import org.openide.util.NbBundle; 31 | import org.openide.util.actions.CookieAction; 32 | import org.openide.windows.WindowManager; 33 | 34 | @ActionID(id = "com.junichi11.netbeans.modules.encoding.actions.SaveInEncoding", category = "File") 35 | @ActionRegistration(lazy = false, displayName = "Save In Encoding...") 36 | @ActionReference(path = "Menu/File", position = 1725) 37 | public final class SaveInEncoding extends CookieAction { 38 | 39 | private static final long serialVersionUID = 546963176836634822L; 40 | 41 | @Override 42 | protected void performAction(Node[] activatedNodes) { 43 | final DataObject dataObject = activatedNodes[0].getLookup().lookup(DataObject.class); 44 | if (dataObject == null) { 45 | return; 46 | } 47 | FileObject fo = dataObject.getPrimaryFile(); 48 | Project project = FileOwnerQuery.getOwner(fo); 49 | // prevent freezing 50 | if (project == null && !dataObject.isModified()) { 51 | UiUtils.showInformationMessage("The file is not modified."); 52 | return; 53 | } 54 | File f = FileUtil.toFile(fo); 55 | if (f == null) { 56 | f = FileUtil.normalizeFile(new File(new File(System.getProperty("user.name")), fo.getNameExt())); 57 | } 58 | final EncodingFileChooser chooser = new EncodingFileChooser(); // Always suggest the default encoding 59 | chooser.setCurrentDirectory(null); 60 | chooser.setDialogTitle(NbBundle.getMessage(OpenInEncoding.class, "TXT_SaveFile")); 61 | chooser.setApproveButtonText(NbBundle.getMessage(OpenInEncoding.class, "CTL_Save")); 62 | chooser.setApproveButtonMnemonic(NbBundle.getMessage(OpenInEncoding.class, "MNE_Save").charAt(0)); 63 | chooser.setSelectedFile(f); 64 | if (chooser.showSaveDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) { 65 | final Charset charset = chooser.getEncoding(); 66 | final String encodingName = (charset == null ? null : charset.name()); 67 | OpenInEncoding.lastFolder = chooser.getCurrentDirectory(); 68 | final File file = FileUtil.normalizeFile(chooser.getSelectedFile()); 69 | if (f.equals(file) && activatedNodes[0].getLookup().lookup(SaveCookie.class) != null) { 70 | try { 71 | fo.setAttribute(OpenInEncodingQueryImpl.ENCODING, encodingName); 72 | final SaveCookie sc = activatedNodes[0].getLookup().lookup(SaveCookie.class); 73 | sc.save(); 74 | } catch (IOException e) { 75 | Exceptions.printStackTrace(e); 76 | } 77 | } else { 78 | try { 79 | 80 | //Todo: Perf, don't load whole data into mem. 81 | final StringBuilder sb = new StringBuilder(); 82 | final char[] buffer = new char[512]; 83 | try (Reader in = new InputStreamReader(fo.getInputStream(), FileEncodingQuery.getEncoding(fo))) { 84 | int len; 85 | while ((len = in.read(buffer)) > 0) { 86 | sb.append(buffer, 0, len); 87 | } 88 | } 89 | fo = FileUtil.createData(file); 90 | fo.setAttribute(OpenInEncodingQueryImpl.ENCODING, encodingName); 91 | final FileLock lock = fo.lock(); 92 | try { 93 | try (Writer out = new OutputStreamWriter(fo.getOutputStream(lock), FileEncodingQuery.getEncoding(fo))) { 94 | out.write(sb.toString()); 95 | } 96 | } finally { 97 | lock.releaseLock(); 98 | } 99 | final DataObject newDobj = DataObject.find(fo); 100 | final OpenCookie oc = newDobj.getLookup().lookup(OpenCookie.class); 101 | if (oc != null) { 102 | EditorCookie ec = dataObject.getLookup().lookup(EditorCookie.class); 103 | if (ec != null) { 104 | ec.close(); 105 | } 106 | oc.open(); 107 | } 108 | } catch (IOException e) { 109 | Exceptions.printStackTrace(e); 110 | } 111 | } 112 | } 113 | } 114 | 115 | @Override 116 | protected int mode() { 117 | return CookieAction.MODE_ALL; 118 | } 119 | 120 | @Override 121 | public String getName() { 122 | return NbBundle.getMessage(SaveInEncoding.class, "CTL_SaveInEncoding"); 123 | } 124 | 125 | @Override 126 | protected Class[] cookieClasses() { 127 | return new Class[]{DataObject.class}; 128 | } 129 | 130 | @Override 131 | protected void initialize() { 132 | super.initialize(); 133 | // see org.openide.util.actions.SystemAction.iconResource() javadoc for more details 134 | putValue("noIconInMenu", Boolean.TRUE); 135 | } 136 | 137 | @Override 138 | public HelpCtx getHelpCtx() { 139 | return HelpCtx.DEFAULT_HELP; 140 | } 141 | 142 | @Override 143 | protected boolean asynchronous() { 144 | return false; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/options/EncodingOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 | * 4 | * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. 5 | * 6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates. 7 | * Other names may be trademarks of their respective owners. 8 | * 9 | * The contents of this file are subject to the terms of either the GNU 10 | * General Public License Version 2 only ("GPL") or the Common 11 | * Development and Distribution License("CDDL") (collectively, the 12 | * "License"). You may not use this file except in compliance with the 13 | * License. You can obtain a copy of the License at 14 | * http://www.netbeans.org/cddl-gplv2.html 15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the 16 | * specific language governing permissions and limitations under the 17 | * License. When distributing the software, include this License Header 18 | * Notice in each file and include the License file at 19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this 20 | * particular file as subject to the "Classpath" exception as provided 21 | * by Oracle in the GPL Version 2 section of the License file that 22 | * accompanied this code. If applicable, add the following below the 23 | * License Header, with the fields enclosed by brackets [] replaced by 24 | * your own identifying information: 25 | * "Portions Copyrighted [year] [name of copyright owner]" 26 | * 27 | * If you wish your version of this file to be governed by only the CDDL 28 | * or only the GPL Version 2, indicate your decision by adding 29 | * "[Contributor] elects to include this software in this distribution 30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a 31 | * single choice of license, a recipient has the option to distribute 32 | * your version of this file under either the CDDL, the GPL Version 2 or 33 | * to extend the choice of license to its licensees as provided above. 34 | * However, if you add GPL Version 2 code and therefore, elected the GPL 35 | * Version 2 license, then the option applies only if the new code is 36 | * made subject to such option by the copyright holder. 37 | * 38 | * Contributor(s): 39 | */ 40 | package com.junichi11.netbeans.modules.encoding.options; 41 | 42 | import java.util.ArrayList; 43 | import java.util.Arrays; 44 | import java.util.Collections; 45 | import java.util.List; 46 | import java.util.prefs.Preferences; 47 | import org.openide.util.NbPreferences; 48 | 49 | /** 50 | * 51 | * @author junichi11 52 | */ 53 | public final class EncodingOptions { 54 | 55 | private static final int LAST_SELECTED_ENCODINGS_DEFAULT_MAX_SIZE = 5; 56 | private static final EncodingOptions INSTANCE = new EncodingOptions(); 57 | private static final String ENCODING = "encoding"; // NOI18N 58 | private static final String LAST_SELECTED_ENCODINGS = "last.selected.encodings"; // NOI18N 59 | private static final String LAST_SELECTED_ENCODINGS_MAX_SIZE = "last.selected.encodings.max.size"; // NOI18N 60 | private static final String DELIMITER = "|"; // NOI18N 61 | 62 | public static EncodingOptions getInstance() { 63 | return INSTANCE; 64 | } 65 | 66 | private EncodingOptions() { 67 | } 68 | 69 | public int getLastSelectedEncodingsMaxSize() { 70 | return getPreferences().getInt(LAST_SELECTED_ENCODINGS_MAX_SIZE, LAST_SELECTED_ENCODINGS_DEFAULT_MAX_SIZE); 71 | } 72 | 73 | public void setLastSelectedEncodingsMazSize(int max) { 74 | getPreferences().putInt(LAST_SELECTED_ENCODINGS_MAX_SIZE, max); 75 | } 76 | 77 | public List getLastSelectedEncodings() { 78 | String encodingString = getPreferences().get(LAST_SELECTED_ENCODINGS, ""); // NOI18N 79 | if (encodingString.isEmpty()) { 80 | return Collections.emptyList(); 81 | } 82 | String[] encodings = encodingString.split("\\" + DELIMITER); // NOI18N 83 | return Arrays.asList(encodings); 84 | } 85 | 86 | public void setLastSelectedEncodings(String encoding) { 87 | List selectedEncodings = new ArrayList<>(getLastSelectedEncodings()); 88 | if (!selectedEncodings.isEmpty() 89 | && selectedEncodings.get(0).equals(encoding)) { 90 | // the same as the last encoding 91 | return; 92 | } 93 | if (selectedEncodings.contains(encoding)) { 94 | selectedEncodings.remove(encoding); 95 | selectedEncodings.add(0, encoding); 96 | } else { 97 | int maxSize = getLastSelectedEncodingsMaxSize(); 98 | int selectedEncodingsSize = selectedEncodings.size(); 99 | if (selectedEncodingsSize >= maxSize) { 100 | for (int i = maxSize - 1; i < selectedEncodingsSize; i++) { 101 | selectedEncodings.remove(i); 102 | } 103 | } 104 | selectedEncodings.add(0, encoding); 105 | } 106 | String join = String.join(DELIMITER, selectedEncodings); 107 | getPreferences().put(LAST_SELECTED_ENCODINGS, join); 108 | } 109 | 110 | private Preferences getPreferences() { 111 | return NbPreferences.forModule(EncodingOptions.class).node(ENCODING); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/resources/encoding_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junichi11/netbeans-encoding-plugin/9cdbe72d25424cfac9f14fc54d79332c11bb6f45/src/com/junichi11/netbeans/modules/encoding/resources/encoding_16.png -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/resources/layer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/resources/license.txt: -------------------------------------------------------------------------------- 1 | License for NetBeans module: 2 | 3 | LICENSE: The Common Development and Distribution License 4 | (CDDL), Version 1.0 or the GNU General Public License 5 | (GPL) with "CLASSPATH" EXCEPTION govern your use of: 6 | NetBeans software. NetBeans software also makes use of 7 | additional libraries made available for use and distribution 8 | by other parties, including open-source projects. 9 | 10 | ------------------------------------------------------------ 11 | 12 | LICENSE: 13 | 14 | COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 15 | 16 | 1. Definitions. 17 | 18 | 1.1. "Contributor" means each individual or entity that 19 | creates or contributes to the creation of Modifications. 20 | 21 | 1.2. "Contributor Version" means the combination of the 22 | Original Software, prior Modifications used by a 23 | Contributor (if any), and the Modifications made by that 24 | particular Contributor. 25 | 26 | 1.3. "Covered Software" means (a) the Original Software, or 27 | (b) Modifications, or (c) the combination of files 28 | containing Original Software with files containing 29 | Modifications, in each case including portions thereof. 30 | 31 | 1.4. "Executable" means the Covered Software in any form 32 | other than Source Code. 33 | 34 | 1.5. "Initial Developer" means the individual or entity 35 | that first makes Original Software available under this 36 | License. 37 | 38 | 1.6. "Larger Work" means a work which combines Covered 39 | Software or portions thereof with code not governed by the 40 | terms of this License. 41 | 42 | 1.7. "License" means this document. 43 | 44 | 1.8. "Licensable" means having the right to grant, to the 45 | maximum extent possible, whether at the time of the initial 46 | grant or subsequently acquired, any and all of the rights 47 | conveyed herein. 48 | 49 | 1.9. "Modifications" means the Source Code and Executable 50 | form of any of the following: 51 | 52 | A. Any file that results from an addition to, 53 | deletion from or modification of the contents of a 54 | file containing Original Software or previous 55 | Modifications; 56 | 57 | B. Any new file that contains any part of the 58 | Original Software or previous Modification; or 59 | 60 | C. Any new file that is contributed or otherwise made 61 | available under the terms of this License. 62 | 63 | 1.10. "Original Software" means the Source Code and 64 | Executable form of computer software code that is 65 | originally released under this License. 66 | 67 | 1.11. "Patent Claims" means any patent claim(s), now owned 68 | or hereafter acquired, including without limitation, 69 | method, process, and apparatus claims, in any patent 70 | Licensable by grantor. 71 | 72 | 1.12. "Source Code" means (a) the common form of computer 73 | software code in which modifications are made and (b) 74 | associated documentation included in or with such code. 75 | 76 | 1.13. "You" (or "Your") means an individual or a legal 77 | entity exercising rights under, and complying with all of 78 | the terms of, this License. For legal entities, "You" 79 | includes any entity which controls, is controlled by, or is 80 | under common control with You. For purposes of this 81 | definition, "control" means (a) the power, direct or 82 | indirect, to cause the direction or management of such 83 | entity, whether by contract or otherwise, or (b) ownership 84 | of more than fifty percent (50%) of the outstanding shares 85 | or beneficial ownership of such entity. 86 | 87 | 2. License Grants. 88 | 89 | 2.1. The Initial Developer Grant. 90 | 91 | Conditioned upon Your compliance with Section 3.1 below and 92 | subject to third party intellectual property claims, the 93 | Initial Developer hereby grants You a world-wide, 94 | royalty-free, non-exclusive license: 95 | 96 | (a) under intellectual property rights (other than 97 | patent or trademark) Licensable by Initial Developer, 98 | to use, reproduce, modify, display, perform, 99 | sublicense and distribute the Original Software (or 100 | portions thereof), with or without Modifications, 101 | and/or as part of a Larger Work; and 102 | 103 | (b) under Patent Claims infringed by the making, 104 | using or selling of Original Software, to make, have 105 | made, use, practice, sell, and offer for sale, and/or 106 | otherwise dispose of the Original Software (or 107 | portions thereof). 108 | 109 | (c) The licenses granted in Sections 2.1(a) and (b) 110 | are effective on the date Initial Developer first 111 | distributes or otherwise makes the Original Software 112 | available to a third party under the terms of this 113 | License. 114 | 115 | (d) Notwithstanding Section 2.1(b) above, no patent 116 | license is granted: (1) for code that You delete from 117 | the Original Software, or (2) for infringements 118 | caused by: (i) the modification of the Original 119 | Software, or (ii) the combination of the Original 120 | Software with other software or devices. 121 | 122 | 2.2. Contributor Grant. 123 | 124 | Conditioned upon Your compliance with Section 3.1 below and 125 | subject to third party intellectual property claims, each 126 | Contributor hereby grants You a world-wide, royalty-free, 127 | non-exclusive license: 128 | 129 | (a) under intellectual property rights (other than 130 | patent or trademark) Licensable by Contributor to 131 | use, reproduce, modify, display, perform, sublicense 132 | and distribute the Modifications created by such 133 | Contributor (or portions thereof), either on an 134 | unmodified basis, with other Modifications, as 135 | Covered Software and/or as part of a Larger Work; and 136 | 137 | (b) under Patent Claims infringed by the making, 138 | using, or selling of Modifications made by that 139 | Contributor either alone and/or in combination with 140 | its Contributor Version (or portions of such 141 | combination), to make, use, sell, offer for sale, 142 | have made, and/or otherwise dispose of: (1) 143 | Modifications made by that Contributor (or portions 144 | thereof); and (2) the combination of Modifications 145 | made by that Contributor with its Contributor Version 146 | (or portions of such combination). 147 | 148 | (c) The licenses granted in Sections 2.2(a) and 149 | 2.2(b) are effective on the date Contributor first 150 | distributes or otherwise makes the Modifications 151 | available to a third party. 152 | 153 | (d) Notwithstanding Section 2.2(b) above, no patent 154 | license is granted: (1) for any code that Contributor 155 | has deleted from the Contributor Version; (2) for 156 | infringements caused by: (i) third party 157 | modifications of Contributor Version, or (ii) the 158 | combination of Modifications made by that Contributor 159 | with other software (except as part of the 160 | Contributor Version) or other devices; or (3) under 161 | Patent Claims infringed by Covered Software in the 162 | absence of Modifications made by that Contributor. 163 | 164 | 3. Distribution Obligations. 165 | 166 | 3.1. Availability of Source Code. 167 | 168 | Any Covered Software that You distribute or otherwise make 169 | available in Executable form must also be made available in 170 | Source Code form and that Source Code form must be 171 | distributed only under the terms of this License. You must 172 | include a copy of this License with every copy of the 173 | Source Code form of the Covered Software You distribute or 174 | otherwise make available. You must inform recipients of any 175 | such Covered Software in Executable form as to how they can 176 | obtain such Covered Software in Source Code form in a 177 | reasonable manner on or through a medium customarily used 178 | for software exchange. 179 | 180 | 3.2. Modifications. 181 | 182 | The Modifications that You create or to which You 183 | contribute are governed by the terms of this License. You 184 | represent that You believe Your Modifications are Your 185 | original creation(s) and/or You have sufficient rights to 186 | grant the rights conveyed by this License. 187 | 188 | 3.3. Required Notices. 189 | 190 | You must include a notice in each of Your Modifications 191 | that identifies You as the Contributor of the Modification. 192 | You may not remove or alter any copyright, patent or 193 | trademark notices contained within the Covered Software, or 194 | any notices of licensing or any descriptive text giving 195 | attribution to any Contributor or the Initial Developer. 196 | 197 | 3.4. Application of Additional Terms. 198 | 199 | You may not offer or impose any terms on any Covered 200 | Software in Source Code form that alters or restricts the 201 | applicable version of this License or the recipients' 202 | rights hereunder. You may choose to offer, and to charge a 203 | fee for, warranty, support, indemnity or liability 204 | obligations to one or more recipients of Covered Software. 205 | However, you may do so only on Your own behalf, and not on 206 | behalf of the Initial Developer or any Contributor. You 207 | must make it absolutely clear that any such warranty, 208 | support, indemnity or liability obligation is offered by 209 | You alone, and You hereby agree to indemnify the Initial 210 | Developer and every Contributor for any liability incurred 211 | by the Initial Developer or such Contributor as a result of 212 | warranty, support, indemnity or liability terms You offer. 213 | 214 | 3.5. Distribution of Executable Versions. 215 | 216 | You may distribute the Executable form of the Covered 217 | Software under the terms of this License or under the terms 218 | of a license of Your choice, which may contain terms 219 | different from this License, provided that You are in 220 | compliance with the terms of this License and that the 221 | license for the Executable form does not attempt to limit 222 | or alter the recipient's rights in the Source Code form 223 | from the rights set forth in this License. If You 224 | distribute the Covered Software in Executable form under a 225 | different license, You must make it absolutely clear that 226 | any terms which differ from this License are offered by You 227 | alone, not by the Initial Developer or Contributor. You 228 | hereby agree to indemnify the Initial Developer and every 229 | Contributor for any liability incurred by the Initial 230 | Developer or such Contributor as a result of any such terms 231 | You offer. 232 | 233 | 3.6. Larger Works. 234 | 235 | You may create a Larger Work by combining Covered Software 236 | with other code not governed by the terms of this License 237 | and distribute the Larger Work as a single product. In such 238 | a case, You must make sure the requirements of this License 239 | are fulfilled for the Covered Software. 240 | 241 | 4. Versions of the License. 242 | 243 | 4.1. New Versions. 244 | 245 | Sun Microsystems, Inc. is the initial license steward and 246 | may publish revised and/or new versions of this License 247 | from time to time. Each version will be given a 248 | distinguishing version number. Except as provided in 249 | Section 4.3, no one other than the license steward has the 250 | right to modify this License. 251 | 252 | 4.2. Effect of New Versions. 253 | 254 | You may always continue to use, distribute or otherwise 255 | make the Covered Software available under the terms of the 256 | version of the License under which You originally received 257 | the Covered Software. If the Initial Developer includes a 258 | notice in the Original Software prohibiting it from being 259 | distributed or otherwise made available under any 260 | subsequent version of the License, You must distribute and 261 | make the Covered Software available under the terms of the 262 | version of the License under which You originally received 263 | the Covered Software. Otherwise, You may also choose to 264 | use, distribute or otherwise make the Covered Software 265 | available under the terms of any subsequent version of the 266 | License published by the license steward. 267 | 268 | 4.3. Modified Versions. 269 | 270 | When You are an Initial Developer and You want to create a 271 | new license for Your Original Software, You may create and 272 | use a modified version of this License if You: (a) rename 273 | the license and remove any references to the name of the 274 | license steward (except to note that the license differs 275 | from this License); and (b) otherwise make it clear that 276 | the license contains terms which differ from this License. 277 | 278 | 5. DISCLAIMER OF WARRANTY. 279 | 280 | COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" 281 | BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 282 | INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED 283 | SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR 284 | PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND 285 | PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY 286 | COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE 287 | INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF 288 | ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF 289 | WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF 290 | ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS 291 | DISCLAIMER. 292 | 293 | 6. TERMINATION. 294 | 295 | 6.1. This License and the rights granted hereunder will 296 | terminate automatically if You fail to comply with terms 297 | herein and fail to cure such breach within 30 days of 298 | becoming aware of the breach. Provisions which, by their 299 | nature, must remain in effect beyond the termination of 300 | this License shall survive. 301 | 302 | 6.2. If You assert a patent infringement claim (excluding 303 | declaratory judgment actions) against Initial Developer or 304 | a Contributor (the Initial Developer or Contributor against 305 | whom You assert such claim is referred to as "Participant") 306 | alleging that the Participant Software (meaning the 307 | Contributor Version where the Participant is a Contributor 308 | or the Original Software where the Participant is the 309 | Initial Developer) directly or indirectly infringes any 310 | patent, then any and all rights granted directly or 311 | indirectly to You by such Participant, the Initial 312 | Developer (if the Initial Developer is not the Participant) 313 | and all Contributors under Sections 2.1 and/or 2.2 of this 314 | License shall, upon 60 days notice from Participant 315 | terminate prospectively and automatically at the expiration 316 | of such 60 day notice period, unless if within such 60 day 317 | period You withdraw Your claim with respect to the 318 | Participant Software against such Participant either 319 | unilaterally or pursuant to a written agreement with 320 | Participant. 321 | 322 | 6.3. If You assert a patent infringement claim against 323 | Participant alleging that the Participant Software directly 324 | or indirectly infringes any patent where such claim is 325 | resolved (such as by license or settlement) prior to the 326 | initiation of patent infringement litigation, then the 327 | reasonable value of the licenses granted by such Participant 328 | under Sections 2.1 or 2.2 shall be taken into account in 329 | determining the amount or value of any payment or license. 330 | 331 | 6.4. In the event of termination under Sections 6.1 or 6.2 332 | above, all end user licenses that have been validly granted 333 | by You or any distributor hereunder prior to termination 334 | (excluding licenses granted to You by any distributor) 335 | shall survive termination. 336 | 337 | 7. LIMITATION OF LIABILITY. 338 | 339 | UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT 340 | (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE 341 | INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF 342 | COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE 343 | LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR 344 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT 345 | LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK 346 | STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER 347 | COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN 348 | INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF 349 | LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL 350 | INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT 351 | APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO 352 | NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR 353 | CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT 354 | APPLY TO YOU. 355 | 356 | 8. U.S. GOVERNMENT END USERS. 357 | 358 | The Covered Software is a "commercial item," as that term is 359 | defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial 360 | computer software" (as that term is defined at 48 C.F.R. 361 | § 252.227-7014(a)(1)) and "commercial computer software 362 | documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 363 | 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 364 | through 227.7202-4 (June 1995), all U.S. Government End Users 365 | acquire Covered Software with only those rights set forth herein. 366 | This U.S. Government Rights clause is in lieu of, and supersedes, 367 | any other FAR, DFAR, or other clause or provision that addresses 368 | Government rights in computer software under this License. 369 | 370 | 9. MISCELLANEOUS. 371 | 372 | This License represents the complete agreement concerning subject 373 | matter hereof. If any provision of this License is held to be 374 | unenforceable, such provision shall be reformed only to the 375 | extent necessary to make it enforceable. This License shall be 376 | governed by the law of the jurisdiction specified in a notice 377 | contained within the Original Software (except to the extent 378 | applicable law, if any, provides otherwise), excluding such 379 | jurisdiction's conflict-of-law provisions. Any litigation 380 | relating to this License shall be subject to the jurisdiction of 381 | the courts located in the jurisdiction and venue specified in a 382 | notice contained within the Original Software, with the losing 383 | party responsible for costs, including, without limitation, court 384 | costs and reasonable attorneys' fees and expenses. The 385 | application of the United Nations Convention on Contracts for the 386 | International Sale of Goods is expressly excluded. Any law or 387 | regulation which provides that the language of a contract shall 388 | be construed against the drafter shall not apply to this License. 389 | You agree that You alone are responsible for compliance with the 390 | United States export administration regulations (and the export 391 | control laws and regulation of any other countries) when You use, 392 | distribute or otherwise make available any Covered Software. 393 | 394 | 10. RESPONSIBILITY FOR CLAIMS. 395 | 396 | As between Initial Developer and the Contributors, each party is 397 | responsible for claims and damages arising, directly or 398 | indirectly, out of its utilization of rights under this License 399 | and You agree to work with Initial Developer and Contributors to 400 | distribute such responsibility on an equitable basis. Nothing 401 | herein is intended or shall be deemed to constitute any admission 402 | of liability. 403 | 404 | NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND 405 | DISTRIBUTION LICENSE (CDDL) 406 | 407 | The code released under the CDDL shall be governed by the laws 408 | of the State of California (excluding conflict-of-law provisions). 409 | Any litigation relating to this License shall be subject to the 410 | jurisdiction of the Federal Courts of the Northern District of 411 | California and the state courts of the State of California, with 412 | venue lying in Santa Clara County, California. 413 | 414 | 415 | The GNU General Public License (GPL) 416 | Version 2, June 1991 417 | 418 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 419 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 420 | Everyone is permitted to copy and distribute verbatim 421 | copies of this license document, but changing it is not 422 | allowed. 423 | 424 | Preamble 425 | 426 | The licenses for most software are designed to take away 427 | your freedom to share and change it. By contrast, the GNU 428 | General Public License is intended to guarantee your freedom 429 | to share and change free software--to make sure the software 430 | is free for all its users. This General Public License 431 | applies to most of the Free Software Foundation's software 432 | and to any other program whose authors commit to using it. 433 | (Some other Free Software Foundation software is covered by 434 | the GNU Library General Public License instead.) You can 435 | apply it to your programs, too. 436 | 437 | When we speak of free software, we are referring to freedom, 438 | not price. Our General Public Licenses are designed to make 439 | sure that you have the freedom to distribute copies of free 440 | software (and charge for this service if you wish), that you 441 | receive source code or can get it if you want it, that you 442 | can change the software or use pieces of it in new free 443 | programs; and that you know you can do these things. 444 | 445 | To protect your rights, we need to make restrictions that 446 | forbid anyone to deny you these rights or to ask you to 447 | surrender the rights. These restrictions translate to 448 | certain responsibilities for you if you distribute copies of 449 | the software, or if you modify it. 450 | 451 | For example, if you distribute copies of such a program, 452 | whether gratis or for a fee, you must give the recipients 453 | all the rights that you have. You must make sure that they, 454 | too, receive or can get the source code. And you must show 455 | them these terms so they know their rights. 456 | 457 | We protect your rights with two steps: (1) copyright the 458 | software, and (2) offer you this license which gives you 459 | legal permission to copy, distribute and/or modify the 460 | software. 461 | 462 | Also, for each author's protection and ours, we want to make 463 | certain that everyone understands that there is no warranty 464 | for this free software. If the software is modified by 465 | someone else and passed on, we want its recipients to know 466 | that what they have is not the original, so that any 467 | problems introduced by others will not reflect on the 468 | original authors' reputations. 469 | 470 | Finally, any free program is threatened constantly by 471 | software patents. We wish to avoid the danger that 472 | redistributors of a free program will individually obtain 473 | patent licenses, in effect making the program proprietary. 474 | To prevent this, we have made it clear that any patent must 475 | be licensed for everyone's free use or not licensed at all. 476 | 477 | The precise terms and conditions for copying, distribution 478 | and modification follow. 479 | 480 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND 481 | MODIFICATION 482 | 483 | 0. This License applies to any program or other work which 484 | contains a notice placed by the copyright holder saying it 485 | may be distributed under the terms of this General Public 486 | License. The "Program", below, refers to any such program or 487 | work, and a "work based on the Program" means either the 488 | Program or any derivative work under copyright law: that is 489 | to say, a work containing the Program or a portion of it, 490 | either verbatim or with modifications and/or translated into 491 | another language. (Hereinafter, translation is included 492 | without limitation in the term "modification".) Each 493 | licensee is addressed as "you". 494 | 495 | Activities other than copying, distribution and modification 496 | are not covered by this License; they are outside its scope. 497 | The act of running the Program is not restricted, and the 498 | output from the Program is covered only if its contents 499 | constitute a work based on the Program (independent of 500 | having been made by running the Program). Whether that is 501 | true depends on what the Program does. 502 | 503 | 1. You may copy and distribute verbatim copies of the 504 | Program's source code as you receive it, in any medium, 505 | provided that you conspicuously and appropriately publish on 506 | each copy an appropriate copyright notice and disclaimer of 507 | warranty; keep intact all the notices that refer to this 508 | License and to the absence of any warranty; and give any 509 | other recipients of the Program a copy of this License along 510 | with the Program. 511 | 512 | You may charge a fee for the physical act of transferring a 513 | copy, and you may at your option offer warranty protection 514 | in exchange for a fee. 515 | 516 | 2. You may modify your copy or copies of the Program or any 517 | portion of it, thus forming a work based on the Program, and 518 | copy and distribute such modifications or work under the 519 | terms of Section 1 above, provided that you also meet all of 520 | these conditions: 521 | 522 | a) You must cause the modified files to carry prominent 523 | notices stating that you changed the files and the date 524 | of any change. 525 | 526 | b) You must cause any work that you distribute or 527 | publish, that in whole or in part contains or is derived 528 | from the Program or any part thereof, to be licensed as 529 | a whole at no charge to all third parties under the 530 | terms of this License. 531 | 532 | c) If the modified program normally reads commands 533 | interactively when run, you must cause it, when started 534 | running for such interactive use in the most ordinary 535 | way, to print or display an announcement including an 536 | appropriate copyright notice and a notice that there is 537 | no warranty (or else, saying that you provide a 538 | warranty) and that users may redistribute the program 539 | under these conditions, and telling the user how to view 540 | a copy of this License. (Exception: if the Program 541 | itself is interactive but does not normally print such 542 | an announcement, your work based on the Program is not 543 | required to print an announcement.) 544 | 545 | These requirements apply to the modified work as a whole. If 546 | identifiable sections of that work are not derived from the 547 | Program, and can be reasonably considered independent and 548 | separate works in themselves, then this License, and its 549 | terms, do not apply to those sections when you distribute 550 | them as separate works. But when you distribute the same 551 | sections as part of a whole which is a work based on the 552 | Program, the distribution of the whole must be on the terms 553 | of this License, whose permissions for other licensees 554 | extend to the entire whole, and thus to each and every part 555 | regardless of who wrote it. 556 | 557 | Thus, it is not the intent of this section to claim rights 558 | or contest your rights to work written entirely by you; 559 | rather, the intent is to exercise the right to control the 560 | distribution of derivative or collective works based on the 561 | Program. 562 | 563 | In addition, mere aggregation of another work not based on 564 | the Program with the Program (or with a work based on the 565 | Program) on a volume of a storage or distribution medium 566 | does not bring the other work under the scope of this 567 | License. 568 | 569 | 3. You may copy and distribute the Program (or a work based 570 | on it, under Section 2) in object code or executable form 571 | under the terms of Sections 1 and 2 above provided that you 572 | also do one of the following: 573 | 574 | a) Accompany it with the complete corresponding 575 | machine-readable source code, which must be distributed 576 | under the terms of Sections 1 and 2 above on a medium 577 | customarily used for software interchange; or, 578 | 579 | b) Accompany it with a written offer, valid for at least 580 | three years, to give any third party, for a charge no 581 | more than your cost of physically performing source 582 | distribution, a complete machine-readable copy of the 583 | corresponding source code, to be distributed under the 584 | terms of Sections 1 and 2 above on a medium customarily 585 | used for software interchange; or, 586 | 587 | c) Accompany it with the information you received as to 588 | the offer to distribute corresponding source code. (This 589 | alternative is allowed only for noncommercial 590 | distribution and only if you received the program in 591 | object code or executable form with such an offer, in 592 | accord with Subsection b above.) 593 | 594 | The source code for a work means the preferred form of the 595 | work for making modifications to it. For an executable work, 596 | complete source code means all the source code for all 597 | modules it contains, plus any associated interface 598 | definition files, plus the scripts used to control 599 | compilation and installation of the executable. However, as 600 | a special exception, the source code distributed need not 601 | include anything that is normally distributed (in either 602 | source or binary form) with the major components (compiler, 603 | kernel, and so on) of the operating system on which the 604 | executable runs, unless that component itself accompanies 605 | the executable. 606 | 607 | If distribution of executable or object code is made by 608 | offering access to copy from a designated place, then 609 | offering equivalent access to copy the source code from the 610 | same place counts as distribution of the source code, even 611 | though third parties are not compelled to copy the source 612 | along with the object code. 613 | 614 | 4. You may not copy, modify, sublicense, or distribute the 615 | Program except as expressly provided under this License. Any 616 | attempt otherwise to copy, modify, sublicense or distribute 617 | the Program is void, and will automatically terminate your 618 | rights under this License. However, parties who have 619 | received copies, or rights, from you under this License will 620 | not have their licenses terminated so long as such parties 621 | remain in full compliance. 622 | 623 | 5. You are not required to accept this License, since you 624 | have not signed it. However, nothing else grants you 625 | permission to modify or distribute the Program or its 626 | derivative works. These actions are prohibited by law if you 627 | do not accept this License. Therefore, by modifying or 628 | distributing the Program (or any work based on the Program), 629 | you indicate your acceptance of this License to do so, and 630 | all its terms and conditions for copying, distributing or 631 | modifying the Program or works based on it. 632 | 633 | 6. Each time you redistribute the Program (or any work based 634 | on the Program), the recipient automatically receives a 635 | license from the original licensor to copy, distribute or 636 | modify the Program subject to these terms and conditions. 637 | You may not impose any further restrictions on the 638 | recipients' exercise of the rights granted herein. You are 639 | not responsible for enforcing compliance by third parties to 640 | this License. 641 | 642 | 7. If, as a consequence of a court judgment or allegation of 643 | patent infringement or for any other reason (not limited to 644 | patent issues), conditions are imposed on you (whether by 645 | court order, agreement or otherwise) that contradict the 646 | conditions of this License, they do not excuse you from the 647 | conditions of this License. If you cannot distribute so as 648 | to satisfy simultaneously your obligations under this 649 | License and any other pertinent obligations, then as a 650 | consequence you may not distribute the Program at all. For 651 | example, if a patent license would not permit royalty-free 652 | redistribution of the Program by all those who receive 653 | copies directly or indirectly through you, then the only way 654 | you could satisfy both it and this License would be to 655 | refrain entirely from distribution of the Program. 656 | 657 | If any portion of this section is held invalid or 658 | unenforceable under any particular circumstance, the balance 659 | of the section is intended to apply and the section as a 660 | whole is intended to apply in other circumstances. 661 | 662 | It is not the purpose of this section to induce you to 663 | infringe any patents or other property right claims or to 664 | contest validity of any such claims; this section has the 665 | sole purpose of protecting the integrity of the free 666 | software distribution system, which is implemented by public 667 | license practices. Many people have made generous 668 | contributions to the wide range of software distributed 669 | through that system in reliance on consistent application of 670 | that system; it is up to the author/donor to decide if he or 671 | she is willing to distribute software through any other 672 | system and a licensee cannot impose that choice. 673 | 674 | This section is intended to make thoroughly clear what is 675 | believed to be a consequence of the rest of this License. 676 | 677 | 8. If the distribution and/or use of the Program is 678 | restricted in certain countries either by patents or by 679 | copyrighted interfaces, the original copyright holder who 680 | places the Program under this License may add an explicit 681 | geographical distribution limitation excluding those 682 | countries, so that distribution is permitted only in or 683 | among countries not thus excluded. In such case, this 684 | License incorporates the limitation as if written in the 685 | body of this License. 686 | 687 | 9. The Free Software Foundation may publish revised and/or 688 | new versions of the General Public License from time to 689 | time. Such new versions will be similar in spirit to the 690 | present version, but may differ in detail to address new 691 | problems or concerns. 692 | 693 | Each version is given a distinguishing version number. If 694 | the Program specifies a version number of this License which 695 | applies to it and "any later version", you have the option 696 | of following the terms and conditions either of that version 697 | or of any later version published by the Free Software 698 | Foundation. If the Program does not specify a version number 699 | of this License, you may choose any version ever published 700 | by the Free Software Foundation. 701 | 702 | 10. If you wish to incorporate parts of the Program into 703 | other free programs whose distribution conditions are 704 | different, write to the author to ask for permission. For 705 | software which is copyrighted by the Free Software 706 | Foundation, write to the Free Software Foundation; we 707 | sometimes make exceptions for this. Our decision will be 708 | guided by the two goals of preserving the free status of all 709 | derivatives of our free software and of promoting the 710 | sharing and reuse of software generally. 711 | 712 | NO WARRANTY 713 | 714 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS 715 | NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 716 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE 717 | COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM 718 | "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR 719 | IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 720 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 721 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE 722 | OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE 723 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 724 | REPAIR OR CORRECTION. 725 | 726 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED 727 | TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY 728 | WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED 729 | ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, 730 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF 731 | THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT 732 | LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR 733 | LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE 734 | PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH 735 | HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 736 | SUCH DAMAGES. 737 | 738 | END OF TERMS AND CONDITIONS 739 | 740 | How to Apply These Terms to Your New Programs 741 | 742 | If you develop a new program, and you want it to be of the 743 | greatest possible use to the public, the best way to achieve 744 | this is to make it free software which everyone can 745 | redistribute and change under these terms. 746 | 747 | To do so, attach the following notices to the program. It is 748 | safest to attach them to the start of each source file to 749 | most effectively convey the exclusion of warranty; and each 750 | file should have at least the "copyright" line and a pointer 751 | to where the full notice is found. 752 | 753 | One line to give the program's name and a brief idea of 754 | what it does. Copyright (C) 755 | 756 | This program is free software; you can redistribute it 757 | and/or modify it under the terms of the GNU General 758 | Public License as published by the Free Software 759 | Foundation; either version 2 of the License, or (at your 760 | option) any later version. 761 | 762 | This program is distributed in the hope that it will be 763 | useful, but WITHOUT ANY WARRANTY; without even the 764 | implied warranty of MERCHANTABILITY or FITNESS FOR A 765 | PARTICULAR PURPOSE. See the GNU General Public License 766 | for more details. 767 | 768 | You should have received a copy of the GNU General 769 | Public License along with this program; if not, write to 770 | the Free Software Foundation, Inc., 59 Temple Place, 771 | Suite 330, Boston, MA 02111-1307 USA 772 | 773 | Also add information on how to contact you by electronic and 774 | paper mail. 775 | 776 | If the program is interactive, make it output a short notice 777 | like this when it starts in an interactive mode: 778 | 779 | Gnomovision version 69, Copyright (C) year name of 780 | author Gnomovision comes with ABSOLUTELY NO WARRANTY; 781 | for details type `show w'. This is free software, and 782 | you are welcome to redistribute it under certain 783 | conditions; type `show c' for details. 784 | 785 | The hypothetical commands `show w' and `show c' should show 786 | the appropriate parts of the General Public License. Of 787 | course, the commands you use may be called something other 788 | than `show w' and `show c'; they could even be mouse-clicks 789 | or menu items--whatever suits your program. 790 | 791 | You should also get your employer (if you work as a 792 | programmer) or your school, if any, to sign a "copyright 793 | disclaimer" for the program, if necessary. Here is a sample; 794 | alter the names: 795 | 796 | Yoyodyne, Inc., hereby disclaims all copyright interest in 797 | the program `Gnomovision' (which makes passes at 798 | compilers) written by James Hacker. 799 | 800 | signature of Ty Coon, 1 April 1989 801 | Ty Coon, President of Vice 802 | 803 | This General Public License does not permit incorporating 804 | your program into proprietary programs. If your program is a 805 | subroutine library, you may consider it more useful to 806 | permit linking proprietary applications with the library. If 807 | this is what you want to do, use the GNU Library General 808 | Public License instead of this License. 809 | 810 | 811 | "CLASSPATH" EXCEPTION TO THE GPL VERSION 2 812 | 813 | 814 | Certain source files distributed by Sun Microsystems, Inc. 815 | are subject to the following clarification and special 816 | exception to the GPL Version 2, but only where Sun has expressly 817 | included in the particular source file's header the words 818 | "Sun designates this particular file as subject to the 819 | "Classpath" exception as provided by Sun in the License file 820 | that accompanied this code." 821 | 822 | Linking this library statically or dynamically with other 823 | modules is making a combined work based on this library. 824 | Thus, the terms and conditions of the GNU General Public 825 | License Version 2 cover the whole combination. 826 | 827 | As a special exception, the copyright holders of this 828 | library give you permission to link this library with 829 | independent modules to produce an executable, regardless of 830 | the license terms of these independent modules, and to copy 831 | and distribute the resulting executable under terms of your 832 | choice, provided that you also meet, for each linked 833 | independent module, the terms and conditions of the license 834 | of that module. An independent module is a module which is 835 | not derived from or based on this library. If you modify 836 | this library, you may extend this exception to your version 837 | of the library, but you are not obligated to do so. If you 838 | do not wish to do so, delete this exception statement from 839 | your version. 840 | _______________________________________ 841 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/ui/Bundle.properties: -------------------------------------------------------------------------------- 1 | EncodingPanel.encodingFilterTextField.text= 2 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/ui/EncodingFileChooser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 | * 4 | * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. 5 | * 6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates. 7 | * Other names may be trademarks of their respective owners. 8 | * 9 | * The contents of this file are subject to the terms of either the GNU 10 | * General Public License Version 2 only ("GPL") or the Common 11 | * Development and Distribution License("CDDL") (collectively, the 12 | * "License"). You may not use this file except in compliance with the 13 | * License. You can obtain a copy of the License at 14 | * http://www.netbeans.org/cddl-gplv2.html 15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the 16 | * specific language governing permissions and limitations under the 17 | * License. When distributing the software, include this License Header 18 | * Notice in each file and include the License file at 19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this 20 | * particular file as subject to the "Classpath" exception as provided 21 | * by Oracle in the GPL Version 2 section of the License file that 22 | * accompanied this code. If applicable, add the following below the 23 | * License Header, with the fields enclosed by brackets [] replaced by 24 | * your own identifying information: 25 | * "Portions Copyrighted [year] [name of copyright owner]" 26 | * 27 | * If you wish your version of this file to be governed by only the CDDL 28 | * or only the GPL Version 2, indicate your decision by adding 29 | * "[Contributor] elects to include this software in this distribution 30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a 31 | * single choice of license, a recipient has the option to distribute 32 | * your version of this file under either the CDDL, the GPL Version 2 or 33 | * to extend the choice of license to its licensees as provided above. 34 | * However, if you add GPL Version 2 code and therefore, elected the GPL 35 | * Version 2 license, then the option applies only if the new code is 36 | * made subject to such option by the copyright holder. 37 | * 38 | * Contributor(s): 39 | */ 40 | package com.junichi11.netbeans.modules.encoding.ui; 41 | 42 | import java.nio.charset.Charset; 43 | import javax.swing.JFileChooser; 44 | 45 | /** 46 | * 47 | * @author junichi11 48 | */ 49 | public class EncodingFileChooser extends JFileChooser { 50 | 51 | private static final long serialVersionUID = -6494800823794492445L; 52 | 53 | private EncodingMetalFileChooserUI fileChooserUI; 54 | 55 | public EncodingFileChooser() { 56 | this(null); 57 | } 58 | 59 | public EncodingFileChooser(Charset defaultEncoding) { 60 | if (fileChooserUI != null) { 61 | fileChooserUI.setDefaultEncoding(defaultEncoding); 62 | } 63 | } 64 | 65 | @Override 66 | public void updateUI() { 67 | super.updateUI(); 68 | if (fileChooserUI == null) { 69 | fileChooserUI = new EncodingMetalFileChooserUI(this); 70 | } 71 | setUI(fileChooserUI); 72 | resetChoosableFileFilters(); 73 | } 74 | 75 | public Charset getEncoding() { 76 | if (fileChooserUI == null) { 77 | return null; 78 | } 79 | return fileChooserUI.getEncoding(); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/ui/EncodingMetalFileChooserUI.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 | * 4 | * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. 5 | * 6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates. 7 | * Other names may be trademarks of their respective owners. 8 | * 9 | * The contents of this file are subject to the terms of either the GNU 10 | * General Public License Version 2 only ("GPL") or the Common 11 | * Development and Distribution License("CDDL") (collectively, the 12 | * "License"). You may not use this file except in compliance with the 13 | * License. You can obtain a copy of the License at 14 | * http://www.netbeans.org/cddl-gplv2.html 15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the 16 | * specific language governing permissions and limitations under the 17 | * License. When distributing the software, include this License Header 18 | * Notice in each file and include the License file at 19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this 20 | * particular file as subject to the "Classpath" exception as provided 21 | * by Oracle in the GPL Version 2 section of the License file that 22 | * accompanied this code. If applicable, add the following below the 23 | * License Header, with the fields enclosed by brackets [] replaced by 24 | * your own identifying information: 25 | * "Portions Copyrighted [year] [name of copyright owner]" 26 | * 27 | * If you wish your version of this file to be governed by only the CDDL 28 | * or only the GPL Version 2, indicate your decision by adding 29 | * "[Contributor] elects to include this software in this distribution 30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a 31 | * single choice of license, a recipient has the option to distribute 32 | * your version of this file under either the CDDL, the GPL Version 2 or 33 | * to extend the choice of license to its licensees as provided above. 34 | * However, if you add GPL Version 2 code and therefore, elected the GPL 35 | * Version 2 license, then the option applies only if the new code is 36 | * made subject to such option by the copyright holder. 37 | * 38 | * Contributor(s): 39 | */ 40 | package com.junichi11.netbeans.modules.encoding.ui; 41 | 42 | import com.junichi11.netbeans.modules.encoding.actions.EncodingAccessories; 43 | import java.awt.Component; 44 | import java.awt.Container; 45 | import java.awt.Dimension; 46 | import java.nio.charset.Charset; 47 | import javax.swing.Box; 48 | import javax.swing.JFileChooser; 49 | import javax.swing.JLabel; 50 | import javax.swing.JPanel; 51 | import javax.swing.plaf.metal.MetalFileChooserUI; 52 | 53 | /** 54 | * 55 | * @author junichi11 56 | */ 57 | public class EncodingMetalFileChooserUI extends MetalFileChooserUI { 58 | 59 | private EncodingAccessories acc = new EncodingAccessories(); 60 | 61 | public EncodingMetalFileChooserUI(JFileChooser filechooser) { 62 | super(filechooser); 63 | } 64 | 65 | @Override 66 | public void installComponents(JFileChooser fileChooser) { 67 | super.installComponents(fileChooser); 68 | JPanel bottomPanel = getBottomPanel(); 69 | Dimension preferredSize = getPreferredJLabelSize(bottomPanel); 70 | if (preferredSize != null) { 71 | acc = new EncodingAccessories(preferredSize); 72 | } 73 | bottomPanel.add(Box.createRigidArea(new Dimension(1, 5)), 3); 74 | bottomPanel.add(acc, 4); 75 | } 76 | 77 | void setDefaultEncoding(Charset defaultEncoding) { 78 | acc.setEncoding(defaultEncoding); 79 | } 80 | 81 | public Charset getEncoding() { 82 | return acc.getEncoding(); 83 | } 84 | 85 | private Dimension getPreferredJLabelSize(Container container) { 86 | Component[] components = container.getComponents(); 87 | for (Component component : components) { 88 | if (component instanceof JLabel) { 89 | return component.getPreferredSize(); 90 | } 91 | if (component instanceof Container) { 92 | Dimension preferredDimension = getPreferredJLabelSize((Container) component); 93 | if (preferredDimension != null) { 94 | return preferredDimension; 95 | } 96 | } 97 | } 98 | return null; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/ui/EncodingPanel.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/ui/EncodingPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 | * 4 | * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. 5 | * 6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates. 7 | * Other names may be trademarks of their respective owners. 8 | * 9 | * The contents of this file are subject to the terms of either the GNU 10 | * General Public License Version 2 only ("GPL") or the Common 11 | * Development and Distribution License("CDDL") (collectively, the 12 | * "License"). You may not use this file except in compliance with the 13 | * License. You can obtain a copy of the License at 14 | * http://www.netbeans.org/cddl-gplv2.html 15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the 16 | * specific language governing permissions and limitations under the 17 | * License. When distributing the software, include this License Header 18 | * Notice in each file and include the License file at 19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this 20 | * particular file as subject to the "Classpath" exception as provided 21 | * by Oracle in the GPL Version 2 section of the License file that 22 | * accompanied this code. If applicable, add the following below the 23 | * License Header, with the fields enclosed by brackets [] replaced by 24 | * your own identifying information: 25 | * "Portions Copyrighted [year] [name of copyright owner]" 26 | * 27 | * If you wish your version of this file to be governed by only the CDDL 28 | * or only the GPL Version 2, indicate your decision by adding 29 | * "[Contributor] elects to include this software in this distribution 30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a 31 | * single choice of license, a recipient has the option to distribute 32 | * your version of this file under either the CDDL, the GPL Version 2 or 33 | * to extend the choice of license to its licensees as provided above. 34 | * However, if you add GPL Version 2 code and therefore, elected the GPL 35 | * Version 2 license, then the option applies only if the new code is 36 | * made subject to such option by the copyright holder. 37 | * 38 | * Contributor(s): 39 | */ 40 | package com.junichi11.netbeans.modules.encoding.ui; 41 | 42 | import com.junichi11.netbeans.modules.encoding.options.EncodingOptions; 43 | import java.awt.Dimension; 44 | import java.awt.EventQueue; 45 | import java.awt.event.FocusAdapter; 46 | import java.awt.event.FocusEvent; 47 | import java.awt.event.KeyAdapter; 48 | import java.awt.event.KeyEvent; 49 | import java.awt.event.KeyListener; 50 | import java.awt.event.MouseListener; 51 | import java.nio.charset.Charset; 52 | import java.util.Collection; 53 | import java.util.List; 54 | import javax.swing.DefaultListModel; 55 | import javax.swing.JPanel; 56 | import javax.swing.event.DocumentEvent; 57 | import javax.swing.event.DocumentListener; 58 | import org.openide.windows.WindowManager; 59 | 60 | /** 61 | * 62 | * @author junichi11 63 | */ 64 | final class EncodingPanel extends JPanel { 65 | 66 | private static final Collection CHARSETS = Charset.availableCharsets().values(); 67 | private static final long serialVersionUID = -7350298167289629517L; 68 | 69 | private DefaultListModel encodingListModel = new DefaultListModel<>(); 70 | // listeners 71 | private KeyListener encodingFilterKeyListener = new EncodingFilterKeyListener(); 72 | private KeyListener encodingListKeyListener = new EncodingListKeyAdapter(); 73 | private DocumentListener encodingFilterDocumentListener = new EncodingFilterDocumentListener(); 74 | 75 | /** 76 | * Creates new form EncodingPanel 77 | */ 78 | public EncodingPanel(Charset encoding) { 79 | initComponents(); 80 | List selectedEncodings = EncodingOptions.getInstance().getLastSelectedEncodings(); 81 | // add last 5 selected encodings to top of the list by default 82 | selectedEncodings.forEach(e -> { 83 | if (!e.equals(encoding.name())) { 84 | encodingListModel.addElement(e); 85 | } 86 | }); 87 | 88 | // add the current encoding to top of the list 89 | CHARSETS.forEach((charset) -> { 90 | if (charset.name().equals(encoding.name())) { 91 | encodingListModel.add(0, charset.name()); 92 | } else { 93 | if (!selectedEncodings.contains(charset.name())) { 94 | encodingListModel.addElement(charset.name()); 95 | } 96 | } 97 | }); 98 | encodingList.setModel(encodingListModel); 99 | encodingList.setSelectedValue(encoding.name(), true); 100 | encodingFilterTextField.getDocument().addDocumentListener(encodingFilterDocumentListener); 101 | encodingFilterTextField.addKeyListener(encodingFilterKeyListener); 102 | // don't select text when the text field is focused 103 | encodingFilterTextField.addFocusListener(new FocusAdapter() { 104 | @Override 105 | public void focusGained(FocusEvent e) { 106 | String selectedText = encodingFilterTextField.getSelectedText(); 107 | if (selectedText != null) { 108 | encodingFilterTextField.select(selectedText.length(), selectedText.length()); 109 | } 110 | } 111 | }); 112 | encodingList.addKeyListener(encodingListKeyListener); 113 | encodingFilterTextField.setVisible(false); 114 | // set Preferred size 115 | int preferredWidth = encodingListScrollPane.getPreferredSize().width; 116 | int preferredHeight = WindowManager.getDefault().getMainWindow().getSize().height / 3; 117 | encodingListScrollPane.setPreferredSize(new Dimension(preferredWidth, preferredHeight)); 118 | 119 | } 120 | 121 | /** 122 | * Clean up listeners. 123 | */ 124 | void shutdown() { 125 | // remove listeners 126 | encodingFilterTextField.removeKeyListener(encodingFilterKeyListener); 127 | encodingList.removeKeyListener(encodingListKeyListener); 128 | encodingFilterTextField.getDocument().removeDocumentListener(encodingFilterDocumentListener); 129 | encodingFilterKeyListener = null; 130 | encodingListKeyListener = null; 131 | encodingFilterDocumentListener = null; 132 | } 133 | 134 | /** 135 | * Invoke when something is typed in the text field. 136 | */ 137 | private void fireChange() { 138 | assert EventQueue.isDispatchThread(); 139 | encodingListModel.clear(); 140 | 141 | // check all keywords separated by whitespaces 142 | String filterText = encodingFilterTextField.getText(); 143 | 144 | // when all chars are selected and something is typed 145 | if (filterText.length() > 0 && !encodingFilterTextField.isVisible()) { 146 | encodingFilterTextField.setVisible(true); 147 | encodingFilterTextField.requestFocusInWindow(); 148 | revalidate(); 149 | } 150 | 151 | String[] filters = filterText.split("\\s"); // NOI18N 152 | CHARSETS.forEach(charset -> { 153 | boolean addItem = true; 154 | for (String filter : filters) { 155 | if (!charset.name().toLowerCase().contains(filter.toLowerCase())) { 156 | addItem = false; 157 | } 158 | } 159 | if (addItem) { 160 | encodingListModel.addElement(charset.name()); 161 | } 162 | }); 163 | 164 | if (encodingListModel.size() > 0) { 165 | String element = encodingListModel.getElementAt(0); 166 | encodingList.setSelectedValue(element, true); 167 | } 168 | 169 | // show the text field 170 | if (filterText.isEmpty()) { 171 | encodingList.requestFocusInWindow(); 172 | encodingFilterTextField.setVisible(false); 173 | revalidate(); 174 | } 175 | } 176 | 177 | void addEncodingListMouseListener(MouseListener listener) { 178 | encodingList.addMouseListener(listener); 179 | } 180 | 181 | void removeEncodingListMouseListener(MouseListener listener) { 182 | encodingList.removeMouseListener(listener); 183 | } 184 | 185 | boolean isEncodingPanelComponent(Object object) { 186 | return object == this 187 | || isEncodingList(object) 188 | || isEncodingListScrollBar(object) 189 | || isEncodingFilterField(object); 190 | } 191 | 192 | boolean isEncodingListScrollBar(Object object) { 193 | return encodingListScrollPane.getVerticalScrollBar() == object; 194 | } 195 | 196 | boolean isEncodingList(Object object) { 197 | return encodingList == object; 198 | } 199 | 200 | boolean isEncodingFilterField(Object object) { 201 | return encodingFilterTextField == object; 202 | } 203 | 204 | void requrestForcusEncodingFilter() { 205 | encodingFilterTextField.requestFocusInWindow(); 206 | } 207 | 208 | void requrestForcusEncodingList() { 209 | encodingList.requestFocusInWindow(); 210 | } 211 | 212 | /** 213 | * Get the selected encoding. 214 | * 215 | * @return the selected encoding 216 | */ 217 | public String getSelectedEncoding() { 218 | return encodingList.getSelectedValue(); 219 | } 220 | 221 | /** 222 | * This method is called from within the constructor to initialize the form. 223 | * WARNING: Do NOT modify this code. The content of this method is always 224 | * regenerated by the Form Editor. 225 | */ 226 | @SuppressWarnings("unchecked") 227 | // //GEN-BEGIN:initComponents 228 | private void initComponents() { 229 | 230 | encodingFilterTextField = new javax.swing.JTextField(); 231 | encodingListScrollPane = new javax.swing.JScrollPane(); 232 | encodingList = new javax.swing.JList<>(); 233 | 234 | encodingFilterTextField.setText(org.openide.util.NbBundle.getMessage(EncodingPanel.class, "EncodingPanel.encodingFilterTextField.text")); // NOI18N 235 | 236 | encodingListScrollPane.setViewportView(encodingList); 237 | 238 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 239 | this.setLayout(layout); 240 | layout.setHorizontalGroup( 241 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 242 | .addComponent(encodingFilterTextField) 243 | .addComponent(encodingListScrollPane) 244 | ); 245 | layout.setVerticalGroup( 246 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 247 | .addGroup(layout.createSequentialGroup() 248 | .addComponent(encodingListScrollPane) 249 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 250 | .addComponent(encodingFilterTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 251 | ); 252 | }// //GEN-END:initComponents 253 | 254 | // Variables declaration - do not modify//GEN-BEGIN:variables 255 | private javax.swing.JTextField encodingFilterTextField; 256 | private javax.swing.JList encodingList; 257 | private javax.swing.JScrollPane encodingListScrollPane; 258 | // End of variables declaration//GEN-END:variables 259 | 260 | //~ Inner classes 261 | private class EncodingFilterKeyListener implements KeyListener { 262 | 263 | public EncodingFilterKeyListener() { 264 | } 265 | 266 | @Override 267 | public void keyTyped(KeyEvent e) { 268 | } 269 | 270 | @Override 271 | public void keyPressed(KeyEvent e) { 272 | // change a selected item 273 | int size = encodingListModel.getSize(); 274 | if (size > 0) { 275 | int selectedIndex = encodingList.getSelectedIndex(); 276 | String element; 277 | switch (e.getKeyCode()) { 278 | case KeyEvent.VK_UP: 279 | if (selectedIndex == 0) { 280 | element = encodingListModel.getElementAt(size - 1); 281 | } else { 282 | element = encodingListModel.getElementAt(selectedIndex - 1); 283 | } 284 | break; 285 | case KeyEvent.VK_DOWN: 286 | if (selectedIndex == size - 1) { 287 | element = encodingListModel.getElementAt(0); 288 | } else { 289 | element = encodingListModel.getElementAt(selectedIndex + 1); 290 | } 291 | break; 292 | default: 293 | element = null; 294 | break; 295 | } 296 | 297 | if (element != null) { 298 | encodingList.setSelectedValue(element, true); 299 | } 300 | } 301 | } 302 | 303 | @Override 304 | public void keyReleased(KeyEvent e) { 305 | } 306 | } 307 | 308 | private class EncodingFilterDocumentListener implements DocumentListener { 309 | 310 | public EncodingFilterDocumentListener() { 311 | } 312 | 313 | @Override 314 | public void insertUpdate(DocumentEvent e) { 315 | processUpdate(); 316 | } 317 | 318 | @Override 319 | public void removeUpdate(DocumentEvent e) { 320 | processUpdate(); 321 | } 322 | 323 | @Override 324 | public void changedUpdate(DocumentEvent e) { 325 | processUpdate(); 326 | } 327 | 328 | private void processUpdate() { 329 | fireChange(); 330 | } 331 | } 332 | 333 | private class EncodingListKeyAdapter extends KeyAdapter { 334 | 335 | public EncodingListKeyAdapter() { 336 | } 337 | 338 | @Override 339 | public void keyTyped(KeyEvent e) { 340 | // XXX validate key char 341 | switch (e.getKeyChar()) { 342 | case '\b': // backspace no break 343 | case '\u007f': // delete 344 | return; 345 | default: 346 | encodingFilterTextField.setVisible(true); 347 | encodingFilterTextField.requestFocusInWindow(); 348 | revalidate(); 349 | encodingFilterTextField.setText(String.valueOf(e.getKeyChar())); 350 | break; 351 | } 352 | } 353 | } 354 | } 355 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/ui/EncodingStatusLineElementProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 | * 4 | * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. 5 | * 6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates. 7 | * Other names may be trademarks of their respective owners. 8 | * 9 | * The contents of this file are subject to the terms of either the GNU 10 | * General Public License Version 2 only ("GPL") or the Common 11 | * Development and Distribution License("CDDL") (collectively, the 12 | * "License"). You may not use this file except in compliance with the 13 | * License. You can obtain a copy of the License at 14 | * http://www.netbeans.org/cddl-gplv2.html 15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the 16 | * specific language governing permissions and limitations under the 17 | * License. When distributing the software, include this License Header 18 | * Notice in each file and include the License file at 19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this 20 | * particular file as subject to the "Classpath" exception as provided 21 | * by Oracle in the GPL Version 2 section of the License file that 22 | * accompanied this code. If applicable, add the following below the 23 | * License Header, with the fields enclosed by brackets [] replaced by 24 | * your own identifying information: 25 | * "Portions Copyrighted [year] [name of copyright owner]" 26 | * 27 | * If you wish your version of this file to be governed by only the CDDL 28 | * or only the GPL Version 2, indicate your decision by adding 29 | * "[Contributor] elects to include this software in this distribution 30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a 31 | * single choice of license, a recipient has the option to distribute 32 | * your version of this file under either the CDDL, the GPL Version 2 or 33 | * to extend the choice of license to its licensees as provided above. 34 | * However, if you add GPL Version 2 code and therefore, elected the GPL 35 | * Version 2 license, then the option applies only if the new code is 36 | * made subject to such option by the copyright holder. 37 | * 38 | * Contributor(s): 39 | */ 40 | package com.junichi11.netbeans.modules.encoding.ui; 41 | 42 | import com.junichi11.netbeans.modules.encoding.OpenInEncodingQueryImpl; 43 | import com.junichi11.netbeans.modules.encoding.options.EncodingOptions; 44 | import java.awt.AWTEvent; 45 | import java.awt.BorderLayout; 46 | import java.awt.Component; 47 | import java.awt.Dimension; 48 | import java.awt.EventQueue; 49 | import java.awt.Point; 50 | import java.awt.Toolkit; 51 | import java.awt.Window; 52 | import java.awt.event.AWTEventListener; 53 | import java.awt.event.MouseAdapter; 54 | import java.awt.event.MouseEvent; 55 | import java.beans.PropertyChangeEvent; 56 | import java.beans.PropertyChangeListener; 57 | import java.io.IOException; 58 | import java.lang.reflect.Field; 59 | import java.lang.reflect.InvocationTargetException; 60 | import java.lang.reflect.Method; 61 | import java.nio.charset.Charset; 62 | import java.util.Set; 63 | import java.util.logging.Level; 64 | import java.util.logging.Logger; 65 | import javax.swing.BorderFactory; 66 | import javax.swing.JEditorPane; 67 | import javax.swing.JLabel; 68 | import javax.swing.JPanel; 69 | import javax.swing.JSeparator; 70 | import javax.swing.Popup; 71 | import javax.swing.PopupFactory; 72 | import javax.swing.SwingConstants; 73 | import javax.swing.SwingUtilities; 74 | import javax.swing.text.JTextComponent; 75 | import org.netbeans.api.annotations.common.StaticResource; 76 | import org.netbeans.api.editor.EditorRegistry; 77 | import org.netbeans.api.queries.FileEncodingQuery; 78 | import org.openide.awt.StatusLineElementProvider; 79 | import org.openide.cookies.EditorCookie; 80 | import org.openide.filesystems.FileObject; 81 | import org.openide.loaders.DataObject; 82 | import org.openide.loaders.DataObjectNotFoundException; 83 | import org.openide.text.CloneableEditorSupport; 84 | import org.openide.text.DataEditorSupport; 85 | import org.openide.util.ImageUtilities; 86 | import org.openide.util.NbBundle; 87 | import org.openide.util.lookup.ServiceProvider; 88 | 89 | /** 90 | * 91 | * @author junichi11 92 | */ 93 | @ServiceProvider(service = StatusLineElementProvider.class) 94 | public class EncodingStatusLineElementProvider implements StatusLineElementProvider { 95 | 96 | private static final JLabel ENCODING_LABEL = EncodingLabel.create(); 97 | private static final Component COMPONENT = panelWithSeparator(ENCODING_LABEL); 98 | private static final Logger LOGGER = Logger.getLogger(EncodingStatusLineElementProvider.class.getName()); 99 | private static volatile boolean SHOWING_POPUP; 100 | 101 | static { 102 | // icon position: right 103 | ENCODING_LABEL.setHorizontalTextPosition(SwingConstants.LEFT); 104 | 105 | // add listeners 106 | EditorRegistry.addPropertyChangeListener((PropertyChangeListener) ENCODING_LABEL); 107 | ENCODING_LABEL.addMouseListener(new EncodingLabelMouseAdapter()); 108 | } 109 | 110 | @Override 111 | public Component getStatusLineElement() { 112 | return COMPONENT; 113 | } 114 | 115 | /** 116 | * Create Component(JPanel) and add separator and JLabel to it. 117 | * 118 | * @param label JLabel 119 | * @return panel 120 | */ 121 | private static Component panelWithSeparator(JLabel label) { 122 | // create separator 123 | JSeparator separator = new JSeparator(SwingConstants.VERTICAL) { 124 | private static final long serialVersionUID = -6385848933295984637L; 125 | 126 | @Override 127 | public Dimension getPreferredSize() { 128 | return new Dimension(3, 3); 129 | } 130 | }; 131 | separator.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); 132 | 133 | // create panel 134 | JPanel panel = new JPanel(new BorderLayout()); 135 | panel.add(separator, BorderLayout.WEST); 136 | panel.add(label, BorderLayout.EAST); 137 | return panel; 138 | } 139 | 140 | /** 141 | * Change the encoding. 142 | * NOTE:The file is reopened. 143 | * 144 | * @param selectedEncoding the selected encoding 145 | */ 146 | @NbBundle.Messages("EncodingStatusLineElementProvider.message.modified.file=Please save the file once.") 147 | private static void changeEncoding(String selectedEncoding) { 148 | if (selectedEncoding == null) { 149 | UiUtils.requestFocusLastFocusedComponent(); 150 | LOGGER.log(Level.WARNING, "The selected encoding is null."); // NOI18N 151 | return; 152 | } 153 | 154 | FileObject fileObject = UiUtils.getLastFocusedFileObject(); 155 | if (fileObject == null) { 156 | return; 157 | } 158 | 159 | // check whether the file is modified 160 | try { 161 | DataObject dataObject = DataObject.find(fileObject); 162 | if (dataObject.isModified()) { 163 | UiUtils.requestFocusLastFocusedComponent(); 164 | UiUtils.showErrorMessage(Bundle.EncodingStatusLineElementProvider_message_modified_file()); 165 | return; 166 | } 167 | } catch (DataObjectNotFoundException ex) { 168 | LOGGER.log(Level.SEVERE, null, ex); 169 | } 170 | 171 | // same encoding? 172 | Charset encoding = EncodingFinder.find(fileObject); 173 | String currentEncoding = encoding.name(); 174 | 175 | // #1 encoding is empty when snippet is inserted with palette 176 | if (selectedEncoding.equals(currentEncoding) || selectedEncoding.isEmpty()) { 177 | UiUtils.requestFocusLastFocusedComponent(); 178 | return; 179 | } 180 | 181 | // set encoding to attribute, reload a document 182 | try { 183 | fileObject.setAttribute(OpenInEncodingQueryImpl.ENCODING, selectedEncoding); 184 | final DataObject dobj = DataObject.find(fileObject); 185 | 186 | // don't show dialog 187 | // if a cancel button is clicked, text can be cleared 188 | Field field = DataEditorSupport.class.getDeclaredField("warnedEncodingFiles"); // NOI18N 189 | field.setAccessible(true); 190 | Set fileObjects = (Set) field.get(null); 191 | fileObjects.add(fileObject); 192 | 193 | // reload editor 194 | EditorCookie ec = dobj.getLookup().lookup(EditorCookie.class); 195 | Method notifyModified = CloneableEditorSupport.class.getDeclaredMethod("checkReload", JEditorPane[].class, boolean.class); // NOI18N 196 | notifyModified.setAccessible(true); 197 | JEditorPane[] focusedPanes = new JEditorPane[]{}; 198 | JTextComponent component = EditorRegistry.lastFocusedComponent(); 199 | if (component instanceof JEditorPane) { 200 | focusedPanes = new JEditorPane[]{(JEditorPane) component}; 201 | } 202 | notifyModified.invoke(ec, focusedPanes, true); 203 | 204 | // save selected encoding to options 205 | EncodingOptions.getInstance().setLastSelectedEncodings(selectedEncoding); 206 | UiUtils.requestFocusLastFocusedComponent(); 207 | } catch (IOException 208 | | IllegalAccessException 209 | | IllegalArgumentException 210 | | InvocationTargetException 211 | | NoSuchMethodException 212 | | SecurityException 213 | | NoSuchFieldException ex) { 214 | LOGGER.log(Level.WARNING, null, ex); 215 | } 216 | } 217 | 218 | //~ inner classes 219 | private static final class EncodingFinder { 220 | 221 | private EncodingFinder() { 222 | } 223 | 224 | private static final OpenInEncodingQueryImpl QUERY_IMPL = new OpenInEncodingQueryImpl(); 225 | 226 | private static Charset find(FileObject fileObject) { 227 | Charset encoding = QUERY_IMPL.getEncoding(fileObject); 228 | if (encoding == null) { 229 | encoding = FileEncodingQuery.getEncoding(fileObject); 230 | } 231 | return encoding; 232 | } 233 | } 234 | 235 | private static class EncodingLabel extends JLabel implements PropertyChangeListener { 236 | 237 | @StaticResource 238 | public static final String ENCODING_LIST_ICON_16 = "com/junichi11/netbeans/modules/encoding/resources/encoding_16.png"; // NOI18N 239 | private static final long serialVersionUID = -5078620344180235634L; 240 | 241 | public static EncodingLabel create() { 242 | EncodingLabel label = new EncodingLabel(); 243 | label.setText(" "); 244 | label.setIcon(ImageUtilities.loadImageIcon(ENCODING_LIST_ICON_16, false)); 245 | return label; 246 | } 247 | 248 | private EncodingLabel() { 249 | } 250 | 251 | @Override 252 | public void propertyChange(PropertyChangeEvent evt) { 253 | updateEncoding(); 254 | } 255 | 256 | private void updateEncoding() { 257 | assert EventQueue.isDispatchThread(); 258 | this.setPreferredSize(null); 259 | FileObject fileObject; 260 | if (SHOWING_POPUP) { 261 | fileObject = UiUtils.getLastFocusedFileObject(); 262 | } else { 263 | fileObject = UiUtils.getFocusedFileObject(); 264 | } 265 | if (fileObject != null) { 266 | Charset encoding = getEncoding(fileObject); 267 | this.setText(String.format(" %s ", encoding.displayName())); // NOI18N 268 | this.setIcon(ImageUtilities.loadImageIcon(ENCODING_LIST_ICON_16, false)); 269 | return; 270 | } 271 | Dimension size = this.getSize(); 272 | this.setPreferredSize(size); 273 | this.setText(""); // NOI18N 274 | this.setIcon(null); 275 | } 276 | 277 | private Charset getEncoding(FileObject fileObject) { 278 | return EncodingFinder.find(fileObject); 279 | } 280 | 281 | } 282 | 283 | private static class EncodingLabelMouseAdapter extends MouseAdapter { 284 | 285 | public EncodingLabelMouseAdapter() { 286 | } 287 | 288 | @Override 289 | public void mouseClicked(MouseEvent e) { 290 | FileObject fileObject = UiUtils.getFocusedFileObject(); 291 | if (fileObject == null) { 292 | return; 293 | } 294 | 295 | // set current encoding 296 | Charset charset = EncodingFinder.find(fileObject); 297 | final EncodingPanel encodingPanel = new EncodingPanel(charset); 298 | Popup popup = getPopup(encodingPanel); 299 | if (popup == null) { 300 | return; 301 | } 302 | 303 | // forcusable 304 | setForcusableWindowState(encodingPanel, true); 305 | 306 | // add listener 307 | final EncodingListMouseAdapter encodingListMouseAdapter = new EncodingListMouseAdapter(encodingPanel, popup); 308 | encodingPanel.addEncodingListMouseListener(encodingListMouseAdapter); 309 | 310 | // hide popup 311 | final AWTEventListener eventListener = new AWTEventListener() { 312 | @Override 313 | public void eventDispatched(AWTEvent event) { 314 | if (isHidable(event)) { 315 | setForcusableWindowState(encodingPanel, false); 316 | Object source = event.getSource(); 317 | popup.hide(); 318 | SHOWING_POPUP = false; 319 | Toolkit.getDefaultToolkit().removeAWTEventListener(this); 320 | encodingPanel.shutdown(); 321 | 322 | if (!UiUtils.isMouseClicked(event) 323 | || !encodingPanel.isEncodingList(source)) { 324 | encodingPanel.removeEncodingListMouseListener(encodingListMouseAdapter); 325 | } 326 | 327 | if (UiUtils.isEscKey(event) || UiUtils.isEnterKey(event)) { 328 | if (encodingPanel.isEncodingFilterField(source) 329 | || encodingPanel.isEncodingList(source)) { 330 | UiUtils.requestFocusLastFocusedComponent(); 331 | } 332 | } 333 | 334 | if (!encodingPanel.isEncodingList(source) 335 | && !encodingPanel.isEncodingFilterField(source)) { 336 | return; 337 | } 338 | 339 | if (UiUtils.isEnterKey(event)) { 340 | changeEncoding(encodingPanel.getSelectedEncoding()); 341 | } 342 | } 343 | } 344 | 345 | private boolean isHidable(AWTEvent event) { 346 | Object source = event.getSource(); 347 | if (UiUtils.isMouseClicked(event) 348 | && !UiUtils.isComponentOfClass(EncodingPanel.class, source) 349 | && source != ENCODING_LABEL) { 350 | return true; 351 | 352 | } 353 | return UiUtils.isEscKey(event) || UiUtils.isEnterKey(event); 354 | } 355 | 356 | }; 357 | Toolkit.getDefaultToolkit().addAWTEventListener(eventListener, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.KEY_EVENT_MASK); 358 | 359 | popup.show(); 360 | SHOWING_POPUP = true; 361 | encodingPanel.requrestForcusEncodingList(); 362 | } 363 | 364 | private Popup getPopup(final JPanel encodingPanel) throws IllegalArgumentException { 365 | Point labelStart = ENCODING_LABEL.getLocationOnScreen(); 366 | int x = Math.min(labelStart.x, labelStart.x + ENCODING_LABEL.getSize().width - encodingPanel.getPreferredSize().width); 367 | int y = labelStart.y - encodingPanel.getPreferredSize().height; 368 | return PopupFactory.getSharedInstance().getPopup(ENCODING_LABEL, encodingPanel, x, y); 369 | } 370 | } 371 | 372 | private static void setForcusableWindowState(Component encodingPanel, boolean focusableWindowState) { 373 | Window window = SwingUtilities.windowForComponent(encodingPanel); 374 | if (window != null) { 375 | window.setFocusableWindowState(focusableWindowState); 376 | } 377 | } 378 | 379 | private static class EncodingListMouseAdapter extends MouseAdapter { 380 | 381 | private final EncodingPanel encodingPanel; 382 | private final Popup popup; 383 | 384 | public EncodingListMouseAdapter(EncodingPanel encodingPanel, Popup popup) { 385 | this.encodingPanel = encodingPanel; 386 | this.popup = popup; 387 | } 388 | 389 | @Override 390 | public void mouseClicked(MouseEvent e) { 391 | setForcusableWindowState(encodingPanel, false); 392 | popup.hide(); 393 | SHOWING_POPUP = false; 394 | encodingPanel.removeEncodingListMouseListener(this); 395 | changeEncoding(encodingPanel.getSelectedEncoding()); 396 | } 397 | 398 | } 399 | } 400 | -------------------------------------------------------------------------------- /src/com/junichi11/netbeans/modules/encoding/ui/UiUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 | * 4 | * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. 5 | * 6 | * Oracle and Java are registered trademarks of Oracle and/or its affiliates. 7 | * Other names may be trademarks of their respective owners. 8 | * 9 | * The contents of this file are subject to the terms of either the GNU 10 | * General Public License Version 2 only ("GPL") or the Common 11 | * Development and Distribution License("CDDL") (collectively, the 12 | * "License"). You may not use this file except in compliance with the 13 | * License. You can obtain a copy of the License at 14 | * http://www.netbeans.org/cddl-gplv2.html 15 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the 16 | * specific language governing permissions and limitations under the 17 | * License. When distributing the software, include this License Header 18 | * Notice in each file and include the License file at 19 | * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this 20 | * particular file as subject to the "Classpath" exception as provided 21 | * by Oracle in the GPL Version 2 section of the License file that 22 | * accompanied this code. If applicable, add the following below the 23 | * License Header, with the fields enclosed by brackets [] replaced by 24 | * your own identifying information: 25 | * "Portions Copyrighted [year] [name of copyright owner]" 26 | * 27 | * If you wish your version of this file to be governed by only the CDDL 28 | * or only the GPL Version 2, indicate your decision by adding 29 | * "[Contributor] elects to include this software in this distribution 30 | * under the [CDDL or GPL Version 2] license." If you do not indicate a 31 | * single choice of license, a recipient has the option to distribute 32 | * your version of this file under either the CDDL, the GPL Version 2 or 33 | * to extend the choice of license to its licensees as provided above. 34 | * However, if you add GPL Version 2 code and therefore, elected the GPL 35 | * Version 2 license, then the option applies only if the new code is 36 | * made subject to such option by the copyright holder. 37 | * 38 | * Contributor(s): 39 | */ 40 | package com.junichi11.netbeans.modules.encoding.ui; 41 | 42 | import java.awt.AWTEvent; 43 | import java.awt.Container; 44 | import java.awt.event.KeyEvent; 45 | import java.awt.event.MouseEvent; 46 | import javax.swing.JComponent; 47 | import javax.swing.SwingUtilities; 48 | import javax.swing.text.Document; 49 | import javax.swing.text.JTextComponent; 50 | import org.netbeans.api.annotations.common.CheckForNull; 51 | import org.netbeans.api.editor.EditorRegistry; 52 | import org.netbeans.modules.editor.NbEditorUtilities; 53 | import org.openide.DialogDisplayer; 54 | import org.openide.NotifyDescriptor; 55 | import org.openide.cookies.CloseCookie; 56 | import org.openide.cookies.EditorCookie; 57 | import org.openide.cookies.OpenCookie; 58 | import org.openide.filesystems.FileObject; 59 | import org.openide.loaders.DataObject; 60 | 61 | /** 62 | * 63 | * @author junichi11 64 | */ 65 | public final class UiUtils { 66 | 67 | private UiUtils() { 68 | } 69 | 70 | @CheckForNull 71 | public static FileObject getLastFocusedFileObject() { 72 | return getFocusedFileObject(true); 73 | } 74 | 75 | @CheckForNull 76 | public static FileObject getFocusedFileObject() { 77 | return getFocusedFileObject(false); 78 | } 79 | 80 | @CheckForNull 81 | private static FileObject getFocusedFileObject(boolean last) { 82 | JTextComponent component; 83 | if (last) { 84 | component = EditorRegistry.lastFocusedComponent(); 85 | } else { 86 | component = EditorRegistry.focusedComponent(); 87 | } 88 | if (component == null) { 89 | return null; 90 | } 91 | 92 | Document document = component.getDocument(); 93 | if (document == null) { 94 | return null; 95 | } 96 | 97 | return NbEditorUtilities.getFileObject(document); 98 | } 99 | 100 | public static void reopen(DataObject dobj) throws InterruptedException { 101 | close(dobj); 102 | 103 | // XXX java.lang.AssertionError is occurred 104 | Thread.sleep(200); 105 | 106 | open(dobj); 107 | } 108 | 109 | public static void close(DataObject dobj) { 110 | CloseCookie cc = dobj.getLookup().lookup(CloseCookie.class); 111 | EditorCookie ec = dobj.getLookup().lookup(EditorCookie.class); 112 | 113 | if (cc != null) { 114 | cc.close(); 115 | } 116 | if (ec != null) { 117 | ec.close(); 118 | } 119 | } 120 | 121 | public static void open(DataObject dobj) { 122 | OpenCookie oc = dobj.getLookup().lookup(OpenCookie.class); 123 | if (oc != null) { 124 | oc.open(); 125 | } 126 | } 127 | 128 | public static boolean isMouseClicked(AWTEvent event) { 129 | return event instanceof MouseEvent && ((MouseEvent) event).getClickCount() > 0; 130 | } 131 | 132 | public static boolean isEscKey(AWTEvent event) { 133 | return event instanceof KeyEvent && ((KeyEvent) event).getKeyCode() == KeyEvent.VK_ESCAPE; 134 | } 135 | 136 | public static boolean isEnterKey(AWTEvent event) { 137 | return event instanceof KeyEvent && ((KeyEvent) event).getKeyCode() == KeyEvent.VK_ENTER; 138 | } 139 | 140 | /** 141 | * Focus the last focused editor pane. 142 | */ 143 | public static void requestFocusLastFocusedComponent() { 144 | JTextComponent lastFocusedComponent = EditorRegistry.lastFocusedComponent(); 145 | if (lastFocusedComponent != null) { 146 | lastFocusedComponent.requestFocusInWindow(); 147 | } 148 | } 149 | 150 | /** 151 | * Check whether the object is a component of the specific class. 152 | * 153 | * @param object the object 154 | * @return {@code true} if the object is a component of the specific class, 155 | * otherwise {@code false} 156 | */ 157 | public static boolean isComponentOfClass(Class clazz, Object object) { 158 | if (object instanceof JComponent) { 159 | JComponent component = (JComponent) object; 160 | Container parent = SwingUtilities.getAncestorOfClass(clazz, component); 161 | return parent != null; 162 | } 163 | return false; 164 | } 165 | 166 | /** 167 | * Show the error message. 168 | * 169 | * @param message the error message 170 | */ 171 | public static void showErrorMessage(String message) { 172 | showMessage(message, NotifyDescriptor.ERROR_MESSAGE); 173 | } 174 | 175 | /** 176 | * Show the information message 177 | * 178 | * @param message the infomation message 179 | */ 180 | public static void showInformationMessage(String message) { 181 | showMessage(message, NotifyDescriptor.INFORMATION_MESSAGE); 182 | } 183 | 184 | private static void showMessage(String message, int messageType) { 185 | NotifyDescriptor descriptor = new NotifyDescriptor.Message( 186 | message, 187 | messageType 188 | ); 189 | DialogDisplayer.getDefault().notifyLater(descriptor); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /test/unit/src/com/junichi11/netbeans/modules/encoding/OpenInEncodingQueryImplTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 | * 4 | * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. 5 | * 6 | * The contents of this file are subject to the terms of either the GNU 7 | * General Public License Version 2 only ("GPL") or the Common 8 | * Development and Distribution License("CDDL") (collectively, the 9 | * "License"). You may not use this file except in compliance with the 10 | * License. You can obtain a copy of the License at 11 | * http://www.netbeans.org/cddl-gplv2.html 12 | * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the 13 | * specific language governing permissions and limitations under the 14 | * License. When distributing the software, include this License Header 15 | * Notice in each file and include the License file at 16 | * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this 17 | * particular file as subject to the "Classpath" exception as provided 18 | * by Sun in the GPL Version 2 section of the License file that 19 | * accompanied this code. If applicable, add the following below the 20 | * License Header, with the fields enclosed by brackets [] replaced by 21 | * your own identifying information: 22 | * "Portions Copyrighted [year] [name of copyright owner]" 23 | * 24 | * If you wish your version of this file to be governed by only the CDDL 25 | * or only the GPL Version 2, indicate your decision by adding 26 | * "[Contributor] elects to include this software in this distribution 27 | * under the [CDDL or GPL Version 2] license." If you do not indicate a 28 | * single choice of license, a recipient has the option to distribute 29 | * your version of this file under either the CDDL, the GPL Version 2 or 30 | * to extend the choice of license to its licensees as provided above. 31 | * However, if you add GPL Version 2 code and therefore, elected the GPL 32 | * Version 2 license, then the option applies only if the new code is 33 | * made subject to such option by the copyright holder. 34 | * 35 | * Contributor(s): 36 | * 37 | * Portions Copyrighted 2007 Sun Microsystems, Inc. 38 | */ 39 | package com.junichi11.netbeans.modules.encoding; 40 | 41 | import java.io.File; 42 | import java.io.IOException; 43 | import java.nio.charset.Charset; 44 | import org.netbeans.junit.NbTestCase; 45 | import org.netbeans.spi.queries.FileEncodingQueryImplementation; 46 | import org.openide.filesystems.FileObject; 47 | import org.openide.filesystems.FileUtil; 48 | 49 | /** 50 | * 51 | * @author Tomas Zezula 52 | */ 53 | public class OpenInEncodingQueryImplTest extends NbTestCase { 54 | 55 | public OpenInEncodingQueryImplTest(String testName) { 56 | super(testName); 57 | } 58 | 59 | @Override 60 | protected void setUp() throws Exception { 61 | clearWorkDir(); 62 | } 63 | 64 | @Override 65 | protected void tearDown() throws Exception { 66 | } 67 | 68 | public void testGetEncoding() throws IOException { 69 | final FileObject testFile = createTestFile(this.getWorkDir()); 70 | final FileEncodingQueryImplementation impl = new OpenInEncodingQueryImpl(); 71 | assertNull(impl.getEncoding(testFile)); 72 | testFile.setAttribute(OpenInEncodingQueryImpl.ENCODING, "UTF-16"); //NOI18N 73 | assertEquals(Charset.forName("UTF-16"), impl.getEncoding(testFile)); 74 | testFile.setAttribute(OpenInEncodingQueryImpl.ENCODING, "UTF-8"); //NOI18N 75 | assertEquals(Charset.forName("UTF-8"), impl.getEncoding(testFile)); 76 | testFile.setAttribute(OpenInEncodingQueryImpl.ENCODING, null); 77 | assertNull(impl.getEncoding(testFile)); 78 | } 79 | 80 | private static FileObject createTestFile(final File wd) throws IOException { 81 | FileObject root = FileUtil.toFileObject(wd); 82 | assert root != null : "No masterfs on classpath"; //NOI18N 83 | return root.createData("test", "foo"); //NOI18N 84 | } 85 | 86 | } 87 | --------------------------------------------------------------------------------