/** * Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ /* * Created on May 5, 2005 * * @author Fabio Zadrozny */ package org.python.pydev.editor.autoedit; import org.eclipse.core.runtime.IAdaptable; import org.python.pydev.core.IIndentPrefs; import org.python.pydev.core.ITabChangedListener; import org.python.pydev.editor.preferences.PyScopedPreferences; import org.python.pydev.editor.preferences.PydevEditorPrefs; import org.python.pydev.editor.preferences.PydevTypingPrefs; import org.python.pydev.plugin.preferences.AbstractPydevPrefs; import org.python.pydev.shared_core.SharedCorePlugin; import org.python.pydev.shared_core.callbacks.ListenerList; /** * Provides indentation preferences from the preferences set in the preferences pages within eclipse. */ public class DefaultIndentPrefs extends AbstractIndentPrefs { /** * Cache for indentation string */ private String indentString = null; private String lastIndentString = null; private boolean lastUseSpaces; private int lastTabWidth; private final IAdaptable projectAdaptable; /** * Singleton instance for the preferences */ private static IIndentPrefs indentPrefs; private ListenerList<ITabChangedListener> listenerList = new ListenerList<>(ITabChangedListener.class); @Override public void addTabChangedListener(ITabChangedListener listener) { listenerList.add(listener); } /** * Should only be used on tests (and on a finally it should be set to null again in the test). */ public synchronized static void set(IIndentPrefs indentPrefs) { DefaultIndentPrefs.indentPrefs = indentPrefs; } /** * @param an IAdaptable which must adapt to IProject. * @return the indentation preferences to be used */ public static IIndentPrefs get(IAdaptable projectAdaptable) { if (indentPrefs != null) { return indentPrefs; } if (SharedCorePlugin.inTestMode()) { return new TestIndentPrefs(true, 4); } return new DefaultIndentPrefs(projectAdaptable); } /** * Not singleton (each pyedit may force to use tabs or not). */ public DefaultIndentPrefs(IAdaptable projectAdaptable) { this.projectAdaptable = projectAdaptable; lastUseSpaces = getBoolFromPreferences(PydevEditorPrefs.SUBSTITUTE_TABS); regenerateIndentString(); } @Override public boolean getUseSpaces(boolean considerForceTabs) { boolean boolFromPreferences = getBoolFromPreferences(PydevEditorPrefs.SUBSTITUTE_TABS); if (lastUseSpaces != boolFromPreferences) { lastUseSpaces = boolFromPreferences; regenerateIndentString(); } if (considerForceTabs && getForceTabs()) { return false; //forcing tabs. } return lastUseSpaces; } @Override public void setForceTabs(boolean forceTabs) { super.setForceTabs(forceTabs); regenerateIndentString(); //When forcing tabs, we must update the cache. } @Override public int getTabWidth() { if (lastTabWidth != getIntFromPreferences(PydevEditorPrefs.TAB_WIDTH, 1)) { lastTabWidth = getIntFromPreferences(PydevEditorPrefs.TAB_WIDTH, 1); regenerateIndentString(); } return lastTabWidth; } Boolean lastGuessTabSubstitution = null; @Override public boolean getGuessTabSubstitution() { boolean curr = getBoolFromPreferences(PydevEditorPrefs.GUESS_TAB_SUBSTITUTION); if (lastGuessTabSubstitution != null && lastGuessTabSubstitution != curr) { regenerateIndentString(); } lastGuessTabSubstitution = curr; return curr; } @Override public void regenerateIndentString() { indentString = super.getIndentationString(); if (lastIndentString == null || !lastIndentString.equals(indentString)) { lastIndentString = indentString; ITabChangedListener[] listeners = this.listenerList.getListeners(); for (ITabChangedListener iTabChangedListener : listeners) { iTabChangedListener.onTabSettingsChanged(this); } } } /** * This class also puts the indentation string in a cache and redoes it * if the preferences are changed. * * @return the indentation string. */ @Override public String getIndentationString() { return indentString; } /** * @see org.python.pydev.core.IIndentPrefs#getAutoParentesis() */ @Override public boolean getAutoParentesis() { return getBoolFromPreferences(PydevTypingPrefs.AUTO_PAR); } @Override public boolean getAutoLink() { return getBoolFromPreferences(PydevTypingPrefs.AUTO_LINK); } @Override public boolean getIndentToParLevel() { return getBoolFromPreferences(PydevTypingPrefs.AUTO_INDENT_TO_PAR_LEVEL); } @Override public boolean getAutoColon() { return getBoolFromPreferences(PydevTypingPrefs.AUTO_COLON); } @Override public boolean getAutoBraces() { return getBoolFromPreferences(PydevTypingPrefs.AUTO_BRACES); } @Override public boolean getAutoWriteImport() { return getBoolFromPreferences(PydevTypingPrefs.AUTO_WRITE_IMPORT_STR); } @Override public boolean getSmartIndentPar() { return getBoolFromPreferences(PydevTypingPrefs.SMART_INDENT_PAR); } @Override public boolean getIndentToParAsPep8() { return getBoolFromPreferences(PydevTypingPrefs.INDENT_AFTER_PAR_AS_PEP8); } @Override public boolean getAutoAddSelf() { return getBoolFromPreferences(PydevTypingPrefs.AUTO_ADD_SELF); } @Override public boolean getAutoDedentElse() { return getBoolFromPreferences(PydevTypingPrefs.AUTO_DEDENT_ELSE); } @Override public int getIndentAfterParWidth() { return getIntFromPreferences(PydevTypingPrefs.AUTO_INDENT_AFTER_PAR_WIDTH, 1); } @Override public boolean getSmartLineMove() { return getBoolFromPreferences(PydevTypingPrefs.SMART_LINE_MOVE); } @Override public boolean getAutoLiterals() { return getBoolFromPreferences(PydevTypingPrefs.AUTO_LITERALS); } @Override public boolean getTabStopInComment() { return getBoolFromPreferences(AbstractPydevPrefs.TAB_STOP_IN_COMMENT); } private boolean getBoolFromPreferences(String pref) { return PyScopedPreferences.getBoolean(pref, projectAdaptable); } private int getIntFromPreferences(String pref, int minVal) { return PyScopedPreferences.getInt(pref, projectAdaptable, minVal); } }