001 /*
002 * Copyright 2002 - 2007 JEuclid, http://jeuclid.sf.net
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 /* $Id: MainFrame.java,v 0b66106c7ff7 2010/08/06 15:35:06 max $ */
018
019 package net.sourceforge.jeuclid.app.mathviewer;
020
021 import java.awt.BorderLayout;
022 import java.awt.Point;
023 import java.awt.Toolkit;
024 import java.awt.datatransfer.DataFlavor;
025 import java.awt.datatransfer.StringSelection;
026 import java.awt.datatransfer.Transferable;
027 import java.awt.event.ActionEvent;
028 import java.awt.event.ActionListener;
029 import java.awt.event.KeyEvent;
030 import java.io.File;
031
032 import javax.swing.JCheckBoxMenuItem;
033 import javax.swing.JDialog;
034 import javax.swing.JFrame;
035 import javax.swing.JMenu;
036 import javax.swing.JMenuBar;
037 import javax.swing.JMenuItem;
038 import javax.swing.JOptionPane;
039 import javax.swing.JPanel;
040 import javax.swing.JPopupMenu;
041 import javax.swing.JScrollPane;
042 import javax.swing.JSplitPane;
043 import javax.swing.KeyStroke;
044 import javax.swing.ScrollPaneConstants;
045 import javax.swing.event.DocumentEvent;
046 import javax.swing.event.DocumentListener;
047
048 import net.sourceforge.jeuclid.MathMLSerializer;
049 import net.sourceforge.jeuclid.biparser.BiTree;
050 import net.sourceforge.jeuclid.biparser.NonIncrementalElementException;
051 import net.sourceforge.jeuclid.biparser.ReparseException;
052 import net.sourceforge.jeuclid.biparser.SAXBiParser;
053 import net.sourceforge.jeuclid.biparser.TextPosition;
054 import net.sourceforge.jeuclid.context.LayoutContextImpl;
055 import net.sourceforge.jeuclid.context.Parameter;
056 import net.sourceforge.jeuclid.swing.CursorListener;
057 import net.sourceforge.jeuclid.swing.JMathComponent;
058
059 import org.apache.batik.util.gui.xmleditor.XMLContext;
060 import org.apache.batik.util.gui.xmleditor.XMLEditorKit;
061 import org.apache.batik.util.gui.xmleditor.XMLTextEditor;
062 import org.w3c.dom.Document;
063 import org.w3c.dom.Node;
064
065 /**
066 * Main frame for the MathViewer application.
067 *
068 * @version $Revision: 0b66106c7ff7 $
069 */
070 // CHECKSTYLE:OFF
071 public class MainFrame extends JFrame implements CursorListener {
072 // CHECKSTYLE:OFF
073
074 private static final int DEFAULT_HEIGHT = 400;
075
076 private static final int DEFAULT_WIDTH = 700;
077
078 private static final FileIO FILEIO = FileIO.getInstance();
079
080 // /**
081 // * Logger for this class
082 // */
083 // currently unused.
084 // private static final Log LOGGER = LogFactory.getLog(MainFrame.class);
085
086 private static final long serialVersionUID = 1L;
087
088 private static final float FONT_SIZE_MULTIPLICATOR = 1.20f;
089
090 private JPanel jContentPane;
091
092 private JMenuBar jJMenuBar;
093
094 private JMenu fileMenu;
095
096 private JMenu editMenu;
097
098 private JMenu helpMenu;
099
100 private JMenuItem exitMenuItem;
101
102 private JMenuItem unformattedCopyMenuItem;
103
104 private JMenuItem formattedCopyMenuItem;
105
106 private JMenuItem pasteMenuItem;
107
108 private JMenuItem aboutMenuItem;
109
110 private JMenuItem openMenuItem;
111
112 private JDialog aboutDialog;
113
114 private JSplitPane splitPane;
115
116 private JScrollPane scrollPane;
117
118 private JScrollPane scrollPane2;
119
120 private XMLTextEditor xmlEditor;
121
122 private JMathComponent mathComponent;
123
124 private BiTree biTree;
125
126 private JMenu viewMenu;
127
128 private JMenuItem refreshMenuItem;
129
130 private JMenuItem biggerMenuItem;
131
132 private JMenuItem smallerMenuItem;
133
134 private JMenuItem exportMenuItem;
135
136 private JCheckBoxMenuItem aliasMenuItem;
137
138 private JCheckBoxMenuItem debugMenuItem;
139
140 // ==================================================
141 // context menu elements
142 // ==================================================
143
144 private JPopupMenu contextPopupMenu;
145
146 private JMenu insertMenu;
147
148 private JMenu greekMenu;
149
150 private JMenu logicsMenu;
151
152 private JMenu symbolsMenu;
153
154 private JMenuItem c_refreshMenuItem;
155
156 private JMenuItem tableMenuItem;
157
158 private JMenuItem polynomMenuItem;
159
160 private JMenuItem orMenuItem;
161
162 private JMenuItem andMenuItem;
163
164 private JMenuItem notMenuItem;
165
166 private JMenuItem alphaMenuItem;
167
168 private JMenuItem betaMenuItem;
169
170 private JMenuItem gammaMenuItem;
171
172 private JMenuItem deltaMenuItem;
173
174 private JMenuItem omegaMenuItem;
175
176 private JMenuItem existsMenuItem;
177
178 private JMenuItem forallMenuItem;
179
180 /**
181 * This is the default constructor.
182 */
183 public MainFrame() {
184 super();
185 this.initialize();
186 }
187
188 @Override
189 public void updateCursorPosition(final Node node) {
190 final TextPosition result = this.biTree.searchNode(node);
191 if (result != null
192 && result.getTotalOffset() < this.getXMLEditor().getText()
193 .length()) {
194 this.getXMLEditor().requestFocusInWindow();
195 this.getXMLEditor().setCaretPosition(result.getTotalOffset());
196 this.getXMLEditor().setSelectionStart(result.getTotalOffset());
197 this.getXMLEditor().setSelectionEnd(
198 result.getTotalOffset() + result.getLength());
199 }
200 }
201
202 /**
203 * This method initializes this
204 *
205 * @return void
206 */
207 private void initialize() {
208 this.setJMenuBar(this.getJJMenuBar());
209 this.setSize(MainFrame.DEFAULT_WIDTH, MainFrame.DEFAULT_HEIGHT);
210 this.setContentPane(this.getJContentPane());
211 this.setTitle(Messages.getString("MathViewer.windowTitle")); //$NON-NLS-1$
212 this.setLocationByPlatform(true);
213 }
214
215 /**
216 * This method initializes jContentPane
217 *
218 * @return javax.swing.JPanel
219 */
220 private JPanel getJContentPane() {
221 if (this.jContentPane == null) {
222 this.jContentPane = new JPanel();
223 this.jContentPane.setLayout(new BorderLayout());
224 this.jContentPane.add(this.getSplitPane(), BorderLayout.CENTER);
225 }
226 return this.jContentPane;
227 }
228
229 /**
230 * This method initializes jJMenuBar
231 *
232 * @return javax.swing.JMenuBar
233 */
234 private JMenuBar getJJMenuBar() {
235 if (this.jJMenuBar == null) {
236 this.jJMenuBar = new JMenuBar();
237 this.jJMenuBar.add(this.getFileMenu());
238 this.jJMenuBar.add(this.getEditMenu());
239 this.jJMenuBar.add(this.getViewMenu());
240 if (!MathViewer.OSX) {
241 // This will need to be changed once the Help menu contains
242 // more that just the About item.
243 this.jJMenuBar.add(this.getHelpMenu());
244 }
245 }
246 return this.jJMenuBar;
247 }
248
249 /**
250 * This method initializes jMenu
251 *
252 * @return javax.swing.JMenu
253 */
254 private JMenu getFileMenu() {
255 if (this.fileMenu == null) {
256 this.fileMenu = new JMenu();
257 this.fileMenu.setText(Messages.getString("MathViewer.FileMenu")); //$NON-NLS-1$
258 this.fileMenu.add(this.getOpenMenuItem());
259 this.fileMenu.add(this.getExportMenuItem());
260 if (!MathViewer.OSX) {
261 this.fileMenu.add(this.getExitMenuItem());
262 }
263 }
264 return this.fileMenu;
265 }
266
267 /**
268 * This method initializes jMenu
269 *
270 * @return javax.swing.JMenu
271 */
272 private JMenu getEditMenu() {
273 if (this.editMenu == null) {
274 this.editMenu = new JMenu();
275 this.editMenu.setText(Messages.getString("MathViewer.EditMenu")); //$NON-NLS-1$
276 this.editMenu.add(this.getUnformattedCopyMenuItem());
277 this.editMenu.add(this.getFormattedCopyMenuItem());
278 this.editMenu.add(this.getPasteMenuItem());
279 }
280 return this.editMenu;
281 }
282
283 /**
284 * This method initializes jMenu
285 *
286 * @return javax.swing.JMenu
287 */
288 private JMenu getHelpMenu() {
289 if (this.helpMenu == null) {
290 this.helpMenu = new JMenu();
291 this.helpMenu.setText(Messages.getString("MathViewer.helpMenu")); //$NON-NLS-1$
292 // If there are more items, please modify getJJMenuBar to always
293 // display the help menu and this function to not display about on
294 // OS X
295 this.helpMenu.add(this.getAboutMenuItem());
296 }
297 return this.helpMenu;
298 }
299
300 /**
301 * This method initializes jMenuItem
302 *
303 * @return javax.swing.JMenuItem
304 */
305 private JMenuItem getExitMenuItem() {
306 if (this.exitMenuItem == null) {
307 this.exitMenuItem = new JMenuItem();
308 this.exitMenuItem.setText(Messages.getString("MathViewer.exit")); //$NON-NLS-1$
309 this.exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(
310 KeyEvent.VK_Q, Toolkit.getDefaultToolkit()
311 .getMenuShortcutKeyMask(), true));
312
313 this.exitMenuItem.addActionListener(new ActionListener() {
314 public void actionPerformed(final ActionEvent e) {
315 System.exit(0);
316 }
317 });
318 }
319 return this.exitMenuItem;
320 }
321
322 private JMenuItem getUnformattedCopyMenuItem() {
323 if (this.unformattedCopyMenuItem == null) {
324 this.unformattedCopyMenuItem = new JMenuItem();
325 this.unformattedCopyMenuItem.setText(Messages
326 .getString("MathViewer.unformattedCopyFull")); //$NON-NLS-1$
327 // this.unformattedCopyMenuItem.setAccelerator(KeyStroke
328 // .getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit()
329 // .getMenuShortcutKeyMask(), true));
330
331 this.unformattedCopyMenuItem
332 .addActionListener(new ActionListener() {
333 public void actionPerformed(final ActionEvent e) {
334 MainFrame.this.copyFullToClipboard(false);
335 }
336 });
337 }
338 return this.unformattedCopyMenuItem;
339 }
340
341 private JMenuItem getFormattedCopyMenuItem() {
342 if (this.formattedCopyMenuItem == null) {
343 this.formattedCopyMenuItem = new JMenuItem();
344 this.formattedCopyMenuItem.setText(Messages
345 .getString("MathViewer.formattedCopyFull")); //$NON-NLS-1$
346 // this.formattedCopyMenuItem.setAccelerator(KeyStroke.getKeyStroke(
347 // KeyEvent.VK_C, Toolkit.getDefaultToolkit()
348 // .getMenuShortcutKeyMask()
349 // | InputEvent.SHIFT_DOWN_MASK, true));
350
351 this.formattedCopyMenuItem.addActionListener(new ActionListener() {
352 public void actionPerformed(final ActionEvent e) {
353 MainFrame.this.copyFullToClipboard(true);
354 }
355 });
356 }
357 return this.formattedCopyMenuItem;
358 }
359
360 /**
361 * This method initializes jMenuItem
362 *
363 * @return javax.swing.JMenuItem
364 */
365 private JMenuItem getPasteMenuItem() {
366 if (this.pasteMenuItem == null) {
367 this.pasteMenuItem = new JMenuItem();
368 this.pasteMenuItem.setText(Messages
369 .getString("MathViewer.pasteFull")); //$NON-NLS-1$
370 // this.pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(
371 // KeyEvent.VK_V, Toolkit.getDefaultToolkit()
372 // .getMenuShortcutKeyMask(), true));
373
374 this.pasteMenuItem.addActionListener(new ActionListener() {
375 public void actionPerformed(final ActionEvent e) {
376 MainFrame.this.pasteFullFromClipboard();
377 }
378 });
379 }
380 return this.pasteMenuItem;
381 }
382
383 /**
384 * This method initializes jMenuItem
385 *
386 * @return javax.swing.JMenuItem
387 */
388 private JMenuItem getAboutMenuItem() {
389 if (this.aboutMenuItem == null) {
390 this.aboutMenuItem = new JMenuItem();
391 this.aboutMenuItem.setText(Messages
392 .getString("MathViewer.aboutMenuItem")); //$NON-NLS-1$
393 this.aboutMenuItem.addActionListener(new ActionListener() {
394 public void actionPerformed(final ActionEvent e) {
395 MainFrame.this.displayAbout();
396 }
397 });
398 }
399 return this.aboutMenuItem;
400 }
401
402 /**
403 * Display the about dialog.
404 */
405 public void displayAbout() {
406 final JDialog aDialog = MainFrame.this.getAboutDialog();
407 aDialog.pack();
408 final Point loc = MainFrame.this.getLocation();
409 loc.translate((MainFrame.this.getWidth() - aDialog.getWidth()) / 2, 0);
410 aDialog.setLocation(loc);
411 aDialog.setVisible(true);
412
413 }
414
415 /**
416 * This method initializes aboutDialog
417 *
418 * @return javax.swing.JDialog
419 */
420 private JDialog getAboutDialog() {
421 if (this.aboutDialog == null) {
422 this.aboutDialog = new AboutDialog(this);
423 }
424 return this.aboutDialog;
425 }
426
427 /**
428 * This method initializes jMenuItem
429 *
430 * @return javax.swing.JMenuItem
431 */
432 private JMenuItem getOpenMenuItem() {
433 if (this.openMenuItem == null) {
434 this.openMenuItem = new JMenuItem();
435 this.openMenuItem.setText(Messages.getString("MathViewer.open")); //$NON-NLS-1$
436 this.openMenuItem.setAccelerator(KeyStroke.getKeyStroke(
437 KeyEvent.VK_O, Toolkit.getDefaultToolkit()
438 .getMenuShortcutKeyMask(), true));
439 this.openMenuItem
440 .addActionListener(new java.awt.event.ActionListener() {
441 public void actionPerformed(
442 final java.awt.event.ActionEvent e) {
443 MainFrame.this.openFile();
444 }
445 });
446 }
447 return this.openMenuItem;
448 }
449
450 /**
451 * Try to load a given file into this frame.
452 *
453 * @param f
454 * reference to the file.
455 */
456 public void loadFile(final File f) {
457 final Document doc = MainFrame.FILEIO.loadFile(this, f);
458 if (doc == null) {
459 this.getXMLEditor().setText("");
460 } else {
461 this.getXMLEditor().setText(
462 MathMLSerializer.serializeDocument(doc, false, false));
463 }
464 this.updateFromTextArea();
465 }
466
467 /**
468 * carries out the actual file-open procedure.
469 */
470 protected void openFile() {
471 final File file = MainFrame.FILEIO.selectFileToOpen(this);
472 this.loadFile(file);
473 }
474
475 /**
476 * This method initializes splitPane
477 *
478 * @return {@link JSplitPane}
479 */
480 private JSplitPane getSplitPane() {
481 if (this.splitPane == null) {
482 this.splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
483 this.getScrollPane(), this.getScrollPane2());
484 this.splitPane.setOneTouchExpandable(true);
485 this.splitPane.setResizeWeight(1.0);
486 }
487 return this.splitPane;
488 }
489
490 private void setText(final String text) {
491 this.xmlEditor.setText(text);
492 try {
493 this.biTree = SAXBiParser.getInstance().parse(text);
494 } catch (NonIncrementalElementException e) {
495 this.biTree = null;
496 this.getMathComponent().setContent(text);
497 }
498 if (this.biTree != null) {
499 this.biTree.createDOMTree();
500 this.mathComponent.setDocument(this.biTree.getDocument());
501 }
502 }
503
504 /**
505 * This method initializes xmlEditor
506 *
507 * @return {@link XMLTextEditor}
508 */
509 private XMLTextEditor getXMLEditor() {
510 if (this.xmlEditor == null) {
511 this.xmlEditor = new XMLTextEditor();
512 this.xmlEditor.setEditorKit(new XMLEditorKit(new XMLContext()));
513 /*
514 * this.xmlEditor.setText("<?xml version='1.0'?>" + Helper.nl() +
515 * "<math xmlns='http://www.w3.org/1998/Math/MathML'>" + Helper.nl()
516 * + "</math>");
517 */
518 this.setText("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
519 + Helper.nl()
520 // DOCTYPE for W3C compliance obviously not
521 // supported
522 // +
523 // "<!DOCTYPE math PUBLIC -//W3C//DTD MathML 2.0//EN' "
524 // +
525 // "'http://www.w3.org/Math/DTD/mathml2/mathml2.dtd'>"
526 // + Helper.nl()
527 + "<math xmlns='http://www.w3.org/1998/Math/MathML'>"
528 + Helper.nl() + "<mrow>" + Helper.nl() + "<mi>a</mi>"
529 + Helper.nl() + "<msup><mi>x</mi><mn>2</mn></msup>"
530 + Helper.nl() + "<mo>+</mo><mi>b</mi>" + Helper.nl()
531 + "<mi>x</mi><mo>+</mo><mi>c</mi>" + Helper.nl()
532 + "<mo>=</mo><mo>0</mo>" + Helper.nl() + "</mrow>"
533 + Helper.nl() + "</math>");
534
535 this.xmlEditor.setEditable(true);
536 this.xmlEditor.setComponentPopupMenu(this.getContextPopupMenu());
537 this.xmlEditor.getDocument().addDocumentListener(
538 new DocumentListener() {
539 public void changedUpdate(
540 final DocumentEvent documentevent) {
541 MainFrame.this.updateFromTextArea(documentevent);
542 }
543
544 public void insertUpdate(
545 final DocumentEvent documentevent) {
546 MainFrame.this.updateFromTextArea(documentevent);
547 }
548
549 public void removeUpdate(
550 final DocumentEvent documentevent) {
551 MainFrame.this.updateFromTextArea(documentevent);
552 }
553 });
554 // this.updateFromTextArea();
555 }
556
557 return this.xmlEditor;
558 }
559
560 private String normalize(final String text) {
561 // workaround for some problems with OS dependency
562 // pane.getDocument().putProperty(DefaultEditorKit.EndOfLineStringProperty,
563 // "\n");
564 return text.replace("\r\n", "\n");
565 }
566
567 /**
568 * Set the content from a String containing the MathML content.
569 *
570 * @param text
571 * the content to set.
572 * @param documentEvent
573 * documentEvent which triggered the change.
574 */
575 private void setContent(final DocumentEvent documentEvent, final String text) {
576 DocumentEvent.EventType type;
577 if (this.biTree == null || this.biTree.getRoot() == null) {
578 this.getMathComponent().setContent(text);
579 } else {
580
581 type = documentEvent.getType();
582
583 try {
584 if (type == DocumentEvent.EventType.INSERT) {
585 this.biTree.insert(documentEvent.getOffset(),
586 documentEvent.getLength(), text);
587
588 } else if (type == DocumentEvent.EventType.REMOVE) {
589 this.biTree.remove(documentEvent.getOffset(),
590 documentEvent.getLength(), text);
591
592 } else {
593 // Other types of events are unsupported.
594 this.getMathComponent().setContent(text);
595 }
596 } catch (final ReparseException ex) {
597 this.getMathComponent().setContent(text);
598 } catch (NonIncrementalElementException e) {
599 this.biTree = null;
600 this.getMathComponent().setContent(text);
601 }
602 }
603 this.getMathComponent().revalidate();
604 this.getMathComponent().repaint();
605 }
606
607 private void updateFromTextArea(final DocumentEvent documentevent) {
608 try {
609 final String txt = this.normalize(this.getXMLEditor().getText());
610 this.setContent(documentevent, txt);
611
612 // CHECKSTYLE:OFF
613 // in this case, we want to explicitly provide catch-all error
614 // handling.
615 } catch (final RuntimeException e) {
616 // CHECKSTYLE:ON
617 }
618 }
619
620 private void updateFromTextArea() {
621 try {
622 final String txt = this.normalize(this.getXMLEditor().getText());
623 this.setText(txt);
624
625 // CHECKSTYLE:OFF
626 // in this case, we want to explicitly provide catch-all error
627 // handling.
628 } catch (final RuntimeException e) {
629 // CHECKSTYLE:ON
630 }
631 }
632
633 /**
634 * This method initializes scrollPane
635 *
636 * @return javax.swing.JScrollPane
637 */
638 private JScrollPane getScrollPane() {
639 if (this.scrollPane == null) {
640 this.scrollPane = new JScrollPane();
641 this.scrollPane.setViewportView(this.getMathComponent());
642
643 if (MathViewer.OSX) {
644 this.scrollPane
645 .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
646 this.scrollPane
647 .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
648 }
649 }
650 return this.scrollPane;
651 }
652
653 /**
654 * This method initializes scrollPane2
655 *
656 * @return javax.swing.JScrollPane
657 */
658 private JScrollPane getScrollPane2() {
659 if (this.scrollPane2 == null) {
660 this.scrollPane2 = new JScrollPane();
661 this.scrollPane2.setViewportView(this.getXMLEditor());
662
663 if (MathViewer.OSX) {
664 this.scrollPane2
665 .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
666 this.scrollPane2
667 .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
668 }
669 }
670 return this.scrollPane2;
671 }
672
673 /**
674 * This method initializes mathComponent.
675 *
676 * @return net.sourceforge.jeuclid.swing.JMathComponent
677 */
678 public JMathComponent getMathComponent() {
679 if (this.mathComponent == null) {
680 this.mathComponent = new JMathComponent(this);
681 this.mathComponent
682 .setContent("<math><mtext>" //$NON-NLS-1$
683 + Messages.getString("MathViewer.noFileLoaded") + "</mtext></math>"); //$NON-NLS-1$ //$NON-NLS-2$
684 this.mathComponent.setFocusable(true);
685 }
686 return this.mathComponent;
687 }
688
689 /**
690 * This method initializes viewMenu
691 *
692 * @return javax.swing.JMenu
693 */
694 private JMenu getViewMenu() {
695 if (this.viewMenu == null) {
696 this.viewMenu = new JMenu();
697 this.viewMenu.setText(Messages.getString("MathViewer.viewMenu")); //$NON-NLS-1$
698 this.viewMenu.add(this.getRefreshMenuItem());
699 this.viewMenu.add(this.getBiggerMenuItem());
700 this.viewMenu.add(this.getSmallerMenuItem());
701 this.viewMenu.add(this.getAliasMenuItem());
702 this.viewMenu.add(this.getDebugMenuItem());
703 if (!MathViewer.OSX) {
704 this.viewMenu.add(this.getViewModifyParams());
705 }
706 }
707 return this.viewMenu;
708 }
709
710 private JMenuItem getViewModifyParams() {
711 final JMenuItem mi = new JMenuItem(
712 Messages.getString("MathViewer.viewModifyParams"));
713 mi.addActionListener(new ActionListener() {
714 public void actionPerformed(final ActionEvent e) {
715 MainFrame.this.displaySettings();
716 }
717 });
718 return mi;
719 }
720
721 /**
722 * Display the settings dialog.
723 */
724 public void displaySettings() {
725 new ParametersDialog(MainFrame.this).setVisible(true);
726 MainFrame.this.debugMenuItem
727 .setSelected(((Boolean) MainFrame.this.mathComponent
728 .getParameters().getParameter(Parameter.DEBUG))
729 .booleanValue());
730 MainFrame.this.aliasMenuItem
731 .setSelected(((Boolean) MainFrame.this.mathComponent
732 .getParameters().getParameter(Parameter.ANTIALIAS))
733 .booleanValue());
734
735 }
736
737 /**
738 * This method initializes refreshMenuItem
739 *
740 * @return javax.swing.JMenuItem
741 */
742 private JMenuItem getRefreshMenuItem() {
743 if (this.refreshMenuItem == null) {
744 this.refreshMenuItem = new JMenuItem();
745 this.refreshMenuItem.setText(Messages
746 .getString("MathViewer.textRefresh"));
747 this.refreshMenuItem.setAccelerator(KeyStroke.getKeyStroke(
748 KeyEvent.VK_Y, Toolkit.getDefaultToolkit()
749 .getMenuShortcutKeyMask(), true));
750 this.refreshMenuItem
751 .addActionListener(new java.awt.event.ActionListener() {
752 public void actionPerformed(
753 final java.awt.event.ActionEvent e) {
754 MainFrame.this.updateFromTextArea();
755 }
756 });
757 }
758 return this.refreshMenuItem;
759 }
760
761 /**
762 * This method initializes biggerMenuItem
763 *
764 * @return javax.swing.JMenuItem
765 */
766 private JMenuItem getBiggerMenuItem() {
767 if (this.biggerMenuItem == null) {
768 this.biggerMenuItem = new JMenuItem();
769 this.biggerMenuItem.setText(Messages
770 .getString("MathViewer.textBigger")); //$NON-NLS-1$
771 this.biggerMenuItem.setAccelerator(KeyStroke.getKeyStroke(
772 /*
773 * KeyEvent.VK_ADD, Toolkit.getDefaultToolkit()
774 * .getMenuShortcutKeyMask(), true));
775 */
776 KeyEvent.VK_PLUS, Toolkit.getDefaultToolkit()
777 .getMenuShortcutKeyMask(), true));
778 this.biggerMenuItem
779 .addActionListener(new java.awt.event.ActionListener() {
780 public void actionPerformed(
781 final java.awt.event.ActionEvent e) {
782 final JMathComponent jmc = MainFrame.this
783 .getMathComponent();
784 jmc.setFontSize(jmc.getFontSize()
785 * MainFrame.FONT_SIZE_MULTIPLICATOR);
786 }
787 });
788 }
789 return this.biggerMenuItem;
790 }
791
792 /**
793 * This method initializes smallerMenuItem
794 *
795 * @return javax.swing.JMenuItem
796 */
797 private JMenuItem getSmallerMenuItem() {
798 if (this.smallerMenuItem == null) {
799 this.smallerMenuItem = new JMenuItem();
800 this.smallerMenuItem.setText(Messages
801 .getString("MathViewer.textSmaller")); //$NON-NLS-1$
802 this.smallerMenuItem.setAccelerator(KeyStroke.getKeyStroke(
803 /*
804 * KeyEvent.VK_SUBTRACT, Toolkit.getDefaultToolkit()
805 * .getMenuShortcutKeyMask(), true));
806 */
807 KeyEvent.VK_MINUS, Toolkit.getDefaultToolkit()
808 .getMenuShortcutKeyMask(), true));
809
810 this.smallerMenuItem
811 .addActionListener(new java.awt.event.ActionListener() {
812 public void actionPerformed(
813 final java.awt.event.ActionEvent e) {
814 final JMathComponent jmc = MainFrame.this
815 .getMathComponent();
816 jmc.setFontSize(jmc.getFontSize()
817 / MainFrame.FONT_SIZE_MULTIPLICATOR);
818 }
819 });
820 }
821 return this.smallerMenuItem;
822 }
823
824 /**
825 * This method initializes exportMenuItem.
826 *
827 * @return javax.swing.JMenuItem
828 */
829 private JMenuItem getExportMenuItem() {
830 if (this.exportMenuItem == null) {
831 this.exportMenuItem = new JMenuItem();
832 this.exportMenuItem
833 .setText(Messages.getString("MathViewer.export")); //$NON-NLS-1$
834 this.exportMenuItem.setAccelerator(KeyStroke.getKeyStroke(
835 KeyEvent.VK_S, Toolkit.getDefaultToolkit()
836 .getMenuShortcutKeyMask(), true));
837 this.exportMenuItem
838 .addActionListener(new java.awt.event.ActionListener() {
839 public void actionPerformed(
840 final java.awt.event.ActionEvent e) {
841 MainFrame.this.exportFile();
842 }
843 });
844 }
845 return this.exportMenuItem;
846 }
847
848 /**
849 * Carries out the actual export File operation.
850 */
851 protected void exportFile() {
852 MainFrame.FILEIO.saveDocument(this, this.getMathComponent()
853 .getDocument(), this.getMathComponent().getParameters());
854 }
855
856 /**
857 * This method initializes aliasMenuItem
858 *
859 * @return javax.swing.JCheckBoxMenuItem
860 */
861 private JCheckBoxMenuItem getAliasMenuItem() {
862 if (this.aliasMenuItem == null) {
863 this.aliasMenuItem = new JCheckBoxMenuItem();
864 this.aliasMenuItem.setText(Messages.getString("MathViewer.alias")); //$NON-NLS-1$
865 this.aliasMenuItem.setSelected((Boolean) LayoutContextImpl
866 .getDefaultLayoutContext()
867 .getParameter(Parameter.ANTIALIAS));
868 this.aliasMenuItem
869 .addItemListener(new java.awt.event.ItemListener() {
870 public void itemStateChanged(
871 final java.awt.event.ItemEvent e) {
872 MainFrame.this.getMathComponent().setParameter(
873 Parameter.ANTIALIAS,
874 MainFrame.this.aliasMenuItem.isSelected());
875 }
876 });
877 }
878 return this.aliasMenuItem;
879 }
880
881 /**
882 * This method initializes debugMenuItem
883 *
884 * @return javax.swing.JCheckBoxMenuItem
885 */
886 private JCheckBoxMenuItem getDebugMenuItem() {
887 if (this.debugMenuItem == null) {
888 this.debugMenuItem = new JCheckBoxMenuItem();
889 this.debugMenuItem.setText(Messages.getString("MathViewer.debug")); //$NON-NLS-1$
890 this.debugMenuItem.setSelected((Boolean) LayoutContextImpl
891 .getDefaultLayoutContext().getParameter(Parameter.DEBUG));
892 this.debugMenuItem
893 .addItemListener(new java.awt.event.ItemListener() {
894 public void itemStateChanged(
895 final java.awt.event.ItemEvent e) {
896 MainFrame.this.getMathComponent().setParameter(
897 Parameter.DEBUG,
898 MainFrame.this.debugMenuItem.isSelected());
899 }
900 });
901 }
902 return this.debugMenuItem;
903 }
904
905 private void pasteFullFromClipboard() {
906 final Transferable content = Toolkit.getDefaultToolkit()
907 .getSystemClipboard().getContents(null);
908 if (content != null
909 && content.isDataFlavorSupported(DataFlavor.stringFlavor)) {
910 try {
911 final String newContent = (String) content
912 .getTransferData(DataFlavor.stringFlavor);
913 this.getMathComponent().setContent(newContent);
914 this.getXMLEditor().setText(newContent);
915 // CHECKSTYLE:OFF
916 // in this case, we want to explicitly provide catch-all error
917 // handling.
918 } catch (final Exception e) {
919 // CHECKSTYLE:ON
920 JOptionPane.showMessageDialog(
921 this,
922 new String[] {
923 Messages.getString("MathViewer.pasteFailure"),
924 e.toString(), },
925 Messages.getString("MathViewer.error"),
926 JOptionPane.ERROR_MESSAGE);
927 }
928 }
929 }
930
931 private void copyFullToClipboard(final boolean formatted) {
932 Toolkit.getDefaultToolkit()
933 .getSystemClipboard()
934 .setContents(
935 new StringSelection(MathMLSerializer.serializeDocument(
936 this.mathComponent.getDocument(), false,
937 formatted)), null);
938 }
939
940 private JMenuItem getCRefreshMenuItem() {
941 if (this.c_refreshMenuItem == null) {
942 this.c_refreshMenuItem = new JMenuItem();
943 this.c_refreshMenuItem.setText(Messages
944 .getString("MathViewer.cRefreshMenuItem")); //$NON-NLS-1$
945 this.c_refreshMenuItem.setAccelerator(KeyStroke.getKeyStroke(
946 KeyEvent.VK_F10, Toolkit.getDefaultToolkit()
947 .getMenuShortcutKeyMask(), true));
948 this.c_refreshMenuItem.addActionListener(new ActionListener() {
949 public void actionPerformed(final ActionEvent e) {
950 MainFrame.this.updateFromTextArea();
951 }
952 });
953 }
954 return this.c_refreshMenuItem;
955 }
956
957 private JMenuItem getTableMenuItem() {
958 if (this.tableMenuItem == null) {
959 this.tableMenuItem = new JMenuItem();
960 this.tableMenuItem.setText(Messages
961 .getString("MathViewer.tableMenuItem")); //$NON-NLS-1$
962 this.tableMenuItem.addActionListener(new ActionListener() {
963 public void actionPerformed(final ActionEvent e) {
964 final InsertTableDialog dlg = new InsertTableDialog(
965 MainFrame.this, true);
966 dlg.setVisible(true);
967
968 if (dlg.getMathMLText() != null) {
969 MainFrame.this.insertMacro(dlg.getMathMLText());
970 }
971 }
972 });
973 }
974 return this.tableMenuItem;
975 }
976
977 private JMenuItem getPolynomMenuItem() {
978 if (this.polynomMenuItem == null) {
979 this.polynomMenuItem = new JMenuItem();
980 this.polynomMenuItem.setText(Messages
981 .getString("MathViewer.polynomMenuItem")); //$NON-NLS-1$
982 this.polynomMenuItem.addActionListener(new ActionListener() {
983 public void actionPerformed(final ActionEvent e) {
984 final InsertPolynomDialog dlg = new InsertPolynomDialog(
985 MainFrame.this, true);
986 dlg.setVisible(true);
987 if (dlg.getMathMLText() != null) {
988 MainFrame.this.insertMacro(dlg.getMathMLText());
989 }
990 }
991 });
992 }
993 return this.polynomMenuItem;
994 }
995
996 private JMenuItem getOrMenuItem() {
997 if (this.orMenuItem == null) {
998 this.orMenuItem = new JMenuItem();
999 this.orMenuItem
1000 .setText(Messages.getString("MathViewer.orMenuItem")); //$NON-NLS-1$
1001 this.orMenuItem.addActionListener(new ActionListener() {
1002 public void actionPerformed(final ActionEvent e) {
1003 MainFrame.this
1004 .insertMacro("<apply><or/><ci>a</ci><ci>b</ci></apply>");
1005 }
1006 });
1007 }
1008 return this.orMenuItem;
1009 }
1010
1011 private JMenuItem getAndMenuItem() {
1012 if (this.andMenuItem == null) {
1013 this.andMenuItem = new JMenuItem();
1014 this.andMenuItem.setText(Messages
1015 .getString("MathViewer.andMenuItem")); //$NON-NLS-1$
1016 this.andMenuItem.addActionListener(new ActionListener() {
1017 public void actionPerformed(final ActionEvent e) {
1018 MainFrame.this
1019 .insertMacro("<apply><and/><ci>a</ci><ci>b</ci></apply>");
1020 }
1021 });
1022 }
1023 return this.andMenuItem;
1024 }
1025
1026 private JMenuItem getNotMenuItem() {
1027 if (this.notMenuItem == null) {
1028 this.notMenuItem = new JMenuItem();
1029 this.notMenuItem.setText(Messages
1030 .getString("MathViewer.notMenuItem")); //$NON-NLS-1$
1031 this.notMenuItem.addActionListener(new ActionListener() {
1032 public void actionPerformed(final ActionEvent e) {
1033 MainFrame.this
1034 .insertMacro("<apply><not/><ci>a</ci></apply>");
1035 }
1036 });
1037 }
1038 return this.notMenuItem;
1039 }
1040
1041 private JMenuItem getAlphaMenuItem() {
1042 if (this.alphaMenuItem == null) {
1043 this.alphaMenuItem = new JMenuItem();
1044 this.alphaMenuItem.setText(Messages
1045 .getString("MathViewer.alphaMenuItem")); //$NON-NLS-1$
1046 this.alphaMenuItem.addActionListener(new ActionListener() {
1047 public void actionPerformed(final ActionEvent e) {
1048 MainFrame.this.insertMacro("<mi>α</mi>");
1049 }
1050 });
1051 }
1052 return this.alphaMenuItem;
1053 }
1054
1055 private JMenuItem getBetaMenuItem() {
1056 if (this.betaMenuItem == null) {
1057 this.betaMenuItem = new JMenuItem();
1058 this.betaMenuItem.setText(Messages
1059 .getString("MathViewer.betaMenuItem")); //$NON-NLS-1$
1060 this.betaMenuItem.addActionListener(new ActionListener() {
1061 public void actionPerformed(final ActionEvent e) {
1062 MainFrame.this.insertMacro("<mi>β</mi>");
1063 }
1064 });
1065 }
1066 return this.betaMenuItem;
1067 }
1068
1069 private JMenuItem getGammaMenuItem() {
1070 if (this.gammaMenuItem == null) {
1071 this.gammaMenuItem = new JMenuItem();
1072 this.gammaMenuItem.setText(Messages
1073 .getString("MathViewer.gammaMenuItem")); //$NON-NLS-1$
1074 this.gammaMenuItem.addActionListener(new ActionListener() {
1075 public void actionPerformed(final ActionEvent e) {
1076 MainFrame.this.insertMacro("<mi>γ</mi>");
1077 }
1078 });
1079 }
1080 return this.gammaMenuItem;
1081 }
1082
1083 private JMenuItem getDeltaMenuItem() {
1084 if (this.deltaMenuItem == null) {
1085 this.deltaMenuItem = new JMenuItem();
1086 this.deltaMenuItem.setText(Messages
1087 .getString("MathViewer.deltaMenuItem")); //$NON-NLS-1$
1088 this.deltaMenuItem.addActionListener(new ActionListener() {
1089 public void actionPerformed(final ActionEvent e) {
1090 MainFrame.this.insertMacro("<mi>δ</mi>");
1091 }
1092 });
1093 }
1094 return this.deltaMenuItem;
1095 }
1096
1097 private JMenuItem getOmegaMenuItem() {
1098 if (this.omegaMenuItem == null) {
1099 this.omegaMenuItem = new JMenuItem();
1100 this.omegaMenuItem.setText(Messages
1101 .getString("MathViewer.omegaMenuItem")); //$NON-NLS-1$
1102 this.omegaMenuItem.addActionListener(new ActionListener() {
1103 public void actionPerformed(final ActionEvent e) {
1104 MainFrame.this.insertMacro("<mi>ω</mi>");
1105 }
1106 });
1107 }
1108 return this.omegaMenuItem;
1109 }
1110
1111 private JMenuItem getExistsMenuItem() {
1112 if (this.existsMenuItem == null) {
1113 this.existsMenuItem = new JMenuItem();
1114 this.existsMenuItem.setText(Messages
1115 .getString("MathViewer.existsMenuItem")); //$NON-NLS-1$
1116 this.existsMenuItem.addActionListener(new ActionListener() {
1117 public void actionPerformed(final ActionEvent e) {
1118 MainFrame.this.insertMacro("<apply><exists/></apply>");
1119 }
1120 });
1121 }
1122 return this.existsMenuItem;
1123 }
1124
1125 private JMenuItem getForAllMenuItem() {
1126 if (this.forallMenuItem == null) {
1127 this.forallMenuItem = new JMenuItem();
1128 this.forallMenuItem.setText(Messages
1129 .getString("MathViewer.forallMenuItem")); //$NON-NLS-1$
1130 this.forallMenuItem.addActionListener(new ActionListener() {
1131 public void actionPerformed(final ActionEvent e) {
1132 MainFrame.this.insertMacro("<apply><forall/></apply>");
1133 }
1134 });
1135 }
1136 return this.forallMenuItem;
1137 }
1138
1139 private JMenu getGreekMenu() {
1140 if (this.greekMenu == null) {
1141 this.greekMenu = new JMenu();
1142 this.greekMenu.setText(Messages.getString("MathViewer.GreekMenu")); //$NON-NLS-1$
1143 this.greekMenu.add(this.getAlphaMenuItem());
1144 this.greekMenu.add(this.getBetaMenuItem());
1145 this.greekMenu.add(this.getGammaMenuItem());
1146 this.greekMenu.add(this.getDeltaMenuItem());
1147 this.greekMenu.add(this.getOmegaMenuItem());
1148 }
1149 return this.greekMenu;
1150 }
1151
1152 private JMenu getLogicsMenu() {
1153 if (this.logicsMenu == null) {
1154 this.logicsMenu = new JMenu();
1155 this.logicsMenu
1156 .setText(Messages.getString("MathViewer.LogicsMenu")); //$NON-NLS-1$
1157 this.logicsMenu.add(this.getAndMenuItem());
1158 this.logicsMenu.add(this.getOrMenuItem());
1159 this.logicsMenu.add(this.getNotMenuItem());
1160 }
1161 return this.logicsMenu;
1162 }
1163
1164 private JMenu getSymbolsMenu() {
1165 if (this.symbolsMenu == null) {
1166 this.symbolsMenu = new JMenu();
1167 this.symbolsMenu.setText(Messages
1168 .getString("MathViewer.SymbolsMenu")); //$NON-NLS-1$
1169 this.symbolsMenu.add(this.getForAllMenuItem());
1170 this.symbolsMenu.add(this.getExistsMenuItem());
1171 }
1172 return this.symbolsMenu;
1173 }
1174
1175 private JMenu getInsertMenu() {
1176 if (this.insertMenu == null) {
1177 this.insertMenu = new JMenu();
1178 this.insertMenu
1179 .setText(Messages.getString("MathViewer.InsertMenu")); //$NON-NLS-1$
1180 this.insertMenu.add(this.getTableMenuItem());
1181 this.insertMenu.add(this.getPolynomMenuItem());
1182 this.insertMenu.add(this.getGreekMenu());
1183 this.insertMenu.add(this.getLogicsMenu());
1184 this.insertMenu.add(this.getSymbolsMenu());
1185 }
1186 return this.insertMenu;
1187 }
1188
1189 private JPopupMenu getContextPopupMenu() {
1190 if (this.contextPopupMenu == null) {
1191 this.contextPopupMenu = new JPopupMenu();
1192 this.contextPopupMenu.add(this.getCRefreshMenuItem());
1193 this.contextPopupMenu.add(this.getInsertMenu());
1194 }
1195 return this.contextPopupMenu;
1196 }
1197
1198 private void insertMacro(final String macroText) {
1199 final int pos = this.getXMLEditor().getCaretPosition();
1200 String s1 = this.getXMLEditor().getText().substring(0, pos);
1201 final String s2 = this.getXMLEditor().getText().substring(pos);
1202 s1 += macroText + s2;
1203 this.getXMLEditor().setText(s1);
1204 this.updateFromTextArea();
1205 }
1206 }