Skip to content

Commit

Permalink
Added preliminary suppport of TLK language selection for BG(2)EE
Browse files Browse the repository at this point in the history
  • Loading branch information
Argent77 committed Jul 28, 2014
1 parent 75bebb7 commit 65a1300
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 24 deletions.
125 changes: 123 additions & 2 deletions src/infinity/gui/BrowserMenuBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
Expand All @@ -52,8 +54,10 @@
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.prefs.Preferences;

import javax.swing.AbstractButton;
Expand Down Expand Up @@ -320,6 +324,13 @@ public boolean showOffsets()
return optionsMenu.optionShowOffset.isSelected();
}

/** Returns the language code of the selected game language (BG(2)EE only). */
public String getSelectedGameLanguage()
{
Preferences prefs = Preferences.userNodeForPackage(getClass());
return prefs.get(OptionsMenu.OPTION_LANGUAGE_GAME, "");
}

public void storePreferences()
{
Preferences prefs = Preferences.userNodeForPackage(getClass());
Expand Down Expand Up @@ -1115,7 +1126,7 @@ else if (event.getSource() == toolConvImageToPvrz) {
// Options Menu
///////////////////////////////

private static final class OptionsMenu extends JMenu implements ActionListener
private static final class OptionsMenu extends JMenu implements ActionListener, ItemListener
{
private static final Font[] FONTS = {
new Font("Monospaced", Font.PLAIN, 12), new Font("Serif", Font.PLAIN, 12),
Expand Down Expand Up @@ -1171,6 +1182,7 @@ private static final class OptionsMenu extends JMenu implements ActionListener
private static final String OPTION_VIEWOREDITSHOWN = "ViewOrEditShown";
private static final String OPTION_FONT = "Font";
private static final String OPTION_TLKCHARSET = "TLKCharsetType";
private static final String OPTION_LANGUAGE_GAME = "GameLanguage";
private static final String OPTION_TEXT_SHOWCURRENTLINE = "TextShowCurrentLine";
private static final String OPTION_TEXT_SHOWLINENUMBERS = "TextShowLineNumbers";
private static final String OPTION_TEXT_SYMBOLWHITESPACE = "TextShowWhiteSpace";
Expand Down Expand Up @@ -1215,9 +1227,12 @@ private static final class OptionsMenu extends JMenu implements ActionListener
private JCheckBoxMenuItem optionShowOffset, optionIgnoreOverride, optionIgnoreReadErrors;
private JCheckBoxMenuItem optionAutocheckBCS, optionCacheOverride, optionCheckScriptNames;
private JCheckBoxMenuItem optionShowStrrefs;
private final JMenu mCharsetMenu;
private final JMenu mCharsetMenu, mLanguageMenu;
private ButtonGroup bgCharsetButtons;

// Stores available languages in BG(2)EE
private final HashMap<JRadioButtonMenuItem, String> gameLanguage = new HashMap<JRadioButtonMenuItem, String>();

private OptionsMenu(Preferences prefs, NearInfinity browser)
{
super("Options");
Expand Down Expand Up @@ -1486,6 +1501,89 @@ private OptionsMenu(Preferences prefs, NearInfinity browser)
}
mCharsetMenu = initCharsetMenu(charset);
add(mCharsetMenu);

// Options->TLK Language
mLanguageMenu = new JMenu("TLK Language (EE only)");
add(mLanguageMenu);
}

// (Re-)creates a list of available TLK languages
private void resetGameLanguage()
{
final String autodetect = "Autodetect";
final String tlkFileName = "dialog.tlk";

for (JRadioButtonMenuItem r: gameLanguage.keySet()) {
r.removeActionListener(this);
}
mLanguageMenu.removeAll();
gameLanguage.clear();

Preferences prefs = Preferences.userNodeForPackage(getClass());
String selectedCode = prefs.get(OPTION_LANGUAGE_GAME, autodetect);

ButtonGroup bg = new ButtonGroup();
JRadioButtonMenuItem rbmi;

// adding "Autodetect" for all available game ids
rbmi = createLanguageMenuItem("", autodetect,
"Autodetect language from baldur.ini. Defaults to english if not available.", bg, true);
mLanguageMenu.add(rbmi);

if (ResourceFactory.getGameID() == ResourceFactory.ID_BGEE ||
ResourceFactory.getGameID() == ResourceFactory.ID_BG2EE) {
File langFile = new File(ResourceFactory.getRootDir(), "lang");
if (langFile.isDirectory()) {
File[] langFileList = langFile.listFiles();
for (int i = 0; i < langFileList.length; i++) {
if (langFileList[i].isDirectory()) {
if ((new File(langFileList[i], tlkFileName)).isFile()) {
String[] langCode = langFileList[i].getName().split("_");
if (langCode.length >= 2) {
Locale locale = new Locale(langCode[0], langCode[1]);
rbmi = createLanguageMenuItem(langFileList[i].getName(),
String.format("%1$s (%2$s)",
locale.getDisplayLanguage(),
langFileList[i].getName()),
null, bg,
selectedCode.equalsIgnoreCase(langFileList[i].getName()));
mLanguageMenu.add(rbmi);
} else {
rbmi = createLanguageMenuItem(langFileList[i].getName(), langFileList[i].getName(),
null, bg,
selectedCode.equalsIgnoreCase(langFileList[i].getName()));
mLanguageMenu.add(rbmi);
}
}
}
}
}
} else {
rbmi.setEnabled(false);
}
}

// Initializes and returns a radio button menuitem
private JRadioButtonMenuItem createLanguageMenuItem(String code, String name, String tooltip,
ButtonGroup bg, boolean selected)
{
JRadioButtonMenuItem rbmi = null;
if (code == null) {
code = "";
}
if (name != null && !name.isEmpty()) {
rbmi = new JRadioButtonMenuItem(name);
if (tooltip != null && !tooltip.isEmpty()) {
rbmi.setToolTipText(tooltip);
}
if (bg != null) {
bg.add(rbmi);
}
rbmi.setSelected(selected);
rbmi.addItemListener(this);
gameLanguage.put(rbmi, code);
}
return rbmi;
}

private JMenu initCharsetMenu(String charset)
Expand Down Expand Up @@ -1662,6 +1760,8 @@ private void gameLoaded()
{
// update charset selection
StringResource.setCharset(charsetName(getSelectedButtonData()));
// update language selection
resetGameLanguage();
}

private void storePreferences(Preferences prefs)
Expand Down Expand Up @@ -1708,6 +1808,14 @@ private void storePreferences(Preferences prefs)

String charset = getSelectedButtonData();
prefs.put(OPTION_TLKCHARSET, charset);

for (JRadioButtonMenuItem r: gameLanguage.keySet()) {
if (r.isSelected() && r.isEnabled()) {
String lang = gameLanguage.get(r);
prefs.put(OPTION_LANGUAGE_GAME, lang);
break;
}
}
}

// Returns the (first) index of the selected AbstractButton array
Expand Down Expand Up @@ -1888,6 +1996,19 @@ public void actionPerformed(ActionEvent event)
fc = null;
}
}

@Override
public void itemStateChanged(ItemEvent event)
{
if (event.getSource() instanceof JRadioButtonMenuItem &&
gameLanguage.containsKey(event.getSource())) {
if (event.getStateChange() == ItemEvent.SELECTED) {
JOptionPane.showMessageDialog(NearInfinity.getInstance(),
"Please restart NearInfinity to make the changes visible.",
"TLK language changed", JOptionPane.INFORMATION_MESSAGE);
}
}
}
}

///////////////////////////////
Expand Down
57 changes: 35 additions & 22 deletions src/infinity/resource/ResourceFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -435,36 +435,49 @@ private String fetchLanguage(File iniRoot)
final String langDefault = "en_US"; // using default language, if no language entry found

if (currentGame == ID_BGEE || currentGame == ID_BG2EE) {
String iniFileName = games[currentGame].inifile;
if (iniFileName == null || iniFileName.isEmpty())
iniFileName = "baldur.ini";
File iniFile = new File(iniRoot, iniFileName);
if (iniFile.exists()) {
try {
BufferedReader br = new BufferedReader(new FileReader(iniFile));
String line = br.readLine();
while (line != null) {
if (line.contains("'Language'")) {
String[] entries = line.split(",");
if (entries.length == 3) {
String lang = entries[2].replace('\'', ' ').trim();
if (lang.matches("[a-z]{2}_[A-Z]{2}")) {
if (new File(rootDir, "lang" + File.separator + lang).exists()) {
br.close();
return lang;
String lang = BrowserMenuBar.getInstance().getSelectedGameLanguage();

if (lang == null || lang.isEmpty()) {
// Attempting to autodetect game language
String iniFileName = games[currentGame].inifile;
if (iniFileName == null || iniFileName.isEmpty())
iniFileName = "baldur.ini";
File iniFile = new File(iniRoot, iniFileName);
if (iniFile.exists()) {
try {
BufferedReader br = new BufferedReader(new FileReader(iniFile));
String line = br.readLine();
while (line != null) {
if (line.contains("'Language'")) {
String[] entries = line.split(",");
if (entries.length == 3) {
lang = entries[2].replace('\'', ' ').trim();
if (lang.matches("[a-z]{2}_[A-Z]{2}")) {
if (new File(rootDir, "lang" + File.separator + lang).exists()) {
br.close();
return lang;
}
}
}
}
line = br.readLine();
}
line = br.readLine();
br.close();
} catch (IOException e) {
JOptionPane.showMessageDialog(NearInfinity.getInstance(), "Error parsing " + iniFileName +
". Using language defaults.", "Error", JOptionPane.ERROR_MESSAGE);
}
br.close();
} catch (IOException e) {
JOptionPane.showMessageDialog(NearInfinity.getInstance(), "Error parsing " + iniFileName +
". Using language defaults.", "Error", JOptionPane.ERROR_MESSAGE);
}
} else {
// Using user-defined language
if (lang.matches("[a-z]{2}_[A-Z]{2}") &&
new File(rootDir, "lang" + File.separator + lang).exists()) {
return lang;
}
}
}

// falling back to default language
return langDefault;
}

Expand Down

0 comments on commit 65a1300

Please sign in to comment.