/* This file is part of leafdigital leafChat. leafChat is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. leafChat is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with leafChat. If not, see <http://www.gnu.org/licenses/>. Copyright 2011 Samuel Marshall. */ package com.leafdigital.uiprefs; import java.io.*; import java.net.MalformedURLException; import java.util.zip.ZipException; import util.PlatformUtils; import util.xml.XML; import com.leafdigital.ui.api.*; import leafchat.core.api.*; /** Options page where user can select theme. */ @UIHandler("themes") public class ThemesPage { private PluginContext context; private Page p; /** UI: Theme list table */ public Table themesUI; /** UI: Name of selected theme */ public Label themeNameUI; /** UI: Description of selected theme */ public Label themeDescriptionUI; /** UI: Authors of selected theme */ public Label themeAuthorsUI; /** UI: Location of selected theme */ public Label themeLocationUI; /** UI: Picture for selected theme */ public Pic themePicUI; /** Current themes */ private Theme[] themes; ThemesPage(PluginContext context) { this.context = context; UI ui = context.getSingle(UI.class); p = ui.createPage("themes", this); } /** @return Page object for adding to dialog */ public Page getPage() { return p; } /** * Checks whether the list of available themes has changed. If it has, redoes * onSet to initialise the list. * @return True if the list changed */ private boolean checkThemesChange() { Theme[] oldThemes = themes; UI ui=context.getSingle(UI.class); themes = ui.getAvailableThemes(); boolean changed = false; if(themes.length != oldThemes.length) { changed = true; } else { for(int i=0; i<themes.length; i++) { if(!themes[i].equals(oldThemes[i])) { changed = true; break; } } } if(changed) { onSet(); return true; } else { return false; } } /** Callback: Page has been selected in options. */ @UIAction public void onSet() { UI ui = context.getSingle(UI.class); themes = ui.getAvailableThemes(); Theme current = ui.getTheme(); themesUI.clear(); for(int i=0; i<themes.length; i++) { int index = themesUI.addItem(); themesUI.setString(index, 0, themes[i].getStringProperty(Theme.META, Theme.META_NAME, "?")); if(themes[i] == current) { themesUI.setBoolean(index, 1, true); themesUI.setEditable(index, 1, false); } else { themesUI.setBoolean(index, 1, false); themesUI.setEditable(index, 1, true); } } selectThemes(); } /** Callback: Change in selected themes. */ @UIAction public void selectThemes() { if(checkThemesChange()) { return; } int selected = themesUI.getSelectedIndex(); if(selected == Table.NONE) { themeNameUI.setText("(Select theme for information)"); themeDescriptionUI.setText(""); themeAuthorsUI.setText(""); themeLocationUI.setText(""); themePicUI.setProperty(null); } else { Theme t = themes[selected]; themeNameUI.setText("<strong>"+XML.esc(t.getStringProperty(Theme.META, Theme.META_NAME, "?"))+"</strong>"); themeAuthorsUI.setText(XML.esc(t.getStringProperty(Theme.META, Theme.META_AUTHORS, "?"))); themeDescriptionUI.setText(XML.esc(t.getStringProperty(Theme.META, Theme.META_DESCRIPTION, "?"))); try { themeLocationUI.setText(XML.esc(t.getLocation().getCanonicalPath())); } catch(IOException e) { themeLocationUI.setText("?"); } themePicUI.setThemeFile(t, "theme.png"); } } /** * Callback: Change in value in themes table. * @param index Row * @param column Column * @param before Previous value */ @UIAction public void changeThemes(int index, int column, Object before) { if(checkThemesChange()) { return; } UI ui = context.getSingle(UI.class); Theme current = ui.getTheme(); for(int i=0; i<themes.length; i++) { if(current == themes[i]) { // Turn off, and re-enable editing, existing column themesUI.setBoolean(i, 1, false); themesUI.setEditable(i, 1, true); } } // Set theme ui.setTheme(themes[index]); // Disable editing for new col themesUI.setEditable(index, 1, false); } /** * Callback: Install button * @throws GeneralException */ @UIAction public void actionInstall() throws GeneralException { UI ui = context.getSingle(UI.class); File selected = ui.showFileSelect(p.getOwner(), "Install theme", false, new File(PlatformUtils.getDownloadFolder()), null, new String[] {".leafChatTheme"}, "leafChat themes"); if(selected != null) { try { ui.installUserTheme(selected); onSet(); } catch(GeneralException e) { String suggestion; if(e.getCause() instanceof ZipException) { suggestion="The theme doesn't seem to be a valid .zip file. " + "Please compress your themes using a standard zip program. " + "The most reliable way to do this is with a command-line program " + "such as that available from <url>www.info-zip.org</url>."; } else { suggestion="Perhaps the theme " + "is invalid? Make sure that the structure of your .zip file is " + "identical to the provided themes (e.g. files are included in the " + "root of the zip and not in folders). See the help page for more " + "information."; } ui.showUserError(p.getOwner(), "Error loading theme", "<para>An error occurred while loading the theme:</para>" + "<para><key>"+XML.esc(e.getMessage())+"</key></para>"+ "<para>"+suggestion+"</para>"); } } } /** * Callback: Help button */ @UIAction public void actionHelp() { try { PlatformUtils.showBrowser( (new File("help/themes/index.html")).toURI().toURL()); } catch(MalformedURLException e) { ErrorMsg.report("Failed to open help", e); } catch(IOException e) { ErrorMsg.report(e.getMessage(), e.getCause()); } } }