1 19 20 package org.netbeans.modules.gsf; 21 22 import java.awt.event.ActionEvent ; 23 import java.io.IOException ; 24 import java.util.ArrayList ; 25 import java.util.List ; 26 import java.util.MissingResourceException ; 27 import javax.swing.Action ; 28 import javax.swing.event.CaretEvent ; 29 import javax.swing.event.CaretListener ; 30 import javax.swing.text.Caret ; 31 import javax.swing.text.JTextComponent ; 32 import org.netbeans.api.gsf.CancellableTask; 33 import org.netbeans.api.gsf.OffsetRange; 34 import org.netbeans.api.retouche.source.CompilationController; 35 import org.netbeans.api.retouche.source.Phase; 36 import org.netbeans.api.retouche.source.Source; 37 import org.netbeans.editor.BaseAction; 38 import org.openide.ErrorManager; 39 import org.openide.util.NbBundle; 40 41 48 final class SelectCodeElementAction extends BaseAction { 49 50 private boolean selectNext; 51 52 64 public SelectCodeElementAction(String name, boolean selectNext) { 65 super(name); 66 this.selectNext = selectNext; 67 String desc = getShortDescription(); 68 if (desc != null) { 69 putValue(SHORT_DESCRIPTION, desc); 70 } 71 } 72 73 public String getShortDescription(){ 74 String name = (String )getValue(Action.NAME); 75 if (name == null) return null; 76 String shortDesc; 77 try { 78 shortDesc = NbBundle.getBundle(GsfEditorKitFactory.class).getString(name); }catch (MissingResourceException mre){ 80 shortDesc = name; 81 } 82 return shortDesc; 83 } 84 85 public void actionPerformed(ActionEvent evt, JTextComponent target) { 86 if (target != null) { 87 int selectionStartOffset = target.getSelectionStart(); 88 int selectionEndOffset = target.getSelectionEnd(); 89 if (selectionEndOffset > selectionStartOffset || selectNext) { 90 SelectionHandler handler = (SelectionHandler)target.getClientProperty(SelectionHandler.class); 91 if (handler == null) { 92 handler = new SelectionHandler(target); 93 target.addCaretListener(handler); 94 target.putClientProperty(SelectionHandler.class, handler); 97 } 98 99 if (selectNext) { handler.selectNext(); 101 } else { handler.selectPrevious(); 103 } 104 } 105 } 106 } 107 108 private static final class SelectionHandler implements CaretListener , CancellableTask<CompilationController>, Runnable { 109 110 private JTextComponent target; 111 private SelectionInfo[] selectionInfos; 112 private int selIndex = -1; 113 private boolean ignoreNextCaretUpdate; 114 115 SelectionHandler(JTextComponent target) { 116 this.target = target; 117 } 118 119 public void selectNext() { 120 if (selectionInfos == null) { 121 Source js = Source.forDocument(target.getDocument()); 122 try { 123 js.runUserActionTask(this, true); 124 } catch (IOException ex) { 125 ErrorManager.getDefault().notify(ex); 126 } 127 } 128 129 run(); 130 } 131 132 public synchronized void selectPrevious() { 133 if (selIndex > 0) { 134 select(selectionInfos[--selIndex]); 135 } 136 } 137 138 private void select(SelectionInfo selectionInfo) { 139 Caret caret = target.getCaret(); 140 markIgnoreNextCaretUpdate(); 141 caret.setDot(selectionInfo.getStartOffset()); 142 markIgnoreNextCaretUpdate(); 143 caret.moveDot(selectionInfo.getEndOffset()); 144 } 145 146 private void markIgnoreNextCaretUpdate() { 147 ignoreNextCaretUpdate = true; 148 } 149 150 public void caretUpdate(CaretEvent e) { 151 if (!ignoreNextCaretUpdate) { 152 synchronized (this) { 153 selectionInfos = null; 154 selIndex = -1; 155 } 156 } 157 ignoreNextCaretUpdate = false; 158 } 159 160 public void cancel() { 161 } 162 163 public void run(CompilationController cc) { 164 try { 165 cc.toPhase(Phase.RESOLVED); 166 selectionInfos = initSelectionPath(target, cc); 167 } catch (IOException ex) { 168 ErrorManager.getDefault().notify(ex); 169 } 170 } 171 172 private SelectionInfo[] initSelectionPath(JTextComponent target, CompilationController ci) { 173 List <SelectionInfo> positions = new ArrayList <SelectionInfo>(); 174 Language language = ci.getLanguage(); 175 if (language.getBracketCompletion() != null) { 176 List <OffsetRange> ranges = language.getBracketCompletion().findLogicalRanges(ci, target.getCaretPosition()); 177 SelectionInfo[] result = new SelectionInfo[ranges.size()]; 178 for (int i = 0; i < ranges.size(); i++) { 179 OffsetRange range = ranges.get(i); 180 result[i] = new SelectionInfo(range.getStart(), range.getEnd()); 181 } 182 return result; 183 } else { 184 return new SelectionInfo[0]; 185 } 186 } 195 196 public void run() { 197 if (selIndex < selectionInfos.length - 1) { 198 select(selectionInfos[++selIndex]); 199 } 200 } 201 202 } 203 204 private static final class SelectionInfo { 206 207 private int startOffset; 208 private int endOffset; 209 210 SelectionInfo(int startOffset, int endOffset) { 211 this.startOffset = startOffset; 212 this.endOffset = endOffset; 213 } 214 215 public int getStartOffset() { 216 return startOffset; 217 } 218 219 public int getEndOffset() { 220 return endOffset; 221 } 222 223 } 224 } 225 | Popular Tags |