2 * (c) Copyright IBM Corp. 2000, 2001.
5 package net.sourceforge.phpdt.internal.ui.preferences;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.Iterator;
10 import java.util.List;
12 import java.util.Vector;
14 import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
15 import net.sourceforge.phpdt.internal.corext.template.Template;
16 import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
17 import net.sourceforge.phpdt.internal.corext.template.TemplateTranslator;
18 import net.sourceforge.phpdt.internal.ui.dialogs.StatusDialog;
19 import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
20 import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
21 import net.sourceforge.phpdt.internal.ui.text.template.TemplateVariableProcessor;
22 import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
23 import net.sourceforge.phpdt.ui.text.JavaTextTools;
24 import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
25 import net.sourceforge.phpeclipse.IPreferenceConstants;
26 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
28 import org.eclipse.core.runtime.CoreException;
29 import org.eclipse.jface.action.Action;
30 import org.eclipse.jface.action.GroupMarker;
31 import org.eclipse.jface.action.IAction;
32 import org.eclipse.jface.action.IMenuListener;
33 import org.eclipse.jface.action.IMenuManager;
34 import org.eclipse.jface.action.MenuManager;
35 import org.eclipse.jface.action.Separator;
36 import org.eclipse.jface.preference.IPreferenceStore;
37 import org.eclipse.jface.preference.PreferenceConverter;
38 import org.eclipse.jface.resource.JFaceResources;
39 import org.eclipse.jface.text.Document;
40 import org.eclipse.jface.text.IDocument;
41 import org.eclipse.jface.text.IDocumentPartitioner;
42 import org.eclipse.jface.text.ITextListener;
43 import org.eclipse.jface.text.ITextOperationTarget;
44 import org.eclipse.jface.text.ITextViewer;
45 import org.eclipse.jface.text.ITextViewerExtension;
46 import org.eclipse.jface.text.TextEvent;
47 import org.eclipse.jface.text.contentassist.ContentAssistant;
48 import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
49 import org.eclipse.jface.text.contentassist.IContentAssistant;
50 import org.eclipse.jface.text.source.ISourceViewer;
51 import org.eclipse.jface.text.source.SourceViewer;
52 import org.eclipse.jface.viewers.ISelectionChangedListener;
53 import org.eclipse.jface.viewers.SelectionChangedEvent;
54 import org.eclipse.swt.SWT;
55 import org.eclipse.swt.custom.StyledText;
56 import org.eclipse.swt.custom.VerifyKeyListener;
57 import org.eclipse.swt.events.KeyEvent;
58 import org.eclipse.swt.events.KeyListener;
59 import org.eclipse.swt.events.ModifyEvent;
60 import org.eclipse.swt.events.ModifyListener;
61 import org.eclipse.swt.events.SelectionEvent;
62 import org.eclipse.swt.events.SelectionListener;
63 import org.eclipse.swt.events.VerifyEvent;
64 import org.eclipse.swt.graphics.Color;
65 import org.eclipse.swt.graphics.Font;
66 import org.eclipse.swt.graphics.RGB;
67 import org.eclipse.swt.layout.GridData;
68 import org.eclipse.swt.layout.GridLayout;
69 import org.eclipse.swt.widgets.Button;
70 import org.eclipse.swt.widgets.Combo;
71 import org.eclipse.swt.widgets.Composite;
72 import org.eclipse.swt.widgets.Control;
73 import org.eclipse.swt.widgets.Display;
74 import org.eclipse.swt.widgets.Label;
75 import org.eclipse.swt.widgets.Menu;
76 import org.eclipse.swt.widgets.Shell;
77 import org.eclipse.swt.widgets.Text;
78 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
79 import org.eclipse.ui.texteditor.IUpdate;
82 * Dialog to edit a template.
84 public class EditTemplateDialog extends StatusDialog {
86 private static class SimpleJavaSourceViewerConfiguration extends PHPSourceViewerConfiguration {
88 private final IContentAssistProcessor fProcessor;
90 // SimpleJavaSourceViewerConfiguration(JavaTextTools tools, ITextEditor editor, IContentAssistProcessor processor) {
91 SimpleJavaSourceViewerConfiguration(JavaTextTools tools, IContentAssistProcessor processor) {
92 super(tools, null, IPHPPartitions.PHP_PARTITIONING);
93 fProcessor= processor;
97 * @see SourceViewerConfiguration#getContentAssistant(ISourceViewer)
99 public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
101 IPreferenceStore store= PHPeclipsePlugin.getDefault().getPreferenceStore();
103 ContentAssistant assistant= new ContentAssistant();
104 assistant.setContentAssistProcessor(fProcessor, IDocument.DEFAULT_CONTENT_TYPE);
105 // Register the same processor for strings and single line comments to get code completion at the start of those partitions.
106 // assistant.setContentAssistProcessor(fProcessor, JavaPartitionScanner.PHP_STRING);
107 // assistant.setContentAssistProcessor(fProcessor, JavaPartitionScanner.JAVA_SINGLE_LINE_COMMENT);
109 // assistant.setContentAssistProcessor(fProcessor, JavaPartitionScanner.JAVA_DOC);
111 // assistant.enableAutoInsert(store.getBoolean(ContentAssistPreference.AUTOINSERT));
112 // assistant.enableAutoActivation(store.getBoolean(ContentAssistPreference.AUTOACTIVATION));
113 // assistant.setAutoActivationDelay(store.getInt(ContentAssistPreference.AUTOACTIVATION_DELAY));
114 assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
115 assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
116 // assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
118 Display display= sourceViewer.getTextWidget().getDisplay();
120 Color background= createColor(store, IPreferenceConstants.PROPOSALS_BACKGROUND, display);
121 assistant.setContextInformationPopupBackground(background);
122 assistant.setContextSelectorBackground(background);
123 assistant.setProposalSelectorBackground(background);
125 Color foreground= createColor(store, IPreferenceConstants.PROPOSALS_FOREGROUND, display);
126 assistant.setContextInformationPopupForeground(foreground);
127 assistant.setContextSelectorForeground(foreground);
128 assistant.setProposalSelectorForeground(foreground);
134 * Creates a color from the information stored in the given preference store.
135 * Returns <code>null</code> if there is no such information available.
137 private Color createColor(IPreferenceStore store, String key, Display display) {
141 if (store.contains(key)) {
143 if (store.isDefault(key))
144 rgb= PreferenceConverter.getDefaultColor(store, key);
146 rgb= PreferenceConverter.getColor(store, key);
149 return new Color(display, rgb);
156 private static class TextViewerAction extends Action implements IUpdate {
158 private int fOperationCode= -1;
159 private ITextOperationTarget fOperationTarget;
161 public TextViewerAction(ITextViewer viewer, int operationCode) {
162 fOperationCode= operationCode;
163 fOperationTarget= viewer.getTextOperationTarget();
168 * Updates the enabled state of the action.
169 * Fires a property change if the enabled state changes.
171 * @see Action#firePropertyChange(String, Object, Object)
173 public void update() {
175 boolean wasEnabled= isEnabled();
176 boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode));
177 setEnabled(isEnabled);
179 if (wasEnabled != isEnabled) {
180 firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE);
188 if (fOperationCode != -1 && fOperationTarget != null) {
189 fOperationTarget.doOperation(fOperationCode);
194 private final Template fTemplate;
196 private Text fNameText;
197 private Text fDescriptionText;
198 private Combo fContextCombo;
199 private SourceViewer fPatternEditor;
200 private Button fInsertVariableButton;
202 private TemplateTranslator fTranslator= new TemplateTranslator();
203 private boolean fSuppressError= true; // #4354
204 private Map fGlobalActions= new HashMap(10);
205 private List fSelectionActions = new ArrayList(3);
206 private Vector fContextTypes= new Vector();
208 private final TemplateVariableProcessor fProcessor= new TemplateVariableProcessor();
210 public EditTemplateDialog(Shell parent, Template template, boolean edit) {
213 setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE);
216 ? TemplateMessages.getString("EditTemplateDialog.title.edit") //$NON-NLS-1$
217 : TemplateMessages.getString("EditTemplateDialog.title.new"); //$NON-NLS-1$
222 ContextTypeRegistry registry= ContextTypeRegistry.getInstance();
223 for (Iterator iterator= registry.iterator(); iterator.hasNext(); )
224 fContextTypes.add(iterator.next());
226 if (fContextTypes.size() > 0)
227 fProcessor.setContextType(ContextTypeRegistry.getInstance().getContextType((String) fContextTypes.get(0)));
231 * @see Dialog#createDialogArea(Composite)
233 protected Control createDialogArea(Composite ancestor) {
234 Composite parent= new Composite(ancestor, SWT.NONE);
235 GridLayout layout= new GridLayout();
236 layout.numColumns= 2;
237 parent.setLayout(layout);
238 parent.setLayoutData(new GridData(GridData.FILL_BOTH));
240 createLabel(parent, TemplateMessages.getString("EditTemplateDialog.name")); //$NON-NLS-1$
242 Composite composite= new Composite(parent, SWT.NONE);
243 composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
244 layout= new GridLayout();
245 layout.numColumns= 3;
246 layout.marginWidth= 0;
247 layout.marginHeight= 0;
248 composite.setLayout(layout);
250 fNameText= createText(composite);
251 fNameText.addModifyListener(new ModifyListener() {
252 public void modifyText(ModifyEvent e) {
253 if (fSuppressError && (fNameText.getText().trim().length() != 0))
254 fSuppressError= false;
260 createLabel(composite, TemplateMessages.getString("EditTemplateDialog.context")); //$NON-NLS-1$
261 fContextCombo= new Combo(composite, SWT.READ_ONLY);
263 for (Iterator iterator= fContextTypes.iterator(); iterator.hasNext(); )
264 fContextCombo.add((String) iterator.next());
266 fContextCombo.addModifyListener(new ModifyListener() {
267 public void modifyText(ModifyEvent e) {
268 String name= fContextCombo.getText();
269 fProcessor.setContextType(ContextTypeRegistry.getInstance().getContextType(name));
273 createLabel(parent, TemplateMessages.getString("EditTemplateDialog.description")); //$NON-NLS-1$
274 fDescriptionText= createText(parent);
276 Label patternLabel= createLabel(parent, TemplateMessages.getString("EditTemplateDialog.pattern")); //$NON-NLS-1$
277 patternLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
278 fPatternEditor= createEditor(parent);
280 Label filler= new Label(parent, SWT.NONE);
281 filler.setLayoutData(new GridData());
283 composite= new Composite(parent, SWT.NONE);
284 layout= new GridLayout();
285 layout.marginWidth= 0;
286 layout.marginHeight= 0;
287 composite.setLayout(layout);
288 composite.setLayoutData(new GridData());
290 fInsertVariableButton= new Button(composite, SWT.NONE);
291 fInsertVariableButton.setLayoutData(getButtonGridData(fInsertVariableButton));
292 fInsertVariableButton.setText(TemplateMessages.getString("EditTemplateDialog.insert.variable")); //$NON-NLS-1$
293 fInsertVariableButton.addSelectionListener(new SelectionListener() {
294 public void widgetSelected(SelectionEvent e) {
295 fPatternEditor.getTextWidget().setFocus();
296 fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
299 public void widgetDefaultSelected(SelectionEvent e) {}
302 fNameText.setText(fTemplate.getName());
303 fDescriptionText.setText(fTemplate.getDescription());
304 fContextCombo.select(getIndex(fTemplate.getContextTypeName()));
311 private static GridData getButtonGridData(Button button) {
312 GridData data= new GridData(GridData.FILL_HORIZONTAL);
313 data.heightHint= SWTUtil.getButtonHeigthHint(button);
318 private static Label createLabel(Composite parent, String name) {
319 Label label= new Label(parent, SWT.NULL);
321 label.setLayoutData(new GridData());
326 private static Text createText(Composite parent) {
327 Text text= new Text(parent, SWT.BORDER);
328 text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
333 private SourceViewer createEditor(Composite parent) {
334 SourceViewer viewer= new SourceViewer(parent, null, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
335 JavaTextTools tools= PHPeclipsePlugin.getDefault().getJavaTextTools();
336 IDocument document= new Document(fTemplate.getPattern());
337 IDocumentPartitioner partitioner= tools.createDocumentPartitioner();
338 document.setDocumentPartitioner(partitioner);
339 partitioner.connect(document);
340 // viewer.configure(new SimpleJavaSourceViewerConfiguration(tools, null, fProcessor));
341 viewer.configure(new SimpleJavaSourceViewerConfiguration(tools, fProcessor));
342 viewer.setEditable(true);
343 viewer.setDocument(document);
345 Font font= JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT);
346 viewer.getTextWidget().setFont(font);
348 Control control= viewer.getControl();
349 GridData data= new GridData(GridData.FILL_BOTH);
350 data.widthHint= convertWidthInCharsToPixels(60);
351 data.heightHint= convertHeightInCharsToPixels(5);
352 control.setLayoutData(data);
354 viewer.addTextListener(new ITextListener() {
355 public void textChanged(TextEvent event) {
357 fTranslator.translate(event.getDocumentEvent().getDocument().get());
358 } catch (CoreException e) {
359 PHPeclipsePlugin.log(e);
367 viewer.addSelectionChangedListener(new ISelectionChangedListener() {
368 public void selectionChanged(SelectionChangedEvent event) {
369 updateSelectionDependentActions();
373 if (viewer instanceof ITextViewerExtension) {
374 ((ITextViewerExtension) viewer).prependVerifyKeyListener(new VerifyKeyListener() {
375 public void verifyKey(VerifyEvent event) {
376 handleVerifyKeyPressed(event);
380 viewer.getTextWidget().addKeyListener(new KeyListener() {
381 public void keyPressed(KeyEvent e) {
385 public void keyReleased(KeyEvent e) {}
392 private void handleKeyPressed(KeyEvent event) {
393 if (event.stateMask != SWT.CTRL)
396 switch (event.character) {
398 fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
402 case (int) 'z' - (int) 'a' + 1:
403 fPatternEditor.doOperation(ITextOperationTarget.UNDO);
408 private void handleVerifyKeyPressed(VerifyEvent event) {
412 if (event.stateMask != SWT.CTRL)
415 switch (event.character) {
417 fPatternEditor.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
422 case (int) 'z' - (int) 'a' + 1:
423 fPatternEditor.doOperation(ITextOperationTarget.UNDO);
429 private void initializeActions() {
430 TextViewerAction action= new TextViewerAction(fPatternEditor, SourceViewer.UNDO);
431 action.setText(TemplateMessages.getString("EditTemplateDialog.undo")); //$NON-NLS-1$
432 fGlobalActions.put(ITextEditorActionConstants.UNDO, action);
434 action= new TextViewerAction(fPatternEditor, SourceViewer.CUT);
435 action.setText(TemplateMessages.getString("EditTemplateDialog.cut")); //$NON-NLS-1$
436 fGlobalActions.put(ITextEditorActionConstants.CUT, action);
438 action= new TextViewerAction(fPatternEditor, SourceViewer.COPY);
439 action.setText(TemplateMessages.getString("EditTemplateDialog.copy")); //$NON-NLS-1$
440 fGlobalActions.put(ITextEditorActionConstants.COPY, action);
442 action= new TextViewerAction(fPatternEditor, SourceViewer.PASTE);
443 action.setText(TemplateMessages.getString("EditTemplateDialog.paste")); //$NON-NLS-1$
444 fGlobalActions.put(ITextEditorActionConstants.PASTE, action);
446 action= new TextViewerAction(fPatternEditor, SourceViewer.SELECT_ALL);
447 action.setText(TemplateMessages.getString("EditTemplateDialog.select.all")); //$NON-NLS-1$
448 fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL, action);
450 action= new TextViewerAction(fPatternEditor, SourceViewer.CONTENTASSIST_PROPOSALS);
451 action.setText(TemplateMessages.getString("EditTemplateDialog.content.assist")); //$NON-NLS-1$
452 fGlobalActions.put("ContentAssistProposal", action); //$NON-NLS-1$
454 fSelectionActions.add(ITextEditorActionConstants.CUT);
455 fSelectionActions.add(ITextEditorActionConstants.COPY);
456 fSelectionActions.add(ITextEditorActionConstants.PASTE);
458 // create context menu
459 MenuManager manager= new MenuManager(null, null);
460 manager.setRemoveAllWhenShown(true);
461 manager.addMenuListener(new IMenuListener() {
462 public void menuAboutToShow(IMenuManager mgr) {
463 fillContextMenu(mgr);
467 StyledText text= fPatternEditor.getTextWidget();
468 Menu menu= manager.createContextMenu(text);
472 private void fillContextMenu(IMenuManager menu) {
473 menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_UNDO));
474 menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO));
476 menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
477 menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.CUT));
478 menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.COPY));
479 menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.PASTE));
480 menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, (IAction) fGlobalActions.get(ITextEditorActionConstants.SELECT_ALL));
482 // menu.add(new Separator(IContextMenuConstants.GROUP_GENERATE));
483 // menu.appendToGroup(IContextMenuConstants.GROUP_GENERATE, (IAction) fGlobalActions.get("ContentAssistProposal")); //$NON-NLS-1$
486 protected void updateSelectionDependentActions() {
487 Iterator iterator= fSelectionActions.iterator();
488 while (iterator.hasNext())
489 updateAction((String)iterator.next());
492 protected void updateUndoAction() {
493 IAction action= (IAction) fGlobalActions.get(ITextEditorActionConstants.UNDO);
494 if (action instanceof IUpdate)
495 ((IUpdate) action).update();
498 protected void updateAction(String actionId) {
499 IAction action= (IAction) fGlobalActions.get(actionId);
500 if (action instanceof IUpdate)
501 ((IUpdate) action).update();
504 private int getIndex(String context) {
505 ContextTypeRegistry registry= ContextTypeRegistry.getInstance();
506 registry.getContextType(context);
511 return fContextTypes.indexOf(context);
514 protected void okPressed() {
515 fTemplate.setName(fNameText.getText());
516 fTemplate.setDescription(fDescriptionText.getText());
517 fTemplate.setContext(fContextCombo.getText());
518 fTemplate.setPattern(fPatternEditor.getTextWidget().getText());
523 private void updateButtons() {
524 boolean valid= fNameText.getText().trim().length() != 0;
526 StatusInfo status= new StatusInfo();
530 status.setError(""); //$NON-NLS-1$
532 status.setError(TemplateMessages.getString("EditTemplateDialog.error.noname")); //$NON-NLS-1$
533 } else if (fTranslator.getErrorMessage() != null) {
534 status.setError(fTranslator.getErrorMessage());
537 updateStatus(status);
541 * @see org.eclipse.jface.window.Window#configureShell(Shell)
543 protected void configureShell(Shell newShell) {
544 super.configureShell(newShell);
545 // WorkbenchHelp.setHelp(newShell, IJavaHelpContextIds.EDIT_TEMPLATE_DIALOG);