1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.preferences;
13 import java.io.BufferedInputStream;
14 import java.io.BufferedOutputStream;
16 import java.io.FileInputStream;
17 import java.io.FileNotFoundException;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.OutputStream;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
26 import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
27 import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
28 import net.sourceforge.phpdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
29 import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
30 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
31 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
32 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ITreeListAdapter;
33 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
34 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
35 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.TreeListDialogField;
36 import net.sourceforge.phpdt.ui.PreferenceConstants;
37 import net.sourceforge.phpdt.ui.text.JavaTextTools;
38 //import net.sourceforge.phpeclipse.PHPeclipsePlugin;
39 import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
40 import net.sourceforge.phpeclipse.ui.WebUI;
42 import org.eclipse.jface.dialogs.MessageDialog;
43 import org.eclipse.jface.preference.IPreferenceStore;
44 import org.eclipse.jface.resource.JFaceResources;
45 import org.eclipse.jface.text.Document;
46 import org.eclipse.jface.text.IDocument;
47 import org.eclipse.jface.text.source.SourceViewer;
48 import org.eclipse.jface.text.templates.Template;
49 import org.eclipse.jface.text.templates.TemplateContextType;
50 import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
51 import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
52 import org.eclipse.jface.text.templates.persistence.TemplateStore;
53 import org.eclipse.jface.viewers.LabelProvider;
54 import org.eclipse.jface.viewers.StructuredSelection;
55 import org.eclipse.jface.window.Window;
56 import org.eclipse.swt.SWT;
57 import org.eclipse.swt.events.KeyEvent;
58 import org.eclipse.swt.graphics.Font;
59 import org.eclipse.swt.graphics.Image;
60 import org.eclipse.swt.layout.GridData;
61 import org.eclipse.swt.layout.GridLayout;
62 import org.eclipse.swt.widgets.Composite;
63 import org.eclipse.swt.widgets.Control;
64 import org.eclipse.swt.widgets.FileDialog;
65 import org.eclipse.swt.widgets.Label;
66 import org.eclipse.swt.widgets.Shell;
70 public class CodeTemplateBlock {
72 private class CodeTemplateAdapter implements ITreeListAdapter,
73 IDialogFieldListener {
75 private final Object[] NO_CHILDREN = new Object[0];
77 public void customButtonPressed(TreeListDialogField field, int index) {
78 doButtonPressed(index, field.getSelectedElements());
81 public void selectionChanged(TreeListDialogField field) {
82 List selected = field.getSelectedElements();
83 field.enableButton(IDX_EDIT, canEdit(selected));
84 field.enableButton(IDX_EXPORT, !selected.isEmpty());
86 updateSourceViewerInput(selected);
89 public void doubleClicked(TreeListDialogField field) {
90 List selected = field.getSelectedElements();
91 if (canEdit(selected)) {
92 doButtonPressed(IDX_EDIT, selected);
96 public Object[] getChildren(TreeListDialogField field, Object element) {
97 if (element == COMMENT_NODE || element == CODE_NODE) {
98 return getTemplateOfCategory(element == COMMENT_NODE);
103 public Object getParent(TreeListDialogField field, Object element) {
104 if (element instanceof TemplatePersistenceData) {
105 TemplatePersistenceData data = (TemplatePersistenceData) element;
106 if (data.getTemplate().getName().endsWith(
107 CodeTemplateContextType.COMMENT_SUFFIX)) {
115 public boolean hasChildren(TreeListDialogField field, Object element) {
116 return (element == COMMENT_NODE || element == CODE_NODE);
119 public void dialogFieldChanged(DialogField field) {
122 public void keyPressed(TreeListDialogField field, KeyEvent event) {
127 private static class CodeTemplateLabelProvider extends LabelProvider {
132 * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
134 public Image getImage(Object element) {
142 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
144 public String getText(Object element) {
145 if (element == COMMENT_NODE || element == CODE_NODE) {
146 return (String) element;
148 TemplatePersistenceData data = (TemplatePersistenceData) element;
149 Template template = data.getTemplate();
150 String name = template.getName();
151 if (CodeTemplateContextType.CATCHBLOCK.equals(name)) {
152 return PreferencesMessages
153 .getString("CodeTemplateBlock.catchblock.label"); //$NON-NLS-1$
154 } else if (CodeTemplateContextType.METHODSTUB.equals(name)) {
155 return PreferencesMessages
156 .getString("CodeTemplateBlock.methodstub.label"); //$NON-NLS-1$
157 } else if (CodeTemplateContextType.CONSTRUCTORSTUB.equals(name)) {
158 return PreferencesMessages
159 .getString("CodeTemplateBlock.constructorstub.label"); //$NON-NLS-1$
160 } else if (CodeTemplateContextType.GETTERSTUB.equals(name)) {
161 return PreferencesMessages
162 .getString("CodeTemplateBlock.getterstub.label"); //$NON-NLS-1$
163 } else if (CodeTemplateContextType.SETTERSTUB.equals(name)) {
164 return PreferencesMessages
165 .getString("CodeTemplateBlock.setterstub.label"); //$NON-NLS-1$
166 } else if (CodeTemplateContextType.NEWTYPE.equals(name)) {
167 return PreferencesMessages
168 .getString("CodeTemplateBlock.newtype.label"); //$NON-NLS-1$
169 } else if (CodeTemplateContextType.TYPECOMMENT.equals(name)) {
170 return PreferencesMessages
171 .getString("CodeTemplateBlock.typecomment.label"); //$NON-NLS-1$
172 } else if (CodeTemplateContextType.FIELDCOMMENT.equals(name)) {
173 return PreferencesMessages
174 .getString("CodeTemplateBlock.fieldcomment.label"); //$NON-NLS-1$
175 } else if (CodeTemplateContextType.METHODCOMMENT.equals(name)) {
176 return PreferencesMessages
177 .getString("CodeTemplateBlock.methodcomment.label"); //$NON-NLS-1$
178 } else if (CodeTemplateContextType.OVERRIDECOMMENT.equals(name)) {
179 return PreferencesMessages
180 .getString("CodeTemplateBlock.overridecomment.label"); //$NON-NLS-1$
181 } else if (CodeTemplateContextType.CONSTRUCTORCOMMENT.equals(name)) {
182 return PreferencesMessages
183 .getString("CodeTemplateBlock.constructorcomment.label"); //$NON-NLS-1$
184 } else if (CodeTemplateContextType.GETTERCOMMENT.equals(name)) {
185 return PreferencesMessages
186 .getString("CodeTemplateBlock.gettercomment.label"); //$NON-NLS-1$
187 } else if (CodeTemplateContextType.SETTERCOMMENT.equals(name)) {
188 return PreferencesMessages
189 .getString("CodeTemplateBlock.settercomment.label"); //$NON-NLS-1$
191 return template.getDescription();
196 private final static int IDX_EDIT = 0;
198 private final static int IDX_IMPORT = 2;
200 private final static int IDX_EXPORT = 3;
202 private final static int IDX_EXPORTALL = 4;
204 protected final static Object COMMENT_NODE = PreferencesMessages
205 .getString("CodeTemplateBlock.templates.comment.node"); //$NON-NLS-1$
207 protected final static Object CODE_NODE = PreferencesMessages
208 .getString("CodeTemplateBlock.templates.code.node"); //$NON-NLS-1$
210 private static final String PREF_JAVADOC_STUBS = PreferenceConstants.CODEGEN_ADD_COMMENTS;
212 private TreeListDialogField fCodeTemplateTree;
214 private SelectionButtonDialogField fCreateJavaDocComments;
216 protected TemplateStore fTemplates;
218 private PixelConverter fPixelConverter;
220 private SourceViewer fPatternViewer;
222 private Control fSWTWidget;
224 private TemplateVariableProcessor fTemplateProcessor;
226 public CodeTemplateBlock() {
228 fTemplates = WebUI.getDefault().getCodeTemplateStore();
229 fTemplateProcessor = new TemplateVariableProcessor();
231 CodeTemplateAdapter adapter = new CodeTemplateAdapter();
233 String[] buttonLabels = new String[] {
234 /* IDX_EDIT */PreferencesMessages
235 .getString("CodeTemplateBlock.templates.edit.button"), //$NON-NLS-1$
237 /* IDX_IMPORT */PreferencesMessages
238 .getString("CodeTemplateBlock.templates.import.button"), //$NON-NLS-1$
239 /* IDX_EXPORT */PreferencesMessages
240 .getString("CodeTemplateBlock.templates.export.button"), //$NON-NLS-1$
241 /* IDX_EXPORTALL */PreferencesMessages
242 .getString("CodeTemplateBlock.templates.exportall.button") //$NON-NLS-1$
245 fCodeTemplateTree = new TreeListDialogField(adapter, buttonLabels,
246 new CodeTemplateLabelProvider());
247 fCodeTemplateTree.setDialogFieldListener(adapter);
248 fCodeTemplateTree.setLabelText(PreferencesMessages
249 .getString("CodeTemplateBlock.templates.label")); //$NON-NLS-1$
251 fCodeTemplateTree.enableButton(IDX_EXPORT, false);
252 fCodeTemplateTree.enableButton(IDX_EDIT, false);
254 fCodeTemplateTree.addElement(COMMENT_NODE);
255 fCodeTemplateTree.addElement(CODE_NODE);
257 fCreateJavaDocComments = new SelectionButtonDialogField(SWT.CHECK
259 fCreateJavaDocComments.setLabelText(PreferencesMessages
260 .getString("CodeTemplateBlock.createcomment.label")); //$NON-NLS-1$
261 fCreateJavaDocComments.setSelection(PreferenceConstants
262 .getPreferenceStore().getBoolean(PREF_JAVADOC_STUBS));
264 fCodeTemplateTree.selectFirstElement();
267 protected Control createContents(Composite parent) {
268 fPixelConverter = new PixelConverter(parent);
271 Composite composite = new Composite(parent, SWT.NONE);
272 GridLayout layout = new GridLayout();
273 layout.marginHeight = 0;
274 layout.marginWidth = 0;
275 layout.numColumns = 2;
276 composite.setLayout(layout);
278 fCodeTemplateTree.doFillIntoGrid(composite, 3);
280 .setHorizontalSpan(fCodeTemplateTree.getLabelControl(null), 2);
282 .setHorizontalGrabbing(fCodeTemplateTree.getTreeControl(null));
284 fPatternViewer = createViewer(composite, 2);
286 fCreateJavaDocComments.doFillIntoGrid(composite, 2);
288 DialogField label = new DialogField();
289 label.setLabelText(PreferencesMessages
290 .getString("CodeTemplateBlock.createcomment.description")); //$NON-NLS-1$
291 label.doFillIntoGrid(composite, 2);
297 private Shell getShell() {
298 if (fSWTWidget != null) {
299 return fSWTWidget.getShell();
301 return WebUI.getActiveWorkbenchShell();
304 private SourceViewer createViewer(Composite parent, int nColumns) {
305 Label label = new Label(parent, SWT.NONE);
306 label.setText(PreferencesMessages
307 .getString("CodeTemplateBlock.preview")); //$NON-NLS-1$
308 GridData data = new GridData();
309 data.horizontalSpan = nColumns;
310 label.setLayoutData(data);
312 IDocument document = new Document();
313 JavaTextTools tools = WebUI.getDefault().getJavaTextTools();
314 tools.setupJavaDocumentPartitioner(document,
315 IPHPPartitions.PHP_PARTITIONING);
316 IPreferenceStore store = WebUI.getDefault()
317 .getCombinedPreferenceStore();
318 SourceViewer viewer = new JavaSourceViewer(parent, null, null, false,
319 SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
320 TemplateEditorSourceViewerConfiguration configuration = new TemplateEditorSourceViewerConfiguration(
321 tools.getColorManager(), store, null, fTemplateProcessor);
322 viewer.configure(configuration);
323 viewer.setEditable(false);
324 viewer.setDocument(document);
326 Font font = JFaceResources
327 .getFont(PreferenceConstants.EDITOR_TEXT_FONT);
328 viewer.getTextWidget().setFont(font);
329 new JavaSourcePreviewerUpdater(viewer, configuration, store);
331 Control control = viewer.getControl();
332 data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
333 | GridData.FILL_VERTICAL);
334 data.horizontalSpan = nColumns;
335 data.heightHint = fPixelConverter.convertHeightInCharsToPixels(5);
336 control.setLayoutData(data);
341 protected TemplatePersistenceData[] getTemplateOfCategory(boolean isComment) {
342 ArrayList res = new ArrayList();
343 TemplatePersistenceData[] templates = fTemplates.getTemplateData(false);
344 for (int i = 0; i < templates.length; i++) {
345 TemplatePersistenceData curr = templates[i];
346 if (isComment == curr.getTemplate().getName().endsWith(
347 CodeTemplateContextType.COMMENT_SUFFIX)) {
351 return (TemplatePersistenceData[]) res
352 .toArray(new TemplatePersistenceData[res.size()]);
355 protected static boolean canEdit(List selected) {
356 return selected.size() == 1
357 && (selected.get(0) instanceof TemplatePersistenceData);
360 protected void updateSourceViewerInput(List selection) {
361 if (fPatternViewer == null
362 || fPatternViewer.getTextWidget().isDisposed()) {
365 if (selection.size() == 1
366 && selection.get(0) instanceof TemplatePersistenceData) {
367 TemplatePersistenceData data = (TemplatePersistenceData) selection
369 Template template = data.getTemplate();
370 TemplateContextType type = WebUI.getDefault()
371 .getCodeTemplateContextRegistry().getContextType(
372 template.getContextTypeId());
373 fTemplateProcessor.setContextType(type);
374 fPatternViewer.getDocument().set(template.getPattern());
376 fPatternViewer.getDocument().set(""); //$NON-NLS-1$
380 protected void doButtonPressed(int buttonIndex, List selected) {
381 if (buttonIndex == IDX_EDIT) {
382 edit((TemplatePersistenceData) selected.get(0));
383 } else if (buttonIndex == IDX_EXPORT) {
385 } else if (buttonIndex == IDX_EXPORTALL) {
387 } else if (buttonIndex == IDX_IMPORT) {
392 private void edit(TemplatePersistenceData data) {
393 Template newTemplate = new Template(data.getTemplate());
394 EditTemplateDialog dialog = new EditTemplateDialog(getShell(),
395 newTemplate, true, false, WebUI.getDefault()
396 .getCodeTemplateContextRegistry());
397 if (dialog.open() == Window.OK) {
399 data.setTemplate(newTemplate);
400 fCodeTemplateTree.refresh(data);
401 fCodeTemplateTree.selectElements(new StructuredSelection(data));
405 private void import_() {
406 FileDialog dialog = new FileDialog(getShell());
407 dialog.setText(PreferencesMessages
408 .getString("CodeTemplateBlock.import.title")); //$NON-NLS-1$
409 dialog.setFilterExtensions(new String[] { PreferencesMessages
410 .getString("CodeTemplateBlock.import.extension") }); //$NON-NLS-1$
411 String path = dialog.open();
417 TemplateReaderWriter reader = new TemplateReaderWriter();
418 File file = new File(path);
420 InputStream input = new BufferedInputStream(
421 new FileInputStream(file));
422 TemplatePersistenceData[] datas = reader.read(input, null);
423 for (int i = 0; i < datas.length; i++) {
424 updateTemplate(datas[i]);
428 fCodeTemplateTree.refresh();
429 updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
431 } catch (FileNotFoundException e) {
432 openReadErrorDialog(e);
433 } catch (IOException e) {
434 openReadErrorDialog(e);
439 private void updateTemplate(TemplatePersistenceData data) {
440 TemplatePersistenceData[] datas = fTemplates.getTemplateData(true);
441 for (int i = 0; i < datas.length; i++) {
442 String id = datas[i].getId();
443 if (id != null && id.equals(data.getId())) {
444 datas[i].setTemplate(data.getTemplate());
450 private void exportAll() {
451 export(fTemplates.getTemplateData(false));
454 private void export(List selected) {
455 List datas = new ArrayList();
456 for (int i = 0; i < selected.size(); i++) {
457 Object curr = selected.get(i);
458 if (curr instanceof TemplatePersistenceData) {
461 TemplatePersistenceData[] cat = getTemplateOfCategory(curr == COMMENT_NODE);
462 datas.addAll(Arrays.asList(cat));
465 export((TemplatePersistenceData[]) datas
466 .toArray(new TemplatePersistenceData[datas.size()]));
469 private void export(TemplatePersistenceData[] templates) {
470 FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
472 .setText(PreferencesMessages
474 "CodeTemplateBlock.export.title", String.valueOf(templates.length))); //$NON-NLS-1$
475 dialog.setFilterExtensions(new String[] { PreferencesMessages
476 .getString("CodeTemplateBlock.export.extension") }); //$NON-NLS-1$
477 dialog.setFileName(PreferencesMessages
478 .getString("CodeTemplateBlock.export.filename")); //$NON-NLS-1$
479 String path = dialog.open();
484 File file = new File(path);
486 if (file.isHidden()) {
487 String title = PreferencesMessages
488 .getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$
489 String message = PreferencesMessages
491 "CodeTemplateBlock.export.error.hidden", file.getAbsolutePath()); //$NON-NLS-1$
492 MessageDialog.openError(getShell(), title, message);
496 if (file.exists() && !file.canWrite()) {
497 String title = PreferencesMessages
498 .getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$
499 String message = PreferencesMessages
501 "CodeTemplateBlock.export.error.canNotWrite", file.getAbsolutePath()); //$NON-NLS-1$
502 MessageDialog.openError(getShell(), title, message);
506 if (!file.exists() || confirmOverwrite(file)) {
508 OutputStream output = new BufferedOutputStream(
509 new FileOutputStream(file));
510 TemplateReaderWriter writer = new TemplateReaderWriter();
511 writer.save(templates, output);
512 } catch (IOException e) {
513 openWriteErrorDialog(e);
519 private boolean confirmOverwrite(File file) {
524 .getString("CodeTemplateBlock.export.exists.title"), //$NON-NLS-1$
527 "CodeTemplateBlock.export.exists.message", file.getAbsolutePath())); //$NON-NLS-1$
530 public void performDefaults() {
531 IPreferenceStore prefs = WebUI.getDefault()
532 .getPreferenceStore();
533 fCreateJavaDocComments.setSelection(prefs
534 .getDefaultBoolean(PREF_JAVADOC_STUBS));
536 fTemplates.restoreDefaults();
539 fCodeTemplateTree.refresh();
540 updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
543 public boolean performOk(boolean enabled) {
544 IPreferenceStore prefs = PreferenceConstants.getPreferenceStore();
545 prefs.setValue(PREF_JAVADOC_STUBS, fCreateJavaDocComments.isSelected());
546 WebUI.getDefault().savePluginPreferences();
550 } catch (IOException e) {
552 openWriteErrorDialog(e);
557 public void performCancel() {
560 } catch (IOException e) {
561 openReadErrorDialog(e);
565 private void openReadErrorDialog(Exception e) {
566 String title = PreferencesMessages
567 .getString("CodeTemplateBlock.error.read.title"); //$NON-NLS-1$
569 String message = e.getLocalizedMessage();
571 message = PreferencesMessages.getFormattedString(
572 "CodeTemplateBlock.error.parse.message", message); //$NON-NLS-1$
574 message = PreferencesMessages
575 .getString("CodeTemplateBlock.error.read.message"); //$NON-NLS-1$
576 MessageDialog.openError(getShell(), title, message);
579 private void openWriteErrorDialog(Exception e) {
580 String title = PreferencesMessages
581 .getString("CodeTemplateBlock.error.write.title"); //$NON-NLS-1$
582 String message = PreferencesMessages
583 .getString("CodeTemplateBlock.error.write.message"); //$NON-NLS-1$
584 MessageDialog.openError(getShell(), title, message);