📄 pref.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Pref.java * * Copyright (c) 2004 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.database.text;import com.sun.electric.Main;import com.sun.electric.technology.TechPool;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.Job;import java.io.BufferedWriter;import java.io.ByteArrayOutputStream;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;import java.io.OutputStreamWriter;import java.io.PrintStream;import java.io.PrintWriter;import java.io.Serializable;import java.io.StringReader;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Set;import java.util.TreeMap;import java.util.prefs.BackingStoreException;import java.util.prefs.InvalidPreferencesFormatException;import java.util.prefs.Preferences;import javax.xml.transform.OutputKeys;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.stream.StreamResult;import javax.xml.transform.stream.StreamSource;import org.xml.sax.SAXParseException;/** * This class manages options. * There are two types of options: <I>appearance</I> and <I>meaning</I>. * Appearance options affect the way that the design is presented to the user. * Examples are grid dot spacing, layer stipple patterns, etc. * Meaning options affect the way that a design is produced (for fabrication, * simulation, and other outputs). Examples are CIF layer names, technology * options, etc.) * <P> * All options are saved in a machine-specific way by the Java Preferences class. * In addition, "meaning" options are stored in libraries. When the libraries * are read back into Electric, the stored meaning options are checked against * the current meaning options, the two are reconciled. * <P> * Where are these options stored? It varies with each operating system. * <UL> * <LI><B>Windows:</B> * In the registry. * Look in: HKEY_CURRENT_USER / Software / JavaSoft / Prefs / com / sun / electric. * </LI> * <LI><B>UNIX/Linux:</B> * In your home directory. * Look in: ~/.java/.userPrefs/com/sun/electric * </LI> * <LI><B>Macintosh System 10:</B> * In your home directory, under Library/Preferences. * Look at: ~/Library/Preferences/com.sun.electric.plist * </LI> * </UL> */public class Pref{ public static class Group { Preferences preferences; private final ArrayList<Pref> prefs = new ArrayList<Pref>(); public Group(Preferences preferences) { this.preferences = preferences; } public String absolutePath() { return preferences.absolutePath(); } private void setCachedObjsFromPreferences() { for(Pref pref : prefs) { switch (pref.type) { case BOOLEAN: pref.setBoolean(getBoolean(pref.name, pref.getBooleanFactoryValue())); break; case INTEGER: pref.setInt(getInt(pref.name, pref.getIntFactoryValue())); break; case LONG: pref.setLong(getLong(pref.name, pref.getLongFactoryValue())); break; case DOUBLE: pref.setDouble(getDouble(pref.name, pref.getDoubleFactoryValue())); break; case STRING: pref.setString(get(pref.name, pref.getStringFactoryValue())); break; } } } private void putBoolean(String key, boolean value) { if (preferences == null) return; preferences.putBoolean(key, value); if (doFlushing) flushOptions(preferences); else queueForFlushing.add(preferences); } private boolean getBoolean(String key, boolean def) { return preferences != null ? preferences.getBoolean(key, def) : def; } private void putInt(String key, int value) { if (preferences == null) return; preferences.putInt(key, value); if (doFlushing) flushOptions(preferences); else queueForFlushing.add(preferences); } private int getInt(String key, int def) { return preferences != null ? preferences.getInt(key, def) : def; } private void putLong(String key, long value) { if (preferences == null) return; preferences.putLong(key, value); if (doFlushing) flushOptions(preferences); else queueForFlushing.add(preferences); } private long getLong(String key, long def) { return preferences != null ? preferences.getLong(key, def) : def; } private void putDouble(String key, double value) { if (preferences == null) return; preferences.putDouble(key, value); if (doFlushing) flushOptions(preferences); else queueForFlushing.add(preferences); } private double getDouble(String key, double def) { return preferences != null ? preferences.getDouble(key, def) : null; } private void put(String key, String value) { if (preferences == null) return; preferences.put(key, value); if (doFlushing) flushOptions(preferences); else queueForFlushing.add(preferences); } private String get(String key, String def) { return preferences != null ? preferences.get(key, def) : null; } } public static Group groupForPackage(Class classFromPackage) { return groupForPackage(classFromPackage, false); } public static Group groupForPackage(Class classFromPackage, boolean techGroup) { Preferences prefs = Preferences.userNodeForPackage(classFromPackage); if (techGroup) return new Group(prefs); synchronized(allGroups) { for (Group group: allGroups) if (group.preferences == prefs) return group; Group newGroup = new Group(prefs); allGroups.add(newGroup); return newGroup; } } public enum PrefType { /** The value for boolean options. */ BOOLEAN, /** The value for integer options. */ INTEGER, /** The value for long options. */ LONG, /** The value for double options. */ DOUBLE, /** The value for string options. */ STRING; } private final String name; private PrefType type; private final Group group; private Object cachedObj; private Object factoryObj;// private boolean changed = false; private static final ArrayList<Group> allGroups = new ArrayList<Group>(); private static boolean doFlushing = true;// private static PrefChangeBatch changes = null; private static Set<Preferences> queueForFlushing; /** * The constructor for the Pref. * @param name the name of this Pref. */ protected Pref(Group group, String name) { this.name = name; this.group = group; synchronized (group.prefs) { group.prefs.add(this); } } /** * Method used in regressions so it has to be public. * @param fileName */ public static void importPrefs(String fileName, TechPool techPool) { if (fileName == null) return; // import preferences importPrefs(TextUtils.makeURLToFile(fileName), techPool); } public static void importPrefs(URL fileURL, TechPool techPool) { if (fileURL == null) return; // import preferences try { URLConnection urlCon = fileURL.openConnection(); InputStream inputStream = urlCon.getInputStream(); System.out.println("Importing preferences..."); // reset all preferences to factory values try { clearPrefs(Preferences.userNodeForPackage(Main.class)); } catch (BackingStoreException e) { System.out.println("Error resetting Electric preferences"); e.printStackTrace(); }// delayPrefFlushing();// synchronized (allPrefs) {// for(Pref pref : allPrefs) {// switch (pref.type) {// case BOOLEAN:// if (pref.getBoolean() != pref.getBooleanFactoryValue())// pref.setBoolean(pref.getBooleanFactoryValue());// break;// case INTEGER:// if (pref.getInt() != pref.getIntFactoryValue())// pref.setInt(pref.getIntFactoryValue());// break;// case LONG:// if (pref.getLong() != pref.getLongFactoryValue())// pref.setLong(pref.getLongFactoryValue());// break;// case DOUBLE:// if (pref.getDouble() != pref.getDoubleFactoryValue())// pref.setDouble(pref.getDoubleFactoryValue());// break;// case STRING:// if (!pref.getString().equals(pref.getStringFactoryValue()))// pref.setString(pref.getStringFactoryValue());// break;// }// }// }// resumePrefFlushing(); // import preferences Preferences.importPreferences(inputStream); inputStream.close(); // recache all prefs delayPrefFlushing(); synchronized (allGroups) { for (Group group: allGroups) group.setCachedObjsFromPreferences(); for (Technology tech: techPool.values()) { for (Group group: tech.getTechnologyAllPreferences()) group.setCachedObjsFromPreferences(); } Setting.saveAllSettingsToPreferences(); } resumePrefFlushing(); // recache technology color information Technology.cacheTransparentLayerColors(); } catch (InvalidPreferencesFormatException e) { String message = "Invalid preferences format"; if (e.getCause() instanceof SAXParseException) { SAXParseException se = (SAXParseException)e.getCause(); message += " (line " + se.getLineNumber() + ")"; } System.out.println(message + ": "+e.getMessage()); return; } catch (IOException e) { System.out.println("Error reading preferences file"); e.printStackTrace(); return; } Job.getExtendedUserInterface().restoreSavedBindings(false); Job.getUserInterface().repaintAllWindows(); System.out.println("...preferences imported from " + fileURL.getFile()); } private static void clearPrefs(Preferences topNode) throws BackingStoreException { topNode.clear(); for (String child: topNode.childrenNames()) clearPrefs(topNode.node(child)); } /** * Method to export the preferences to an XML file. This function is public due to the regressions. * @param fileName the file to write. */ public static void exportPrefs(String fileName) { if (fileName == null) return; // save preferences there try { // dump the preferences as a giant XML string (unformatted) Preferences root = Preferences.userNodeForPackage(Main.class); ByteArrayOutputStream bs = new ByteArrayOutputStream(); root.exportSubtree(bs); String xmlDump = bs.toString(); // remove the DTD statement (causes trouble) int sunPos = xmlDump.indexOf("java.sun.com"); String insertDTD = ""; if (sunPos >= 0) { int openPos = xmlDump.lastIndexOf('<', sunPos); int closePos = xmlDump.indexOf('>', sunPos); if (openPos >= 0 && closePos >= 0) { insertDTD = xmlDump.substring(openPos, closePos+1); xmlDump = xmlDump.substring(0, openPos) + xmlDump.substring(closePos+1); } } // reformat the XML StreamSource source = new StreamSource(new StringReader(xmlDump)); TransformerFactory factory = TransformerFactory.newInstance(); factory.setAttribute("indent-number", new Integer(2)); Transformer transformer = factory.newTransformer(); transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); ByteArrayOutputStream bos = new ByteArrayOutputStream(); StreamResult result = new StreamResult(new OutputStreamWriter(bos, "utf-8")); transformer.transform(source, result); // add the removed DTD line back into the XML String xmlFormatted = bos.toString(); int closePos = xmlFormatted.indexOf('>'); if (closePos >= 0) xmlFormatted = xmlFormatted.substring(0, closePos+1) + "\n" + insertDTD + xmlFormatted.substring(closePos+1); // save the XML to disk PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter(fileName))); printWriter.print(xmlFormatted); printWriter.close(); } catch (Exception e) { if (Job.getDebug()) e.printStackTrace(); System.out.println("Error exporting Preferences"); return; } System.out.println("Preferences saved to " + fileName); } /** * Factory methods to create a boolean Pref objects. * The proper way to create a boolean Pref is with makeBooleanPref; * use of this method is only for subclasses. * @param factory the "factory" default value (if nothing is stored). */ protected void initBoolean(boolean factory) { type = PrefType.BOOLEAN; factoryObj = new Integer(factory ? 1 : 0); cachedObj = new Integer(group.getBoolean(name, factory) ? 1 : 0); } /** * Factory methods to create a boolean Pref objects. * @param name the name of this Pref. * @param group group of preferences to which a new Pref belongs * @param factory the "factory" default value (if nothing is stored). */ public static Pref makeBooleanPref(String name, Group group, boolean factory) { Pref pref = new Pref(group, name); pref.initBoolean(factory); return pref; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -