• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ide.eclipse.adt.internal.preferences;
18 
19 
20 import com.android.ide.eclipse.adt.AdtPlugin;
21 import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
22 import com.android.prefs.AndroidLocation.AndroidLocationException;
23 import com.android.sdklib.internal.build.DebugKeyProvider;
24 import com.android.sdklib.internal.build.DebugKeyProvider.KeytoolException;
25 import com.android.sdkstats.DdmsPreferenceStore;
26 
27 import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
28 import org.eclipse.jface.preference.IPreferenceStore;
29 import org.eclipse.jface.util.PropertyChangeEvent;
30 
31 import java.io.File;
32 
33 public final class AdtPrefs extends AbstractPreferenceInitializer {
34     public final static String PREFS_SDK_DIR = AdtPlugin.PLUGIN_ID + ".sdk"; //$NON-NLS-1$
35 
36     public final static String PREFS_BUILD_RES_AUTO_REFRESH = AdtPlugin.PLUGIN_ID + ".resAutoRefresh"; //$NON-NLS-1$
37 
38     public final static String PREFS_BUILD_FORCE_ERROR_ON_NATIVELIB_IN_JAR = AdtPlugin.PLUGIN_ID + ".forceErrorNativeLibInJar"; //$NON-NLS-1$
39 
40     public final static String PREFS_BUILD_SKIP_POST_COMPILE_ON_FILE_SAVE = AdtPlugin.PLUGIN_ID + ".skipPostCompileOnFileSave"; //$NON-NLS-1$
41 
42     public final static String PREFS_BUILD_VERBOSITY = AdtPlugin.PLUGIN_ID + ".buildVerbosity"; //$NON-NLS-1$
43 
44     public final static String PREFS_DEFAULT_DEBUG_KEYSTORE = AdtPlugin.PLUGIN_ID + ".defaultDebugKeyStore"; //$NON-NLS-1$
45 
46     public final static String PREFS_CUSTOM_DEBUG_KEYSTORE = AdtPlugin.PLUGIN_ID + ".customDebugKeyStore"; //$NON-NLS-1$
47 
48     public final static String PREFS_HOME_PACKAGE = AdtPlugin.PLUGIN_ID + ".homePackage"; //$NON-NLS-1$
49 
50     public final static String PREFS_EMU_OPTIONS = AdtPlugin.PLUGIN_ID + ".emuOptions"; //$NON-NLS-1$
51 
52     public final static String PREFS_MONITOR_DENSITY = AdtPlugin.PLUGIN_ID + ".monitorDensity"; //$NON-NLS-1$
53 
54     public final static String PREFS_FORMAT_GUI_XML = AdtPlugin.PLUGIN_ID + ".formatXml"; //$NON-NLS-1$
55     public final static String PREFS_USE_CUSTOM_XML_FORMATTER = AdtPlugin.PLUGIN_ID + ".androidForm"; //$NON-NLS-1$
56 
57     public final static String PREFS_PALETTE_MODE = AdtPlugin.PLUGIN_ID + ".palette"; //$NON-NLS-1$
58 
59     public final static String PREFS_USE_ECLIPSE_INDENT = AdtPlugin.PLUGIN_ID + ".eclipseIndent"; //$NON-NLS-1$
60     public final static String PREVS_REMOVE_EMPTY_LINES = AdtPlugin.PLUGIN_ID + ".removeEmpty"; //$NON-NLS-1$
61     public final static String PREFS_ONE_ATTR_PER_LINE = AdtPlugin.PLUGIN_ID + ".oneAttrPerLine"; //$NON-NLS-1$
62     public final static String PREFS_SPACE_BEFORE_CLOSE = AdtPlugin.PLUGIN_ID + ".spaceBeforeClose"; //$NON-NLS-1$
63     public final static String PREFS_FORMAT_ON_SAVE = AdtPlugin.PLUGIN_ID + ".formatOnSave"; //$NON-NLS-1$
64     public final static String PREFS_LINT_ON_SAVE = AdtPlugin.PLUGIN_ID + ".lintOnSave"; //$NON-NLS-1$
65     public final static String PREFS_LINT_ON_EXPORT = AdtPlugin.PLUGIN_ID + ".lintOnExport"; //$NON-NLS-1$
66     public final static String PREFS_ATTRIBUTE_SORT = AdtPlugin.PLUGIN_ID + ".attrSort"; //$NON-NLS-1$
67     public final static String PREFS_LINT_SEVERITIES = AdtPlugin.PLUGIN_ID + ".lintSeverities"; //$NON-NLS-1$
68     public final static String PREFS_FIX_LEGACY_EDITORS = AdtPlugin.PLUGIN_ID + ".fixLegacyEditors"; //$NON-NLS-1$
69 
70     /** singleton instance */
71     private final static AdtPrefs sThis = new AdtPrefs();
72 
73     /** default store, provided by eclipse */
74     private IPreferenceStore mStore;
75 
76     /** cached location for the sdk folder */
77     private String mOsSdkLocation;
78 
79     /** Verbosity of the build */
80     private BuildVerbosity mBuildVerbosity = BuildVerbosity.NORMAL;
81 
82     private boolean mBuildForceResResfresh = false;
83     private boolean mBuildForceErrorOnNativeLibInJar = true;
84     private boolean mBuildSkipPostCompileOnFileSave = true;
85     private float mMonitorDensity = 0.f;
86     private String mPalette;
87 
88     private boolean mFormatGuiXml;
89     private boolean mCustomXmlFormatter;
90     private boolean mUseEclipseIndent;
91     private boolean mRemoveEmptyLines;
92     private boolean mOneAttributeOnFirstLine;
93     private boolean mSpaceBeforeClose;
94     private boolean mFormatOnSave;
95     private boolean mLintOnSave;
96     private boolean mLintOnExport;
97     private AttributeSortOrder mAttributeSort;
98 
99     public static enum BuildVerbosity {
100         /** Build verbosity "Always". Those messages are always displayed, even in silent mode */
101         ALWAYS(0),
102         /** Build verbosity level "Normal" */
103         NORMAL(1),
104         /** Build verbosity level "Verbose". Those messages are only displayed in verbose mode */
105         VERBOSE(2);
106 
107         private int mLevel;
108 
BuildVerbosity(int level)109         BuildVerbosity(int level) {
110             mLevel = level;
111         }
112 
getLevel()113         public int getLevel() {
114             return mLevel;
115         }
116 
117         /**
118          * Finds and returns a {@link BuildVerbosity} whose {@link #name()} matches a given name.
119          * <p/>This is different from {@link Enum#valueOf(Class, String)} in that it returns null
120          * if no matches are found.
121          *
122          * @param name the name to look up.
123          * @return returns the matching enum or null of no match where found.
124          */
find(String name)125         public static BuildVerbosity find(String name) {
126             for (BuildVerbosity v : values()) {
127                 if (v.name().equals(name)) {
128                     return v;
129                 }
130             }
131 
132             return null;
133         }
134     }
135 
init(IPreferenceStore preferenceStore)136     public static void init(IPreferenceStore preferenceStore) {
137         sThis.mStore = preferenceStore;
138     }
139 
getPrefs()140     public static AdtPrefs getPrefs() {
141         return sThis;
142     }
143 
loadValues(PropertyChangeEvent event)144     public synchronized void loadValues(PropertyChangeEvent event) {
145         // get the name of the property that changed, if any
146         String property = event != null ? event.getProperty() : null;
147 
148         if (property == null || PREFS_SDK_DIR.equals(property)) {
149             mOsSdkLocation = mStore.getString(PREFS_SDK_DIR);
150 
151             // Make it possible to override the SDK path using an environment variable.
152             // The value will only be used if it matches an existing directory.
153             // Useful for testing from Eclipse.
154             // Note: this is a hack that does not change the preferences, so if the user
155             // looks at Window > Preferences > Android, the path will be the preferences
156             // one and not the overridden one.
157             String override = System.getenv("ADT_TEST_SDK_PATH");   //$NON-NLS-1$
158             if (override != null && override.length() > 0 && new File(override).isDirectory()) {
159                 mOsSdkLocation = override;
160             }
161 
162             // make sure it ends with a separator. Normally this is done when the preference
163             // is set. But to make sure older version still work, we fix it here as well.
164             if (mOsSdkLocation.length() > 0 && mOsSdkLocation.endsWith(File.separator) == false) {
165                 mOsSdkLocation = mOsSdkLocation + File.separator;
166             }
167         }
168 
169         if (property == null || PREFS_BUILD_VERBOSITY.equals(property)) {
170             mBuildVerbosity = BuildVerbosity.find(mStore.getString(PREFS_BUILD_VERBOSITY));
171             if (mBuildVerbosity == null) {
172                 mBuildVerbosity = BuildVerbosity.NORMAL;
173             }
174         }
175 
176         if (property == null || PREFS_BUILD_RES_AUTO_REFRESH.equals(property)) {
177             mBuildForceResResfresh = mStore.getBoolean(PREFS_BUILD_RES_AUTO_REFRESH);
178         }
179 
180         if (property == null || PREFS_BUILD_FORCE_ERROR_ON_NATIVELIB_IN_JAR.equals(property)) {
181             mBuildForceErrorOnNativeLibInJar =
182                     mStore.getBoolean(PREFS_BUILD_FORCE_ERROR_ON_NATIVELIB_IN_JAR);
183         }
184 
185         if (property == null || PREFS_BUILD_SKIP_POST_COMPILE_ON_FILE_SAVE.equals(property)) {
186             mBuildSkipPostCompileOnFileSave =
187                 mStore.getBoolean(PREFS_BUILD_SKIP_POST_COMPILE_ON_FILE_SAVE);
188         }
189 
190         if (property == null || PREFS_MONITOR_DENSITY.equals(property)) {
191             mMonitorDensity = mStore.getFloat(PREFS_MONITOR_DENSITY);
192         }
193 
194         if (property == null || PREFS_FORMAT_GUI_XML.equals(property)) {
195             mFormatGuiXml = mStore.getBoolean(PREFS_FORMAT_GUI_XML);
196         }
197 
198         if (property == null || PREFS_USE_CUSTOM_XML_FORMATTER.equals(property)) {
199             mCustomXmlFormatter = mStore.getBoolean(PREFS_USE_CUSTOM_XML_FORMATTER);
200         }
201 
202         if (property == null || PREFS_PALETTE_MODE.equals(property)) {
203             mPalette = mStore.getString(PREFS_PALETTE_MODE);
204         }
205 
206         if (property == null || PREFS_USE_ECLIPSE_INDENT.equals(property)) {
207             mUseEclipseIndent = mStore.getBoolean(PREFS_USE_ECLIPSE_INDENT);
208         }
209 
210         if (property == null || PREVS_REMOVE_EMPTY_LINES.equals(property)) {
211             mRemoveEmptyLines = mStore.getBoolean(PREVS_REMOVE_EMPTY_LINES);
212         }
213 
214         if (property == null || PREFS_ONE_ATTR_PER_LINE.equals(property)) {
215             mOneAttributeOnFirstLine = mStore.getBoolean(PREFS_ONE_ATTR_PER_LINE);
216         }
217 
218         if (property == null || PREFS_ATTRIBUTE_SORT.equals(property)) {
219             String order = mStore.getString(PREFS_ATTRIBUTE_SORT);
220             mAttributeSort = AttributeSortOrder.LOGICAL;
221             if (AttributeSortOrder.ALPHABETICAL.key.equals(order)) {
222                 mAttributeSort = AttributeSortOrder.ALPHABETICAL;
223             } else if (AttributeSortOrder.NO_SORTING.key.equals(order)) {
224                 mAttributeSort = AttributeSortOrder.NO_SORTING;
225             }
226         }
227 
228         if (property == null || PREFS_SPACE_BEFORE_CLOSE.equals(property)) {
229             mSpaceBeforeClose = mStore.getBoolean(PREFS_SPACE_BEFORE_CLOSE);
230         }
231 
232         if (property == null || PREFS_FORMAT_ON_SAVE.equals(property)) {
233             mFormatOnSave = mStore.getBoolean(PREFS_FORMAT_ON_SAVE);
234         }
235 
236         if (property == null || PREFS_LINT_ON_SAVE.equals(property)) {
237             mLintOnSave = mStore.getBoolean(PREFS_LINT_ON_SAVE);
238         }
239 
240         if (property == null || PREFS_LINT_ON_EXPORT.equals(property)) {
241             mLintOnExport = mStore.getBoolean(PREFS_LINT_ON_EXPORT);
242         }
243     }
244 
245     /**
246      * Returns the SDK folder.
247      * Guaranteed to be terminated by a platform-specific path separator.
248      */
getOsSdkFolder()249     public synchronized String getOsSdkFolder() {
250         return mOsSdkLocation;
251     }
252 
getBuildVerbosity()253     public synchronized BuildVerbosity getBuildVerbosity() {
254         return mBuildVerbosity;
255     }
256 
getBuildForceResResfresh()257     public boolean getBuildForceResResfresh() {
258         return mBuildForceResResfresh;
259     }
260 
261     /**
262      * Should changes made by GUI editors automatically format the corresponding XML nodes
263      * affected by the edit?
264      *
265      * @return true if the GUI editors should format affected XML regions
266      */
getFormatGuiXml()267     public boolean getFormatGuiXml() {
268         // The format-GUI-editors flag only applies when the custom formatter is used,
269         // since the built-in formatter has problems editing partial documents
270         return mFormatGuiXml && mCustomXmlFormatter;
271     }
272 
273     /**
274      * Should the XML formatter use a custom Android XML formatter (following
275      * Android code style) or use the builtin Eclipse XML formatter?
276      *
277      * @return true if the Android formatter should be used instead of the
278      *         default Eclipse one
279      */
getUseCustomXmlFormatter()280     public boolean getUseCustomXmlFormatter() {
281         return mCustomXmlFormatter;
282     }
283 
284     /**
285      * Should the Android XML formatter use the Eclipse XML indentation settings
286      * (usually one tab character) instead of the default 4 space character
287      * indent?
288      *
289      * @return true if the Eclipse XML indentation settings should be use
290      */
isUseEclipseIndent()291     public boolean isUseEclipseIndent() {
292         return mUseEclipseIndent;
293     }
294 
295     /**
296      * Should the Android XML formatter try to avoid inserting blank lines to
297      * make the format as compact as possible (no blank lines between elements,
298      * no blank lines surrounding comments, etc).
299      *
300      * @return true to remove blank lines
301      */
isRemoveEmptyLines()302     public boolean isRemoveEmptyLines() {
303         return mRemoveEmptyLines;
304     }
305 
306     /**
307      * Should the Android XML formatter attempt to place a single attribute on
308      * the same line as the element open tag?
309      *
310      * @return true if single-attribute elements should place the attribute on
311      *         the same line as the element open tag
312      */
isOneAttributeOnFirstLine()313     public boolean isOneAttributeOnFirstLine() {
314         return mOneAttributeOnFirstLine;
315     }
316 
317     /**
318      * Returns the sort order to be applied to the attributes (one of which can
319      * be {@link AttributeSortOrder#NO_SORTING}).
320      *
321      * @return the sort order to apply to the attributes
322      */
getAttributeSort()323     public AttributeSortOrder getAttributeSort() {
324         if (mAttributeSort == null) {
325             return AttributeSortOrder.LOGICAL;
326         }
327         return mAttributeSort;
328     }
329 
330     /**
331      * Returns whether a space should be inserted before the closing {@code >}
332      * character in open tags and before the closing {@code />} characters in
333      * empty tag. Note that the {@link XmlFormatStyle#RESOURCE} style overrides
334      * this setting to make it more compact for the {@code <item>} elements.
335      *
336      * @return true if an empty space should be inserted before {@code >} or
337      *         {@code />}.
338      */
isSpaceBeforeClose()339     public boolean isSpaceBeforeClose() {
340         return mSpaceBeforeClose;
341     }
342 
343     /**
344      * Returns whether the file should be automatically formatted on save.
345      *
346      * @return true if the XML files should be formatted on save.
347      */
isFormatOnSave()348     public boolean isFormatOnSave() {
349         return mFormatOnSave;
350     }
351 
isLintOnSave()352     public boolean isLintOnSave() {
353         return mLintOnSave;
354     }
355 
setLintOnSave(boolean on)356     public void setLintOnSave(boolean on) {
357         mLintOnSave = on;
358         IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
359         store.setValue(PREFS_LINT_ON_SAVE, on);
360     }
361 
isLintOnExport()362     public boolean isLintOnExport() {
363         return mLintOnExport;
364     }
365 
setLintOnExport(boolean on)366     public void setLintOnExport(boolean on) {
367         mLintOnExport = on;
368         IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
369         store.setValue(PREFS_LINT_ON_EXPORT, on);
370     }
371 
getBuildForceErrorOnNativeLibInJar()372     public boolean getBuildForceErrorOnNativeLibInJar() {
373         return mBuildForceErrorOnNativeLibInJar;
374     }
375 
getBuildSkipPostCompileOnFileSave()376     public boolean getBuildSkipPostCompileOnFileSave() {
377         return mBuildSkipPostCompileOnFileSave;
378     }
379 
getPaletteModes()380     public String getPaletteModes() {
381         return mPalette;
382     }
383 
setPaletteModes(String palette)384     public void setPaletteModes(String palette) {
385         mPalette = palette;
386 
387         // need to save this new value to the store
388         IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
389         store.setValue(PREFS_PALETTE_MODE, palette);
390     }
391 
getMonitorDensity()392     public float getMonitorDensity() {
393         return mMonitorDensity;
394     }
395 
setMonitorDensity(float density)396     public void setMonitorDensity(float density) {
397         mMonitorDensity = density;
398 
399         // need to save this new value to the store
400         IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
401         store.setValue(PREFS_MONITOR_DENSITY, density);
402     }
403 
404     /**
405      * Sets the new location of the SDK
406      *
407      * @param location the location of the SDK
408      */
setSdkLocation(File location)409     public void setSdkLocation(File location) {
410         mOsSdkLocation = location != null ? location.getPath() : null;
411 
412         // TODO: Also store this location in the .android settings directory
413         // such that we can support using multiple workspaces without asking
414         // over and over.
415         if (mOsSdkLocation != null && mOsSdkLocation.length() > 0) {
416             DdmsPreferenceStore ddmsStore = new DdmsPreferenceStore();
417             ddmsStore.setLastSdkPath(mOsSdkLocation);
418         }
419 
420         // need to save this new value to the store
421         IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
422         store.setValue(PREFS_SDK_DIR, mOsSdkLocation);
423     }
424 
425     @Override
initializeDefaultPreferences()426     public void initializeDefaultPreferences() {
427         IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
428         initializeStoreWithDefaults(store);
429     }
430 
initializeStoreWithDefaults(IPreferenceStore store)431     public void initializeStoreWithDefaults(IPreferenceStore store) {
432         store.setDefault(PREFS_BUILD_RES_AUTO_REFRESH, true);
433         store.setDefault(PREFS_BUILD_FORCE_ERROR_ON_NATIVELIB_IN_JAR, true);
434         store.setDefault(PREFS_BUILD_SKIP_POST_COMPILE_ON_FILE_SAVE, true);
435 
436         store.setDefault(PREFS_BUILD_VERBOSITY, BuildVerbosity.ALWAYS.name());
437 
438         store.setDefault(PREFS_HOME_PACKAGE, "android.process.acore"); //$NON-NLS-1$
439 
440         store.setDefault(PREFS_MONITOR_DENSITY, 0.f);
441 
442         store.setDefault(PREFS_FORMAT_GUI_XML, true);
443         store.setDefault(PREFS_USE_CUSTOM_XML_FORMATTER, true);
444         store.setDefault(PREFS_ONE_ATTR_PER_LINE, true);
445         store.setDefault(PREFS_SPACE_BEFORE_CLOSE, true);
446         store.setDefault(PREFS_LINT_ON_SAVE, true);
447         store.setDefault(PREFS_LINT_ON_EXPORT, true);
448 
449         // Defaults already handled; no need to write into map:
450         //store.setDefault(PREFS_ATTRIBUTE_SORT, AttributeSortOrder.LOGICAL.key);
451         //store.setDefault(PREFS_USE_ECLIPSE_INDENT, false);
452         //store.setDefault(PREVS_REMOVE_EMPTY_LINES, false);
453         //store.setDefault(PREFS_FORMAT_ON_SAVE, false);
454 
455         try {
456             store.setDefault(PREFS_DEFAULT_DEBUG_KEYSTORE,
457                     DebugKeyProvider.getDefaultKeyStoreOsPath());
458         } catch (KeytoolException e) {
459             AdtPlugin.log(e, "Get default debug keystore path failed"); //$NON-NLS-1$
460         } catch (AndroidLocationException e) {
461             AdtPlugin.log(e, "Get default debug keystore path failed"); //$NON-NLS-1$
462         }
463     }
464 }
465