001: package Language.Editor;
002:
003: import Schmortopf.Utility.SortableTable.*;
004: import Schmortopf.Utility.gui.*;
005: import Language.*;
006:
007: import java.awt.*;
008: import java.awt.event.*;
009: import javax.swing.*;
010: import javax.swing.event.*;
011: import javax.swing.table.*;
012: import java.util.*;
013: import java.io.*;
014: import java.net.*;
015:
016: /** to edit the application sentences
017: */
018: public class TranslationEditor extends JFrame implements
019: ListSelectionListener {
020: SentenceDictionary actualDictionary = null;
021: SentenceDictionary helpTranslation = null;
022:
023: final SentencesTableModel sentencesTableModel = new SentencesTableModel();
024: SortableTableModel sortableTableModel;
025:
026: JTextArea textEnglish = new JTextArea("", 4, 70);
027: JTextArea textTranslated = new JTextArea("", 5, 70);
028:
029: final JTable sentencesTable = new JTable();
030: final SearchStringTableCellRenderer searchStringTableCellRenderer = new SearchStringTableCellRenderer();
031:
032: public static String TITLE = "Translator" + " 2.0 ";
033:
034: final JLabel translationLabel = new JContrastLabel("Translation");
035: JButton saveTranslation;
036:
037: // another language
038: JTextArea textAlternateTranslated = new JTextArea("", 4, 70);
039: JLabel alternateTranslationLabel = new JContrastLabel(
040: "Translation in the help language");
041: JPanel panAlternateText;
042:
043: TranslationEditor ref = null;
044:
045: // the english sentences
046: //private final Vector englishSentences = new Vector();
047:
048: String[] languagesNamesFoundOnDisk = null;
049:
050: public TranslationEditor() {
051: super ();
052: ref = this ;
053:
054: // list of languages found on the disk in Language/
055: languagesNamesFoundOnDisk = Language.GetInstance()
056: .GetAvailableLanguages();
057:
058: this .setTitle(TITLE);
059: getContentPane().setLayout(new BorderLayout());
060:
061: JPanel trPanel = new JPanel();
062: trPanel.setLayout(new BoxLayout(trPanel, BoxLayout.Y_AXIS));
063:
064: JScrollPane jsp = new JScrollPane(sentencesTable);
065:
066: JSplitPane splitPane = new JSplitPane(
067: JSplitPane.VERTICAL_SPLIT, jsp, trPanel);
068: splitPane.setOneTouchExpandable(true);
069:
070: getContentPane().add(splitPane, BorderLayout.CENTER);
071:
072: JPanel panText = new JPanel(new BorderLayout());
073: trPanel.add(panText);
074: panText.add(new JContrastLabel("English original sentence:"),
075: BorderLayout.NORTH);
076: panText.add(wrapLeft(new JScrollPane(textEnglish), 20),
077: BorderLayout.CENTER);
078:
079: panAlternateText = new JPanel(new BorderLayout());
080:
081: trPanel.add(panAlternateText);
082: panAlternateText.add(alternateTranslationLabel,
083: BorderLayout.NORTH);
084: panAlternateText.add(wrapLeft(new JScrollPane(
085: textAlternateTranslated), 20), BorderLayout.CENTER);
086: textAlternateTranslated.setEditable(false);
087:
088: textEnglish.setBackground(UIManager
089: .getColor("Label.background"));
090: textAlternateTranslated.setBackground(UIManager
091: .getColor("Label.background"));
092:
093: createMenu();
094:
095: textEnglish.setEditable(false);
096:
097: JPanel panTransl = new JPanel(new BorderLayout());
098: trPanel.add(panTransl);
099: panTransl.add(translationLabel, BorderLayout.NORTH);
100: panTransl.add(wrapLeft(new JScrollPane(textTranslated), 20),
101: BorderLayout.CENTER);
102:
103: saveTranslation = new JButton("Save Translation");
104: saveTranslation.setBackground(Color.orange);
105: JPanel btPanel = new JPanel();
106: btPanel.add(saveTranslation);
107: panTransl.add(btPanel, BorderLayout.SOUTH);
108:
109: saveTranslation.addActionListener(new ActionListener() {
110: public void actionPerformed(ActionEvent e) {
111: saveActualTranslation();
112: }
113: });
114:
115: JPanel northPanel = new EFCNGradientPanel(new FlowLayout(
116: FlowLayout.LEFT, 5, 5),
117: EFCNGradientPanel.ApplyVerticalHighLight,
118: EFCNGradientPanel.MediumGradientStrength,
119: EFCNGradientPanel.PanelBackground);
120:
121: getContentPane().add(northPanel, BorderLayout.NORTH);
122:
123: // load parsed sentences from the file in the language directory
124: final Vector englishSentences = SourceSentencesParser
125: .ReadEnglishSourceCodeSentencesFromFile();
126:
127: if (englishSentences.size() == 0) {
128: System.out
129: .println("No sentences found in Language/english_sentences.vec, trying to load from jar");
130:
131: // load parsed sentences from the jar file
132: try {
133: englishSentences.addAll(SourceSentencesParser
134: .ReadEnglishSentencesVectorFromJarFile());
135: } catch (Exception e) {
136: }
137:
138: if (englishSentences.size() == 0) {
139: JOptionPane
140: .showMessageDialog(
141: ref,
142: "The original english sentences to translate were not found on your system."
143: + "\nPlease download and install the latest optional language pack or parse"
144: + "\nthe source code with the utility Language/SourceSentencesParserEditor.java"
145: + "\nand install the generated english_sentences.vec file in the directory Language/"
146: + "\nlocated in the same directory as Schmortopf.jar.",
147: "The file english_sentences.vec is missing.",
148: JOptionPane.ERROR_MESSAGE);
149: }
150: }
151:
152: Vector toShow = updateAllDictionaries(englishSentences);
153:
154: if (toShow.size() == 0) {
155: JOptionPane
156: .showMessageDialog(ref,
157: "There are no sentences to translate, in any language");
158: }
159:
160: final JComboBox langCB = new JComboBox((String[]) toShow
161: .toArray(new String[toShow.size()]));
162: northPanel.add(new JContrastLabel("Language "));
163: northPanel.add(langCB);
164: langCB.addActionListener(new ActionListener() {
165: public void actionPerformed(ActionEvent e) {
166: if (actualDictionary != null) {
167: try {
168: System.out.println("saving...");
169: actualDictionary.saveToFile();
170: } catch (Exception ee) {
171: //ee.printStackTrace();
172: }
173: } else {
174: System.out.println("actual dic = null");
175: }
176:
177: actualDictionary = Language.GetInstance()
178: .getDictionaryFromFile(
179: (String) langCB.getSelectedItem(),
180: false);
181:
182: if (actualDictionary == null) {
183: sentencesTable.setEnabled(false);
184: setTitle(TITLE + " [No dictionary loaded]");
185: } else {
186: boolean isEditable = actualDictionary
187: .getIsEditable();
188: textTranslated.setEditable(isEditable);
189: saveTranslation.setVisible(isEditable);
190:
191: if (!isEditable) {
192: File dicFile = new File("Language/"
193: + (String) langCB.getSelectedItem()
194: + ".translation");
195: if (dicFile.exists() && !dicFile.canWrite()) {
196: JOptionPane
197: .showMessageDialog(
198: ref,
199: "The language file "
200: + dicFile
201: .getAbsolutePath()
202: + "is not editable\nbecause the file flag is read-only.",
203: "Warning",
204: JOptionPane.WARNING_MESSAGE);
205: } else {
206: JOptionPane.showMessageDialog(ref,
207: "The language is not editable",
208: "Warning",
209: JOptionPane.WARNING_MESSAGE);
210: }
211: }
212:
213: setTitle(TITLE
214: + " ["
215: + actualDictionary.getFileName()
216: + "] "
217: + actualDictionary
218: .getNumberOfTranslatedSentences()
219: + " translated words");
220: sentencesTable.setEnabled(true);
221:
222: sentencesTableModel.setDictionary(actualDictionary,
223: isEditable);
224: }
225: }
226: });
227:
228: sortableTableModel = new SortableTableModel(sentencesTableModel);
229: sentencesTable.setModel(sortableTableModel);
230: sortableTableModel.installGUI(sentencesTable);
231: int fontSize = UIManager.getFont("Label.font").getSize();
232: sentencesTable.getColumnModel().getColumn(0).setPreferredWidth(
233: fontSize * 12);
234: sentencesTable.getColumnModel().getColumn(1).setPreferredWidth(
235: fontSize * 12);
236:
237: northPanel.add(new JContrastLabel(" Search in sentences: "));
238: final JTextField searchTF = new JTextField("", 8);
239: northPanel.add(searchTF);
240: searchTF.addKeyListener(new KeyAdapter() {
241: public void keyPressed(KeyEvent e) {
242: }
243:
244: public void keyTyped(KeyEvent e) {
245: }
246:
247: public void keyReleased(KeyEvent e) {
248: sortableTableModel.search(searchTF.getText());
249: searchStringTableCellRenderer.setSearchstring(searchTF
250: .getText());
251: //if(actualDictionary==null)
252: {
253: sentencesTable.updateUI();
254: }
255: }
256: });
257:
258: // selection when focus
259: searchTF.addFocusListener(new FocusAdapter() {
260: public void focusGained(FocusEvent e) {
261: searchTF.setSelectionStart(0);
262: searchTF.setSelectionEnd(searchTF.getText().length());
263: }
264: });
265: textEnglish.addFocusListener(new FocusAdapter() {
266: public void focusGained(FocusEvent e) {
267: textEnglish.setSelectionStart(0);
268: textEnglish.setSelectionEnd(textEnglish.getText()
269: .length());
270: }
271: });
272:
273: this .addWindowListener(new WindowAdapter() {
274: public void windowClosing(WindowEvent e) {
275: terminateFrame();
276: }
277:
278: public void windowClosed(WindowEvent e) {
279: terminateFrame();
280: }
281: });
282:
283: sentencesTable.getSelectionModel().addListSelectionListener(
284: this );
285: sentencesTable
286: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
287: //sentencesTable.setDefaultRenderer(String.class, searchStringTableCellRenderer);
288:
289: final Dimension screen = Toolkit.getDefaultToolkit()
290: .getScreenSize();
291: splitPane.setDividerLocation(screen.height / 2);
292:
293: this .setSize(screen.width - 20, screen.height - 30);
294: this .setLocation(10, 5);
295: this .setVisible(true);
296:
297: // select first avaiable language for traduction
298: if (langCB.getModel().getSize() > 0) {
299: langCB.setSelectedIndex(0);
300: }
301:
302: } // Constructor
303:
304: /** menubar
305: */
306: private void createMenu() {
307: this .setJMenuBar(new JMenuBar());
308: JMenu menuFile = new JMenu("File");
309: this .getJMenuBar().add(menuFile);
310:
311: JMenuItem newLanguage = new JMenuItem(
312: "Create New Language Pack");
313: menuFile.add(newLanguage);
314: newLanguage.addActionListener(new ActionListener() {
315: public void actionPerformed(ActionEvent e) {
316: String rep = JOptionPane.showInputDialog(ref,
317: "Enter the name of the new language");
318: if (rep != null) {
319: Language.GetInstance().setActualTranslation(rep,
320: false);
321: SentenceDictionary sd = Language.GetInstance()
322: .getDictionaryFromFile(rep, false);
323: try {
324: sd.saveToFile();
325: JOptionPane
326: .showMessageDialog(ref,
327: "You must restart the translation editor to see the new language");
328: } catch (Exception ex) {
329: ex.printStackTrace();
330: JOptionPane.showMessageDialog(ref, "Error: "
331: + ex.getMessage());
332: }
333: }
334: }
335: });
336:
337: JMenuItem quit = new JMenuItem("Quit");
338: menuFile.addSeparator();
339: menuFile.add(quit);
340: quit.addActionListener(new ActionListener() {
341: public void actionPerformed(ActionEvent e) {
342: terminateFrame();
343: }
344: });
345:
346: JMenu menuLang = new JMenu("Translation Help Language");
347: this .getJMenuBar().add(menuLang);
348: ButtonGroup bg = new ButtonGroup();
349:
350: int act = -1;
351: for (int i = 0; i < this .languagesNamesFoundOnDisk.length; i++) {
352: String at = Language.GetInstance().GetActualTranslation();
353: JRadioButtonMenuItem lmi = new JRadioButtonMenuItem(
354: languagesNamesFoundOnDisk[i], at
355: .equals(languagesNamesFoundOnDisk[i]));
356:
357: if (at.equals(languagesNamesFoundOnDisk[i]))
358: act = i;
359:
360: bg.add(lmi);
361: menuLang.add(lmi);
362: final int ii = i;
363: lmi.addActionListener(new ActionListener() {
364: public void actionPerformed(ActionEvent e) {
365: helpTranslation = Language
366: .GetInstance()
367: .getDictionaryFromFile(
368: languagesNamesFoundOnDisk[ii], true);
369: }
370: });
371: }
372:
373: if (act != -1) {
374: helpTranslation = Language.GetInstance()
375: .getDictionaryFromFile(
376: languagesNamesFoundOnDisk[act], true);
377: }
378:
379: JMenu menuUtils = new JMenu("Utilities");
380: this .getJMenuBar().add(menuUtils);
381:
382: JMenuItem viewTextOfAllSentences = new JMenuItem(
383: "View text of all translated sentences");
384: menuUtils.add(viewTextOfAllSentences);
385: viewTextOfAllSentences.addActionListener(new ActionListener() {
386: public void actionPerformed(ActionEvent e) {
387: JTextArea ta = new JTextArea();
388: if (actualDictionary != null) {
389: ta.append(actualDictionary
390: .getStringOfAllTranslatedSentences());
391: }
392:
393: JDialog dialog = new JDialog(TranslationEditor.this ,
394: "All translated sentences", false);
395: dialog.getContentPane().setLayout(new BorderLayout());
396: dialog.getContentPane().add(new JScrollPane(ta),
397: BorderLayout.CENTER);
398: dialog.setSize(400, 600);
399: dialog.setVisible(true);
400: }
401: });
402:
403: }
404:
405: /** update all the dictionaries with the new words and return a list of
406: names of valid dictionaries
407: */
408: private Vector updateAllDictionaries(Vector englishSentences) {
409: // only show languages for which a translation is required and ignore english
410: // that don't require a translation
411: Vector languagesNames = new Vector();
412: for (int i = 0; i < languagesNamesFoundOnDisk.length; i++) {
413: String langName = languagesNamesFoundOnDisk[i];
414: if (!langName.equals(Language.ENGLISH)) {
415: SentenceDictionary sd = Language.GetInstance()
416: .getDictionaryFromFile(langName, false);
417: if (sd != null) {
418: languagesNames.addElement(langName);
419:
420: if (sd.getIsEditable()) {
421: // only if the list is not empty
422: if (englishSentences.size() > 0) {
423: sd
424: .updateSentencesFromSource(englishSentences);
425:
426: // save
427: try {
428: sd.saveToFile();
429: } catch (Exception e) {
430: e.printStackTrace();
431: }
432: }
433: } else {
434: System.out
435: .println("No updates performed for "
436: + langName
437: + ", file not existing or not editable");
438: }
439: }
440: }
441: }
442: return languagesNames;
443: }
444:
445: /** list selection changed
446: */
447: public void valueChanged(ListSelectionEvent e) {
448: //### ask to save actual translation, if required
449: int sel = sentencesTable.getSelectedRow();
450:
451: if (sel != -1 && actualDictionary != null) {
452: int pos = sortableTableModel
453: .getIndexInUnsortedFromTablePos(sel);
454: Sentence sent = sentencesTableModel.getSentenceAt(pos);
455:
456: String eng = sent.getSentence();
457: String tra = sent.getTranslation();
458: String classLocation = sent.getLocationClass();
459: int linePos = sent.getLinePosition();
460:
461: try {
462: int na = Common.GetNumberOfParametersInSentence(eng);
463: } catch (Exception ee) {
464: JOptionPane.showMessageDialog(this , ee.getMessage(),
465: "Bad arguments", JOptionPane.WARNING_MESSAGE);
466: }
467:
468: textEnglish.setText(eng);
469:
470: //no influence... ???
471: textEnglish.setSelectionStart(0);
472: textEnglish.setSelectionEnd(eng.length());
473: //textEnglish.requestFocus();
474:
475: textTranslated.setText(tra);
476: //textTranslated.requestFocus();
477:
478: if (helpTranslation != null) {
479: String helpTr = helpTranslation
480: .getTranslatedSentence(eng);
481: textAlternateTranslated.setText(helpTr);
482: } else {
483: textAlternateTranslated.setText("");
484: }
485:
486: } else {
487: textEnglish.setText("");
488: textTranslated.setText("");
489: //locationTA.setText("");
490: textAlternateTranslated.setText("");
491: }
492: }
493:
494: /** user pressed the save button
495: */
496: private void saveActualTranslation() {
497: String to = textEnglish.getText();
498: String tr = textTranslated.getText();
499:
500: // ignore if any is blank
501: if (to.equals("") || tr.equals(""))
502: return;
503:
504: if (actualDictionary != null) {
505: int ne = -1;
506: try {
507: ne = Common.GetNumberOfParametersInSentence(to);
508: } catch (Exception ee) {
509: // already tested ...JOptionPane.showMessageDialog(ref, e.getMessage());
510: }
511: int nt = -1;
512: try {
513: nt = Common.GetNumberOfParametersInSentence(tr);
514: if (nt != ne)
515: throw new Exception(
516: Language
517: .Translate("Translated sentence has not the same number of parameters as the original sentence.")
518: + Language
519: .Translate(
520: "\nOrignal has %1 and translated has %2",
521: "" + ne, "" + nt));
522: } catch (Exception ee) {
523: JOptionPane.showMessageDialog(this , Language.Translate(
524: "Error: %.", ee.getMessage()));
525:
526: return;
527: //if(rep!= JOptionPane.OK_OPTION) return;
528: }
529:
530: // ok,save
531: System.out.println("add translation " + to + " => " + tr);
532: final int sr = sentencesTable.getSelectedRow();
533:
534: actualDictionary.addTranslation(to, tr);
535:
536: EventQueue.invokeLater(new Runnable() {
537: public void run() {
538: if (sr < sentencesTable.getRowCount()) {
539: sentencesTable.getSelectionModel()
540: .setSelectionInterval(sr, sr);
541: }
542:
543: if (actualDictionary != null) {
544: setTitle(TITLE
545: + " ["
546: + actualDictionary.getFileName()
547: + "] "
548: + actualDictionary
549: .getNumberOfTranslatedSentences()
550: + " translated words");
551: }
552: }
553: });
554:
555: }
556: }
557:
558: public static boolean standalone = false;
559:
560: private void terminateFrame() {
561: if (actualDictionary != null)
562: try {
563: actualDictionary.saveToFile();
564: } catch (Exception ee) {
565: ee.printStackTrace();
566: }
567:
568: //Language.GetInstance().saveActualLanguageSentences();
569:
570: if (standalone) {
571: System.exit(0);
572: } else {
573: setVisible(false);
574: }
575: }
576:
577: /** load an ImageIcon, either in the jar file (during the normal execution)
578: * or in the source path, during the development.
579: */
580: public static synchronized ImageIcon LoadImageIcon(String name) {
581: ClassLoader cl = TranslationEditor.class.getClassLoader();
582:
583: if (cl == null) {
584: System.out.println("ERROR: class loader is null");
585: return null;
586: }
587:
588: URL url = cl.getResource(name);
589: if (url != null) {
590: // in the jar and with jnlp
591: return new ImageIcon(url);
592: } else {
593: url = cl.getResource("Language/" + name);
594: if (url != null) {
595: // works in the IDE mode
596: return new ImageIcon(url);
597: } else {
598: System.out.println("URL is null, can't find image "
599: + name);
600: return null;
601: }
602: }
603:
604: }
605:
606: /**
607: * sets the design of the header table (fonts, colors, ...)
608: *
609: private void setHeaders(JTable table, boolean ascending, int sortedColumn)
610: {
611: JTableHeader tableHeader = table.getTableHeader();
612: for (int i=0; i<table.getColumnCount(); i++)
613: {
614: TableColumn column = table.getColumnModel().getColumn(i);
615: DefaultTableCellRenderer headerRenderer = new DefaultTableCellRenderer();
616:
617: if(i==sortedColumn)
618: {
619: if (ascending)
620: {
621: headerRenderer.setIcon(SORT_ASC);
622: }
623: else
624: {
625: headerRenderer.setIcon(SORT_DESC);
626: }
627: }
628: else
629: {
630: headerRenderer.setIcon(null);
631: }
632: table.getColumnModel().getColumn(i).setHeaderRenderer(headerRenderer);
633: table.repaint();
634: }
635:
636: } */
637:
638: private JPanel wrapLeft(Component comp, int hgap) {
639: JPanel pan = new JPanel(
640: new FlowLayout(FlowLayout.LEFT, hgap, 0));
641: pan.add(comp);
642: return pan;
643: }
644:
645: /*
646: public static void main(String[] a)
647: {
648: //Language.GetInstance().setActualTranslation("LuzernerSchwytzerdutch");
649: TranslationEditor te = new TranslationEditor();
650: te.standalone = true;
651: }
652: */
653:
654: } // TranslationEditor
|