1 11 package org.eclipse.jdt.internal.ui.dialogs; 12 13 import com.ibm.icu.text.BreakIterator; 14 15 import java.util.ArrayList ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 19 import org.eclipse.core.commands.Command; 20 import org.eclipse.core.commands.CommandManager; 21 import org.eclipse.core.commands.ParameterizedCommand; 22 import org.eclipse.core.commands.common.NotDefinedException; 23 import org.eclipse.core.commands.contexts.ContextManager; 24 25 import org.eclipse.swt.SWT; 26 import org.eclipse.swt.custom.StyledText; 27 import org.eclipse.swt.events.DisposeEvent; 28 import org.eclipse.swt.events.DisposeListener; 29 import org.eclipse.swt.events.FocusEvent; 30 import org.eclipse.swt.events.FocusListener; 31 import org.eclipse.swt.events.KeyAdapter; 32 import org.eclipse.swt.events.KeyEvent; 33 import org.eclipse.swt.events.MouseAdapter; 34 import org.eclipse.swt.events.MouseEvent; 35 import org.eclipse.swt.graphics.Point; 36 import org.eclipse.swt.widgets.Combo; 37 import org.eclipse.swt.widgets.Control; 38 import org.eclipse.swt.widgets.Text; 39 40 import org.eclipse.jface.bindings.BindingManager; 41 import org.eclipse.jface.bindings.Scheme; 42 import org.eclipse.jface.bindings.TriggerSequence; 43 import org.eclipse.jface.bindings.keys.KeySequence; 44 import org.eclipse.jface.bindings.keys.SWTKeySupport; 45 import org.eclipse.jface.preference.IPreferenceStore; 46 47 import org.eclipse.ui.PlatformUI; 48 import org.eclipse.ui.commands.ICommandService; 49 import org.eclipse.ui.keys.IBindingService; 50 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; 51 52 import org.eclipse.jdt.ui.PreferenceConstants; 53 54 import org.eclipse.jdt.internal.ui.JavaPlugin; 55 import org.eclipse.jdt.internal.ui.text.JavaWordIterator; 56 57 60 public class TextFieldNavigationHandler { 61 62 public static void install(Text text) { 63 if (isSubWordNavigationEnabled()) 64 new FocusHandler(new TextNavigable(text)); 65 } 66 67 public static void install(StyledText styledText) { 68 if (isSubWordNavigationEnabled()) 69 new FocusHandler(new StyledTextNavigable(styledText)); 70 } 71 72 public static void install(Combo combo) { 73 if (isSubWordNavigationEnabled()) 74 new FocusHandler(new ComboNavigable(combo)); 75 } 76 77 private static boolean isSubWordNavigationEnabled() { 78 IPreferenceStore preferenceStore= JavaPlugin.getDefault().getCombinedPreferenceStore(); 79 return preferenceStore.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION); 80 } 81 82 private abstract static class WorkaroundNavigable extends Navigable { 83 87 Point fLastSelection; 88 int fCaretPosition; 89 90 void selectionChanged() { 91 Point selection= getSelection(); 92 if (selection.equals(fLastSelection)) { 93 } else if (selection.x == selection.y) { fCaretPosition= selection.x; 96 } else if (fLastSelection.y == selection.y) { 97 fCaretPosition= selection.x; } else { 99 fCaretPosition= selection.y; 100 } 101 fLastSelection= selection; 102 } 103 } 104 105 private abstract static class Navigable { 106 public abstract Control getControl(); 107 108 public abstract String getText(); 109 110 public abstract void setText(String text); 111 112 public abstract Point getSelection(); 113 114 public abstract void setSelection(int start, int end); 115 116 public abstract int getCaretPosition(); 117 } 118 119 private static class TextNavigable extends WorkaroundNavigable { 120 static final boolean BUG_106024_TEXT_SELECTION= 121 "win32".equals(SWT.getPlatform()) || "carbon".equals(SWT.getPlatform()); 125 private final Text fText; 126 127 public TextNavigable(Text text) { 128 fText= text; 129 if (BUG_106024_TEXT_SELECTION) { 131 fLastSelection= getSelection(); 132 fCaretPosition= fLastSelection.y; 133 fText.addKeyListener(new KeyAdapter() { 134 public void keyReleased(KeyEvent e) { 135 selectionChanged(); 136 } 137 }); 138 fText.addMouseListener(new MouseAdapter() { 139 public void mouseUp(MouseEvent e) { 140 selectionChanged(); 141 } 142 }); 143 } 144 } 145 146 public Control getControl() { 147 return fText; 148 } 149 150 public String getText() { 151 return fText.getText(); 152 } 153 154 public void setText(String text) { 155 fText.setText(text); 156 } 157 158 public Point getSelection() { 159 return fText.getSelection(); 160 } 161 162 public int getCaretPosition() { 163 if (BUG_106024_TEXT_SELECTION) { 164 selectionChanged(); 165 return fCaretPosition; 166 } else { 167 return fText.getCaretPosition(); 168 } 169 } 170 171 public void setSelection(int start, int end) { 172 fText.setSelection(start, end); 173 } 174 } 175 176 private static class StyledTextNavigable extends Navigable { 177 private final StyledText fStyledText; 178 179 public StyledTextNavigable(StyledText styledText) { 180 fStyledText= styledText; 181 } 182 183 public Control getControl() { 184 return fStyledText; 185 } 186 187 public String getText() { 188 return fStyledText.getText(); 189 } 190 191 public void setText(String text) { 192 fStyledText.setText(text); 193 } 194 195 public Point getSelection() { 196 return fStyledText.getSelection(); 197 } 198 199 public int getCaretPosition() { 200 return fStyledText.getCaretOffset(); 201 } 202 203 public void setSelection(int start, int end) { 204 fStyledText.setSelection(start, end); 205 } 206 } 207 208 private static class ComboNavigable extends WorkaroundNavigable { 209 private final Combo fCombo; 210 211 public ComboNavigable(Combo combo) { 212 fCombo= combo; 213 fLastSelection= getSelection(); 215 fCaretPosition= fLastSelection.y; 216 fCombo.addKeyListener(new KeyAdapter() { 217 public void keyReleased(KeyEvent e) { 218 selectionChanged(); 219 } 220 }); 221 fCombo.addMouseListener(new MouseAdapter() { 222 public void mouseUp(MouseEvent e) { 223 selectionChanged(); 224 } 225 }); 226 } 227 228 public Control getControl() { 229 return fCombo; 230 } 231 232 public String getText() { 233 return fCombo.getText(); 234 } 235 236 public void setText(String text) { 237 fCombo.setText(text); 238 } 239 240 public Point getSelection() { 241 return fCombo.getSelection(); 242 } 243 244 public int getCaretPosition() { 245 selectionChanged(); 246 return fCaretPosition; 247 } 249 250 public void setSelection(int start, int end) { 251 fCombo.setSelection(new Point(start, end)); 252 } 253 } 254 255 private static class FocusHandler implements FocusListener { 256 257 private static final String EMPTY_TEXT= ""; 259 private final JavaWordIterator fIterator; 260 private final Navigable fNavigable; 261 private KeyAdapter fKeyListener; 262 263 private FocusHandler(Navigable navigable) { 264 fIterator= new JavaWordIterator(); 265 fNavigable= navigable; 266 267 Control control= navigable.getControl(); 268 control.addFocusListener(this); 269 if (control.isFocusControl()) 270 activate(); 271 control.addDisposeListener(new DisposeListener() { 272 public void widgetDisposed(DisposeEvent e) { 273 deactivate(); 274 } 275 }); 276 } 277 278 public void focusGained(FocusEvent e) { 279 activate(); 280 } 281 282 public void focusLost(FocusEvent e) { 283 deactivate(); 284 } 285 286 private void activate() { 287 fNavigable.getControl().addKeyListener(getKeyListener()); 288 } 289 290 private void deactivate() { 291 if (fKeyListener != null) { 292 Control control= fNavigable.getControl(); 293 if (! control.isDisposed()) 294 control.removeKeyListener(fKeyListener); 295 fKeyListener= null; 296 } 297 } 298 299 private KeyAdapter getKeyListener() { 300 if (fKeyListener == null) { 301 fKeyListener= new KeyAdapter() { 302 private final boolean IS_WORKAROUND= (fNavigable instanceof ComboNavigable) 303 || (fNavigable instanceof TextNavigable && TextNavigable.BUG_106024_TEXT_SELECTION); 304 private List fSubmissions; 305 306 public void keyPressed(KeyEvent e) { 307 if (IS_WORKAROUND) { 308 if (e.keyCode == SWT.ARROW_LEFT && e.stateMask == SWT.MOD2) { 309 int caretPosition= fNavigable.getCaretPosition(); 310 if (caretPosition != 0) { 311 Point selection= fNavigable.getSelection(); 312 if (caretPosition == selection.x) 313 fNavigable.setSelection(selection.y, caretPosition - 1); 314 else 315 fNavigable.setSelection(selection.x, caretPosition - 1); 316 } 317 e.doit= false; 318 return; 319 320 } else if (e.keyCode == SWT.ARROW_RIGHT && e.stateMask == SWT.MOD2) { 321 String text= fNavigable.getText(); 322 int caretPosition= fNavigable.getCaretPosition(); 323 if (caretPosition != text.length()) { 324 Point selection= fNavigable.getSelection(); 325 if (caretPosition == selection.y) 326 fNavigable.setSelection(selection.x, caretPosition + 1); 327 else 328 fNavigable.setSelection(selection.y, caretPosition + 1); 329 } 330 e.doit= false; 331 return; 332 } 333 } 334 int accelerator = SWTKeySupport.convertEventToUnmodifiedAccelerator(e); 335 KeySequence keySequence = KeySequence.getInstance(SWTKeySupport.convertAcceleratorToKeyStroke(accelerator)); 336 getSubmissions(); 337 for (Iterator iter= getSubmissions().iterator(); iter.hasNext();) { 338 Submission submission= (Submission) iter.next(); 339 TriggerSequence[] triggerSequences= submission.getTriggerSequences(); 340 for (int i= 0; i < triggerSequences.length; i++) { 341 if (triggerSequences[i].equals(keySequence)) { e.doit= false; 343 submission.execute(); 344 return; 345 } 346 } 347 } 348 } 349 350 private List getSubmissions() { 351 if (fSubmissions != null) 352 return fSubmissions; 353 354 fSubmissions= new ArrayList (); 355 356 ICommandService commandService= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class); 357 IBindingService bindingService= (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class); 358 if (commandService == null || bindingService == null) 359 return fSubmissions; 360 361 BindingManager localBindingManager= new BindingManager(new ContextManager(), new CommandManager()); 364 final Scheme[] definedSchemes= bindingService.getDefinedSchemes(); 365 if (definedSchemes != null) { 366 try { 367 for (int i = 0; i < definedSchemes.length; i++) { 368 Scheme scheme= definedSchemes[i]; 369 Scheme localSchemeCopy= localBindingManager.getScheme(scheme.getId()); 370 localSchemeCopy.define(scheme.getName(), scheme.getDescription(), scheme.getParentId()); 371 } 372 } catch (final NotDefinedException e) { 373 JavaPlugin.log(e); 374 } 375 } 376 localBindingManager.setLocale(bindingService.getLocale()); 377 localBindingManager.setPlatform(bindingService.getPlatform()); 378 379 localBindingManager.setBindings(bindingService.getBindings()); 380 try { 381 Scheme activeScheme= bindingService.getActiveScheme(); 382 if (activeScheme != null) 383 localBindingManager.setActiveScheme(activeScheme); 384 } catch (NotDefinedException e) { 385 JavaPlugin.log(e); 386 } 387 388 fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.SELECT_WORD_NEXT)) { 389 public void execute() { 390 fIterator.setText(fNavigable.getText()); 391 int caretPosition= fNavigable.getCaretPosition(); 392 int newCaret= fIterator.following(caretPosition); 393 if (newCaret != BreakIterator.DONE) { 394 Point selection= fNavigable.getSelection(); 395 if (caretPosition == selection.y) 396 fNavigable.setSelection(selection.x, newCaret); 397 else 398 fNavigable.setSelection(selection.y, newCaret); 399 } 400 fIterator.setText(EMPTY_TEXT); 401 } 402 }); 403 fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS)) { 404 public void execute() { 405 fIterator.setText(fNavigable.getText()); 406 int caretPosition= fNavigable.getCaretPosition(); 407 int newCaret= fIterator.preceding(caretPosition); 408 if (newCaret != BreakIterator.DONE) { 409 Point selection= fNavigable.getSelection(); 410 if (caretPosition == selection.x) 411 fNavigable.setSelection(selection.y, newCaret); 412 else 413 fNavigable.setSelection(selection.x, newCaret); 414 } 415 fIterator.setText(EMPTY_TEXT); 416 } 417 }); 418 fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.WORD_NEXT)) { 419 public void execute() { 420 fIterator.setText(fNavigable.getText()); 421 int caretPosition= fNavigable.getCaretPosition(); 422 int newCaret= fIterator.following(caretPosition); 423 if (newCaret != BreakIterator.DONE) 424 fNavigable.setSelection(newCaret, newCaret); 425 fIterator.setText(EMPTY_TEXT); 426 } 427 }); 428 fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.WORD_PREVIOUS)) { 429 public void execute() { 430 fIterator.setText(fNavigable.getText()); 431 int caretPosition= fNavigable.getCaretPosition(); 432 int newCaret= fIterator.preceding(caretPosition); 433 if (newCaret != BreakIterator.DONE) 434 fNavigable.setSelection(newCaret, newCaret); 435 fIterator.setText(EMPTY_TEXT); 436 } 437 }); 438 fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.DELETE_NEXT_WORD)) { 439 public void execute() { 440 Point selection= fNavigable.getSelection(); 441 String text= fNavigable.getText(); 442 int start; 443 int end; 444 if (selection.x != selection.y) { 445 start= selection.x; 446 end= selection.y; 447 } else { 448 fIterator.setText(text); 449 start= fNavigable.getCaretPosition(); 450 end= fIterator.following(start); 451 fIterator.setText(EMPTY_TEXT); 452 if (end == BreakIterator.DONE) 453 return; 454 } 455 fNavigable.setText(text.substring(0, start) + text.substring(end)); 456 fNavigable.setSelection(start, start); 457 } 458 }); 459 fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD)) { 460 public void execute() { 461 Point selection= fNavigable.getSelection(); 462 String text= fNavigable.getText(); 463 int start; 464 int end; 465 if (selection.x != selection.y) { 466 start= selection.x; 467 end= selection.y; 468 } else { 469 fIterator.setText(text); 470 end= fNavigable.getCaretPosition(); 471 start= fIterator.preceding(end); 472 fIterator.setText(EMPTY_TEXT); 473 if (start == BreakIterator.DONE) 474 return; 475 } 476 fNavigable.setText(text.substring(0, start) + text.substring(end)); 477 fNavigable.setSelection(start, start); 478 } 479 }); 480 481 return fSubmissions; 482 } 483 484 private TriggerSequence[] getKeyBindings(BindingManager localBindingManager, ICommandService commandService, String commandID) { 485 Command command= commandService.getCommand(commandID); 486 ParameterizedCommand pCmd= new ParameterizedCommand(command, null); 487 return localBindingManager.getActiveBindingsDisregardingContextFor(pCmd); 488 } 489 490 }; 491 } 492 return fKeyListener; 493 } 494 } 495 496 private abstract static class Submission { 497 private TriggerSequence[] fTriggerSequences; 498 499 public Submission(TriggerSequence[] triggerSequences) { 500 fTriggerSequences= triggerSequences; 501 } 502 503 public TriggerSequence[] getTriggerSequences() { 504 return fTriggerSequences; 505 } 506 507 public abstract void execute(); 508 } 509 510 } 511 | Popular Tags |