KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > texteditor > templates > EditTemplateDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.texteditor.templates;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
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 /**
71  * Dialog to edit a template. Clients will usually instantiate, but may also may
72  * extend.
73  *
74  * @since 3.0
75  */

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         /**
84          * Creates a new action.
85          *
86          * @param viewer the viewer
87          * @param operationCode the opcode
88          */

89         public TextViewerAction(ITextViewer viewer, int operationCode) {
90             fOperationCode= operationCode;
91             fOperationTarget= viewer.getTextOperationTarget();
92             update();
93         }
94
95         /**
96          * Updates the enabled state of the action.
97          * Fires a property change if the enabled state changes.
98          *
99          * @see Action#firePropertyChange(String, Object, Object)
100          */

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         /**
113          * @see Action#run()
114          */

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; // #4354
134
private Map JavaDoc fGlobalActions= new HashMap JavaDoc(10);
135     private List JavaDoc fSelectionActions = new ArrayList JavaDoc(3);
136     private String JavaDoc[][] fContextTypes;
137
138     private ContextTypeRegistry fContextTypeRegistry;
139
140     private final TemplateVariableProcessor fTemplateProcessor= new TemplateVariableProcessor();
141
142     private Template fNewTemplate;
143
144     /**
145      * Creates a new dialog.
146      *
147      * @param parent the shell parent of the dialog
148      * @param template the template to edit
149      * @param edit whether this is a new template or an existing being edited
150      * @param isNameModifiable whether the name of the template may be modified
151      * @param registry the context type registry to use
152      */

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 JavaDoc 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 JavaDoc contexts= new ArrayList JavaDoc();
167         for (Iterator JavaDoc it= registry.contextTypes(); it.hasNext();) {
168             TemplateContextType type= (TemplateContextType) it.next();
169             contexts.add(new String JavaDoc[] { type.getId(), type.getName() });
170         }
171         fContextTypes= (String JavaDoc[][]) contexts.toArray(new String JavaDoc[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     /*
182      * @see org.eclipse.ui.texteditor.templates.StatusDialog#create()
183      */

184     public void create() {
185         super.create();
186         // update initial OK button to be disabled for new templates
187
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     /*
196      * @see Dialog#createDialogArea(Composite)
197      */

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 JavaDoc contextId= getContextId();
304             fTemplateProcessor.setContextType(fContextTypeRegistry.getContextType(contextId));
305         } else if (w == fDescriptionText) {
306             // oh, nothing
307
}
308     }
309
310     private String JavaDoc getContextId() {
311         if (fContextCombo != null && !fContextCombo.isDisposed()) {
312             String JavaDoc 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 JavaDoc 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         // TODO get some button hints.
342
// data.heightHint= SWTUtil.getButtonHeightHint(button);
343

344         return data;
345     }
346
347     private static Label createLabel(Composite parent, String JavaDoc 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 JavaDoc 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 JavaDoc 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     /**
414      * Creates the viewer to be used to display the pattern. Subclasses may override.
415      *
416      * @param parent the parent composite of the viewer
417      * @return a configured <code>SourceViewer</code>
418      */

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             // CTRL-Z
449
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); //$NON-NLS-1$
480

481         fSelectionActions.add(ITextEditorActionConstants.CUT);
482         fSelectionActions.add(ITextEditorActionConstants.COPY);
483         fSelectionActions.add(ITextEditorActionConstants.PASTE);
484
485         // create context menu
486
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")); //$NON-NLS-1$
510
menu.appendToGroup("templates", (IAction) fGlobalActions.get("ContentAssistProposal")); //$NON-NLS-1$ //$NON-NLS-2$
511
}
512
513     private void updateSelectionDependentActions() {
514         Iterator JavaDoc iterator= fSelectionActions.iterator();
515         while (iterator.hasNext())
516             updateAction((String JavaDoc)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 JavaDoc actionId) {
526         IAction action= (IAction) fGlobalActions.get(actionId);
527         if (action instanceof IUpdate)
528             ((IUpdate) action).update();
529     }
530
531     private int getIndex(String JavaDoc 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     /*
560      * @since 3.1
561      */

562     protected void okPressed() {
563         String JavaDoc 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     /**
570      * Returns the created template.
571      *
572      * @return the created template
573      * @since 3.1
574      */

575     public Template getTemplate() {
576         return fNewTemplate;
577     }
578     
579     /*
580      * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
581      * @since 3.2
582      */

583     protected IDialogSettings getDialogBoundsSettings() {
584         String JavaDoc sectionName= getClass().getName() + "_dialogBounds"; //$NON-NLS-1$
585
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