diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index eaafbff74..e3cc8fd93 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -85,6 +85,8 @@ public class SnarkManager implements Snark.CompleteListener { //public static final String DEFAULT_LINK_PREFIX = "file:///"; public static final String PROP_STARTUP_DELAY = "i2psnark.startupDelay"; public static final String PROP_REFRESH_DELAY = "i2psnark.refreshSeconds"; + public static final String RC_PROP_THEME = "routerconsole.theme"; + public static final String RC_PROP_UNIVERSAL_THEMING = "routerconsole.theme.universal"; public static final String PROP_THEME = "i2psnark.theme"; public static final String DEFAULT_THEME = "ubergine"; private static final String PROP_USE_OPENTRACKERS = "i2psnark.useOpentrackers"; @@ -296,6 +298,22 @@ public class SnarkManager implements Snark.CompleteListener { */ public String getTheme() { String theme = _config.getProperty(PROP_THEME); + boolean universalTheming = _context.getBooleanProperty(RC_PROP_UNIVERSAL_THEMING); + if (universalTheming) { + // Fetch routerconsole theme (or use our default if it doesn't exist) + theme = _context.getProperty(RC_PROP_THEME, DEFAULT_THEME); + // Ensure that theme exists + String[] themes = getThemes(); + boolean themeExists = false; + for (int i = 0; i < themes.length; i++) { + if (themes[i].equals(theme)) + themeExists = true; + } + if (!themeExists) { + theme = DEFAULT_THEME; + _config.setProperty(PROP_THEME, DEFAULT_THEME); + } + } return theme; } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java index 75991e393..e4609593c 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java @@ -393,8 +393,8 @@ public class IndexBean { //// public String getTheme() { - String theme = _context.getProperty(PROP_THEME_NAME, DEFAULT_THEME); - return "/themes/console/" + theme + "/"; + String theme = _context.getProperty(PROP_THEME_NAME, DEFAULT_THEME); + return "/themes/console/" + theme + "/"; } public boolean allowCSS() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java index 130af3c9d..ddea8c8cd 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java @@ -12,7 +12,8 @@ public class CSSHelper extends HelperBase { private static final Map _UACache = new ConcurrentHashMap(); public CSSHelper() {} - + + public static final String PROP_UNIVERSAL_THEMING = "routerconsole.theme.universal"; public static final String PROP_THEME_NAME = "routerconsole.theme"; public static final String DEFAULT_THEME = "light"; public static final String BASE_THEME_PATH = "/themes/console/"; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHandler.java index 514068ebf..9616e74b3 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHandler.java @@ -1,8 +1,14 @@ package net.i2p.router.web; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** set the theme */ public class ConfigUIHandler extends FormHandler { private boolean _shouldSave; + private boolean _universalTheming; private String _config; @Override @@ -12,7 +18,9 @@ public class ConfigUIHandler extends FormHandler { } public void setShouldsave(String moo) { _shouldSave = true; } - + + public void setUniversalTheming(String baa) { _universalTheming = true; } + public void setTheme(String val) { _config = val; } @@ -21,12 +29,18 @@ public class ConfigUIHandler extends FormHandler { private void saveChanges() { if (_config == null) return; + Map changes = new HashMap(); + List removes = new ArrayList(); String oldTheme = _context.getProperty(CSSHelper.PROP_THEME_NAME, CSSHelper.DEFAULT_THEME); - boolean ok; if (_config.equals("default")) // obsolete - ok = _context.router().saveConfig(CSSHelper.PROP_THEME_NAME, null); + removes.add(CSSHelper.PROP_THEME_NAME); else - ok = _context.router().saveConfig(CSSHelper.PROP_THEME_NAME, _config); + changes.put(CSSHelper.PROP_THEME_NAME, _config); + if (_universalTheming) + changes.put(CSSHelper.PROP_UNIVERSAL_THEMING, "true"); + else + removes.add(CSSHelper.PROP_UNIVERSAL_THEMING); + boolean ok = _context.router().saveConfig(changes, removes); if (ok) { if (!oldTheme.equals(_config)) addFormNotice(_("Theme change saved.") + diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java index 3812d48dd..990572ab4 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java @@ -17,6 +17,13 @@ public class ConfigUIHelper extends HelperBase { buf.append("checked=\"checked\" "); buf.append("value=\"").append(theme).append("\">").append(_(theme)).append("
\n"); } + boolean universalTheming = _context.getBooleanProperty(CSSHelper.PROP_UNIVERSAL_THEMING); + buf.append("") + .append(_("Set theme universally across all apps")) + .append("
\n"); return buf.toString(); } diff --git a/apps/susidns/src/java/src/i2p/susi/dns/BaseBean.java b/apps/susidns/src/java/src/i2p/susi/dns/BaseBean.java index a5cc49e2d..36e0a2b38 100644 --- a/apps/susidns/src/java/src/i2p/susi/dns/BaseBean.java +++ b/apps/susidns/src/java/src/i2p/susi/dns/BaseBean.java @@ -1,27 +1,35 @@ package i2p.susi.dns; +import java.io.File; +import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; +import net.i2p.I2PAppContext; + /** * Holds methods common to several Beans. * @since 0.9.1 */ public class BaseBean { + private final I2PAppContext _context; protected final Properties properties; private long configLastLoaded = 0; private static final String PRIVATE_BOOK = "private_addressbook"; private static final String DEFAULT_PRIVATE_BOOK = "../privatehosts.txt"; + public static final String RC_PROP_THEME_NAME = "routerconsole.theme"; + public static final String RC_PROP_UNIVERSAL_THEMING = "routerconsole.theme.universal"; public static final String PROP_THEME_NAME = "theme"; public static final String DEFAULT_THEME = "light"; public static final String BASE_THEME_PATH = "/themes/susidns/"; public BaseBean() { + _context = I2PAppContext.getGlobalContext(); properties = new Properties(); } @@ -58,7 +66,43 @@ public class BaseBean loadConfig(); String url = BASE_THEME_PATH; String theme = properties.getProperty(PROP_THEME_NAME, DEFAULT_THEME); + boolean universalTheming = _context.getBooleanProperty(RC_PROP_UNIVERSAL_THEMING); + if (universalTheming) { + // Fetch routerconsole theme (or use our default if it doesn't exist) + theme = _context.getProperty(RC_PROP_THEME_NAME, DEFAULT_THEME); + // Ensure that theme exists + String[] themes = getThemes(); + boolean themeExists = false; + for (int i = 0; i < themes.length; i++) { + if (themes[i].equals(theme)) + themeExists = true; + } + if (!themeExists) + theme = DEFAULT_THEME; + } url += theme + "/"; return url; } + + /** + * Get all themes + * @return String[] -- Array of all the themes found. + * @since 0.9.2 + */ + public String[] getThemes() { + String[] themes = null; + // "docs/themes/susidns/" + File dir = new File(_context.getBaseDir(), "docs/themes/susidns"); + FileFilter fileFilter = new FileFilter() { public boolean accept(File file) { return file.isDirectory(); } }; + // Walk the themes dir, collecting the theme names, and append them to the map + File[] dirnames = dir.listFiles(fileFilter); + if (dirnames != null) { + themes = new String[dirnames.length]; + for(int i = 0; i < dirnames.length; i++) { + themes[i] = dirnames[i].getName(); + } + } + // return the map. + return themes; + } } diff --git a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java index 65cb6404a..cfb12c0b6 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java @@ -37,6 +37,8 @@ import i2p.susi.webmail.smtp.SMTPClient; import java.io.BufferedReader; import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -58,6 +60,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import net.i2p.I2PAppContext; + /** * @author susi23 */ @@ -164,6 +168,8 @@ public class WebMail extends HttpServlet private static final String CONFIG_BCC_TO_SELF = "composer.bcc.to.self"; + private static final String RC_PROP_THEME = "routerconsole.theme"; + private static final String RC_PROP_UNIVERSAL_THEMING = "routerconsole.theme.universal"; private static final String CONFIG_THEME = "theme"; private static final String DEFAULT_THEME = "light"; @@ -1187,6 +1193,24 @@ public class WebMail extends HttpServlet private void processRequest( HttpServletRequest httpRequest, HttpServletResponse response ) throws IOException, ServletException { + String theme = Config.getProperty(CONFIG_THEME, DEFAULT_THEME); + I2PAppContext ctx = I2PAppContext.getGlobalContext(); + boolean universalTheming = ctx.getBooleanProperty(RC_PROP_UNIVERSAL_THEMING); + if (universalTheming) { + // Fetch routerconsole theme (or use our default if it doesn't exist) + theme = ctx.getProperty(RC_PROP_THEME, DEFAULT_THEME); + // Ensure that theme exists + String[] themes = getThemes(); + boolean themeExists = false; + for (int i = 0; i < themes.length; i++) { + if (themes[i].equals(theme)) + themeExists = true; + } + if (!themeExists) { + theme = DEFAULT_THEME; + } + } + httpRequest.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setHeader("X-Frame-Options", "SAMEORIGIN"); @@ -1206,7 +1230,7 @@ public class WebMail extends HttpServlet sessionObject.info = ""; sessionObject.pageChanged = false; sessionObject.showAttachment = null; - sessionObject.themePath = "/themes/susimail/" + Config.getProperty(CONFIG_THEME, DEFAULT_THEME) + '/'; + sessionObject.themePath = "/themes/susimail/" + theme + '/'; sessionObject.imgPath = sessionObject.themePath + "images/"; processStateChangeButtons( sessionObject, request ); @@ -1732,4 +1756,25 @@ public class WebMail extends HttpServlet private static String ngettext(String s, String p, int n) { return Messages.getString(n, s, p); } + + /** + * Get all themes + * @return String[] -- Array of all the themes found. + */ + public String[] getThemes() { + String[] themes = null; + // "docs/themes/susimail/" + File dir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs/themes/susimail"); + FileFilter fileFilter = new FileFilter() { public boolean accept(File file) { return file.isDirectory(); } }; + // Walk the themes dir, collecting the theme names, and append them to the map + File[] dirnames = dir.listFiles(fileFilter); + if (dirnames != null) { + themes = new String[dirnames.length]; + for(int i = 0; i < dirnames.length; i++) { + themes[i] = dirnames[i].getName(); + } + } + // return the map. + return themes; + } }