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 }