1 19 20 21 package org.netbeans.modules.tasklist.suggestions; 22 23 import org.openide.windows.TopComponent; 24 import org.openide.windows.Workspace; 25 import org.openide.windows.WindowManager; 26 import org.openide.windows.Mode; 27 import org.openide.loaders.DataObject; 28 import org.openide.text.*; 29 import org.openide.nodes.Node; 30 import org.openide.cookies.EditorCookie; 31 import org.openide.util.RequestProcessor; 32 import org.openide.filesystems.FileObject; 33 import org.openide.ErrorManager; 34 import org.netbeans.modules.tasklist.suggestions.settings.ManagerSettings; 35 import org.netbeans.modules.tasklist.core.TLUtils; 36 import org.netbeans.modules.tasklist.core.Task; 37 import org.netbeans.modules.tasklist.providers.DocumentSuggestionProvider; 38 import org.netbeans.modules.tasklist.providers.SuggestionProvider; 39 40 import javax.swing.*; 41 import javax.swing.Timer ; 42 import javax.swing.event.*; 43 import javax.swing.text.Document ; 44 import javax.swing.text.StyledDocument ; 45 import java.beans.PropertyChangeEvent ; 46 import java.beans.PropertyChangeListener ; 47 import java.awt.event.*; 48 import java.awt.*; 49 import java.util.*; 50 import java.util.List ; 51 import java.util.logging.Logger ; 52 import java.lang.reflect.InvocationTargetException ; 53 54 66 public final class SuggestionsBroker { 67 68 private static SuggestionsBroker instance; 69 70 private SuggestionList list; 71 72 private int clientCount = 0; 73 74 private SuggestionManagerImpl manager = (SuggestionManagerImpl) SuggestionManagerImpl.getDefault(); 75 76 Env env = new Env(); 78 79 private Map openedFilesSuggestionsMap = new HashMap(); 81 82 private int allOpenedClientsCount = 0; 83 84 85 private Job allOpenedJob; 86 87 private SuggestionList allOpenedList; 88 89 private static final Logger LOGGER = TLUtils.getLogger(SuggestionsBroker.class); 90 91 private List acceptors = new ArrayList(5); 93 94 private final ProviderAcceptor compound = new ProviderAcceptor() { 95 public boolean accept(SuggestionProvider provider) { 96 Iterator it = acceptors.iterator(); 97 while (it.hasNext()) { 98 ProviderAcceptor acceptor = (ProviderAcceptor) it.next(); 99 if (acceptor.accept(provider)) return true; 100 } 101 return false; 102 } 103 }; 104 105 private SuggestionsBroker() { 106 } 107 108 public static SuggestionsBroker getDefault() { 109 if (instance == null) { 110 instance = new SuggestionsBroker(); 111 } 112 return instance; 113 } 114 115 116 public Job startBroker(ProviderAcceptor acceptor) { 117 clientCount++; 118 if (clientCount == 1) { 119 manager.dispatchRun(); 120 startActiveSuggestionFetching(); 121 } 122 return new Job(acceptor); 123 } 124 125 126 public class Job { 127 128 private boolean stopped = false; 129 private final ProviderAcceptor acceptor; 130 131 private Job(ProviderAcceptor acceptor) { 132 this.acceptor = acceptor; 133 acceptors.add(acceptor); 134 } 135 136 public void stopBroker() { 137 if (stopped) return; 138 stopped = true; 139 acceptors.remove(acceptor); 140 141 clientCount--; 142 if (clientCount == 0) { 143 stopActiveSuggestionFetching(); 144 if (cache != null) { 147 cache.flush(); 148 } 149 list = null; 150 instance = null; 151 } 152 } 153 154 164 public SuggestionList getSuggestionsList() { 165 return getCurrentSuggestionsList(); 166 } 167 168 } 169 170 171 public AllOpenedJob startAllOpenedBroker(ProviderAcceptor acceptor) { 172 allOpenedClientsCount++; 173 if (allOpenedClientsCount == 1) { 174 acceptors.add(acceptor); 175 TopComponent[] documents = SuggestionsScanner.openedTopComponents(); 176 SuggestionsScanner scanner = SuggestionsScanner.getDefault(); 177 List allSuggestions = new LinkedList(); 178 for (int i = 0; i<documents.length; i++) { 179 DataObject dobj = extractDataObject(documents[i]); 180 if (dobj == null) continue; 181 FileObject fileObject = dobj.getPrimaryFile(); 182 183 if (openedFilesSuggestionsMap.keySet().contains(fileObject) == false) { 185 List suggestions = scanner.scanTopComponent(documents[i], compound); 186 openedFilesSuggestionsMap.put(fileObject, suggestions); 187 allSuggestions.addAll(suggestions); 188 } 189 } 190 getAllOpenedSuggestionList().addRemove(allSuggestions, null, true, null, null); 191 192 allOpenedJob = startBroker(acceptor); 193 } 194 return new AllOpenedJob(acceptor); 195 } 196 197 198 public class AllOpenedJob { 199 200 private boolean stopped = false; 201 private final ProviderAcceptor acceptor; 202 203 private AllOpenedJob(ProviderAcceptor acceptor) { 204 this.acceptor = acceptor; 205 acceptors.add(acceptor); 206 } 207 208 public SuggestionList getSuggestionList() { 209 return getAllOpenedSuggestionList(); 210 } 211 212 public void stopBroker() { 213 214 if (stopped) return; 215 stopped = true; 216 acceptors.remove(acceptor); 217 218 allOpenedClientsCount--; 219 if (allOpenedClientsCount == 0) { 220 allOpenedJob.stopBroker(); 221 openedFilesSuggestionsMap.clear(); 222 } 223 } 224 } 225 226 private SuggestionList getCurrentSuggestionsList() { 227 if (list == null) { 228 list = new SuggestionList(); 229 } 230 return list; 231 } 232 233 private SuggestionList getAllOpenedSuggestionList() { 234 if (allOpenedList == null) { 235 allOpenedList = new SuggestionList(); 236 } 237 return allOpenedList; 238 } 239 240 260 261 262 265 private volatile Long currRequest = new Long (0); 266 267 270 private volatile Comparable finishedRequest = null; 271 272 final Object getCurrRequest() { 273 return currRequest; 274 } 275 276 281 private void startActiveSuggestionFetching() { 282 283 LOGGER.info("Starting active suggestions fetching...."); 285 WindowSystemMonitor monitor = getWindowSystemMonitor(); 287 monitor.enableOpenCloseEvents(); 288 env.addTCRegistryListener(monitor); 289 env.addDORegistryListener(getDataSystemMonitor()); 290 291 316 317 366 367 374 375 prepareRescanInAWT(false); 376 } 377 378 379 private SuggestionCache cache = null; 380 381 383 private List docSuggestions = null; 384 385 393 private boolean prepareCurrent() { 394 395 assert SwingUtilities.isEventDispatchThread() : "This method must be run in the AWT thread"; 397 if (currentTC != null) { 399 currentTC.removeComponentListener(getWindowSystemMonitor()); 400 currentTC = null; 401 } 402 if (currentDocument != null) { 403 currentDocument.removeDocumentListener(getEditorMonitor()); 404 handleDocHidden(currentDocument, currentDO); 405 } 406 removeCurrentCaretListeners(); 407 408 413 TopComponent tc = env.findActiveEditor(); 415 if (tc == null) { 416 419 List previous = new ArrayList(getCurrentSuggestionsList().getTasks()); 421 getCurrentSuggestionsList().addRemove(null, previous, false, null, null); 422 424 LOGGER.fine("Cannot find active source editor!"); return false; 426 } 427 428 429 DataObject dao = extractDataObject(tc); 430 if (dao == null) { 431 LOGGER.warning("Suspicious editor without dataobject: " + tc); return false; 434 } 435 436 450 451 final EditorCookie edit = (EditorCookie) dao.getCookie(EditorCookie.class); 452 if (edit == null) { 453 return false; 455 } 456 457 final Document doc = edit.getDocument(); 459 472 if (doc == null) { 473 LOGGER.fine("No document is loaded in editor!"); return false; 475 } 476 477 currentDocument = doc; 478 currentDocument.addDocumentListener(getEditorMonitor()); 479 480 currentTC = tc; 483 currentTC.addComponentListener(getWindowSystemMonitor()); 484 485 currentDO = dao; 486 currentModified = dao.isModified(); 487 488 addCurrentCaretListeners(); 489 490 return true; 491 492 } 493 494 495 private boolean serveByCache() { 496 if (cache != null) { 497 docSuggestions = cache.lookup(currentDocument); 502 if (docSuggestions != null) { 503 manager.register(null, docSuggestions, null, getCurrentSuggestionsList(), true); 504 509 514 finishedRequest = currRequest; 516 return true; 517 } 518 } 519 return false; 520 } 521 522 private static DataObject extractDataObject(TopComponent topComponent) { 523 DataObject dobj = (DataObject) topComponent.getLookup().lookup(DataObject.class); 524 if (dobj != null && dobj.isValid()) { 525 return dobj; 526 } else { 527 return null; 528 } 529 } 530 531 550 private RequestProcessor.Task performRescanInRP(final TopComponent tc, final DataObject dataobject, int delay) { 551 552 572 573 assert currRequest.longValue() != Long.MAX_VALUE : "Wrap around logic needed!"; currRequest = new Long (currRequest.longValue() + 1); 580 final Object origRequest = currRequest; 581 582 return serializeOnBackground(new Runnable () { 584 public void run() { 585 586 scheduledRescan = null; 587 588 591 if (wait) { 593 waitingEvent = true; 594 return; 595 } 596 597 600 if (isTopComponentOpened(tc) == false) { 601 return; 602 } 603 604 LOGGER.fine("Dispatching rescan() request to providers..."); 605 606 setScanning(true); 607 608 List scannedSuggestions = manager.dispatchScan(dataobject, compound); 609 610 613 if (isTopComponentOpened(tc) == false) { 614 return; 615 } 616 617 619 if (allOpenedClientsCount > 0) { 620 FileObject fo = dataobject.getPrimaryFile(); 621 List previous = (List ) openedFilesSuggestionsMap.remove(fo); 622 openedFilesSuggestionsMap.put(fo, scannedSuggestions); 623 624 if (previous == null || previous.size() != scannedSuggestions.size() || previous.containsAll(scannedSuggestions) == false) { 626 getAllOpenedSuggestionList().addRemove(scannedSuggestions, previous, false, null, null); 627 } 628 } 629 630 if (clientCount > 0) { 631 List previous = new ArrayList(getCurrentSuggestionsList().getTasks()); 632 633 if (previous == null || previous.size() != scannedSuggestions.size() || previous.containsAll(scannedSuggestions) == false) { 635 getCurrentSuggestionsList().addRemove(scannedSuggestions, previous, false, null, null); 636 } 637 } 638 639 if ((finishedRequest == null) || 641 ((Comparable )origRequest).compareTo(finishedRequest) > 0) { 642 finishedRequest = (Comparable ) origRequest; 643 } 644 if (currRequest == finishedRequest) { 645 setScanning(false); LOGGER.fine("It was last pending request."); 647 } 648 } 649 }, delay); 650 } 651 652 656 private static boolean isTopComponentOpened(final TopComponent tc) { 657 if (tc == null) return false; 658 final boolean[] isOpened = new boolean[1]; 659 int attempt = 0; 660 while (attempt < 57) { try { 662 SwingUtilities.invokeAndWait(new Runnable () { 663 public void run() { 664 isOpened[0] = tc.isOpened(); } 666 }); 667 return isOpened[0]; 668 } catch (InterruptedException e) { 669 ErrorManager err = ErrorManager.getDefault(); 670 err.annotate(e, "[TODO] while get " + tc.getDisplayName() + " state, interrupted, ignoring..."); err.notify(ErrorManager.INFORMATIONAL, e); 672 attempt++; 673 } catch (InvocationTargetException e) { 674 ErrorManager err = ErrorManager.getDefault(); 675 err.annotate(e, "[TODO] cannot get " + tc.getDisplayName() + " state."); err.notify(e); 677 return false; 678 } finally { 679 if (attempt != 0) Thread.currentThread().interrupt(); } 681 } 682 return false; 683 } 684 685 private RequestProcessor rp = new RequestProcessor("Suggestions Broker"); 687 688 private RequestProcessor.Task serializeOnBackground(Runnable request, int delay) { 689 return rp.post(request, delay , Thread.MIN_PRIORITY); 690 } 691 692 696 private void stuffCache(Document document, DataObject dataobject, 697 boolean unregisterOnly) { 698 699 boolean filteredTaskListFixed = false; if (filteredTaskListFixed == false) return; 701 702 705 SuggestionList tasklist = getCurrentSuggestionsList(); 706 if (tasklist.getTasks().size() == 0) { 707 return; 708 } 709 Iterator it = tasklist.getTasks().iterator(); 710 List sgs = new ArrayList(tasklist.getTasks().size()); 711 while (it.hasNext()) { 712 SuggestionImpl s = (SuggestionImpl) it.next(); 713 Object seed = s.getSeed(); 714 if (seed != SuggestionList.CATEGORY_NODE_SEED) { 716 sgs.add(s); 717 } 718 719 Iterator sit = s.subtasksIterator(); 720 while (sit.hasNext()) { 721 s = (SuggestionImpl) sit.next(); 722 seed = s.getSeed(); 723 if (seed != SuggestionList.CATEGORY_NODE_SEED) { 724 sgs.add(s); 725 } 726 } 727 } 728 if (!unregisterOnly) { 729 if (cache == null) { 730 cache = new SuggestionCache(); 731 } 732 cache.add(document, dataobject, sgs); 733 } 734 735 if (sgs.size() > 0) { 738 manager.register(null, null, sgs, tasklist, true); 739 } 740 } 741 742 743 private TopComponent currentTC = null; 744 745 746 private Document currentDocument = null; 747 748 749 private DataObject currentDO = null; 750 751 private JEditorPane[] editorsWithCaretListener = null; 753 754 755 private boolean currentModified = false; 756 757 758 private void addCurrentCaretListeners() { 759 760 assert editorsWithCaretListener == null : "addCaretListeners() must not be called twice without removeCaretListeners() => memory leak"; 762 EditorCookie edit = (EditorCookie) currentDO.getCookie(EditorCookie.class); 763 if (edit != null) { 764 JEditorPane panes[] = edit.getOpenedPanes(); 765 if ((panes != null) && (panes.length > 0)) { 766 editorsWithCaretListener = panes; 768 for (int i = 0; i < editorsWithCaretListener.length; i++) { 769 editorsWithCaretListener[i].addCaretListener(getEditorMonitor()); 770 } 771 } 772 } 773 } 774 775 776 private void removeCurrentCaretListeners() { 777 if (editorsWithCaretListener != null) { 778 for (int i = 0; i < editorsWithCaretListener.length; i++) { 779 editorsWithCaretListener[i].removeCaretListener(getEditorMonitor()); 780 } 781 } 782 editorsWithCaretListener = null; 783 } 784 785 boolean pendingScan = false; 786 787 789 private volatile RequestProcessor.Task scheduledRescan; 790 791 801 private void scheduleRescan(boolean delay, final int scanDelay) { 802 803 if (delay && (scheduledRescan == null)) { 808 return; 809 } 810 811 if (scheduledRescan != null) { 814 scheduledRescan.cancel(); 815 scheduledRescan = null; 816 LOGGER.fine("Scheduled rescan task delayed by " + scanDelay + " ms."); } 818 819 821 Runnable task = new Runnable () { 822 public void run() { 823 if (prepareCurrent()) { 824 assert currentDO.equals(extractDataObject(currentTC)) : "DO=" + currentDO + " TC=" + currentTC; 826 scheduledRescan = performRescanInRP(currentTC, currentDO, scanDelay); 827 } 828 } 829 }; 830 831 if (SwingUtilities.isEventDispatchThread()) { 832 task.run(); 833 } else { 834 SwingUtilities.invokeLater(task); 835 } 836 } 837 838 839 private boolean waitingEvent = false; 840 private boolean wait = false; 841 842 847 final void setFixing(boolean wait) { 848 boolean wasWaiting = this.wait; 849 this.wait = wait; 850 if (!wait && wasWaiting && (waitingEvent)) { 851 scheduleRescan(false, ManagerSettings.getDefault().getEditScanDelay()); 852 waitingEvent = false; 853 } 854 } 855 856 857 858 private void componentsChanged() { 859 865 871 prepareRescanInAWT(true); 872 873 } 874 875 880 private void prepareRescanInAWT(final boolean delay) { 881 882 884 Runnable performer = new Runnable () { 885 public void run() { 886 if (clientCount > 0) { 887 prepareCurrent(); 888 if (serveByCache() == false) { 889 if (ManagerSettings.getDefault().isScanOnShow()) { 890 if (delay) { 891 performRescanInRP(currentTC, currentDO, ManagerSettings.getDefault().getShowScanDelay()); 892 } else { 893 performRescanInRP(currentTC, currentDO, 0); 894 } 895 } 896 } 897 } 898 } 899 }; 900 901 if (SwingUtilities.isEventDispatchThread()) { 902 performer.run(); 903 } else { 904 SwingUtilities.invokeLater(performer); 909 } 910 } 911 912 916 private void stopActiveSuggestionFetching() { 917 918 LOGGER.info("Stopping active suggestions fetching...."); 920 if (scheduledRescan != null) { 921 scheduledRescan.cancel(); 922 scheduledRescan = null; 923 } 924 925 env.removeTCRegistryListener(getWindowSystemMonitor()); 926 env.removeDORegistryListener(getDataSystemMonitor()); 927 928 if (currentTC != null) { 930 currentTC.removeComponentListener(getWindowSystemMonitor()); 931 currentTC = null; 932 } 933 if (currentDocument != null) { 934 currentDocument.removeDocumentListener(getEditorMonitor()); 935 } 938 removeCurrentCaretListeners(); 939 940 handleDocHidden(currentDocument, currentDO); 941 currentDocument = null; 942 } 943 944 945 private void setScanning(boolean scanning) { 946 } 954 955 private void handleDocHidden(Document document, DataObject dataobject) { 956 if (currRequest != finishedRequest) { 961 if (cache != null) { 962 cache.remove(document); 963 } 964 stuffCache(document, dataobject, true); 967 } else { 968 stuffCache(document, dataobject, false); 969 } 970 971 docSuggestions = null; 972 } 973 974 private void handleTopComponentClosed(TopComponent tc) { 975 976 978 componentsChanged(); 979 980 DataObject dobj = extractDataObject(tc); 981 if (dobj == null) { 982 return; 984 } 985 986 List previous = (List ) openedFilesSuggestionsMap.remove(dobj.getPrimaryFile()); 987 if (previous != null) { 988 getAllOpenedSuggestionList().addRemove(null, previous, false, null, null); 990 } else { 991 } 993 } 994 995 private void handleTopComponentOpened(TopComponent tc) { 996 if (tc.isShowing()) { 998 componentsChanged(); 1000 } else { 1001 DataObject dao = extractDataObject(tc); 1003 if (dao == null) return; 1004 performRescanInRP(tc, dao, ManagerSettings.getDefault().getShowScanDelay()); 1005 } 1006 } 1007 1008 private WindowSystemMonitor windowSystemMonitor; 1009 1010 1011 private WindowSystemMonitor getWindowSystemMonitor() { 1012 if (windowSystemMonitor == null) { 1013 windowSystemMonitor = new WindowSystemMonitor(); 1014 } 1015 return windowSystemMonitor; 1016 } 1017 1018 private class WindowSystemMonitor implements PropertyChangeListener , ComponentListener { 1020 1021 1022 private Set openedSoFar = Collections.EMPTY_SET; 1023 1024 1028 private void enableOpenCloseEvents() { 1029 List list = Arrays.asList(SuggestionsScanner.openedTopComponents()); 1030 openedSoFar = new HashSet(list); 1031 1032 Iterator it = list.iterator(); 1033 while (it.hasNext()) { 1034 TopComponent tc = (TopComponent) it.next(); 1035 tc.addComponentListener(new ComponentAdapter() { 1036 public void componentShown(ComponentEvent e) { 1037 TopComponent tcomp = (TopComponent) e.getComponent(); 1038 tcomp.removeComponentListener(this); 1039 handleTopComponentOpened(tcomp); 1040 } 1041 }); 1042 1043 } 1044 } 1045 1046 1047 public void propertyChange(PropertyChangeEvent ev) { 1048 1049 String prop = ev.getPropertyName(); 1050 if (prop.equals(TopComponent.Registry.PROP_OPENED)) { 1051 1052 LOGGER.fine("EVENT opened top-components changed"); 1053 1054 1058 List list = Arrays.asList(SuggestionsScanner.openedTopComponents()); 1059 Set actual = new HashSet(list); 1060 1061 if (openedSoFar != null) { 1062 Iterator it = openedSoFar.iterator(); 1063 while(it.hasNext()) { 1064 TopComponent tc = (TopComponent) it.next(); 1065 if (actual.contains(tc) ) continue; 1066 handleTopComponentClosed(tc); 1067 } 1068 1069 Iterator ita = actual.iterator(); 1070 while(ita.hasNext()) { 1071 TopComponent tc = (TopComponent) ita.next(); 1072 if (openedSoFar.contains(tc)) continue; 1073 tc.addComponentListener(new ComponentAdapter() { 1076 public void componentShown(ComponentEvent e) { 1077 TopComponent tcomp = (TopComponent) e.getComponent(); 1078 tcomp.removeComponentListener(this); 1079 handleTopComponentOpened(tcomp); 1080 } 1081 }); 1082 } 1083 } 1084 1085 openedSoFar = actual; 1086 } else if (TopComponent.Registry.PROP_ACTIVATED.equals(prop)) { 1091 LOGGER.fine("EVENT top-component activated"); 1092 1093 TopComponent activated = WindowManager.getDefault().getRegistry().getActivated(); 1094 if (clientCount > 0 && isSelectedEditor(activated) && currentTC == null) { 1095 prepareRescanInAWT(false); 1096 } 1097 } 1098 } 1099 1100 public void componentShown(ComponentEvent e) { 1101 } 1103 1104 public void componentHidden(ComponentEvent e) { 1105 1106 LOGGER.fine("EVENT " + e.getComponent() + " has been hidden"); 1107 1108 if (allOpenedClientsCount == 0) { 1110 componentsChanged(); 1111 } 1112 } 1113 1114 public void componentResized(ComponentEvent e) { 1115 } 1117 1118 public void componentMoved(ComponentEvent e) { 1119 } 1121 1122 private boolean isSelectedEditor(Component tc) { 1123 Mode mode = WindowManager.getDefault().findMode(CloneableEditorSupport.EDITOR_MODE); 1124 TopComponent selected = null; 1125 if (mode != null) { 1126 selected = mode.getSelectedTopComponent(); 1127 } 1128 return selected == tc; 1129 } 1130 } 1131 1132 1133 private DataSystemMonitor dataSystemMonitor; 1134 1135 private DataSystemMonitor getDataSystemMonitor() { 1136 if (dataSystemMonitor == null) { 1137 dataSystemMonitor = new DataSystemMonitor(); 1138 } 1139 return dataSystemMonitor; 1140 } 1141 1142 1148 private class DataSystemMonitor implements ChangeListener { 1149 public void stateChanged(ChangeEvent e) { 1150 1159 1160 LOGGER.fine("EVENT " + e.getSource() + " changed."); 1161 1162 Set mods = DataObject.getRegistry().getModifiedSet(); 1163 boolean wasModified = currentModified; 1164 currentModified = mods.contains(currentDO); 1165 if (currentModified != wasModified) { 1166 if (!currentModified) { 1167 if (ManagerSettings.getDefault().isScanOnSave()) { 1168 scheduleRescan(false, ManagerSettings.getDefault().getSaveScanDelay()); 1169 } 1170 } 1171 } 1172 } 1173 } 1174 1175 private EditorMonitor editorMonitor; 1176 1177 private EditorMonitor getEditorMonitor() { 1178 if (editorMonitor == null) { 1179 editorMonitor = new EditorMonitor(); 1180 } 1181 return editorMonitor; 1182 } 1183 1184 private class EditorMonitor implements DocumentListener, CaretListener { 1185 1186 private int prevLineNo = -1; 1188 1189 public void changedUpdate(DocumentEvent e) { 1190 } 1195 1196 public void insertUpdate(DocumentEvent e) { 1197 1198 LOGGER.fine("EVENT document changed"); 1199 1200 if (ManagerSettings.getDefault().isScanOnEdit()) { 1201 scheduleRescan(false, ManagerSettings.getDefault().getEditScanDelay()); 1202 } 1203 } 1204 1205 public void removeUpdate(DocumentEvent e) { 1206 1207 LOGGER.fine("EVENT document changed"); 1208 1209 if (ManagerSettings.getDefault().isScanOnEdit()) { 1210 scheduleRescan(false, ManagerSettings.getDefault().getEditScanDelay()); 1211 } 1212 } 1213 1214 1216 public void caretUpdate(CaretEvent caretEvent) { 1217 1218 LOGGER.fine("EVENT caret moved"); 1219 1220 scheduleRescan(true, ManagerSettings.getDefault().getEditScanDelay()); 1221 1222 if (currentDocument instanceof StyledDocument ) { 1225 int offset = caretEvent.getDot(); 1226 int lineno = NbDocument.findLineNumber((StyledDocument ) currentDocument, offset); 1227 if (lineno == prevLineNo) { 1228 return; 1230 } 1231 prevLineNo = lineno; 1232 1233 1239 Line line = TLUtils.getLineByNumber(currentDO, lineno + 1); 1241 1254 if (line != null) { 1255 } 1258 } 1259 } 1260 1261 } 1262 1263 1264 1265 1268 static class Env { 1269 1270 void addTCRegistryListener(PropertyChangeListener pcl) { 1271 TopComponent.getRegistry().addPropertyChangeListener(pcl); 1272 } 1273 1274 void removeTCRegistryListener(PropertyChangeListener pcl) { 1275 TopComponent.getRegistry().removePropertyChangeListener(pcl); 1276 } 1277 1278 void addDORegistryListener(ChangeListener cl) { 1279 DataObject.getRegistry().addChangeListener(cl); 1280 1281 } 1282 1283 void removeDORegistryListener(ChangeListener cl) { 1284 DataObject.getRegistry().removeChangeListener(cl); 1285 } 1286 1287 1293 private TopComponent findActiveEditor() { 1294 Mode mode = WindowManager.getDefault().findMode(CloneableEditorSupport.EDITOR_MODE); 1295 if (mode == null) { 1296 return null; 1298 } 1299 TopComponent tc = mode.getSelectedTopComponent(); 1300 1301 if (tc instanceof CloneableEditorSupport.Pane) { 1305 return tc; 1310 } 1312 return null; 1313 } 1314 } 1315 1316} 1317 | Popular Tags |