/*
Copyright (C) 2013-2020 Nicola L.C. Talbot
www.dickimaw-books.com
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.dickimawbooks.makeglossariesgui;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Arrays;
import javax.swing.*;
import javax.swing.event.*;
public class PropertiesDialog extends JDialog
implements ActionListener,ItemListener,ChangeListener
{
public PropertiesDialog(MakeGlossariesGUI application)
{
super(application, application.getLabel("properties.title"), true);
app = application;
JTabbedPane tabbedPane = new JTabbedPane();
getContentPane().add(tabbedPane, "Center");
properties = app.getProperties();
File file = new File(properties.getDefaultDirectory());
String setting = properties.getDefaultDirectorySetting();
if (setting == null) setting = "home";
fileChooser = new JFileChooser(getDir());
Box box = Box.createVerticalBox();
newTab(tabbedPane, box, "properties.start_dir");
Box startDirBox = Box.createVerticalBox();
startDirBox.setAlignmentX(Component.LEFT_ALIGNMENT);
box.add(startDirBox);
ButtonGroup bg = new ButtonGroup();
homeButton = createRadioButton("properties.dir.home", "disablecustom",
bg);
startDirBox.add(homeButton);
lastButton = createRadioButton("properties.dir.last", "disablecustom",
bg);
startDirBox.add(lastButton);
Box panel = Box.createHorizontalBox();
panel.setAlignmentX(Component.LEFT_ALIGNMENT);
panel.setAlignmentY(Component.TOP_ALIGNMENT);
startDirBox.add(panel);
customButton = createRadioButton("properties.dir.custom", "enablecustom",
bg);
customButton.setAlignmentY(Component.TOP_ALIGNMENT);
panel.add(customButton);
customField = new FileField(app, this, fileChooser,
JFileChooser.DIRECTORIES_ONLY);
customField.setOpaque(false);
customField.setAlignmentY(Component.TOP_ALIGNMENT);
panel.add(customField);
if (setting.equals("home"))
{
homeButton.setSelected(true);
customField.setEnabled(false);
}
else if (setting.equals("last"))
{
lastButton.setSelected(true);
customField.setEnabled(false);
}
else if (setting.equals("custom"))
{
customButton.setSelected(true);
customField.setFileName(file.getAbsolutePath());
}
box = Box.createVerticalBox();
newTab(tabbedPane, box, "properties.diagnostics");
docDefCheckBox = createCheckBox("properties", "docdefcheck",
properties.isDocDefsCheckOn());
box.add(docDefCheckBox);
missingLangModBox = createCheckBox("properties", "langcheck",
properties.isMissingLangCheckOn());
box.add(missingLangModBox);
box = Box.createVerticalBox();
newTab(tabbedPane, box, "properties.applications");
Box makeindexBox = Box.createVerticalBox();
makeindexBox.setBorder(BorderFactory.createEtchedBorder());
box.add(makeindexBox);
panel = Box.createHorizontalBox();
panel.setAlignmentX(Component.LEFT_ALIGNMENT);
makeindexBox.add(panel);
JLabel makeindexLabel = createLabel("properties.makeindex");
panel.add(makeindexLabel);
makeindexField = new FileField(app, this,
properties.getMakeIndexApp(),
fileChooser);
makeindexLabel.setLabelFor(makeindexField.getTextField());
panel.add(makeindexField);
makeindexField.setOpaque(false);
Box xindyBox = Box.createVerticalBox();
xindyBox.setBorder(BorderFactory.createEtchedBorder());
box.add(xindyBox);
panel = Box.createHorizontalBox();
panel.setAlignmentX(Component.LEFT_ALIGNMENT);
xindyBox.add(panel);
JLabel xindyLabel = createLabel("properties.xindy");
panel.add(xindyLabel);
JPanel xindyDefaultsPanel = new JPanel();
xindyDefaultsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
xindyBox.add(xindyDefaultsPanel);
xindyDefaultsPanel.setOpaque(false);
langLabel = createLabel("properties.language");
xindyDefaultsPanel.add(langLabel);
String[] languages = XindyModule.getKnownLanguages();
Arrays.sort(languages);
languageBox = new JComboBox<String>(languages);
langLabel.setLabelFor(languageBox);
languageBox.setSelectedItem(properties.getDefaultLanguage());
languageBox.addItemListener(this);
xindyDefaultsPanel.add(languageBox);
xindyModuleLayout = new CardLayout();
modulesPanel = new JPanel(xindyModuleLayout);
modulesPanel.setOpaque(false);
initVariants((String)languageBox.getSelectedItem(),
properties.getDefaultXindyVariant(),
properties.getDefaultCodePage());
xindyDefaultsPanel.add(modulesPanel);
overrideBox = createCheckBox("properties", "override",
properties.isOverride());
xindyBox.add(overrideBox);
xindyField = new FileField(app, this,
properties.getXindyApp(), fileChooser);
xindyLabel.setLabelFor(xindyField.getTextField());
panel.add(xindyField);
xindyField.setOpaque(false);
box = Box.createVerticalBox();
newTab(tabbedPane, box, "properties.gui");
JPanel lfPanel = new JPanel();
lfPanel.setOpaque(false);
box.add(lfPanel);
JLabel lfLabel = createLabel("properties.look_and_feel");
lfPanel.add(lfLabel);
UIManager.LookAndFeelInfo[] lfInfo = UIManager.getInstalledLookAndFeels();
lookAndFeelBox = new JComboBox<UIManager.LookAndFeelInfo>(lfInfo);
lookAndFeelBox.setRenderer(new LookAndFeelCellRenderer());
String currentLF = properties.getLookAndFeel();
if (currentLF != null)
{
for (int i = 0; i < lfInfo.length; i++)
{
if (lfInfo[i].getClassName().equals(currentLF))
{
lookAndFeelBox.setSelectedIndex(i);
break;
}
}
}
lfPanel.add(lookAndFeelBox);
lfLabel.setLabelFor(lookAndFeelBox);
JLabel restartLabel = new JLabel(app.getLabel("properties.restart"));
lfPanel.add(restartLabel);
JPanel fontPanel = new JPanel();
fontPanel.setOpaque(false);
box.add(fontPanel);
JLabel fontLabel = createLabel("properties.font");
fontPanel.add(fontLabel);
GraphicsEnvironment env =
GraphicsEnvironment.getLocalGraphicsEnvironment();
fontBox = new JComboBox<String>(env.getAvailableFontFamilyNames());
fontBox.setSelectedItem(properties.getFontName());
fontBox.addItemListener(this);
fontPanel.add(fontBox);
int style = properties.getFontStyle();
boldBox = createCheckBox("properties.bold", "font",
(style & Font.BOLD) != 0);
fontPanel.add(boldBox);
italicBox = createCheckBox("properties.italic", "font",
(style & Font.ITALIC) != 0);
fontPanel.add(italicBox);
JLabel fontSizeLabel = createLabel("properties.size.font");
fontPanel.add(fontSizeLabel);
fontSizeBox = new JSpinner(
new SpinnerNumberModel(properties.getFontSize(), 2,100,1));
fontPanel.add(fontSizeBox);
fontSizeLabel.setLabelFor(fontSizeBox);
fontSizeBox.addChangeListener(this);
JPanel p = new JPanel();
box.add(p);
fontSample = new JLabel(app.getLabel("properties.font.sample"));
p.setBackground(Color.white);
p.setOpaque(true);
p.setBorder(BorderFactory.createEtchedBorder());
p.add(fontSample);
updateFontSample();
JPanel buttonPanel = new JPanel();
getContentPane().add(buttonPanel, "South");
buttonPanel.add(app.createOkayButton(this));
buttonPanel.add(app.createCancelButton(this));
JButton helpButton = new JButton(app.getLabel("button.help"));
helpButton.setMnemonic(app.getMnemonic("button.help"));
app.enableHelpOnButton(helpButton, "properties");
buttonPanel.add(helpButton);
pack();
setLocationRelativeTo(app);
updateOverride();
}
private void newTab(JTabbedPane tabbedPane, JComponent comp,
String label)
{
tabbedPane.add(app.getLabel(label), comp);
tabbedPane.setMnemonicAt(tabbedPane.getTabCount()-1,
app.getMnemonic(label));
}
private JRadioButton createRadioButton(String label, String action,
ButtonGroup bg)
{
JRadioButton button = new JRadioButton(app.getLabel(label));
button.setMnemonic(app.getMnemonic(label));
button.setActionCommand(action);
button.addActionListener(this);
bg.add(button);
button.setOpaque(false);
return button;
}
private JCheckBox createCheckBox(String parent, String label, boolean set)
{
JCheckBox box = new JCheckBox(app.getLabel(parent, label), set);
box.setMnemonic(app.getMnemonic(parent, label));
box.setActionCommand(label);
box.addActionListener(this);
box.setOpaque(false);
return box;
}
private JLabel createLabel(String label)
{
JLabel comp = new JLabel(app.getLabel(label));
comp.setDisplayedMnemonic(app.getMnemonic(label));
return comp;
}
private File getDir()
{
String makeindexApp = app.getMakeIndexApp();
String xindyApp = app.getXindyApp();
if ((makeindexApp == null || makeindexApp.equals(""))
&&(xindyApp == null || xindyApp.equals("")))
{
try
{
Process p = Runtime.getRuntime().exec("kpsewhich texmf.cnf");
if (p.waitFor() == 0)
{
BufferedReader in = null;
try
{
in = new BufferedReader(
new InputStreamReader(p.getInputStream(),
app.getEncoding()));
String line = in.readLine();
if (line != null)
{
File dir = (new File(line)).getParentFile();
if (dir.isDirectory())
{
return dir;
}
}
}
finally
{
if (in != null)
{
in.close();
}
}
}
}
catch (Exception e)
{
}
}
return new File(properties.getDefaultDirectory());
}
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
if (action == null) return;
if (action.equals("disablecustom"))
{
customField.setEnabled(false);
}
else if (action.equals("enablecustom"))
{
customField.setEnabled(true);
customField.requestFocusInWindow();
}
else if (action.equals("font"))
{
updateFontSample();
}
else if (action.equals("cancel"))
{
setVisible(false);
}
else if (action.equals("override"))
{
updateOverride();
}
else if (action.equals("okay"))
{
properties.setMakeIndexApp(makeindexField.getFileName());
properties.setXindyApp(xindyField.getFileName());
properties.setDefaultLanguage((String)languageBox.getSelectedItem());
properties.setDefaultCodePage(currentModule.getSelectedCodePage());
String variant = currentModule.getSelectedVariant();
if (variant != null)
{
properties.setDefaultXindyVariant(variant);
}
properties.setOverride(overrideBox.isSelected());
properties.setDocDefsCheck(docDefCheckBox.isSelected());
properties.setMissingLangCheck(missingLangModBox.isSelected());
if (homeButton.isSelected())
{
properties.setDefaultHomeDir();
}
else if (lastButton.isSelected())
{
properties.setDefaultLastDir();
}
else
{
String fileName = customField.getFileName();
if (fileName.equals(""))
{
app.error(this, app.getLabel("error.missing_dir_name"));
return;
}
File file = new File(fileName);
if (!file.isDirectory())
{
app.error(this,
app.getLabelWithValues("error.no_such_directory", fileName));
}
properties.setDefaultCustomDir(fileName);
}
boolean fontChanged=false;
String oldFont = properties.getFontName();
String newFont = (String)fontBox.getSelectedItem();
int oldStyle = properties.getFontStyle();
int newStyle = Font.PLAIN;
int oldSize = properties.getFontSize();
int newSize = ((Number)fontSizeBox.getValue()).intValue();
if (boldBox.isSelected())
{
newStyle = Font.BOLD;
}
if (italicBox.isSelected())
{
newStyle = newStyle | Font.ITALIC;
}
if (!oldFont.equals(newFont))
{
fontChanged = true;
properties.setFontName(newFont);
}
if (oldStyle != newStyle)
{
fontChanged = true;
properties.setFontStyle(newStyle);
}
if (oldSize != newSize)
{
fontChanged = true;
properties.setFontSize(newSize);
}
if (fontChanged)
{
app.updateFont();
}
properties.setLookAndFeel(
(UIManager.LookAndFeelInfo)lookAndFeelBox.getSelectedItem());
setVisible(false);
}
}
public void display()
{
setVisible(true);
}
private void updateOverride()
{
boolean enable = overrideBox.isSelected();
langLabel.setEnabled(enable);
languageBox.setEnabled(enable);
currentModule.setEnabled(enable);
}
public void setXindy(File path)
{
xindyField.setFile(path);
}
public void setMakeIndex(File path)
{
makeindexField.setFile(path);
}
private void initVariants(String lang, String defVariant, String defCode)
{
HashMap<String,XindyModule> modules = XindyModule.getKnownModules();
for (Iterator<String> it = modules.keySet().iterator(); it.hasNext();)
{
String key = it.next();
XindyModule mod = modules.get(key);
XindyModulePanel panel;
if (lang.equals(key))
{
panel = new XindyModulePanel(app, mod, defVariant, defCode);
currentModule = panel;
}
else
{
panel = new XindyModulePanel(app, mod);
}
modulesPanel.add(panel);
xindyModuleLayout.addLayoutComponent(panel, key);
}
xindyModuleLayout.show(modulesPanel, lang);
}
public void itemStateChanged(ItemEvent e)
{
Object source = e.getSource();
if (source == languageBox)
{
updateXindyModule();
}
else if (source == fontBox)
{
updateFontSample();
}
}
public void stateChanged(ChangeEvent e)
{
if (e.getSource() == fontSizeBox)
{
updateFontSample();
}
}
private void updateFontSample()
{
int style = Font.PLAIN;
if (boldBox.isSelected())
{
style = Font.BOLD;
}
if (italicBox.isSelected())
{
style = style | Font.ITALIC;
}
fontSample.setFont(new Font((String)fontBox.getSelectedItem(),
style, ((Number)fontSizeBox.getValue()).intValue()));
fontSample.repaint();
}
public void updateFontSize(int size)
{
fontSizeBox.setValue(size);
}
private void updateXindyModule()
{
String language = (String)languageBox.getSelectedItem();
for (int i = 0, n = modulesPanel.getComponentCount(); i < n; i++)
{
Component comp = modulesPanel.getComponent(i);
if (comp.getName().equals(language))
{
currentModule = (XindyModulePanel)comp;
xindyModuleLayout.show(modulesPanel, language);
return;
}
}
app.debug("Can't find module panel for language "+language);
currentModule = (XindyModulePanel)modulesPanel.getComponent(0);
xindyModuleLayout.first(modulesPanel);
}
private MakeGlossariesGUI app;
private CardLayout xindyModuleLayout;
private JPanel modulesPanel;
private JLabel langLabel, fontSample;
private XindyModulePanel currentModule;
private JRadioButton homeButton, lastButton, customButton;
private JComboBox<String> languageBox, fontBox;
private JComboBox<UIManager.LookAndFeelInfo> lookAndFeelBox;
private JSpinner fontSizeBox;
private FileField customField, makeindexField, xindyField;
private JFileChooser fileChooser;
private JCheckBox overrideBox, docDefCheckBox, missingLangModBox,
boldBox, italicBox;
private MakeGlossariesProperties properties;
}
class XindyModulePanel extends JPanel
{
public XindyModulePanel(MakeGlossariesGUI app, XindyModule module)
{
this(app, module, null, null);
}
public XindyModulePanel(MakeGlossariesGUI app,
XindyModule module, String defVar, String defCode)
{
super();
setName(module.getLanguage());
this.module = module;
setOpaque(false);
encodingLabel = new JLabel(app.getLabel("properties.encoding"));
encodingLabel.setDisplayedMnemonic(app.getMnemonic("properties.encoding"));
add(encodingLabel);
codePageBox = new JComboBox<String>(module.getCodePages());
add(codePageBox);
if (defCode != null)
{
codePageBox.setSelectedItem(defCode);
}
else
{
codePageBox.setSelectedIndex(codePageBox.getItemCount()-1);
}
encodingLabel.setLabelFor(codePageBox);
if (module.hasVariants())
{
variantBox = new JComboBox<String>(module.getVariants());
variantBox.setSelectedItem(
defVar == null ? module.getDefaultVariant() : defVar);
add(variantBox);
}
}
public String getSelectedVariant()
{
return variantBox == null ? null :
(String)variantBox.getSelectedItem();
}
public String getSelectedCodePage()
{
return (String)codePageBox.getSelectedItem();
}
public void setEnabled(boolean enabled)
{
if (variantBox != null)
{
variantBox.setEnabled(enabled);
}
encodingLabel.setEnabled(enabled);
codePageBox.setEnabled(enabled);
}
private XindyModule module;
private JComboBox<String> variantBox = null;
private JComboBox<String> codePageBox = null;
private JLabel encodingLabel;
}
class LookAndFeelCellRenderer extends DefaultListCellRenderer
{
public Component getListCellRendererComponent(JList<?> list,
Object value, int index, boolean isSelected, boolean cellHasFocus)
{
Component comp = super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
if (value instanceof UIManager.LookAndFeelInfo)
{
setText(((UIManager.LookAndFeelInfo)value).getName());
}
return comp;
}
}