1 19 20 package org.netbeans.modules.properties; 21 22 import java.awt.*; 23 import java.awt.event.*; 24 import java.beans.*; 25 import java.io.IOException ; 26 import java.io.ObjectInput ; 27 import java.io.ObjectOutput ; 28 import java.io.Serializable ; 29 import java.util.*; 30 import javax.swing.Action ; 31 import javax.swing.event.ChangeListener ; 32 import javax.swing.*; 33 import javax.swing.undo.CannotRedoException ; 34 import javax.swing.undo.CannotUndoException ; 35 36 import org.openide.actions.FindAction; 37 import org.openide.awt.UndoRedo; 38 import org.openide.cookies.CloseCookie; 39 import org.openide.cookies.OpenCookie; 40 import org.openide.cookies.SaveCookie; 41 import org.openide.filesystems.FileObject; 42 import org.openide.filesystems.FileStateInvalidException; 43 import org.openide.filesystems.FileStatusEvent; 44 import org.openide.filesystems.FileStatusListener; 45 import org.openide.filesystems.FileSystem; 46 import org.openide.loaders.DataObject; 47 import org.openide.loaders.OpenSupport; 48 import org.openide.nodes.Node; 49 import org.openide.NotifyDescriptor; 50 import org.openide.DialogDisplayer; 51 import org.openide.ErrorManager; 52 import org.openide.util.actions.CallbackSystemAction; 53 import org.openide.util.actions.SystemAction; 54 import org.openide.util.*; 55 import org.openide.windows.*; 56 import org.openide.util.Utilities; 57 import org.openide.DialogDescriptor; 58 import org.openide.filesystems.FileUtil; 59 60 61 66 public class PropertiesOpen extends CloneableOpenSupport 67 implements OpenCookie, CloseCookie { 68 69 70 PropertiesDataObject propDataObject; 71 72 73 PropertyChangeListener modifL; 74 75 76 protected transient UndoRedo.Manager undoRedoManager; 77 78 79 transient Object atomicUndoRedoFlag; 80 81 82 83 public PropertiesOpen(PropertiesDataObject propDataObject) { 84 super(new Environment(propDataObject)); 85 86 this.propDataObject = propDataObject; 87 88 this.propDataObject.addPropertyChangeListener(WeakListeners.propertyChange(modifL = 89 new ModifiedListener(), this.propDataObject)); 90 } 91 92 93 98 protected boolean canClose() { 99 SaveCookie saveCookie = propDataObject.getCookie(SaveCookie.class); 100 if (saveCookie == null) { 101 return true; 102 } 103 stopEditing(); 104 if (!shouldAskSave()) { 105 return true; 106 } 107 108 109 String title = NbBundle.getMessage(PropertiesOpen.class, 110 "CTL_Question"); String question = NbBundle.getMessage(PropertiesOpen.class, 112 "MSG_SaveFile", propDataObject.getName()); 114 String optionSave = NbBundle.getMessage(PropertiesOpen.class, 115 "CTL_Save"); String optionDiscard = NbBundle.getMessage(PropertiesOpen.class, 117 "CTL_Discard"); NotifyDescriptor descr = new DialogDescriptor( 119 question, 120 title, true, new Object [] {optionSave, 123 optionDiscard, 124 NotifyDescriptor.CANCEL_OPTION}, 125 optionSave, DialogDescriptor.DEFAULT_ALIGN, null, (ActionListener) null); 129 descr.setMessageType(NotifyDescriptor.QUESTION_MESSAGE); 130 Object answer = DialogDisplayer.getDefault().notify(descr); 131 132 133 if (answer == optionSave) { 134 try { 135 saveCookie.save(); 136 propDataObject.updateModificationStatus(); 137 } 138 catch (IOException e) { 139 ErrorManager.getDefault().notify(e); 140 return false; 141 } 142 } 143 propDataObject.updateModificationStatus(); 144 145 return (answer == optionSave || answer == optionDiscard); 146 } 147 148 private void stopEditing() { 149 Enumeration en = allEditors.getComponents(); 150 while (en.hasMoreElements()) { 151 Object o = en.nextElement(); 152 if (o instanceof PropertiesCloneableTopComponent) { 153 BundleEditPanel bep = (BundleEditPanel)((PropertiesCloneableTopComponent)o).getComponent(0); 154 bep.stopEditing(); 155 } 156 } 157 } 158 159 164 protected CloneableTopComponent createCloneableTopComponent() { 165 return new PropertiesCloneableTopComponent(propDataObject); 166 } 167 168 173 protected String messageOpening() { 174 return NbBundle.getMessage(PropertiesOpen.class, "LBL_ObjectOpen", propDataObject.getName(), 176 propDataObject.getPrimaryFile().toString() 177 ); 178 } 179 180 185 protected String messageOpened() { 186 return NbBundle.getMessage(PropertiesOpen.class, "LBL_ObjectOpened"); } 188 189 190 public synchronized boolean hasOpenedTableComponent() { 191 return !allEditors.isEmpty(); 192 } 193 194 195 public UndoRedo getUndoRedo () { 196 if(undoRedoManager != null) 197 return undoRedoManager; 198 else 199 return new CompoundUndoRedoManager(propDataObject); 200 } 201 202 203 private synchronized void closeDocuments() { 204 closeEntry((PropertiesFileEntry)propDataObject.getPrimaryEntry()); 205 for (Iterator it = propDataObject.secondaryEntries().iterator(); it.hasNext(); ) { 206 closeEntry((PropertiesFileEntry)it.next()); 207 } 208 } 209 210 211 private void closeEntry(PropertiesFileEntry entry) { 212 PropertiesEditorSupport editorSupport = entry.getPropertiesEditor(); 213 if (editorSupport.hasOpenedEditorComponent()) 214 return; 216 else { 217 editorSupport.forceNotifyClosed(); 219 220 if(entry.getFile().isValid() && !entry.getFile().isVirtual()) { 222 entry.getHandler().autoParse(); 223 } 224 } 225 } 226 227 232 private boolean shouldAskSave() { 233 PropertiesFileEntry entry = (PropertiesFileEntry)propDataObject.getPrimaryEntry(); 236 SaveCookie savec = (SaveCookie)entry.getCookie(SaveCookie.class); 237 238 if ((savec != null) && !entry.getPropertiesEditor().hasOpenedEditorComponent()) 239 return true; 240 for (Iterator it = propDataObject.secondaryEntries().iterator(); it.hasNext(); ) { 241 entry = (PropertiesFileEntry)it.next(); 242 savec = (SaveCookie)entry.getCookie(SaveCookie.class); 243 if ((savec != null) && !entry.getPropertiesEditor().hasOpenedEditorComponent()) 244 return true; 245 } 246 return false; 247 } 248 249 250 251 private static class Environment implements CloneableOpenSupport.Env, Serializable , 252 PropertyChangeListener, VetoableChangeListener { 253 254 255 static final long serialVersionUID = -1934890789745432531L; 256 257 258 private DataObject dataObject; 259 260 261 private transient PropertyChangeSupport propSupp; 262 263 264 private transient VetoableChangeSupport vetoSupp; 265 266 267 273 public Environment(PropertiesDataObject dataObject) { 274 this.dataObject = dataObject; 275 dataObject.addPropertyChangeListener(WeakListeners.propertyChange(this, dataObject)); 276 dataObject.addVetoableChangeListener(WeakListeners.vetoableChange(this, dataObject)); 277 } 278 279 280 281 public void addPropertyChangeListener(PropertyChangeListener l) { 282 prop().addPropertyChangeListener(l); 283 } 284 285 286 public void removePropertyChangeListener(PropertyChangeListener l) { 287 prop().removePropertyChangeListener(l); 288 } 289 290 291 public void addVetoableChangeListener(VetoableChangeListener l) { 292 veto().addVetoableChangeListener(l); 293 } 294 295 296 public void removeVetoableChangeListener(VetoableChangeListener l) { 297 veto().removeVetoableChangeListener(l); 298 } 299 300 307 public CloneableOpenSupport findCloneableOpenSupport() { 308 return (CloneableOpenSupport)dataObject.getCookie(OpenCookie.class); 309 } 310 311 318 public boolean isValid() { 319 return dataObject.isValid(); 320 } 321 322 327 public boolean isModified() { 328 return dataObject.isModified(); 329 } 330 331 338 public void markModified() throws java.io.IOException { 339 dataObject.setModified(true); 340 } 341 342 346 public void unmarkModified() { 347 dataObject.setModified(false); 348 } 349 350 354 public void propertyChange(PropertyChangeEvent evt) { 355 if(DataObject.PROP_MODIFIED.equals(evt.getPropertyName())) { 356 if(dataObject.isModified()) { 357 dataObject.addVetoableChangeListener(this); 358 } else { 359 dataObject.removeVetoableChangeListener(this); 360 } 361 } else if(DataObject.PROP_VALID.equals(evt.getPropertyName ())) { 362 if(Boolean.FALSE.equals(evt.getOldValue())) return; 365 366 PropertiesOpen support = (PropertiesOpen)findCloneableOpenSupport(); 368 if(support != null) { 369 370 unmarkModified(); 373 374 support.close(false); 375 } 376 } else { 377 firePropertyChange ( 378 evt.getPropertyName(), 379 evt.getOldValue(), 380 evt.getNewValue() 381 ); 382 } 383 } 384 385 389 public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { 390 fireVetoableChange ( 391 evt.getPropertyName(), 392 evt.getOldValue(), 393 evt.getNewValue() 394 ); 395 } 396 397 402 private void firePropertyChange (String name, Object oldValue, Object newValue) { 403 prop().firePropertyChange(name, oldValue, newValue); 404 } 405 406 411 private void fireVetoableChange (String name, Object oldValue, Object newValue) throws PropertyVetoException { 412 veto().fireVetoableChange(name, oldValue, newValue); 413 } 414 415 416 private PropertyChangeSupport prop() { 417 if(propSupp == null) { 418 synchronized(this) { 419 if(propSupp == null) { 420 propSupp = new PropertyChangeSupport(this); 421 } 422 } 423 } 424 return propSupp; 425 } 426 427 428 private VetoableChangeSupport veto() { 429 if(vetoSupp == null) { 430 synchronized(this) { 431 if(vetoSupp == null) { 432 vetoSupp = new VetoableChangeSupport(this); 433 } 434 } 435 } 436 return vetoSupp; 437 } 438 } 440 441 442 private final class ModifiedListener implements SaveCookie, PropertyChangeListener { 443 444 447 public void propertyChange(PropertyChangeEvent evt) { 448 if(evt.getSource().equals(propDataObject)) 450 ((CompoundUndoRedoManager)PropertiesOpen.this.getUndoRedo()).reset(propDataObject); 451 452 if ((evt.getSource() == propDataObject) && (DataObject.PROP_MODIFIED.equals(evt.getPropertyName()))) { 453 if (((Boolean )evt.getNewValue()).booleanValue()) { 454 addSaveCookie(); 455 } else { 456 removeSaveCookie(); 457 } 458 } 459 } 460 461 462 public void save() throws IOException { 463 stopEditing(); 464 saveDocument(); 466 } 467 468 472 public void saveDocument() throws IOException { 473 PropertiesFileEntry pfe = (PropertiesFileEntry)propDataObject.getPrimaryEntry(); 474 SaveCookie save = (SaveCookie)pfe.getCookie(SaveCookie.class); 475 if (save != null) 476 save.save(); 477 for (Iterator it = propDataObject.secondaryEntries().iterator(); it.hasNext();) { 478 save = (SaveCookie)((PropertiesFileEntry)it.next()).getCookie(SaveCookie.class); 479 if(save != null) 480 save.save(); 481 } 482 } 483 484 485 private void addSaveCookie() { 486 if(propDataObject.getCookie(SaveCookie.class) == null) { 487 propDataObject.getCookieSet0().add(this); 488 } 489 } 490 491 492 private void removeSaveCookie() { 493 if(propDataObject.getCookie(SaveCookie.class) == this) { 494 propDataObject.getCookieSet0().remove(this); 495 } 496 } 497 } 499 500 501 public class PropertiesOpenAt implements OpenCookie { 502 503 504 private PropertiesFileEntry entry; 505 506 507 private String key; 508 509 510 511 PropertiesOpenAt(PropertiesFileEntry entry, String key) { 512 this.entry = entry; 513 this.key = key; 514 } 515 516 517 518 public void setKey(String key) { 519 this.key = key; 520 } 521 522 523 public void open() { 524 final PropertiesCloneableTopComponent editor = (PropertiesCloneableTopComponent)PropertiesOpen.super.openCloneableTopComponent(); 527 editor.requestActive(); 528 529 BundleStructure bs = propDataObject.getBundleStructure(); 530 int entryIndex = bs.getEntryIndexByFileName(entry.getFile().getName()); 532 int rowIndex = bs.getKeyIndexByName(key); 533 534 if ((entryIndex != -1) && (rowIndex != -1)) { 535 final int row = rowIndex; 536 final int column = entryIndex + 1; 537 538 SwingUtilities.invokeLater(new Runnable () { 539 public void run() { 540 JTable table = ((BundleEditPanel)editor.getComponent(0)).getTable(); 541 if (table.getAutoscrolls()) { 543 Rectangle cellRect = table.getCellRect(row, column, false); 544 if (cellRect != null) { 545 table.scrollRectToVisible(cellRect); 546 } 547 } 548 549 table.getColumnModel().getSelectionModel().setSelectionInterval(row, column); 551 table.getSelectionModel().setSelectionInterval(row, column); 552 553 table.editCellAt(row, column); 554 } 555 }); 556 } 557 } 558 } 560 561 562 public static class PropertiesCloneableTopComponent extends CloneableTopComponent { 563 564 565 private PropertiesDataObject propDataObject; 566 567 569 private transient PropertyChangeListener dataObjectListener; 570 571 572 static final long serialVersionUID =2836248291419024296L; 573 574 575 576 public PropertiesCloneableTopComponent() { 577 } 578 579 581 public PropertiesCloneableTopComponent (PropertiesDataObject propDataObject) { 582 this.propDataObject = propDataObject; 583 584 initialize(); 585 } 586 587 589 public void open() { 590 if (discard()) { 591 return; 592 } 593 super.open(); 594 } 595 596 public void requestActive() { 597 super.requestActive(); 598 getComponent(0).requestFocusInWindow(); 599 } 600 601 public boolean canClose () { 602 ((BundleEditPanel)getComponent(0)).stopEditing(); 603 return super.canClose(); 604 } 605 606 607 private void initialize() { 608 initComponents(); 609 setupActions(); 610 setActivatedNodes(new Node[] {propDataObject.getNodeDelegate()}); 611 612 dataObjectListener = new NameUpdater(); 613 propDataObject.addPropertyChangeListener( 614 WeakListeners.propertyChange(dataObjectListener, 615 propDataObject)); 616 617 updateName(); 618 } 619 620 621 final class NameUpdater implements PropertyChangeListener, 622 FileStatusListener, 623 Runnable { 624 625 626 private static final int NO_ACTION = 0; 627 628 private static final int ACTION_UPDATE_NAME = 1; 629 630 private static final int ACTION_UPDATE_DISPLAY_NAME = 2; 631 632 633 private FileStatusListener weakL; 634 635 private FileSystem previous; 636 637 638 private final int action; 639 640 642 NameUpdater() { 643 this(NO_ACTION); 644 updateStatusListener(); 645 } 646 647 649 NameUpdater(int action) { 650 this.action = action; 651 } 652 653 654 private void updateStatusListener() { 655 if (previous != null) { 656 previous.removeFileStatusListener(weakL); 657 } 658 try { 659 previous = propDataObject.getPrimaryFile().getFileSystem(); 660 if (weakL == null) { 661 weakL = org.openide.filesystems.FileUtil 662 .weakFileStatusListener(this, previous); 663 } 664 previous.addFileStatusListener(weakL); 665 } catch (FileStateInvalidException ex) { 666 previous = null; 667 } 668 } 669 670 673 public void annotationChanged(FileStatusEvent ev) { 674 if (!ev.isNameChange()) { 675 return; 676 } 677 678 boolean thisChanged = false; 679 for (FileObject fo : propDataObject.files()) { 680 if (ev.hasChanged(fo)) { 681 thisChanged = true; 682 break; 683 } 684 } 685 if (thisChanged) { 686 Mutex.EVENT.writeAccess( 687 new NameUpdater(ACTION_UPDATE_DISPLAY_NAME)); 688 } 689 } 690 691 693 public void propertyChange(PropertyChangeEvent e) { 694 if (!propDataObject.isValid()) { 695 return; 696 } 697 698 final String property = e.getPropertyName(); 699 if (property == null) { 700 return; 701 } 702 if (property.equals(DataObject.PROP_NAME)) { 703 Mutex.EVENT.writeAccess( 704 new NameUpdater(ACTION_UPDATE_NAME)); 705 } else if (property.equals(DataObject.PROP_PRIMARY_FILE)) { 706 updateStatusListener(); 707 Mutex.EVENT.writeAccess( 708 new NameUpdater(ACTION_UPDATE_NAME)); 709 } else if (property.equals(DataObject.PROP_COOKIE) 710 || property.equals(DataObject.PROP_FILES)) { 711 Mutex.EVENT.writeAccess( 712 new NameUpdater(ACTION_UPDATE_DISPLAY_NAME)); 713 } 714 } 715 716 718 public void run() { 719 assert EventQueue.isDispatchThread(); 720 721 if (action == ACTION_UPDATE_NAME) { 722 updateName(); 723 } else if (action == ACTION_UPDATE_DISPLAY_NAME) { 724 updateDisplayName(); 725 } else { 726 assert false; 727 } 728 } 729 730 } 731 732 736 private void setupActions() { 737 JTable bundleTable = ((BundleEditPanel) getComponent(0)).getTable(); 738 FindAction findAction = SystemAction.get(FindAction.class); 739 Action action = FindPerformer.getFindPerformer(bundleTable); 740 getActionMap().put(findAction.getActionMapKey(), action); 741 } 742 743 745 private void updateName() { 746 assert EventQueue.isDispatchThread(); 747 748 final String name = propDataObject.getName(); 749 final String displayName = displayName(); 750 final String htmlDisplayName = htmlDisplayName(); 751 final String toolTip = messageToolTip(); 752 753 Enumeration<CloneableTopComponent> en = getReference().getComponents(); 754 while (en.hasMoreElements()) { 755 CloneableTopComponent tc = en.nextElement(); 756 tc.setName(name); 757 tc.setDisplayName(displayName); 758 tc.setHtmlDisplayName(htmlDisplayName); 759 tc.setToolTipText(toolTip); 760 } 761 } 762 763 765 private void updateDisplayName() { 766 assert EventQueue.isDispatchThread(); 767 768 final String displayName = displayName(); 769 final String htmlDisplayName = htmlDisplayName(); 770 771 Enumeration<CloneableTopComponent> en = getReference().getComponents(); 772 while (en.hasMoreElements()) { 773 CloneableTopComponent tc = en.nextElement(); 774 tc.setDisplayName(displayName); 775 tc.setHtmlDisplayName(htmlDisplayName); 776 } 777 } 778 779 781 private String addModifiedInfo(String name) { 782 boolean modified 783 = propDataObject.getCookie(SaveCookie.class) != null; 784 int version = modified ? 1 : 3; 785 return NbBundle.getMessage(PropertiesCloneableTopComponent.class, 786 "LBL_EditorName", new Integer (version), 788 name); 789 } 790 791 797 private String displayName() { 798 String nameBase = propDataObject.getNodeDelegate().getDisplayName(); 799 return addModifiedInfo(nameBase); 800 } 801 802 808 private String htmlDisplayName() { 809 final Node node = propDataObject.getNodeDelegate(); 810 String displayName = node.getHtmlDisplayName(); 811 if (displayName != null) { 812 if (!displayName.startsWith("<html>")) { displayName = "<html>" + displayName; } 815 } else { 816 displayName = node.getDisplayName(); 817 } 818 return addModifiedInfo(displayName); 819 } 820 821 822 private String messageToolTip() { 823 FileObject fo = propDataObject.getPrimaryFile(); 824 return FileUtil.getFileDisplayName(fo); 825 } 826 827 831 protected boolean closeLast () { 832 if (!propDataObject.getOpenSupport().canClose ()) { 833 return false; 835 } 836 propDataObject.getOpenSupport().closeDocuments(); 837 838 return true; 839 } 840 841 847 protected CloneableTopComponent createClonedObject () { 848 return new PropertiesCloneableTopComponent(propDataObject); 849 } 850 851 852 public Image getIcon () { 853 return Utilities.loadImage("org/netbeans/modules/properties/propertiesEditorMode.gif"); } 855 856 857 public HelpCtx getHelpCtx () { 858 return new HelpCtx(Util.HELP_ID_MODIFYING); 859 } 860 861 protected String preferredID() { 862 return getName(); 863 } 864 865 public int getPersistenceType() { 866 return PERSISTENCE_ONLY_OPENED; 867 } 868 869 873 public UndoRedo getUndoRedo () { 874 return propDataObject.getOpenSupport().getUndoRedo(); 875 } 876 877 879 private void initComponents() { 880 GridBagLayout gridbag = new GridBagLayout(); 881 setLayout(gridbag); 882 883 GridBagConstraints c = new GridBagConstraints(); 884 c.fill = GridBagConstraints.BOTH; 885 c.weightx = 1.0; 886 c.weighty = 1.0; 887 c.gridwidth = GridBagConstraints.REMAINDER; 888 JPanel panel = new BundleEditPanel(propDataObject, new PropertiesTableModel(propDataObject.getBundleStructure())); 889 gridbag.setConstraints(panel, c); 890 add(panel); 891 } 892 893 896 private boolean discard () { 897 return propDataObject == null; 898 } 899 900 901 906 public void writeExternal (ObjectOutput out) throws IOException { 907 super.writeExternal(out); 908 out.writeObject(propDataObject); 909 } 910 911 916 public void readExternal (ObjectInput in) throws IOException , ClassNotFoundException { 917 super.readExternal(in); 918 919 propDataObject = (PropertiesDataObject)in.readObject(); 920 921 initialize(); 922 } 923 } 925 926 931 private static class CompoundUndoRedoManager implements UndoRedo { 932 933 934 private WeakSet<Manager> managers = new WeakSet<Manager>(5); 935 936 938 939 public CompoundUndoRedoManager(PropertiesDataObject obj) { 940 init(obj); 941 } 942 943 944 private void init(PropertiesDataObject obj) { 945 managers.add( ((PropertiesFileEntry)obj.getPrimaryEntry()).getPropertiesEditor().getUndoRedoManager()); 946 for (Iterator it = obj.secondaryEntries().iterator(); it.hasNext(); ) { 947 managers.add( ((PropertiesFileEntry)it.next()).getPropertiesEditor().getUndoRedoManager() ); 948 } 949 } 950 951 952 public synchronized void reset(PropertiesDataObject obj) { 953 managers.clear(); 954 init(obj); 955 } 956 957 958 private UndoRedo getNextUndo() { 959 UndoRedo chosenManager = null; 960 long time = 0L; long timeManager; 963 for (Iterator<Manager> it = managers.iterator(); it.hasNext(); ) { 964 PropertiesEditorSupport.UndoRedoStampFlagManager manager = (PropertiesEditorSupport.UndoRedoStampFlagManager)it.next(); 965 timeManager = manager.getTimeStampOfEditToBeUndone(); 966 if(timeManager > time) { 967 time = timeManager; 968 chosenManager = manager; 969 } 970 } 971 return chosenManager; 972 } 973 974 975 private UndoRedo getNextRedo() { 976 UndoRedo chosenManager = null; 977 long time = 0L; long timeManager; 980 for (Iterator<Manager> it = managers.iterator(); it.hasNext(); ) { 981 PropertiesEditorSupport.UndoRedoStampFlagManager manager = (PropertiesEditorSupport.UndoRedoStampFlagManager)it.next(); 982 timeManager = manager.getTimeStampOfEditToBeRedone(); 983 if(timeManager > time) { 984 time = timeManager; 985 chosenManager = manager; 986 } 987 } 988 return chosenManager; 989 } 990 991 994 public synchronized boolean canUndo () { 995 for (Manager manager : managers) { 996 if (manager.canUndo()) { 997 return true; 998 } 999 } 1000 return false; 1001 } 1002 1003 1006 public synchronized boolean canRedo () { 1007 for (Manager manager : managers) { 1008 if (manager.canRedo()) { 1009 return true; 1010 } 1011 } 1012 return false; 1013 } 1014 1015 1019 public synchronized void undo () throws CannotUndoException { 1020 PropertiesEditorSupport.UndoRedoStampFlagManager chosenManager = (PropertiesEditorSupport.UndoRedoStampFlagManager)getNextUndo(); 1021 1022 if(chosenManager == null) 1023 throw new CannotUndoException (); 1024 else { 1025 Object atomicFlag = chosenManager.getAtomicFlagOfEditToBeUndone(); 1026 if(atomicFlag == null) chosenManager.undo(); 1028 else { boolean undone; 1030 do { undone = false; 1032 for (Iterator<Manager> it = managers.iterator(); it.hasNext(); ) { 1033 PropertiesEditorSupport.UndoRedoStampFlagManager manager = (PropertiesEditorSupport.UndoRedoStampFlagManager)it.next(); 1034 if(atomicFlag.equals(manager.getAtomicFlagOfEditToBeUndone())) { 1035 manager.undo(); 1036 undone = true; 1037 } 1038 } 1039 } while(undone); 1040 } 1041 } 1042 } 1043 1044 1048 public synchronized void redo () throws CannotRedoException { 1049 PropertiesEditorSupport.UndoRedoStampFlagManager chosenManager = (PropertiesEditorSupport.UndoRedoStampFlagManager)getNextRedo(); 1050 1051 if(chosenManager == null) 1052 throw new CannotRedoException (); 1053 else { 1054 Object atomicFlag = chosenManager.getAtomicFlagOfEditToBeRedone(); 1055 if(atomicFlag == null) chosenManager.redo(); 1057 else { boolean redone; 1059 do { redone = false; 1061 for (Iterator<Manager> it = managers.iterator(); it.hasNext(); ) { 1062 PropertiesEditorSupport.UndoRedoStampFlagManager manager = (PropertiesEditorSupport.UndoRedoStampFlagManager)it.next(); 1063 if(atomicFlag.equals(manager.getAtomicFlagOfEditToBeRedone())) { 1064 manager.redo(); 1065 redone = true; 1066 } 1067 } 1068 } while(redone); 1069 } 1070 } 1071 } 1072 1073 1076 public void addChangeListener (ChangeListener l) { 1077 } 1079 1080 1084 public void removeChangeListener (ChangeListener l) { 1085 } 1087 1088 1092 public synchronized String getUndoPresentationName () { 1093 UndoRedo chosenManager = getNextUndo(); 1094 1095 if(chosenManager == null) 1096 return "Undo"; else 1098 return chosenManager.getUndoPresentationName(); 1099 } 1100 1101 1105 public synchronized String getRedoPresentationName () { 1106 UndoRedo chosenManager = getNextRedo(); 1107 if(chosenManager == null) 1108 return "Redo"; else 1110 return chosenManager.getRedoPresentationName(); 1111 } 1112 1113 } 1115} 1116 | Popular Tags |