2 * Copyright 2000-2015 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.ide.ui;
18 import com.intellij.ide.WelcomeWizardUtil;
19 import com.intellij.openapi.Disposable;
20 import com.intellij.openapi.application.Application;
21 import com.intellij.openapi.application.ApplicationManager;
22 import com.intellij.openapi.components.*;
23 import com.intellij.openapi.util.Pair;
24 import com.intellij.openapi.util.SimpleModificationTracker;
25 import com.intellij.openapi.util.SystemInfo;
26 import com.intellij.util.EventDispatcher;
27 import com.intellij.util.PlatformUtils;
28 import com.intellij.util.SystemProperties;
29 import com.intellij.util.ui.UIUtil;
30 import com.intellij.util.xmlb.Accessor;
31 import com.intellij.util.xmlb.SerializationFilter;
32 import com.intellij.util.xmlb.XmlSerializerUtil;
33 import com.intellij.util.xmlb.annotations.Property;
34 import com.intellij.util.xmlb.annotations.Transient;
35 import org.jetbrains.annotations.NonNls;
36 import org.jetbrains.annotations.NotNull;
42 import static com.intellij.util.ui.UIUtil.isValidFont;
46 storages = @Storage(file = StoragePathMacros.APP_CONFIG + "/ui.lnf.xml")
48 public class UISettings extends SimpleModificationTracker implements PersistentStateComponent<UISettings> {
49 /** Not tabbed pane. */
50 public static final int TABS_NONE = 0;
52 public static UISettings getInstance() {
53 return ServiceManager.getService(UISettings.class);
57 * Use this method if you are not sure whether the application is initialized.
58 * @return persisted UISettings instance or default values.
60 public static UISettings getShadowInstance() {
61 Application application = ApplicationManager.getApplication();
62 UISettings settings = application == null ? null : getInstance();
63 return settings == null ? new UISettings() : settings;
66 @Property(filter = FontFilter.class) public String FONT_FACE;
67 @Property(filter = FontFilter.class) public int FONT_SIZE;
68 public int RECENT_FILES_LIMIT = 50;
69 public int CONSOLE_COMMAND_HISTORY_LIMIT = 300;
70 public boolean OVERRIDE_CONSOLE_CYCLE_BUFFER_SIZE = false;
71 public int CONSOLE_CYCLE_BUFFER_SIZE_KB = 1024;
72 public int EDITOR_TAB_LIMIT = 10;
73 public boolean REUSE_NOT_MODIFIED_TABS = false;
74 public boolean ANIMATE_WINDOWS = true;
75 @Deprecated //todo remove in IDEA 16
76 public int ANIMATION_SPEED = 4000; // Pixels per second
77 public int ANIMATION_DURATION = 300; // Milliseconds
78 public boolean SHOW_TOOL_WINDOW_NUMBERS = true;
79 public boolean HIDE_TOOL_STRIPES = true;
80 public boolean WIDESCREEN_SUPPORT = false;
81 public boolean LEFT_HORIZONTAL_SPLIT = false;
82 public boolean RIGHT_HORIZONTAL_SPLIT = false;
83 public boolean SHOW_EDITOR_TOOLTIP = true;
84 public boolean SHOW_MEMORY_INDICATOR = false;
85 public boolean ALLOW_MERGE_BUTTONS = true;
86 public boolean SHOW_MAIN_TOOLBAR = false;
87 public boolean SHOW_STATUS_BAR = true;
88 public boolean SHOW_NAVIGATION_BAR = true;
89 public boolean ALWAYS_SHOW_WINDOW_BUTTONS = false;
90 public boolean CYCLE_SCROLLING = true;
91 public boolean SCROLL_TAB_LAYOUT_IN_EDITOR = true;
92 public boolean HIDE_TABS_IF_NEED = true;
93 public boolean SHOW_CLOSE_BUTTON = true;
94 public int EDITOR_TAB_PLACEMENT = 1;
95 public boolean HIDE_KNOWN_EXTENSION_IN_TABS = false;
96 public boolean SHOW_ICONS_IN_QUICK_NAVIGATION = true;
97 public boolean CLOSE_NON_MODIFIED_FILES_FIRST = false;
98 public boolean ACTIVATE_MRU_EDITOR_ON_CLOSE = false;
99 public boolean ACTIVATE_RIGHT_EDITOR_ON_CLOSE = false;
101 public boolean ANTIALIASING_IN_EDITOR = true;
102 public boolean ANTIALIASING_IN_IDE = ANTIALIASING_IN_EDITOR;
103 public LCDRenderingScope LCD_RENDERING_SCOPE = UIUtil.isRetina() ? LCDRenderingScope.OFF : LCDRenderingScope.IDE;
104 public boolean USE_LCD_RENDERING_IN_EDITOR = true;
105 public boolean MOVE_MOUSE_ON_DEFAULT_BUTTON = false;
106 public boolean ENABLE_ALPHA_MODE = false;
107 public int ALPHA_MODE_DELAY = 1500;
108 public float ALPHA_MODE_RATIO = 0.5f;
109 public int MAX_CLIPBOARD_CONTENTS = 5;
110 public boolean OVERRIDE_NONIDEA_LAF_FONTS = false;
111 public boolean SHOW_ICONS_IN_MENUS = true;
112 public boolean DISABLE_MNEMONICS = SystemInfo.isMac; // IDEADEV-33409, should be disabled by default on MacOS
113 public boolean DISABLE_MNEMONICS_IN_CONTROLS = false;
114 public boolean USE_SMALL_LABELS_ON_TABS = SystemInfo.isMac;
115 public boolean SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = false;
116 public int MAX_LOOKUP_WIDTH2 = 500;
117 public int MAX_LOOKUP_LIST_HEIGHT = 11;
118 public boolean HIDE_NAVIGATION_ON_FOCUS_LOSS = true;
119 public boolean DND_WITH_PRESSED_ALT_ONLY = false;
120 public boolean FILE_COLORS_IN_PROJECT_VIEW = false;
121 public boolean DEFAULT_AUTOSCROLL_TO_SOURCE = false;
123 public boolean PRESENTATION_MODE = false;
124 public int PRESENTATION_MODE_FONT_SIZE = 24;
125 public boolean MARK_MODIFIED_TABS_WITH_ASTERISK = false;
126 public boolean SHOW_TABS_TOOLTIPS = true;
127 public boolean SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES = true;
128 public boolean NAVIGATE_TO_PREVIEW = false;
129 public boolean SORT_BOOKMARKS = false;
131 private final EventDispatcher<UISettingsListener> myDispatcher = EventDispatcher.create(UISettingsListener.class);
133 public UISettings() {
134 tweakPlatformDefaults();
135 setSystemFontFaceAndSize();
137 Boolean scrollToSource = WelcomeWizardUtil.getAutoScrollToSource();
138 if (scrollToSource != null) {
139 DEFAULT_AUTOSCROLL_TO_SOURCE = scrollToSource;
143 private void tweakPlatformDefaults() {
144 // TODO[anton] consider making all IDEs use the same settings
145 if (PlatformUtils.isAppCode()) {
146 SCROLL_TAB_LAYOUT_IN_EDITOR = true;
147 ACTIVATE_RIGHT_EDITOR_ON_CLOSE = true;
148 SHOW_ICONS_IN_MENUS = false;
153 * @deprecated use {@link UISettings#addUISettingsListener(com.intellij.ide.ui.UISettingsListener, Disposable disposable)} instead.
155 public void addUISettingsListener(UISettingsListener listener) {
156 myDispatcher.addListener(listener);
159 public void addUISettingsListener(@NotNull final UISettingsListener listener, @NotNull Disposable parentDisposable) {
160 myDispatcher.addListener(listener, parentDisposable);
164 * Notifies all registered listeners that UI settings has been changed.
166 public void fireUISettingsChanged() {
167 incModificationCount();
168 myDispatcher.getMulticaster().uiSettingsChanged(this);
169 ApplicationManager.getApplication().getMessageBus().syncPublisher(UISettingsListener.TOPIC).uiSettingsChanged(this);
172 public void removeUISettingsListener(UISettingsListener listener) {
173 myDispatcher.removeListener(listener);
176 private void setSystemFontFaceAndSize() {
177 if (FONT_FACE == null || FONT_SIZE <= 0) {
178 final Pair<String, Integer> fontData = getSystemFontFaceAndSize();
179 FONT_FACE = fontData.first;
180 FONT_SIZE = fontData.second;
184 private static Pair<String, Integer> getSystemFontFaceAndSize() {
185 final Pair<String,Integer> fontData = UIUtil.getSystemFontData();
186 if (fontData != null) {
190 return Pair.create("Dialog", 12);
193 public static class FontFilter implements SerializationFilter {
195 public boolean accepts(@NotNull Accessor accessor, @NotNull Object bean) {
196 UISettings settings = (UISettings)bean;
197 return !hasDefaultFontSetting(settings);
201 private static boolean hasDefaultFontSetting(final UISettings settings) {
202 final Pair<String, Integer> fontData = getSystemFontFaceAndSize();
203 return fontData.first.equals(settings.FONT_FACE) && fontData.second.equals(settings.FONT_SIZE);
207 public UISettings getState() {
212 public void loadState(UISettings object) {
213 XmlSerializerUtil.copyBean(object, this);
215 // Check tab placement in editor
216 if (EDITOR_TAB_PLACEMENT != TABS_NONE &&
217 EDITOR_TAB_PLACEMENT != SwingConstants.TOP &&
218 EDITOR_TAB_PLACEMENT != SwingConstants.LEFT &&
219 EDITOR_TAB_PLACEMENT != SwingConstants.BOTTOM &&
220 EDITOR_TAB_PLACEMENT != SwingConstants.RIGHT) {
221 EDITOR_TAB_PLACEMENT = SwingConstants.TOP;
224 // Check that alpha delay and ratio are valid
225 if (ALPHA_MODE_DELAY < 0) {
226 ALPHA_MODE_DELAY = 1500;
228 if (ALPHA_MODE_RATIO < 0.0f || ALPHA_MODE_RATIO > 1.0f) {
229 ALPHA_MODE_RATIO = 0.5f;
232 setSystemFontFaceAndSize();
233 // 1. Sometimes system font cannot display standard ASCII symbols. If so we have
234 // find any other suitable font withing "preferred" fonts first.
235 boolean fontIsValid = isValidFont(new Font(FONT_FACE, Font.PLAIN, FONT_SIZE));
237 @NonNls final String[] preferredFonts = {"dialog", "Arial", "Tahoma"};
238 for (String preferredFont : preferredFonts) {
239 if (isValidFont(new Font(preferredFont, Font.PLAIN, FONT_SIZE))) {
240 FONT_FACE = preferredFont;
246 // 2. If all preferred fonts are not valid in current environment
247 // we have to find first valid font (if any)
249 String[] fontNames = UIUtil.getValidFontNames(false);
250 if (fontNames.length > 0) {
251 FONT_FACE = fontNames[0];
256 if (MAX_CLIPBOARD_CONTENTS <= 0) {
257 MAX_CLIPBOARD_CONTENTS = 5;
260 fireUISettingsChanged();
263 public static final boolean FORCE_USE_FRACTIONAL_METRICS =
264 SystemProperties.getBooleanProperty("idea.force.use.fractional.metrics", false);
266 public static void setupFractionalMetrics(final Graphics2D g2d) {
267 if (FORCE_USE_FRACTIONAL_METRICS) {
268 g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
272 /* This method must not be used for set up antialiasing for editor components
274 public static void setupAntialiasing(final Graphics g) {
276 Application application = ApplicationManager.getApplication();
277 if (application == null) {
278 // We cannot use services while Aplication has not been loaded yet
279 // So let's apply the default hints.
280 UIUtil.applyRenderingHints(g);
284 Graphics2D g2d = (Graphics2D)g;
285 UISettings uiSettings = getInstance();
287 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
289 if (uiSettings != null) {
290 g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, LCDRenderingScope.getKeyForCurrentScope(false));
292 g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
295 setupFractionalMetrics(g2d);
299 * @return true when Remote Desktop (i.e. Windows RDP) is connected
301 // TODO[neuro]: move to UIUtil
302 public static boolean isRemoteDesktopConnected() {
303 if (System.getProperty("os.name").contains("Windows")) {
304 final Map map = (Map)Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints");
305 return map != null && RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT.equals(map.get(RenderingHints.KEY_TEXT_ANTIALIASING));