continue WEB-2093: reference by id

This commit is contained in:
Vladimir Krivosheev
2014-01-05 20:17:03 +01:00
parent 1b1bd74c46
commit a848ce57bb
14 changed files with 393 additions and 532 deletions
@@ -18,9 +18,9 @@ package com.intellij.ide.browsers;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.util.ArrayUtil;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.Nullable;
@@ -77,7 +77,7 @@ public class BrowserSelector {
}
activeBrowsers.addAll(WebBrowserManager.getInstance().getActiveBrowsers());
//noinspection unchecked
myBrowserComboWithBrowse.getComboBox().setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(activeBrowsers)));
myBrowserComboWithBrowse.getComboBox().setModel(new CollectionComboBoxModel(activeBrowsers));
}
@SuppressWarnings({"deprecation", "UnusedDeclaration"})
@@ -97,9 +97,9 @@ public class BrowserSelector {
}
@Nullable
public String getSelectedBrowserFamilyName() {
public String getSelectedBrowserId() {
WebBrowser browser = getSelected();
return browser != null ? browser.getName() : null;
return browser != null ? browser.getId().toString() : null;
}
@SuppressWarnings("UnusedDeclaration")
@@ -108,7 +108,7 @@ public class BrowserSelector {
* @deprecated to remove in IDEA 14
*/
public void setSelectedBrowser(@SuppressWarnings("deprecation") @Nullable BrowsersConfiguration.BrowserFamily selectedItem) {
setSelected(selectedItem == null ? null : WebBrowser.getStandardBrowser(selectedItem));
setSelected(selectedItem == null ? null : WebBrowserManager.getInstance().getBrowser(selectedItem));
}
public void setSelected(@Nullable WebBrowser selectedItem) {
@@ -24,6 +24,7 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.TableSpeedSearch;
@@ -36,6 +37,7 @@ import com.intellij.util.ui.LocalPathCellEditor;
import com.intellij.util.ui.table.ComboBoxTableCellEditor;
import com.intellij.util.ui.table.IconTableCellRenderer;
import gnu.trove.THashMap;
import gnu.trove.TObjectObjectProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,10 +46,10 @@ import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Map;
import static com.intellij.ide.browsers.BrowsersConfiguration.BrowserFamily;
import static com.intellij.ide.browsers.WebBrowserSettings.MutableWebBrowserSettings;
public class BrowserSettingsPanel {
private JPanel root;
@@ -64,7 +66,7 @@ public class BrowserSettingsPanel {
@SuppressWarnings("UnusedDeclaration")
private JComponent browsersTable;
private final THashMap<WebBrowserSettings, MutableWebBrowserSettings> modifiedBrowsers = new THashMap<WebBrowserSettings, MutableWebBrowserSettings>();
private final THashMap<ConfigurableWebBrowser, ConfigurableWebBrowser> modifiedBrowsers = new THashMap<ConfigurableWebBrowser, ConfigurableWebBrowser>();
private final FileChooserDescriptor appFileChooserDescriptor;
public BrowserSettingsPanel() {
@@ -103,78 +105,78 @@ public class BrowserSettingsPanel {
});
}
private WebBrowserSettings getEffective(WebBrowserSettings info) {
MutableWebBrowserSettings mutable = modifiedBrowsers.isEmpty() ? null : modifiedBrowsers.get(info);
private ConfigurableWebBrowser getEffective(ConfigurableWebBrowser info) {
ConfigurableWebBrowser mutable = modifiedBrowsers.isEmpty() ? null : modifiedBrowsers.get(info);
return mutable == null ? info : mutable;
}
private MutableWebBrowserSettings getMutable(WebBrowserSettings info) {
MutableWebBrowserSettings mutable = modifiedBrowsers.get(info);
private ConfigurableWebBrowser getMutable(ConfigurableWebBrowser info) {
ConfigurableWebBrowser mutable = modifiedBrowsers.get(info);
if (mutable == null) {
mutable = info.createMutable();
mutable = new ConfigurableWebBrowser(info.getId(), info.getFamily(), info.getName(), info.getPath(), info.isActive(), info.getSpecificSettings());
modifiedBrowsers.put(info, mutable);
}
return mutable;
}
private void createUIComponents() {
ColumnInfo[] columns = {new ColumnInfo<WebBrowserSettings, Boolean>("") {
ColumnInfo[] columns = {new ColumnInfo<ConfigurableWebBrowser, Boolean>("") {
@Override
public Class getColumnClass() {
return Boolean.class;
}
@Override
public Boolean valueOf(WebBrowserSettings info) {
public Boolean valueOf(ConfigurableWebBrowser info) {
return getEffective(info).isActive();
}
@Override
public boolean isCellEditable(WebBrowserSettings info) {
public boolean isCellEditable(ConfigurableWebBrowser info) {
return true;
}
@Override
public void setValue(WebBrowserSettings info, Boolean value) {
if (value != info.active) {
public void setValue(ConfigurableWebBrowser info, Boolean value) {
if (value != info.isActive()) {
getMutable(info).setActive(value);
}
}
}, new ColumnInfo<WebBrowserSettings, String>("Name") {
}, new ColumnInfo<ConfigurableWebBrowser, String>("Name") {
@Override
public String valueOf(WebBrowserSettings info) {
public String valueOf(ConfigurableWebBrowser info) {
return getEffective(info).getName();
}
@Override
public boolean isCellEditable(WebBrowserSettings info) {
public boolean isCellEditable(ConfigurableWebBrowser info) {
return true;
}
@Override
public void setValue(WebBrowserSettings info, String value) {
public void setValue(ConfigurableWebBrowser info, String value) {
if (!value.equals(info.getName())) {
getMutable(info).setName(value);
}
}
}, new ColumnInfo<WebBrowserSettings, BrowserFamily>("Family") {
}, new ColumnInfo<ConfigurableWebBrowser, BrowserFamily>("Family") {
@Override
public Class getColumnClass() {
return BrowserFamily.class;
}
@Override
public BrowserFamily valueOf(WebBrowserSettings info) {
public BrowserFamily valueOf(ConfigurableWebBrowser info) {
return getEffective(info).getFamily();
}
@Override
public boolean isCellEditable(WebBrowserSettings info) {
public boolean isCellEditable(ConfigurableWebBrowser info) {
return true;
}
@Override
public void setValue(WebBrowserSettings info, BrowserFamily value) {
public void setValue(ConfigurableWebBrowser info, BrowserFamily value) {
if (value != info.getFamily()) {
getMutable(info).setFamily(value);
}
@@ -182,41 +184,41 @@ public class BrowserSettingsPanel {
@Nullable
@Override
public TableCellRenderer getRenderer(WebBrowserSettings info) {
public TableCellRenderer getRenderer(ConfigurableWebBrowser info) {
return IconTableCellRenderer.ICONABLE;
}
@Nullable
@Override
public TableCellEditor getEditor(WebBrowserSettings o) {
public TableCellEditor getEditor(ConfigurableWebBrowser o) {
return ComboBoxTableCellEditor.INSTANCE;
}
}, new ColumnInfo<WebBrowserSettings, String>("Path") {
}, new ColumnInfo<ConfigurableWebBrowser, String>("Path") {
@Override
public String valueOf(WebBrowserSettings info) {
public String valueOf(ConfigurableWebBrowser info) {
return getEffective(info).getPath();
}
@Override
public boolean isCellEditable(WebBrowserSettings info) {
public boolean isCellEditable(ConfigurableWebBrowser info) {
return true;
}
@Override
public void setValue(WebBrowserSettings info, String value) {
public void setValue(ConfigurableWebBrowser info, String value) {
if (!value.equals(info.getPath())) {
getMutable(info).setPath(value);
getMutable(info).setPath(StringUtil.nullize(value, true));
}
}
@Nullable
@Override
public TableCellEditor getEditor(WebBrowserSettings info) {
public TableCellEditor getEditor(ConfigurableWebBrowser info) {
return new LocalPathCellEditor(null).fileChooserDescriptor(appFileChooserDescriptor);
}
}};
ListTableModel<WebBrowserSettings> tableModel = new ListTableModel<WebBrowserSettings>(columns, WebBrowserManager.getInstance().getInfos());
TableView<WebBrowserSettings> table = new TableView<WebBrowserSettings>(tableModel);
ListTableModel<ConfigurableWebBrowser> tableModel = new ListTableModel<ConfigurableWebBrowser>(columns, new ArrayList<ConfigurableWebBrowser>(WebBrowserManager.getInstance().getList()));
TableView<ConfigurableWebBrowser> table = new TableView<ConfigurableWebBrowser>(tableModel);
table.setStriped(true);
new TableSpeedSearch(table);
TableUtil.setupCheckboxColumn(table.getColumnModel().getColumn(0));
@@ -240,7 +242,7 @@ public class BrowserSettingsPanel {
}
if (!modifiedBrowsers.isEmpty()) {
for (Map.Entry<WebBrowserSettings, MutableWebBrowserSettings> entry : modifiedBrowsers.entrySet()) {
for (Map.Entry<ConfigurableWebBrowser, ConfigurableWebBrowser> entry : modifiedBrowsers.entrySet()) {
if (entry.getValue().isChanged(entry.getKey())) {
return true;
}
@@ -267,7 +269,17 @@ public class BrowserSettingsPanel {
settings.setConfirmExtractFiles(confirmExtractFiles.isSelected());
if (!modifiedBrowsers.isEmpty()) {
WebBrowserManager.getInstance().apply(modifiedBrowsers);
modifiedBrowsers.forEachEntry(new TObjectObjectProcedure<ConfigurableWebBrowser, ConfigurableWebBrowser>() {
@Override
public boolean execute(ConfigurableWebBrowser info, ConfigurableWebBrowser newInfo) {
info.setName(newInfo.getName());
info.setFamily(newInfo.getFamily());
info.setPath(newInfo.getPath());
info.setActive(newInfo.isActive());
info.setSpecificSettings(newInfo.getSpecificSettings());
return true;
}
});
}
}
@@ -24,7 +24,7 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.xml.XmlBundle;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -54,11 +54,11 @@ public class BrowsersConfiguration {
private final String myMacPath;
private final Icon myIcon;
BrowserFamily(final String name,
@NonNls final String windowsPath,
@NonNls final String unixPath,
@NonNls final String macPath,
final Icon icon) {
BrowserFamily(@NotNull String name,
@NotNull final String windowsPath,
@Nullable final String unixPath,
@Nullable final String macPath,
@NotNull Icon icon) {
myName = name;
myWindowsPath = windowsPath;
myUnixPath = unixPath;
@@ -79,11 +79,9 @@ public class BrowsersConfiguration {
else if (SystemInfo.isMac) {
return myMacPath;
}
else if (SystemInfo.isUnix) {
else {
return myUnixPath;
}
return null;
}
public String getName() {
@@ -0,0 +1,86 @@
package com.intellij.ide.browsers;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.UUID;
final class ConfigurableWebBrowser extends WebBrowser {
private boolean active;
private final UUID id;
private String path;
private BrowserSpecificSettings specificSettings;
public ConfigurableWebBrowser(@NotNull UUID id, @NotNull BrowsersConfiguration.BrowserFamily family) {
this(id, family, family.getName(), family.getExecutionPath(), true, family.createBrowserSpecificSettings());
}
public ConfigurableWebBrowser(@NotNull UUID id,
@NotNull BrowsersConfiguration.BrowserFamily family,
@NotNull String name,
@Nullable String path,
boolean active,
@Nullable BrowserSpecificSettings specificSettings) {
super(family, name);
this.id = id;
this.path = path;
this.active = active;
this.specificSettings = specificSettings;
}
public void setName(@NotNull String value) {
name = value;
}
public void setFamily(@NotNull BrowsersConfiguration.BrowserFamily value) {
family = value;
}
@NotNull
@Override
public Icon getIcon() {
return family.getIcon();
}
@Nullable
@Override
public String getPath() {
return path;
}
public void setPath(@Nullable String value) {
path = value;
}
@Override
@Nullable
public BrowserSpecificSettings getSpecificSettings() {
return specificSettings;
}
public void setSpecificSettings(@Nullable BrowserSpecificSettings value) {
specificSettings = value;
}
public boolean isActive() {
return active;
}
public void setActive(boolean value) {
active = value;
}
@Override
@NotNull
public UUID getId() {
return id;
}
public boolean isChanged(@NotNull ConfigurableWebBrowser info) {
return active != info.active || family != info.family || !StringUtil.equals(name, info.name) || !StringUtil.equals(path, info.path);
}
}
@@ -0,0 +1,54 @@
package com.intellij.ide.browsers;
import com.intellij.openapi.util.Computable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.UUID;
final class CustomWebBrowser extends WebBrowser {
private final Computable<String> pathComputable;
private final Icon icon;
private final String browserNotFoundMessage;
CustomWebBrowser(@NotNull BrowsersConfiguration.BrowserFamily family,
@NotNull String name,
@NotNull Icon icon,
@NotNull Computable<String> pathComputable,
@Nullable String browserNotFoundMessage) {
super(family, name);
this.pathComputable = pathComputable;
this.icon = icon;
this.browserNotFoundMessage = browserNotFoundMessage;
}
@NotNull
@Override
public UUID getId() {
// todo - refine Dartium usage
throw new IllegalStateException("Custom browser must not be referenced in this way");
}
@Override
@NotNull
public Icon getIcon() {
return icon;
}
@Override
@Nullable
public String getPath() {
return pathComputable.compute();
}
@Override
@NotNull
public String getBrowserNotFoundMessage() {
String message = browserNotFoundMessage;
return message == null ? super.getBrowserNotFoundMessage() : message;
}
}
@@ -54,7 +54,7 @@ public class StartBrowserSettings {
Element child = parent.getChild(BROWSER_ELEMENT);
if (child != null) {
builder.setSelected(Boolean.parseBoolean(getAttrValue(child, START_BROWSER_ATTR)));
builder.setBrowser(WebBrowserManager.getInstance().findBrowserByName(getAttrValue(child, BROWSER_NAME_ATTR)));
builder.setBrowser(WebBrowserManager.getInstance().findBrowserById(getAttrValue(child, BROWSER_NAME_ATTR)));
builder.setUrl(StringUtil.notNullize(getAttrValue(child, URL_ATTR)));
builder.setStartJavaScriptDebugger(Boolean.parseBoolean(getAttrValue(child, WITH_JS_DEBUGGER_ATTR)));
}
@@ -65,7 +65,7 @@ public class StartBrowserSettings {
Element child = new Element(BROWSER_ELEMENT);
child.setAttribute(START_BROWSER_ATTR, String.valueOf(isSelected()));
if (myBrowser != null) {
child.setAttribute(BROWSER_NAME_ATTR, myBrowser.getName());
child.setAttribute(BROWSER_NAME_ATTR, myBrowser.getId().toString());
}
child.setAttribute(URL_ATTR, getUrl());
child.setAttribute(WITH_JS_DEBUGGER_ATTR, String.valueOf(isStartJavaScriptDebugger()));
@@ -24,7 +24,7 @@ public abstract class UrlOpener {
public static final ExtensionPointName<UrlOpener> EP_NAME = ExtensionPointName.create("org.jetbrains.urlOpener");
public static void launchBrowser(final @Nullable BrowsersConfiguration.BrowserFamily family, final @NotNull String url) {
launchBrowser(url, family == null ? null : WebBrowser.getStandardBrowser(family));
launchBrowser(url, family == null ? null : WebBrowserManager.getInstance().getBrowser(family));
}
// different params order in order not to break compilation for launchBrowser(null, url)
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,121 +17,60 @@ package com.intellij.ide.browsers;
import com.intellij.CommonBundle;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.NullableComputable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.UUID;
import static com.intellij.ide.browsers.BrowsersConfiguration.BrowserFamily;
/*
This class is a temporary solution that allows to use browser not listed in the BrowserFamily enum.
TODO Vladimir Krivosheev: get rid of BrowserFamily enum usage, allow to create custom browsers at Web Browsers page in Settings (WEB-2093).
*/
public class WebBrowser {
public static final WebBrowser CHROME = createStandardBrowser(BrowserFamily.CHROME);
public static final WebBrowser FIREFOX = createStandardBrowser(BrowserFamily.FIREFOX);
public static final WebBrowser EXPLORER = createStandardBrowser(BrowserFamily.EXPLORER);
public static final WebBrowser OPERA = createStandardBrowser(BrowserFamily.OPERA);
public static final WebBrowser SAFARI = createStandardBrowser(BrowserFamily.SAFARI);
public abstract class WebBrowser {
protected @NotNull BrowserFamily family;
protected @NotNull String name;
private final @NotNull BrowserFamily myFamily;
private final @NotNull String myName;
private final @NotNull Icon myIcon;
private final Computable<String> myPathComputable;
private final String myBrowserNotFoundMessage;
@NotNull
public static WebBrowser getStandardBrowser(final @NotNull BrowserFamily browserFamily) {
switch (browserFamily) {
case CHROME:
return CHROME;
case FIREFOX:
return FIREFOX;
case EXPLORER:
return EXPLORER;
case OPERA:
return OPERA;
case SAFARI:
return SAFARI;
default:
assert false : browserFamily;
return null;
}
}
private WebBrowser(final @NotNull BrowserFamily family,
final @NotNull String name,
final @NotNull Icon icon,
final @Nullable NullableComputable<String> pathComputable,
final @Nullable String browserNotFoundMessage) {
myFamily = family;
myName = name;
myIcon = icon;
myPathComputable = pathComputable;
myBrowserNotFoundMessage = browserNotFoundMessage;
protected WebBrowser(@NotNull BrowserFamily family, @NotNull String name) {
this.family = family;
this.name = name;
}
@NotNull
public String getName() {
return myName;
return name;
}
@NotNull
public abstract UUID getId();
@NotNull
public BrowserFamily getFamily() {
return myFamily;
return family;
}
@NotNull
public Icon getIcon() {
return myIcon;
}
public abstract Icon getIcon();
@Nullable
public String getPath() {
assert myPathComputable != null;
return myPathComputable.compute();
}
public abstract String getPath();
@NotNull
public String getBrowserNotFoundMessage() {
String message = myBrowserNotFoundMessage;
if (message == null) {
message = IdeBundle.message("error.0.browser.path.not.specified", getFamily().getName(), CommonBundle.settingsActionPath());
}
return message;
return IdeBundle.message("error.0.browser.path.not.specified", getFamily().getName(), CommonBundle.settingsActionPath());
}
@Nullable
public BrowserSpecificSettings getBrowserSpecificSettings() {
public BrowserSpecificSettings getSpecificSettings() {
return null;
}
private static WebBrowser createStandardBrowser(final BrowserFamily family) {
return new WebBrowser(family, family.getName(), family.getIcon(), null, null) {
@Override
@Nullable
public BrowserSpecificSettings getBrowserSpecificSettings() {
return WebBrowserManager.getInstance().getBrowserSettings(this).getSpecificSettings();
}
@Nullable
@Override
public String getPath() {
return WebBrowserManager.getInstance().getBrowserSettings(this).getPath();
}
};
}
@NotNull
public static WebBrowser createCustomBrowser(final @NotNull BrowserFamily family,
final @NotNull String name,
final @NotNull Icon icon,
final @NotNull NullableComputable<String> pathComputable,
final @NotNull String browserNotFoundMessage) {
return new WebBrowser(family, name, icon, pathComputable, browserNotFoundMessage);
public static WebBrowser createCustomBrowser(@NotNull BrowserFamily family,
@NotNull String name,
@NotNull Icon icon,
@NotNull NullableComputable<String> pathComputable,
@Nullable String browserNotFoundMessage) {
return new CustomWebBrowser(family, name, icon, pathComputable, browserNotFoundMessage);
}
@Override
@@ -16,26 +16,43 @@
package com.intellij.ide.browsers;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.hash.LinkedHashMap;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializer;
import gnu.trove.THashMap;
import gnu.trove.TObjectObjectProcedure;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static com.intellij.ide.browsers.BrowsersConfiguration.BrowserFamily;
@State(name = "WebBrowsersConfiguration", storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/browsers.xml")})
public class WebBrowserManager implements PersistentStateComponent<Element> {
final Map<String, WebBrowserSettings> nameToInfo = new LinkedHashMap<String, WebBrowserSettings>();
private static final Logger LOG = Logger.getInstance(WebBrowserManager.class);
// default standard browser ID must be constant across all IDE versions on all machines for all users
private static final UUID DEFAULT_CHROME_ID = UUID.fromString("98CA6316-2F89-46D9-A9E5-FA9E2B0625B3");
private static final UUID DEFAULT_FIREFOX_ID = UUID.fromString("A7BB68E0-33C0-4D6F-A81A-AAC1FDB870C8");
private static final UUID DEFAULT_SAFARI_ID = UUID.fromString("E5120D43-2C3F-47EF-9F26-65E539E05186");
private static final UUID DEFAULT_OPERA_ID = UUID.fromString("53E2F627-B1A7-4DFA-BFA7-5B83CC034776");
private static final UUID DEFAULT_EXPLORER_ID = UUID.fromString("16BF23D4-93E0-4FFC-BFD6-CB13575177B0");
private final List<ConfigurableWebBrowser> browsers;
public WebBrowserManager() {
browsers = new ArrayList<ConfigurableWebBrowser>();
browsers.add(new ConfigurableWebBrowser(DEFAULT_CHROME_ID, BrowserFamily.CHROME));
browsers.add(new ConfigurableWebBrowser(DEFAULT_FIREFOX_ID, BrowserFamily.FIREFOX));
browsers.add(new ConfigurableWebBrowser(DEFAULT_SAFARI_ID, BrowserFamily.SAFARI));
browsers.add(new ConfigurableWebBrowser(DEFAULT_OPERA_ID, BrowserFamily.OPERA));
browsers.add(new ConfigurableWebBrowser(DEFAULT_EXPLORER_ID, BrowserFamily.EXPLORER));
}
public static WebBrowserManager getInstance() {
return ServiceManager.getService(WebBrowserManager.class);
@@ -43,136 +60,198 @@ public class WebBrowserManager implements PersistentStateComponent<Element> {
@Override
public Element getState() {
Element element = new Element("WebBrowsersConfiguration");
for (WebBrowserSettings info : nameToInfo.values()) {
Element browser = new Element("browser");
browser.setAttribute("family", info.getName());
browser.setAttribute("path", info.getPath());
if (!info.isActive()) {
browser.setAttribute("active", "false");
Element state = new Element("state");
for (ConfigurableWebBrowser browser : browsers) {
Element entry = new Element("browser");
entry.setAttribute("id", browser.getId().toString());
entry.setAttribute("name", browser.getName());
entry.setAttribute("family", browser.getFamily().name());
if (!StringUtil.isEmpty(browser.getPath())) {
entry.setAttribute("path", browser.getPath());
}
if (!browser.isActive()) {
entry.setAttribute("active", "false");
}
BrowserSpecificSettings specificSettings = info.getSpecificSettings();
BrowserSpecificSettings specificSettings = browser.getSpecificSettings();
if (specificSettings != null) {
Element settingsElement = new Element("settings");
XmlSerializer.serializeInto(specificSettings, settingsElement, new SkipDefaultValuesSerializationFilters());
if (!settingsElement.getContent().isEmpty()) {
browser.addContent(settingsElement);
entry.addContent(settingsElement);
}
}
element.addContent(browser);
state.addContent(entry);
}
return element;
return state;
}
@NotNull
public List<WebBrowserSettings> getInfos() {
return new ArrayList<WebBrowserSettings>(nameToInfo.values());
@Nullable
private static BrowserFamily readFamily(String value) {
try {
return BrowserFamily.valueOf(value);
}
catch (RuntimeException e) {
LOG.warn(e);
for (BrowserFamily family : BrowserFamily.values()) {
if (family.getName().equalsIgnoreCase(value)) {
return family;
}
}
return null;
}
}
@Nullable
private static UUID readId(String value, @NotNull BrowserFamily family, @NotNull List<ConfigurableWebBrowser> existingBrowsers) {
if (StringUtil.isEmpty(value)) {
UUID id;
switch (family) {
case CHROME:
id = DEFAULT_CHROME_ID;
break;
case EXPLORER:
id = DEFAULT_EXPLORER_ID;
break;
case FIREFOX:
id = DEFAULT_FIREFOX_ID;
break;
case OPERA:
id = DEFAULT_OPERA_ID;
break;
case SAFARI:
id = DEFAULT_SAFARI_ID;
break;
default:
return null;
}
for (ConfigurableWebBrowser browser : existingBrowsers) {
if (browser.getId() == id) {
// duplicated entry, skip
return null;
}
}
return id;
}
else {
try {
return UUID.fromString(value);
}
catch (Exception e) {
LOG.warn(e);
}
}
return null;
}
@Override
public void loadState(Element element) {
List<ConfigurableWebBrowser> list = new ArrayList<ConfigurableWebBrowser>();
for (Element child : element.getChildren("browser")) {
Element settingsElement = child.getChild("settings");
BrowserFamily browserFamily;
try {
browserFamily = BrowserFamily.valueOf(child.getAttributeValue("family"));
}
catch (RuntimeException e) {
BrowserFamily family = readFamily(child.getAttributeValue("family"));
if (family == null) {
continue;
}
BrowserSpecificSettings specificSettings = settingsElement == null ? null : browserFamily.createBrowserSpecificSettings();
if (specificSettings != null) {
XmlSerializer.deserializeInto(specificSettings, settingsElement);
UUID id = readId(child.getAttributeValue("id"), family, list);
if (id == null) {
continue;
}
String active = child.getAttributeValue("active");
String name = StringUtil.notNullize(child.getAttributeValue("name"), browserFamily.getName());
nameToInfo.put(name, new WebBrowserSettings(browserFamily,
name,
StringUtil.notNullize(child.getAttributeValue("path")),
active == null || Boolean.parseBoolean(active),
specificSettings));
Element settingsElement = child.getChild("settings");
BrowserSpecificSettings specificSettings = settingsElement == null ? null : family.createBrowserSpecificSettings();
if (specificSettings != null) {
try {
XmlSerializer.deserializeInto(specificSettings, settingsElement);
}
catch (Exception e) {
LOG.warn(e);
}
}
String activeValue = child.getAttributeValue("active");
list.add(new ConfigurableWebBrowser(id,
family,
StringUtil.notNullize(child.getAttributeValue("name"), family.getName()),
StringUtil.nullize(child.getAttributeValue("path"), true),
activeValue == null || Boolean.parseBoolean(activeValue),
specificSettings));
}
browsers.clear();
browsers.addAll(list);
}
@NotNull
public List<WebBrowser> getBrowsers() {
List<WebBrowser> result = new ArrayList<WebBrowser>();
for (BrowserFamily family : BrowserFamily.values()) {
result.add(WebBrowser.getStandardBrowser(family));
}
return result;
return Collections.<WebBrowser>unmodifiableList(browsers);
}
@NotNull
List<ConfigurableWebBrowser> getList() {
return browsers;
}
@NotNull
public List<WebBrowser> getActiveBrowsers() {
List<WebBrowser> result = new SmartList<WebBrowser>();
for (WebBrowser browser : getBrowsers()) {
if (getBrowserSettings(browser).isActive()) {
for (ConfigurableWebBrowser browser : browsers) {
if (browser.isActive()) {
result.add(browser);
}
}
return result;
}
@NotNull
public WebBrowserSettings getBrowserSettings(@NotNull WebBrowser browser) {
return getBrowserSettings(browser.getFamily());
public void setBrowserSpecificSettings(@NotNull WebBrowser browser, @NotNull BrowserSpecificSettings specificSettings) {
((ConfigurableWebBrowser)browser).setSpecificSettings(specificSettings);
}
void apply(THashMap<WebBrowserSettings, WebBrowserSettings.MutableWebBrowserSettings> map) {
map.forEachEntry(new TObjectObjectProcedure<WebBrowserSettings, WebBrowserSettings.MutableWebBrowserSettings>() {
@Override
public boolean execute(WebBrowserSettings info, WebBrowserSettings.MutableWebBrowserSettings newInfo) {
info.active = newInfo.active;
info.name = newInfo.name;
info.path = newInfo.path;
info.family = newInfo.family;
info.specificSettings = newInfo.specificSettings;
return true;
}
});
}
@NotNull
public WebBrowserSettings getBrowserSettings(@NotNull BrowserFamily family) {
WebBrowserSettings result = nameToInfo.get(family.getName());
if (result == null) {
String path = family.getExecutionPath();
result = new WebBrowserSettings(family, family.getName(), StringUtil.notNullize(path), path != null, null);
nameToInfo.put(result.getName(), result);
}
return result;
}
public void updateBrowserSpecificSettings(@NotNull WebBrowser browser, BrowserSpecificSettings specificSettings) {
updateBrowserSpecificSettings(browser.getFamily(), specificSettings);
}
public void updateBrowserSpecificSettings(@NotNull BrowserFamily family, BrowserSpecificSettings specificSettings) {
WebBrowserSettings settings = getBrowserSettings(family);
nameToInfo.put(family.getName(), new WebBrowserSettings(family, family.getName(), settings.getPath(), settings.isActive(), specificSettings));
}
public void updateBrowserValue(@NotNull WebBrowser browser, @NotNull String path, boolean isActive) {
WebBrowserSettings settings = getBrowserSettings(browser);
nameToInfo.put(browser.getFamily().getName(), new WebBrowserSettings(browser.getFamily(), browser.getFamily().getName(), path, isActive, settings.getSpecificSettings()));
public void setBrowserPath(@NotNull WebBrowser browser, @Nullable String path, boolean isActive) {
((ConfigurableWebBrowser)browser).setPath(path);
((ConfigurableWebBrowser)browser).setActive(isActive);
}
@Nullable
public WebBrowser findBrowserByName(@Nullable String name) {
for (BrowserFamily family : BrowserFamily.values()) {
if (family.getName().equals(name)) {
return WebBrowser.getStandardBrowser(family);
public WebBrowser findBrowserById(@Nullable String idOrName) {
UUID id;
try {
id = UUID.fromString(idOrName);
}
catch (Exception e) {
LOG.warn(e);
for (ConfigurableWebBrowser browser : browsers) {
if (browser.getFamily().name().equals(idOrName) || browser.getFamily().getName().equals(idOrName)) {
return browser;
}
}
return null;
}
for (ConfigurableWebBrowser browser : browsers) {
if (browser.getId().equals(id)) {
return browser;
}
}
return null;
}
public void updateBrowserValue(BrowserFamily family, String path, boolean isActive) {
nameToInfo.put(family.getName(), new WebBrowserSettings(family, family.getName(), path, isActive, getBrowserSettings(family).getSpecificSettings()));
@NotNull
public WebBrowser getBrowser(@NotNull BrowserFamily family) {
for (ConfigurableWebBrowser browser : browsers) {
if (family.equals(browser.getFamily())) {
return browser;
}
}
throw new IllegalStateException("Must be at least one browser per family");
}
public boolean isActive(@NotNull WebBrowser browser) {
return !(browser instanceof ConfigurableWebBrowser) || ((ConfigurableWebBrowser)browser).isActive();
}
}
@@ -1,90 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.browsers;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.ide.browsers.BrowsersConfiguration.BrowserFamily;
public class WebBrowserSettings {
protected BrowserFamily family;
protected String name;
protected String path;
protected boolean active;
protected BrowserSpecificSettings specificSettings;
public WebBrowserSettings(@NotNull BrowserFamily family, @NotNull String name, @NotNull String path, boolean active, @Nullable BrowserSpecificSettings specificSettings) {
this.family = family;
this.name = name;
this.path = path;
this.active = active;
this.specificSettings = specificSettings;
}
@NotNull
public String getPath() {
return path;
}
public boolean isActive() {
return active;
}
@Nullable
public BrowserSpecificSettings getSpecificSettings() {
return specificSettings;
}
public MutableWebBrowserSettings createMutable() {
return new MutableWebBrowserSettings(this);
}
public String getName() {
return name;
}
public BrowserFamily getFamily() {
return family;
}
public static class MutableWebBrowserSettings extends WebBrowserSettings {
private MutableWebBrowserSettings(@NotNull WebBrowserSettings settings) {
super(settings.family, settings.name, settings.path, settings.active, settings.specificSettings);
}
public void setActive(boolean value) {
active = value;
}
public void setName(@NotNull String value) {
name = value;
}
public void setFamily(@NotNull BrowserFamily value) {
family = value;
}
public void setPath(@NotNull String value) {
path = value;
}
public boolean isChanged(@NotNull WebBrowserSettings info) {
return active != info.active || family != info.family || !StringUtil.equals(name, info.name) || !StringUtil.equals(path, info.path);
}
}
}
@@ -1,217 +0,0 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.browsers;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.browsers.impl.BrowserConfigurationHelper;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.xml.XmlBundle;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.concurrent.ExecutionException;
public class WebBrowsersPanel extends JPanel {
private final JPanel mySettingsPanel;
private Map<BrowsersConfiguration.BrowserFamily, Pair<JCheckBox, TextFieldWithBrowseButton>> myBrowserSettingsMap = new THashMap<BrowsersConfiguration.BrowserFamily, Pair<JCheckBox, TextFieldWithBrowseButton>>();
private final WebBrowserManager myBrowserManager;
public WebBrowsersPanel() {
setLayout(new BorderLayout());
myBrowserManager = WebBrowserManager.getInstance();
mySettingsPanel = new JPanel();
mySettingsPanel.setLayout(new BoxLayout(mySettingsPanel, BoxLayout.Y_AXIS));
add(mySettingsPanel, BorderLayout.NORTH);
createIndividualSettings(BrowsersConfiguration.BrowserFamily.FIREFOX, mySettingsPanel);
createIndividualSettings(BrowsersConfiguration.BrowserFamily.EXPLORER, mySettingsPanel);
createIndividualSettings(BrowsersConfiguration.BrowserFamily.SAFARI, mySettingsPanel);
createIndividualSettings(BrowsersConfiguration.BrowserFamily.CHROME, mySettingsPanel);
createIndividualSettings(BrowsersConfiguration.BrowserFamily.OPERA, mySettingsPanel);
createPlatformSpecificAction(mySettingsPanel);
}
private void createIndividualSettings(@NotNull final BrowsersConfiguration.BrowserFamily family, final JPanel container) {
final JPanel result = new JPanel();
result.setBorder(IdeBorderFactory.createTitledBorder(family.getName(), true));
result.setLayout(new BoxLayout(result, BoxLayout.Y_AXIS));
final TextFieldWithBrowseButton field = new TextFieldWithBrowseButton();
FileChooserDescriptor descriptor = SystemInfo.isMac
? FileChooserDescriptorFactory.createSingleFolderDescriptor()
: FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor();
field.addBrowseFolderListener(IdeBundle.message("title.select.path.to.browser"), null, null, descriptor);
result.add(field);
final JPanel bottomPanel = new JPanel(new BorderLayout());
final JPanel activePanel = new JPanel();
activePanel.setLayout(new BoxLayout(activePanel, BoxLayout.X_AXIS));
final JCheckBox checkBox = new JCheckBox();
activePanel.add(checkBox);
final JLabel label = new JLabel(XmlBundle.message("browser.active"));
label.setLabelFor(checkBox);
activePanel.add(label);
bottomPanel.add(activePanel, BorderLayout.WEST);
final JButton resetButton = new JButton(XmlBundle.message("browser.default.settings"));
resetButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
field.getTextField().setText(family.getExecutionPath());
}
});
JPanel buttonsPanel = new JPanel(new BorderLayout());
if (family.createBrowserSpecificSettings() != null) {
final JButton editSettingsButton = new JButton(XmlBundle.message("button.text.settings"));
editSettingsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
editSettings(family);
}
});
buttonsPanel.add(editSettingsButton, BorderLayout.CENTER);
}
buttonsPanel.add(resetButton, BorderLayout.EAST);
bottomPanel.add(buttonsPanel, BorderLayout.EAST);
result.add(bottomPanel);
container.add(result);
final WebBrowserSettings settings = myBrowserManager.getBrowserSettings(family);
field.getTextField().setText(settings.getPath());
checkBox.setSelected(settings.isActive());
myBrowserSettingsMap.put(family, Pair.create(checkBox, field));
}
private void editSettings(BrowsersConfiguration.BrowserFamily family) {
BrowserSpecificSettings settings = myBrowserManager.getBrowserSettings(family).getSpecificSettings();
if (settings == null) {
settings = family.createBrowserSpecificSettings();
}
if (settings != null && ShowSettingsUtil.getInstance().editConfigurable(mySettingsPanel, settings.createConfigurable())) {
myBrowserManager.updateBrowserSpecificSettings(family, settings);
}
}
private void createPlatformSpecificAction(JPanel container) {
if (SystemInfo.isWindows) {
JButton registryButton = new JButton(XmlBundle.message("read.win.registry"));
registryButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
applySettingsFromWindowsRegistry();
}
});
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
panel.add(registryButton, BorderLayout.EAST);
container.add(panel);
}
}
private void applySettingsFromWindowsRegistry() {
ApplicationManager.getApplication().executeOnPooledThread(new SwingWorker<Map<BrowsersConfiguration.BrowserFamily, String>, Void>() {
@Override
protected Map<BrowsersConfiguration.BrowserFamily, String> doInBackground() throws Exception {
return BrowserConfigurationHelper.getBrowserPathsFromRegistry();
}
@Override
protected void done() {
Map<BrowsersConfiguration.BrowserFamily, String> map = null;
try {
map = get();
}
catch (InterruptedException ignore) { }
catch (ExecutionException ignore) { }
if (myBrowserSettingsMap == null || map == null || map.isEmpty()) {
return;
}
for (BrowsersConfiguration.BrowserFamily family : BrowsersConfiguration.BrowserFamily.values()) {
Pair<JCheckBox, TextFieldWithBrowseButton> pair = myBrowserSettingsMap.get(family);
String pathToExe = map.get(family);
if (pathToExe != null) {
pair.first.setSelected(true);
pair.second.setText(pathToExe);
}
else {
pair.first.setSelected(false);
}
}
}
});
}
public void dispose() {
myBrowserSettingsMap = null;
}
public boolean isModified() {
for (BrowsersConfiguration.BrowserFamily family : BrowsersConfiguration.BrowserFamily.values()) {
final WebBrowserSettings old = myBrowserManager.getBrowserSettings(family);
final Pair<JCheckBox, TextFieldWithBrowseButton> settings = myBrowserSettingsMap.get(family);
if (old.isActive() != settings.first.isSelected() || !old.getPath().equals(settings.second.getText())) {
return true;
}
}
return false;
}
public void apply() {
for (BrowsersConfiguration.BrowserFamily family : myBrowserSettingsMap.keySet()) {
final Pair<JCheckBox, TextFieldWithBrowseButton> buttonPair = myBrowserSettingsMap.get(family);
myBrowserManager.updateBrowserValue(family, buttonPair.second.getText(), buttonPair.first.isSelected());
}
}
public void reset() {
for (BrowsersConfiguration.BrowserFamily family : myBrowserSettingsMap.keySet()) {
final Pair<JCheckBox, TextFieldWithBrowseButton> buttonPair = myBrowserSettingsMap.get(family);
final WebBrowserSettings settings = myBrowserManager.getBrowserSettings(family);
buttonPair.first.setSelected(settings.isActive());
buttonPair.second.getTextField().setText(settings.getPath());
}
}
}
@@ -33,6 +33,6 @@ final class BaseWebBrowserAction extends BaseOpenInBrowserAction {
@Nullable
@Override
protected WebBrowser getBrowser(@NotNull AnActionEvent event) {
return WebBrowserManager.getInstance().getBrowserSettings(browser).isActive() ? browser : null;
return WebBrowserManager.getInstance().isActive(browser) ? browser : null;
}
}
@@ -59,7 +59,7 @@ public class OpenFileInDefaultBrowserAction extends DumbAwareAction {
GeneralSettings settings = GeneralSettings.getInstance();
if (!settings.isUseDefaultBrowser()) {
WebBrowser browser = WebBrowserManager.getInstance().findBrowserByName(settings.getBrowserPath());
WebBrowser browser = WebBrowserManager.getInstance().findBrowserById(settings.getBrowserPath());
if (browser != null) {
presentation.setIcon(browser.getIcon());
}
@@ -54,7 +54,7 @@ public class DefaultUrlOpener extends UrlOpener {
return false;
}
return doLaunchBrowser(browserPath, browser.getBrowserSpecificSettings(), url, newWindowIfPossible, additionalParameters);
return doLaunchBrowser(browserPath, browser.getSpecificSettings(), url, newWindowIfPossible, additionalParameters);
}
private static boolean doLaunchBrowser(final String browserPath,