1 11 package org.eclipse.ui.texteditor.templates; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Map ; 18 import org.eclipse.swt.SWT; 19 import org.eclipse.swt.custom.StyledText; 20 import org.eclipse.swt.custom.VerifyKeyListener; 21 import org.eclipse.swt.events.FocusEvent; 22 import org.eclipse.swt.events.FocusListener; 23 import org.eclipse.swt.events.ModifyEvent; 24 import org.eclipse.swt.events.ModifyListener; 25 import org.eclipse.swt.events.SelectionEvent; 26 import org.eclipse.swt.events.SelectionListener; 27 import org.eclipse.swt.events.VerifyEvent; 28 import org.eclipse.swt.layout.GridData; 29 import org.eclipse.swt.layout.GridLayout; 30 import org.eclipse.swt.widgets.Button; 31 import org.eclipse.swt.widgets.Combo; 32 import org.eclipse.swt.widgets.Composite; 33 import org.eclipse.swt.widgets.Control; 34 import org.eclipse.swt.widgets.Label; 35 import org.eclipse.swt.widgets.Menu; 36 import org.eclipse.swt.widgets.Shell; 37 import org.eclipse.swt.widgets.Text; 38 import org.eclipse.swt.widgets.Widget; 39 import org.eclipse.jface.action.Action; 40 import org.eclipse.jface.action.GroupMarker; 41 import org.eclipse.jface.action.IAction; 42 import org.eclipse.jface.action.IMenuListener; 43 import org.eclipse.jface.action.IMenuManager; 44 import org.eclipse.jface.action.MenuManager; 45 import org.eclipse.jface.action.Separator; 46 import org.eclipse.jface.dialogs.IDialogSettings; 47 import org.eclipse.jface.dialogs.StatusDialog; 48 import org.eclipse.jface.viewers.ISelectionChangedListener; 49 import org.eclipse.jface.viewers.SelectionChangedEvent; 50 import org.eclipse.jface.text.Document; 51 import org.eclipse.jface.text.IDocument; 52 import org.eclipse.jface.text.ITextListener; 53 import org.eclipse.jface.text.ITextOperationTarget; 54 import org.eclipse.jface.text.ITextViewer; 55 import org.eclipse.jface.text.TextEvent; 56 import org.eclipse.jface.text.contentassist.ContentAssistant; 57 import org.eclipse.jface.text.contentassist.IContentAssistant; 58 import org.eclipse.jface.text.source.ISourceViewer; 59 import org.eclipse.jface.text.source.SourceViewer; 60 import org.eclipse.jface.text.source.SourceViewerConfiguration; 61 import org.eclipse.jface.text.templates.TemplateContextType; 62 import org.eclipse.jface.text.templates.ContextTypeRegistry; 63 import org.eclipse.jface.text.templates.Template; 64 import org.eclipse.jface.text.templates.TemplateException; 65 66 import org.eclipse.ui.internal.texteditor.TextEditorPlugin; 67 import org.eclipse.ui.texteditor.ITextEditorActionConstants; 68 import org.eclipse.ui.texteditor.IUpdate; 69 70 76 class EditTemplateDialog extends StatusDialog { 77 78 private static class TextViewerAction extends Action implements IUpdate { 79 80 private int fOperationCode= -1; 81 private ITextOperationTarget fOperationTarget; 82 83 89 public TextViewerAction(ITextViewer viewer, int operationCode) { 90 fOperationCode= operationCode; 91 fOperationTarget= viewer.getTextOperationTarget(); 92 update(); 93 } 94 95 101 public void update() { 102 103 boolean wasEnabled= isEnabled(); 104 boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode)); 105 setEnabled(isEnabled); 106 107 if (wasEnabled != isEnabled) { 108 firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE); 109 } 110 } 111 112 115 public void run() { 116 if (fOperationCode != -1 && fOperationTarget != null) { 117 fOperationTarget.doOperation(fOperationCode); 118 } 119 } 120 } 121 122 private final Template fOriginalTemplate; 123 124 private Text fNameText; 125 private Text fDescriptionText; 126 private Combo fContextCombo; 127 private SourceViewer fPatternEditor; 128 private Button fInsertVariableButton; 129 private Button fAutoInsertCheckbox; 130 private boolean fIsNameModifiable; 131 132 private StatusInfo fValidationStatus; 133 private boolean fSuppressError= true; private Map fGlobalActions= new HashMap (10); 135 private List fSelectionActions = new ArrayList (3); 136 private String [][] fContextTypes; 137 138 private ContextTypeRegistry fContextTypeRegistry; 139 140 private final TemplateVariableProcessor fTemplateProcessor= new TemplateVariableProcessor(); 141 142 private Template fNewTemplate; 143 144 153 public EditTemplateDialog(Shell parent, Template template, boolean edit, boolean isNameModifiable, ContextTypeRegistry registry) { 154 super(parent); 155 156 setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE); 157 158 String title= edit 159 ? TextEditorTemplateMessages.EditTemplateDialog_title_edit 160 : TextEditorTemplateMessages.EditTemplateDialog_title_new; 161 setTitle(title); 162 163 fOriginalTemplate= template; 164 fIsNameModifiable= isNameModifiable; 165 166 List contexts= new ArrayList (); 167 for (Iterator it= registry.contextTypes(); it.hasNext();) { 168 TemplateContextType type= (TemplateContextType) it.next(); 169 contexts.add(new String [] { type.getId(), type.getName() }); 170 } 171 fContextTypes= (String [][]) contexts.toArray(new String [contexts.size()][]); 172 173 fValidationStatus= new StatusInfo(); 174 175 fContextTypeRegistry= registry; 176 177 TemplateContextType type= fContextTypeRegistry.getContextType(template.getContextTypeId()); 178 fTemplateProcessor.setContextType(type); 179 } 180 181 184 public void create() { 185 super.create(); 186 boolean valid= fNameText == null || fNameText.getText().trim().length() != 0; 188 if (!valid) { 189 StatusInfo status = new StatusInfo(); 190 status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname); 191 updateButtonsEnableState(status); 192 } 193 } 194 195 198 protected Control createDialogArea(Composite ancestor) { 199 Composite parent= new Composite(ancestor, SWT.NONE); 200 GridLayout layout= new GridLayout(); 201 layout.numColumns= 2; 202 parent.setLayout(layout); 203 parent.setLayoutData(new GridData(GridData.FILL_BOTH)); 204 205 ModifyListener listener= new ModifyListener() { 206 public void modifyText(ModifyEvent e) { 207 doTextWidgetChanged(e.widget); 208 } 209 }; 210 211 if (fIsNameModifiable) { 212 createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_name); 213 214 Composite composite= new Composite(parent, SWT.NONE); 215 composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 216 layout= new GridLayout(); 217 layout.numColumns= 4; 218 layout.marginWidth= 0; 219 layout.marginHeight= 0; 220 composite.setLayout(layout); 221 222 fNameText= createText(composite); 223 fNameText.addModifyListener(listener); 224 fNameText.addFocusListener(new FocusListener() { 225 226 public void focusGained(FocusEvent e) { 227 } 228 229 public void focusLost(FocusEvent e) { 230 if (fSuppressError) { 231 fSuppressError= false; 232 updateButtons(); 233 } 234 } 235 }); 236 237 createLabel(composite, TextEditorTemplateMessages.EditTemplateDialog_context); 238 fContextCombo= new Combo(composite, SWT.READ_ONLY); 239 240 for (int i= 0; i < fContextTypes.length; i++) { 241 fContextCombo.add(fContextTypes[i][1]); 242 } 243 244 fContextCombo.addModifyListener(listener); 245 246 fAutoInsertCheckbox= createCheckbox(composite, TextEditorTemplateMessages.EditTemplateDialog_autoinsert); 247 fAutoInsertCheckbox.setSelection(fOriginalTemplate.isAutoInsertable()); 248 } 249 250 createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_description); 251 252 int descFlags= fIsNameModifiable ? SWT.BORDER : SWT.BORDER | SWT.READ_ONLY; 253 fDescriptionText= new Text(parent, descFlags ); 254 fDescriptionText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 255 256 fDescriptionText.addModifyListener(listener); 257 258 Label patternLabel= createLabel(parent, TextEditorTemplateMessages.EditTemplateDialog_pattern); 259 patternLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); 260 fPatternEditor= createEditor(parent, fOriginalTemplate.getPattern()); 261 262 Label filler= new Label(parent, SWT.NONE); 263 filler.setLayoutData(new GridData()); 264 265 Composite composite= new Composite(parent, SWT.NONE); 266 layout= new GridLayout(); 267 layout.marginWidth= 0; 268 layout.marginHeight= 0; 269 composite.setLayout(layout); 270 composite.setLayoutData(new GridData()); 271 272 fInsertVariableButton= new Button(composite, SWT.NONE); 273 fInsertVariableButton.setLayoutData(getButtonGridData(fInsertVariableButton)); 274 fInsertVariableButton.setText(TextEditorTemplateMessages.EditTemplateDialog_insert_variable); 275 fInsertVariableButton.addSelectionListener(new SelectionListener() { 276 public void widgetSelected(SelectionEvent e) { 277 fPatternEditor.getTextWidget().setFocus(); 278 fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); 279 } 280 281 public void widgetDefaultSelected(SelectionEvent e) {} 282 }); 283 284 fDescriptionText.setText(fOriginalTemplate.getDescription()); 285 if (fIsNameModifiable) { 286 fNameText.setText(fOriginalTemplate.getName()); 287 fNameText.addModifyListener(listener); 288 fContextCombo.select(getIndex(fOriginalTemplate.getContextTypeId())); 289 } else { 290 fPatternEditor.getControl().setFocus(); 291 } 292 initializeActions(); 293 294 applyDialogFont(parent); 295 return composite; 296 } 297 298 private void doTextWidgetChanged(Widget w) { 299 if (w == fNameText) { 300 fSuppressError= false; 301 updateButtons(); 302 } else if (w == fContextCombo) { 303 String contextId= getContextId(); 304 fTemplateProcessor.setContextType(fContextTypeRegistry.getContextType(contextId)); 305 } else if (w == fDescriptionText) { 306 } 308 } 309 310 private String getContextId() { 311 if (fContextCombo != null && !fContextCombo.isDisposed()) { 312 String name= fContextCombo.getText(); 313 for (int i= 0; i < fContextTypes.length; i++) { 314 if (name.equals(fContextTypes[i][1])) { 315 return fContextTypes[i][0]; 316 } 317 } 318 } 319 320 return fOriginalTemplate.getContextTypeId(); 321 } 322 323 private void doSourceChanged(IDocument document) { 324 String text= document.get(); 325 fValidationStatus.setOK(); 326 TemplateContextType contextType= fContextTypeRegistry.getContextType(getContextId()); 327 if (contextType != null) { 328 try { 329 contextType.validate(text); 330 } catch (TemplateException e) { 331 fValidationStatus.setError(e.getLocalizedMessage()); 332 } 333 } 334 335 updateUndoAction(); 336 updateButtons(); 337 } 338 339 private static GridData getButtonGridData(Button button) { 340 GridData data= new GridData(GridData.FILL_HORIZONTAL); 341 344 return data; 345 } 346 347 private static Label createLabel(Composite parent, String name) { 348 Label label= new Label(parent, SWT.NULL); 349 label.setText(name); 350 label.setLayoutData(new GridData()); 351 352 return label; 353 } 354 355 private static Text createText(Composite parent) { 356 Text text= new Text(parent, SWT.BORDER); 357 text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 358 359 return text; 360 } 361 362 private static Button createCheckbox(Composite parent, String name) { 363 Button button= new Button(parent, SWT.CHECK); 364 button.setText(name); 365 button.setLayoutData(new GridData()); 366 367 return button; 368 } 369 370 private SourceViewer createEditor(Composite parent, String pattern) { 371 SourceViewer viewer= createViewer(parent); 372 373 IDocument document= new Document(pattern); 374 viewer.setEditable(true); 375 viewer.setDocument(document); 376 377 378 int nLines= document.getNumberOfLines(); 379 if (nLines < 5) { 380 nLines= 5; 381 } else if (nLines > 12) { 382 nLines= 12; 383 } 384 385 Control control= viewer.getControl(); 386 GridData data= new GridData(GridData.FILL_BOTH); 387 data.widthHint= convertWidthInCharsToPixels(80); 388 data.heightHint= convertHeightInCharsToPixels(nLines); 389 control.setLayoutData(data); 390 391 viewer.addTextListener(new ITextListener() { 392 public void textChanged(TextEvent event) { 393 if (event .getDocumentEvent() != null) 394 doSourceChanged(event.getDocumentEvent().getDocument()); 395 } 396 }); 397 398 viewer.addSelectionChangedListener(new ISelectionChangedListener() { 399 public void selectionChanged(SelectionChangedEvent event) { 400 updateSelectionDependentActions(); 401 } 402 }); 403 404 viewer.prependVerifyKeyListener(new VerifyKeyListener() { 405 public void verifyKey(VerifyEvent event) { 406 handleVerifyKeyPressed(event); 407 } 408 }); 409 410 return viewer; 411 } 412 413 419 protected SourceViewer createViewer(Composite parent) { 420 SourceViewer viewer= new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); 421 SourceViewerConfiguration configuration= new SourceViewerConfiguration() { 422 public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { 423 424 ContentAssistant assistant= new ContentAssistant(); 425 assistant.enableAutoActivation(true); 426 assistant.enableAutoInsert(true); 427 assistant.setContentAssistProcessor(fTemplateProcessor, IDocument.DEFAULT_CONTENT_TYPE); 428 return assistant; 429 } 430 }; 431 viewer.configure(configuration); 432 return viewer; 433 } 434 435 private void handleVerifyKeyPressed(VerifyEvent event) { 436 if (!event.doit) 437 return; 438 439 if (event.stateMask != SWT.MOD1) 440 return; 441 442 switch (event.character) { 443 case ' ': 444 fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); 445 event.doit= false; 446 break; 447 448 case 'z' - 'a' + 1: 450 fPatternEditor.doOperation(ITextOperationTarget.UNDO); 451 event.doit= false; 452 break; 453 } 454 } 455 456 private void initializeActions() { 457 TextViewerAction action= new TextViewerAction(fPatternEditor, ITextOperationTarget.UNDO); 458 action.setText(TextEditorTemplateMessages.EditTemplateDialog_undo); 459 fGlobalActions.put(ITextEditorActionConstants.UNDO, action); 460 461 action= new TextViewerAction(fPatternEditor, ITextOperationTarget.CUT); 462 action.setText(TextEditorTemplateMessages.EditTemplateDialog_cut); 463 fGlobalActions.put(ITextEditorActionConstants.CUT, action); 464 465 action= new TextViewerAction(fPatternEditor, ITextOperationTarget.COPY); 466 action.setText(TextEditorTemplateMessages.EditTemplateDialog_copy); 467 fGlobalActions.put(ITextEditorActionConstants.COPY, action); 468 469 action= new TextViewerAction(fPatternEditor, ITextOperationTarget.PASTE); 470 action.setText(TextEditorTemplateMessages.EditTemplateDialog_paste); 471 fGlobalActions.put(ITextEditorActionConstants.PASTE, action); 472 473 action= new TextViewerAction(fPatternEditor, ITextOperationTarget.SELECT_ALL); 474 action.setText(TextEditorTemplateMessages.EditTemplateDialog_select_all); 475 fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL, action); 476 477 action= new TextViewerAction(fPatternEditor, ISourceViewer.CONTENTASSIST_PROPOSALS); 478 action.setText(TextEditorTemplateMessages.EditTemplateDialog_content_assist); 479 fGlobalActions.put("ContentAssistProposal", action); 481 fSelectionActions.add(ITextEditorActionConstants.CUT); 482 fSelectionActions.add(ITextEditorActionConstants.COPY); 483 fSelectionActions.add(ITextEditorActionConstants.PASTE); 484 485 MenuManager manager= new MenuManager(null, null); 487 manager.setRemoveAllWhenShown(true); 488 manager.addMenuListener(new IMenuListener() { 489 public void menuAboutToShow(IMenuManager mgr) { 490 fillContextMenu(mgr); 491 } 492 }); 493 494 StyledText text= fPatternEditor.getTextWidget(); 495 Menu menu= manager.createContextMenu(text); 496 text.setMenu(menu); 497 } 498 499 private void fillContextMenu(IMenuManager menu) { 500 menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_UNDO)); 501 menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO)); 502 503 menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT)); 504 menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.CUT)); 505 menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.COPY)); 506 menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.PASTE)); 507 menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.SELECT_ALL)); 508 509 menu.add(new Separator("templates")); menu.appendToGroup("templates", (IAction) fGlobalActions.get("ContentAssistProposal")); } 512 513 private void updateSelectionDependentActions() { 514 Iterator iterator= fSelectionActions.iterator(); 515 while (iterator.hasNext()) 516 updateAction((String )iterator.next()); 517 } 518 519 private void updateUndoAction() { 520 IAction action= (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO); 521 if (action instanceof IUpdate) 522 ((IUpdate) action).update(); 523 } 524 525 private void updateAction(String actionId) { 526 IAction action= (IAction) fGlobalActions.get(actionId); 527 if (action instanceof IUpdate) 528 ((IUpdate) action).update(); 529 } 530 531 private int getIndex(String contextid) { 532 533 if (contextid == null) 534 return -1; 535 536 for (int i= 0; i < fContextTypes.length; i++) { 537 if (contextid.equals(fContextTypes[i][0])) { 538 return i; 539 } 540 } 541 return -1; 542 } 543 544 private void updateButtons() { 545 StatusInfo status; 546 547 boolean valid= fNameText == null || fNameText.getText().trim().length() != 0; 548 if (!valid) { 549 status = new StatusInfo(); 550 if (!fSuppressError) { 551 status.setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname); 552 } 553 } else { 554 status= fValidationStatus; 555 } 556 updateStatus(status); 557 } 558 559 562 protected void okPressed() { 563 String name= fNameText == null ? fOriginalTemplate.getName() : fNameText.getText(); 564 boolean isAutoInsertable= fAutoInsertCheckbox != null && fAutoInsertCheckbox.getSelection(); 565 fNewTemplate= new Template(name, fDescriptionText.getText(), getContextId(), fPatternEditor.getDocument().get(), isAutoInsertable); 566 super.okPressed(); 567 } 568 569 575 public Template getTemplate() { 576 return fNewTemplate; 577 } 578 579 583 protected IDialogSettings getDialogBoundsSettings() { 584 String sectionName= getClass().getName() + "_dialogBounds"; IDialogSettings settings= TextEditorPlugin.getDefault().getDialogSettings(); 586 IDialogSettings section= settings.getSection(sectionName); 587 if (section == null) 588 section= settings.addNewSection(sectionName); 589 return section; 590 } 591 592 } 593 | Popular Tags |