1 19 package org.lucane.client.widgets; 20 import java.awt.BorderLayout ; 21 import java.awt.Color ; 22 import java.awt.Component ; 23 import java.awt.Event ; 24 import java.awt.event.ActionEvent ; 25 import java.awt.event.ActionListener ; 26 import java.awt.event.KeyEvent ; 27 import java.io.InputStream ; 28 import java.io.InputStreamReader ; 29 import java.net.URL ; 30 import java.util.HashMap ; 31 32 import javax.swing.*; 33 import javax.swing.event.ChangeEvent ; 34 import javax.swing.event.ChangeListener ; 35 import javax.swing.text.*; 36 import javax.swing.text.html.*; 37 38 import org.lucane.client.Client; 39 import org.lucane.client.util.Translation; 40 41 import com.swabunga.spell.engine.SpellDictionaryHashMap; 42 43 import org.lucane.client.widgets.jazzy.JTextComponentSpellChecker; 44 import org.lucane.common.Logging; 45 46 53 public class HTMLEditor extends JComponent { 54 55 private static SpellDictionaryHashMap dictionary = null; 56 57 private JEditorPane editor; 58 private HTMLDocument htmlDocument; 59 private HTMLEditorKit kit; 60 private Caret caret; 61 62 private JPanel panel; 63 private JScrollPane jScrollPane; 64 private JToolBar toolBar; 65 private JPopupMenu mnuSize; 66 private JPopupMenu mnuFamily; 67 private JPopupMenu mnuAlign; 68 private JToggleButton btnBold; 69 private JToggleButton btnItalic; 70 private JToggleButton btnUnderline; 71 private JToggleButton btnLeftAlign; 72 private JToggleButton btnRightAlign; 73 private JToggleButton btnCenterAlign; 74 private JButton btnSize; 75 private JButton btnFamily; 76 private JButton btnColor; 77 private JButton btnInsertTable; 78 private JButton btnInsertCellDown; 79 private JButton btnInsertCellRight; 80 private JButton btnSpellCheck; 81 82 private HashMap actions; 83 84 85 88 public HTMLEditor() { 89 init(); 90 } 91 92 private void init() { 93 panel = new JPanel(); 94 panel.setLayout(new BorderLayout ()); 95 96 97 editor = new JEditorPane(); 98 kit = new HTMLEditorKit(); 99 htmlDocument = (HTMLDocument)(kit.createDefaultDocument()); 100 editor.setEditorKit(kit); 101 editor.setDocument(htmlDocument); 102 editor.setCaretPosition(0); 103 caret = editor.getCaret(); 104 caret.addChangeListener(new ChangeListener () { 105 public void stateChanged(ChangeEvent e) { 106 Element elm = htmlDocument.getCharacterElement(editor 107 .getCaretPosition()); 108 Element par = htmlDocument.getParagraphElement( 109 editor.getCaretPosition()); 110 AttributeSet parAttr = par.getAttributes(); 111 AttributeSet elmAttr = elm.getAttributes(); 112 113 btnBold.setSelected( 114 htmlDocument.getFont(elm.getAttributes()).isBold()); 115 btnItalic.setSelected( 116 htmlDocument.getFont(elm.getAttributes()).isItalic()); 117 btnUnderline.setSelected( 118 elmAttr.isDefined(CSS.Attribute.TEXT_DECORATION) 119 && elmAttr.getAttribute(CSS.Attribute.TEXT_DECORATION).toString().equals("underline")); 120 121 btnRightAlign.setSelected( 122 parAttr.isDefined(CSS.Attribute.TEXT_ALIGN) 123 && parAttr.getAttribute(CSS.Attribute.TEXT_ALIGN).toString().equals("right")); 124 btnCenterAlign.setSelected( 125 parAttr.isDefined(CSS.Attribute.TEXT_ALIGN) 126 && parAttr.getAttribute(CSS.Attribute.TEXT_ALIGN).toString().equals("center")); 127 btnLeftAlign.setSelected( 128 parAttr.isDefined(CSS.Attribute.TEXT_ALIGN) 129 && parAttr.getAttribute(CSS.Attribute.TEXT_ALIGN).toString().equals("left")); 130 } 131 }); 132 133 createActions(); 134 135 136 Keymap keymap = JTextComponent.addKeymap("LucaneHTMLEditorKeyMap", editor.getKeymap()); 137 keymap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_B, Event.CTRL_MASK), (Action)actions.get("bold")); 138 keymap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.CTRL_MASK), (Action)actions.get("italic")); 139 keymap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_U, Event.CTRL_MASK), (Action)actions.get("underlined")); 140 editor.setKeymap(keymap); 141 142 143 toolBar = new JToolBar(); 144 toolBar.setFloatable(false); 145 146 147 mnuSize = new JPopupMenu(); 148 mnuSize.add(new HTMLEditorKit.FontSizeAction( "8", 8)); 149 mnuSize.add(new HTMLEditorKit.FontSizeAction("10", 10)); 150 mnuSize.add(new HTMLEditorKit.FontSizeAction("12", 12)); 151 mnuSize.add(new HTMLEditorKit.FontSizeAction("14", 14)); 152 mnuSize.add(new HTMLEditorKit.FontSizeAction("16", 16)); 153 mnuSize.add(new HTMLEditorKit.FontSizeAction("18", 18)); 154 mnuSize.add(new HTMLEditorKit.FontSizeAction("24", 24)); 155 mnuSize.add(new HTMLEditorKit.FontSizeAction("36", 36)); 156 mnuSize.add(new HTMLEditorKit.FontSizeAction("48", 48)); 157 158 159 mnuFamily = new JPopupMenu(); 160 mnuFamily.add(new HTMLEditorKit.FontFamilyAction("Serif", "Serif")); 161 mnuFamily.add(new HTMLEditorKit.FontFamilyAction("SansSerif", "SansSerif")); 162 mnuFamily.add(new HTMLEditorKit.FontFamilyAction("Monospaced", "Monospaced")); 163 164 165 btnLeftAlign = new JToggleButton((Action)actions.get("left_align")); 166 btnLeftAlign.addActionListener(new ActionListener () { 167 public void actionPerformed(ActionEvent e) { 168 btnCenterAlign.setSelected(false); 169 btnRightAlign.setSelected(false); 170 } 171 }); 172 btnLeftAlign.setFocusable(false); 173 btnLeftAlign.setText(""); 174 toolBar.add(btnLeftAlign); 175 176 177 btnCenterAlign = new JToggleButton((Action)actions.get("center_align")); 178 btnCenterAlign.addActionListener(new ActionListener () { 179 public void actionPerformed(ActionEvent e) { 180 btnLeftAlign.setSelected(false); 181 btnRightAlign.setSelected(false); 182 } 183 }); 184 btnCenterAlign.setFocusable(false); 185 btnCenterAlign.setText(""); 186 toolBar.add(btnCenterAlign); 187 188 189 btnRightAlign = new JToggleButton((Action)actions.get("right_align")); 190 btnRightAlign.addActionListener(new ActionListener () { 191 public void actionPerformed(ActionEvent e) { 192 btnLeftAlign.setSelected(false); 193 btnCenterAlign.setSelected(false); 194 } 195 }); 196 btnRightAlign.setFocusable(false); 197 btnRightAlign.setText(""); 198 toolBar.add(btnRightAlign); 199 200 toolBar.addSeparator(); 201 202 203 btnBold = new JToggleButton((Action)actions.get("bold")); 204 btnBold.setFocusable(false); 205 btnBold.setText(""); 206 toolBar.add(btnBold); 207 208 209 btnItalic = new JToggleButton((Action)actions.get("italic")); 210 btnItalic.setFocusable(false); 211 btnItalic.setText(""); 212 toolBar.add(btnItalic); 213 214 215 btnUnderline = new JToggleButton((Action)actions.get("underlined")); 216 btnUnderline.setFocusable(false); 217 btnUnderline.setText(""); 218 toolBar.add(btnUnderline); 219 220 toolBar.addSeparator(); 221 222 223 btnSize = new JButton(new ShowFontSizeMenuAction(mnuSize)); 224 btnSize.setFocusable(false); 225 btnSize.setText(""); 226 toolBar.add(btnSize); 227 228 229 btnFamily = new JButton(new ShowFontFamilyMenuAction(mnuFamily)); 230 btnFamily.setFocusable(false); 231 btnFamily.setText(""); 232 toolBar.add(btnFamily); 233 234 235 btnColor = new JButton(new TextColorAction(toolBar.getParent(), editor)); 236 btnColor.setFocusable(false); 237 btnColor.setText(""); 238 toolBar.add(btnColor); 239 240 toolBar.addSeparator(); 241 242 243 btnInsertTable = new JButton((Action)actions.get("insert_table")); 244 btnInsertTable.setFocusable(false); 245 btnInsertTable.setText(""); 246 toolBar.add(btnInsertTable); 247 248 249 btnInsertCellDown = new JButton((Action)actions.get("insert_cell_down")); 250 btnInsertCellDown.setFocusable(false); 251 btnInsertCellDown.setText(""); 252 toolBar.add(btnInsertCellDown); 253 254 255 btnInsertCellRight = new JButton((Action)actions.get("insert_cell_right")); 256 btnInsertCellRight.setFocusable(false); 257 btnInsertCellRight.setText(""); 258 toolBar.add(btnInsertCellRight); 259 260 toolBar.addSeparator(); 261 262 btnSpellCheck = new JButton((Action) actions.get("spell_check")); 263 btnSpellCheck.setFocusable(false); 264 btnSpellCheck.setText(""); 265 toolBar.add(btnSpellCheck); 266 267 268 jScrollPane = new JScrollPane(editor); 269 jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 270 jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 271 panel.add(jScrollPane, BorderLayout.CENTER); 272 panel.add(toolBar, BorderLayout.NORTH); 273 274 this.setLayout(new BorderLayout ()); 275 this.add(panel); 276 277 this.validate(); 278 } 279 280 283 public static SpellDictionaryHashMap getDictionary() 284 { 285 if(HTMLEditor.dictionary == null) 286 { 287 String language = Client.getInstance().getConfig().getLanguage(); 288 try { 289 URL url = new URL ("file:///" 290 + System.getProperty("user.dir") + "/etc/dictionaries/" 291 + language + ".dict"); 292 InputStream is = url.openStream(); 293 if (is != null) 294 HTMLEditor.dictionary = new SpellDictionaryHashMap(new InputStreamReader (is), null); 295 } catch (Exception e) { 296 Logging.getLogger().warning(e.toString()); 297 } 298 } 299 300 return HTMLEditor.dictionary; 301 } 302 303 304 308 public String getText() { 309 return editor.getText(); 310 } 311 312 316 318 public void setText(String txt) { 319 editor.setText(txt); 320 } 321 322 327 public void setEditable(boolean b) { 328 toolBar.setEnabled(b); 329 editor.setEditable(b); 330 } 331 332 336 public boolean isEditable() { 337 return editor.isEditable(); 338 } 339 340 344 public void setToolbarVisible(boolean b) { 345 toolBar.setVisible(b); 346 } 347 348 352 public boolean isToolbarVisible() { 353 return toolBar.isVisible(); 354 } 355 356 360 public void addHTML(String html) { 361 String txt = editor.getText(); 362 int pos; 363 pos = txt.lastIndexOf("</body>"); 364 if (pos == -1) 365 pos = txt.lastIndexOf("</BODY>"); 366 if (pos >= 0) 367 editor.setText(txt.substring(0, pos) + html + txt.substring(pos)); 368 369 editor.setCaretPosition(htmlDocument.getLength()); 370 } 371 372 public void scrollToBottom() 373 { 374 JScrollBar bar = jScrollPane.getVerticalScrollBar(); 375 bar.setValue(bar.getMaximum()); 376 } 377 378 381 public JEditorPane getEditorPane() { 382 return this.editor; 383 } 384 385 389 public String getBodyText() { 390 String txt = editor.getText(); 391 int pos1=txt.indexOf("<body>")+6; 392 int pos2=txt.lastIndexOf("</body>"); 393 return txt.substring(pos1,pos2); 394 } 395 396 399 public void clear() { 400 htmlDocument = (HTMLDocument)(kit.createDefaultDocument()); 401 editor.setDocument(htmlDocument); 402 } 404 405 406 407 private void createActions() { 408 actions = new HashMap (); 409 Action tmpAction; 410 411 tmpAction = new SpellCheckAction(editor); 412 actions.put("spell_check",tmpAction); 413 414 tmpAction = new HTMLEditorKit.InsertHTMLTextAction(Translation.tr("toolbar.insertTable"), "<table border=1><tr><td></td></tr></table>", HTML.Tag.BODY, HTML.Tag.TABLE); 415 tmpAction.putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.insertTable")); 416 try { 417 ImageIcon img = Client.getImageIcon("stock_form-table-control.png"); 418 tmpAction.putValue(Action.SMALL_ICON, img); 419 } catch (Exception e) { 420 } 421 actions.put("insert_table",tmpAction); 422 423 tmpAction = new InsertCellRightAction(htmlDocument, editor); 424 actions.put("insert_cell_right",tmpAction); 425 426 tmpAction = new InsertCellDownAction(htmlDocument, editor); 427 actions.put("insert_cell_down",tmpAction); 428 429 tmpAction = new StyledEditorKit.AlignmentAction(Translation.tr("toolbar.alignRight"), StyleConstants.ALIGN_RIGHT); 430 tmpAction.putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.alignRight")); 431 try { 432 ImageIcon img = Client.getImageIcon("stock_text_right.png"); 433 tmpAction.putValue(Action.SMALL_ICON, img); 434 } catch (Exception e) { 435 } 436 actions.put("right_align",tmpAction); 437 438 tmpAction = new StyledEditorKit.AlignmentAction(Translation.tr("toolbar.alignCenter"), StyleConstants.ALIGN_CENTER); 439 tmpAction.putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.alignCenter")); 440 try { 441 ImageIcon img = Client.getImageIcon("stock_text_center.png"); 442 tmpAction.putValue(Action.SMALL_ICON, img); 443 } catch (Exception e) { 444 } 445 actions.put("center_align",tmpAction); 446 447 tmpAction = new StyledEditorKit.AlignmentAction(Translation.tr("toolbar.alignLeft"), StyleConstants.ALIGN_LEFT); 448 tmpAction.putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.alignLeft")); 449 try { 450 ImageIcon img = Client.getImageIcon("stock_text_left.png"); 451 tmpAction.putValue(Action.SMALL_ICON, img); 452 } catch (Exception e) { 453 } 454 actions.put("left_align",tmpAction); 455 456 tmpAction = new HTMLEditorKit.BoldAction(); 457 tmpAction.putValue(Action.NAME, Translation.tr("toolbar.bold")); 458 tmpAction.putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.bold")); 459 try { 460 ImageIcon img = Client.getImageIcon("stock_text_bold.png"); 461 tmpAction.putValue(Action.SMALL_ICON, img); 462 } catch (Exception e) { 463 } 464 actions.put("bold",tmpAction); 465 466 tmpAction = new HTMLEditorKit.ItalicAction(); 467 tmpAction.putValue(Action.NAME, Translation.tr("toolbar.italic")); 468 tmpAction.putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.italic")); 469 try { 470 ImageIcon img = Client.getImageIcon("stock_text_italic.png"); 471 tmpAction.putValue(Action.SMALL_ICON, img); 472 } catch (Exception e) { 473 } 474 actions.put("italic",tmpAction); 475 476 tmpAction = new HTMLEditorKit.UnderlineAction(); 477 tmpAction.putValue(Action.NAME, Translation.tr("toolbar.underlined")); 478 tmpAction.putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.underlined")); 479 try { 480 ImageIcon img = Client.getImageIcon("stock_text_underlined.png"); 481 tmpAction.putValue(Action.SMALL_ICON, img); 482 } catch (Exception e) { 483 } 484 actions.put("underlined",tmpAction); 485 486 } 487 488 489 public static class InsertCellRightAction extends AbstractAction { 490 private HTMLDocument htmlDocument; 491 private JEditorPane editor; 492 493 private InsertCellRightAction() { 494 putValue(Action.NAME, Translation.tr("toolbar.insertCellRight")); 495 putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.insertCellRight")); 496 try { 497 ImageIcon img = Client.getImageIcon("stock_insert-cells-right.png"); 498 putValue(Action.SMALL_ICON, img); 499 } catch (Exception e) { 500 } 501 } 502 503 public InsertCellRightAction(HTMLDocument htmlDocument, JEditorPane editor) { 504 this(); 505 this.htmlDocument = htmlDocument; 506 this.editor = editor; 507 } 508 509 public void actionPerformed(ActionEvent ae) { 510 Element elm = htmlDocument.getCharacterElement(editor.getCaretPosition()); 512 while (elm!=null && !elm.getName().equals("td")) 513 elm = elm.getParentElement(); 514 if (elm == null) 515 return; 516 517 try { 518 htmlDocument.insertAfterEnd(elm, "<td></td>"); 519 } catch (Exception e) { 520 } 521 } 522 } 523 524 public static class InsertCellDownAction extends AbstractAction { 525 private HTMLDocument htmlDocument; 526 private JEditorPane editor; 527 528 private InsertCellDownAction() { 529 putValue(Action.NAME, Translation.tr("toolbar.insertCellDown")); 530 putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.insertCellDown")); 531 try { 532 ImageIcon img = Client.getImageIcon("stock_insert-cells-down.png"); 533 putValue(Action.SMALL_ICON, img); 534 } catch (Exception e) { 535 } 536 } 537 538 public InsertCellDownAction(HTMLDocument htmlDocument, JEditorPane editor) { 539 this(); 540 this.htmlDocument = htmlDocument; 541 this.editor = editor; 542 } 543 544 public void actionPerformed(ActionEvent ae) { 545 Element elm = htmlDocument.getCharacterElement(editor.getCaretPosition()); 546 while (elm!=null && !elm.getName().equals("tr")) 547 elm = elm.getParentElement(); 548 if (elm == null) 549 return; 550 551 try { 552 htmlDocument.insertAfterEnd(elm, "<tr><td></td></tr>"); 553 } catch (Exception e) { 554 } 555 } 556 } 557 558 public static class TextColorAction extends AbstractAction { 559 private JEditorPane editor = null; 560 private Component cmp = null; 561 562 private TextColorAction() {} 563 564 public TextColorAction(Component cmp, JEditorPane editor) { 565 this.editor = editor; 566 this.cmp = cmp; 567 568 putValue(Action.NAME, Translation.tr("toolbar.textColor")); 569 putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.textColor")); 570 try { 571 ImageIcon img = Client.getImageIcon("stock_text_color_foreground.png"); 572 putValue(Action.SMALL_ICON, img); 573 } catch (Exception e) { 574 } 575 } 576 577 public void actionPerformed(ActionEvent ae) { 578 Color color = 579 JColorChooser.showDialog( 580 cmp, 581 "Text color", 582 editor.getForeground()); 583 if (color != null) 584 new StyledEditorKit.ForegroundAction( 585 "", 586 color).actionPerformed( 587 new ActionEvent (editor, ActionEvent.ACTION_PERFORMED, "")); 588 } 589 } 590 591 public static class ShowMenuAction extends AbstractAction { 592 private JPopupMenu mnu = null; 593 594 private ShowMenuAction() { 595 } 596 597 public ShowMenuAction(JPopupMenu mnu) { 598 this.mnu = mnu; 599 } 600 601 public void actionPerformed(ActionEvent ae) { 602 if (!(ae.getSource() instanceof Component )) 603 return; 604 Component source = (Component ) ae.getSource(); 605 if (mnu != null) 606 mnu.show(source, 0, source.getHeight()); 607 } 608 } 609 610 public static class ShowFontSizeMenuAction extends ShowMenuAction { 611 public ShowFontSizeMenuAction(JPopupMenu mnu) { 612 super(mnu); 613 putValue(Action.NAME, Translation.tr("toolbar.fontSize")); 614 putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.fontSize")); 615 try { 616 ImageIcon img = Client.getImageIcon("stock_chart-scale-text.png"); 617 putValue(Action.SMALL_ICON, img); 618 } catch (Exception e) { 619 } 620 } 621 } 622 623 public static class ShowFontFamilyMenuAction extends ShowMenuAction { 624 public ShowFontFamilyMenuAction(JPopupMenu mnu) { 625 super(mnu); 626 putValue(Action.NAME, Translation.tr("toolbar.fontFamily")); 627 putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.fontFamily")); 628 try { 629 ImageIcon img = Client.getImageIcon("stock_draw-text.png"); 630 putValue(Action.SMALL_ICON, img); 631 } catch (Exception e) { 632 } 633 } 634 } 635 636 637 public static class SpellCheckAction extends AbstractAction { 638 JEditorPane editor; 639 640 private SpellCheckAction(JEditorPane editor) { 641 this.editor=editor; 642 putValue(Action.NAME, Translation.tr("toolbar.spellCheck")); 643 putValue(Action.SHORT_DESCRIPTION, Translation.tr("toolbar.spellCheck")); 644 try { 645 ImageIcon img = Client.getImageIcon("stock_spellcheck.png"); 646 putValue(Action.SMALL_ICON, img); 647 } catch (Exception e) { 648 } 649 } 650 651 public void actionPerformed(ActionEvent ae) { 652 SpellDictionaryHashMap sdhm = HTMLEditor.getDictionary(); 653 if (sdhm != null) { 654 Thread t = new SpellThread(editor, sdhm); 655 t.start(); 656 } else { 657 DialogBox.info(Translation.tr("err.noDictionaryFound")); 658 } 659 } 660 } 661 662 665 private static class SpellThread extends Thread { 666 JEditorPane editor; 667 SpellDictionaryHashMap dictionary; 668 public SpellThread(JEditorPane editor, SpellDictionaryHashMap dictionary) { 669 this.editor=editor; 670 this.dictionary=dictionary; 671 } 672 public void run() { 673 try { 674 JTextComponentSpellChecker sc = new JTextComponentSpellChecker(dictionary); 675 sc.spellCheck(editor); 676 } catch (Exception ex) { 677 ex.printStackTrace(); 678 } 679 } 680 } 681 } 682 | Popular Tags |