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;
41 import org.eclipse.jface.dialogs.MessageDialog;
42 import org.eclipse.jface.preference.IPreferenceStore;
43 import org.eclipse.jface.resource.JFaceResources;
44 import org.eclipse.jface.text.Document;
45 import org.eclipse.jface.text.IDocument;
46 import org.eclipse.jface.text.source.SourceViewer;
47 import org.eclipse.jface.text.templates.Template;
48 import org.eclipse.jface.text.templates.TemplateContextType;
49 import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
50 import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
51 import org.eclipse.jface.text.templates.persistence.TemplateStore;
52 import org.eclipse.jface.viewers.LabelProvider;
53 import org.eclipse.jface.viewers.StructuredSelection;
54 import org.eclipse.jface.window.Window;
55 import org.eclipse.swt.SWT;
56 import org.eclipse.swt.events.KeyEvent;
57 import org.eclipse.swt.graphics.Font;
58 import org.eclipse.swt.graphics.Image;
59 import org.eclipse.swt.layout.GridData;
60 import org.eclipse.swt.layout.GridLayout;
61 import org.eclipse.swt.widgets.Composite;
62 import org.eclipse.swt.widgets.Control;
63 import org.eclipse.swt.widgets.FileDialog;
64 import org.eclipse.swt.widgets.Label;
65 import org.eclipse.swt.widgets.Shell;
69 public class CodeTemplateBlock {
71 private class CodeTemplateAdapter implements ITreeListAdapter,
72 IDialogFieldListener {
74 private final Object[] NO_CHILDREN = new Object[0];
76 public void customButtonPressed(TreeListDialogField field, int index) {
77 doButtonPressed(index, field.getSelectedElements());
80 public void selectionChanged(TreeListDialogField field) {
81 List selected = field.getSelectedElements();
82 field.enableButton(IDX_EDIT, canEdit(selected));
83 field.enableButton(IDX_EXPORT, !selected.isEmpty());
85 updateSourceViewerInput(selected);
88 public void doubleClicked(TreeListDialogField field) {
89 List selected = field.getSelectedElements();
90 if (canEdit(selected)) {
91 doButtonPressed(IDX_EDIT, selected);
95 public Object[] getChildren(TreeListDialogField field, Object element) {
96 if (element == COMMENT_NODE || element == CODE_NODE) {
97 return getTemplateOfCategory(element == COMMENT_NODE);
102 public Object getParent(TreeListDialogField field, Object element) {
103 if (element instanceof TemplatePersistenceData) {
104 TemplatePersistenceData data = (TemplatePersistenceData) element;
105 if (data.getTemplate().getName().endsWith(
106 CodeTemplateContextType.COMMENT_SUFFIX)) {
114 public boolean hasChildren(TreeListDialogField field, Object element) {
115 return (element == COMMENT_NODE || element == CODE_NODE);
118 public void dialogFieldChanged(DialogField field) {
121 public void keyPressed(TreeListDialogField field, KeyEvent event) {
126 private static class CodeTemplateLabelProvider extends LabelProvider {
131 * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
133 public Image getImage(Object element) {
141 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
143 public String getText(Object element) {
144 if (element == COMMENT_NODE || element == CODE_NODE) {
145 return (String) element;
147 TemplatePersistenceData data = (TemplatePersistenceData) element;
148 Template template = data.getTemplate();
149 String name = template.getName();
150 if (CodeTemplateContextType.CATCHBLOCK.equals(name)) {
151 return PreferencesMessages
152 .getString("CodeTemplateBlock.catchblock.label"); //$NON-NLS-1$
153 } else if (CodeTemplateContextType.METHODSTUB.equals(name)) {
154 return PreferencesMessages
155 .getString("CodeTemplateBlock.methodstub.label"); //$NON-NLS-1$
156 } else if (CodeTemplateContextType.CONSTRUCTORSTUB.equals(name)) {
157 return PreferencesMessages
158 .getString("CodeTemplateBlock.constructorstub.label"); //$NON-NLS-1$
159 } else if (CodeTemplateContextType.GETTERSTUB.equals(name)) {
160 return PreferencesMessages
161 .getString("CodeTemplateBlock.getterstub.label"); //$NON-NLS-1$
162 } else if (CodeTemplateContextType.SETTERSTUB.equals(name)) {
163 return PreferencesMessages
164 .getString("CodeTemplateBlock.setterstub.label"); //$NON-NLS-1$
165 } else if (CodeTemplateContextType.NEWTYPE.equals(name)) {
166 return PreferencesMessages
167 .getString("CodeTemplateBlock.newtype.label"); //$NON-NLS-1$
168 } else if (CodeTemplateContextType.TYPECOMMENT.equals(name)) {
169 return PreferencesMessages
170 .getString("CodeTemplateBlock.typecomment.label"); //$NON-NLS-1$
171 } else if (CodeTemplateContextType.FIELDCOMMENT.equals(name)) {
172 return PreferencesMessages
173 .getString("CodeTemplateBlock.fieldcomment.label"); //$NON-NLS-1$
174 } else if (CodeTemplateContextType.METHODCOMMENT.equals(name)) {
175 return PreferencesMessages
176 .getString("CodeTemplateBlock.methodcomment.label"); //$NON-NLS-1$
177 } else if (CodeTemplateContextType.OVERRIDECOMMENT.equals(name)) {
178 return PreferencesMessages
179 .getString("CodeTemplateBlock.overridecomment.label"); //$NON-NLS-1$
180 } else if (CodeTemplateContextType.CONSTRUCTORCOMMENT.equals(name)) {
181 return PreferencesMessages
182 .getString("CodeTemplateBlock.constructorcomment.label"); //$NON-NLS-1$
183 } else if (CodeTemplateContextType.GETTERCOMMENT.equals(name)) {
184 return PreferencesMessages
185 .getString("CodeTemplateBlock.gettercomment.label"); //$NON-NLS-1$
186 } else if (CodeTemplateContextType.SETTERCOMMENT.equals(name)) {
187 return PreferencesMessages
188 .getString("CodeTemplateBlock.settercomment.label"); //$NON-NLS-1$
190 return template.getDescription();
195 private final static int IDX_EDIT = 0;
197 private final static int IDX_IMPORT = 2;
199 private final static int IDX_EXPORT = 3;
201 private final static int IDX_EXPORTALL = 4;
203 protected final static Object COMMENT_NODE = PreferencesMessages
204 .getString("CodeTemplateBlock.templates.comment.node"); //$NON-NLS-1$
206 protected final static Object CODE_NODE = PreferencesMessages
207 .getString("CodeTemplateBlock.templates.code.node"); //$NON-NLS-1$
209 private static final String PREF_JAVADOC_STUBS = PreferenceConstants.CODEGEN_ADD_COMMENTS;
211 private TreeListDialogField fCodeTemplateTree;
213 private SelectionButtonDialogField fCreateJavaDocComments;
215 protected TemplateStore fTemplates;
217 private PixelConverter fPixelConverter;
219 private SourceViewer fPatternViewer;
221 private Control fSWTWidget;
223 private TemplateVariableProcessor fTemplateProcessor;
225 public CodeTemplateBlock() {
227 fTemplates = PHPeclipsePlugin.getDefault().getCodeTemplateStore();
228 fTemplateProcessor = new TemplateVariableProcessor();
230 CodeTemplateAdapter adapter = new CodeTemplateAdapter();
232 String[] buttonLabels = new String[] {
233 /* IDX_EDIT */PreferencesMessages
234 .getString("CodeTemplateBlock.templates.edit.button"), //$NON-NLS-1$
236 /* IDX_IMPORT */PreferencesMessages
237 .getString("CodeTemplateBlock.templates.import.button"), //$NON-NLS-1$
238 /* IDX_EXPORT */PreferencesMessages
239 .getString("CodeTemplateBlock.templates.export.button"), //$NON-NLS-1$
240 /* IDX_EXPORTALL */PreferencesMessages
241 .getString("CodeTemplateBlock.templates.exportall.button") //$NON-NLS-1$
244 fCodeTemplateTree = new TreeListDialogField(adapter, buttonLabels,
245 new CodeTemplateLabelProvider());
246 fCodeTemplateTree.setDialogFieldListener(adapter);
247 fCodeTemplateTree.setLabelText(PreferencesMessages
248 .getString("CodeTemplateBlock.templates.label")); //$NON-NLS-1$
250 fCodeTemplateTree.enableButton(IDX_EXPORT, false);
251 fCodeTemplateTree.enableButton(IDX_EDIT, false);
253 fCodeTemplateTree.addElement(COMMENT_NODE);
254 fCodeTemplateTree.addElement(CODE_NODE);
256 fCreateJavaDocComments = new SelectionButtonDialogField(SWT.CHECK
258 fCreateJavaDocComments.setLabelText(PreferencesMessages
259 .getString("CodeTemplateBlock.createcomment.label")); //$NON-NLS-1$
260 fCreateJavaDocComments.setSelection(PreferenceConstants
261 .getPreferenceStore().getBoolean(PREF_JAVADOC_STUBS));
263 fCodeTemplateTree.selectFirstElement();
266 protected Control createContents(Composite parent) {
267 fPixelConverter = new PixelConverter(parent);
270 Composite composite = new Composite(parent, SWT.NONE);
271 GridLayout layout = new GridLayout();
272 layout.marginHeight = 0;
273 layout.marginWidth = 0;
274 layout.numColumns = 2;
275 composite.setLayout(layout);
277 fCodeTemplateTree.doFillIntoGrid(composite, 3);
279 .setHorizontalSpan(fCodeTemplateTree.getLabelControl(null), 2);
281 .setHorizontalGrabbing(fCodeTemplateTree.getTreeControl(null));
283 fPatternViewer = createViewer(composite, 2);
285 fCreateJavaDocComments.doFillIntoGrid(composite, 2);
287 DialogField label = new DialogField();
288 label.setLabelText(PreferencesMessages
289 .getString("CodeTemplateBlock.createcomment.description")); //$NON-NLS-1$
290 label.doFillIntoGrid(composite, 2);
296 private Shell getShell() {
297 if (fSWTWidget != null) {
298 return fSWTWidget.getShell();
300 return PHPeclipsePlugin.getActiveWorkbenchShell();
303 private SourceViewer createViewer(Composite parent, int nColumns) {
304 Label label = new Label(parent, SWT.NONE);
305 label.setText(PreferencesMessages
306 .getString("CodeTemplateBlock.preview")); //$NON-NLS-1$
307 GridData data = new GridData();
308 data.horizontalSpan = nColumns;
309 label.setLayoutData(data);
311 IDocument document = new Document();
312 JavaTextTools tools = PHPeclipsePlugin.getDefault().getJavaTextTools();
313 tools.setupJavaDocumentPartitioner(document,
314 IPHPPartitions.PHP_PARTITIONING);
315 IPreferenceStore store = PHPeclipsePlugin.getDefault()
316 .getCombinedPreferenceStore();
317 SourceViewer viewer = new JavaSourceViewer(parent, null, null, false,
318 SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
319 TemplateEditorSourceViewerConfiguration configuration = new TemplateEditorSourceViewerConfiguration(
320 tools.getColorManager(), store, null, fTemplateProcessor);
321 viewer.configure(configuration);
322 viewer.setEditable(false);
323 viewer.setDocument(document);
325 Font font = JFaceResources
326 .getFont(PreferenceConstants.EDITOR_TEXT_FONT);
327 viewer.getTextWidget().setFont(font);
328 new JavaSourcePreviewerUpdater(viewer, configuration, store);
330 Control control = viewer.getControl();
331 data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
332 | GridData.FILL_VERTICAL);
333 data.horizontalSpan = nColumns;
334 data.heightHint = fPixelConverter.convertHeightInCharsToPixels(5);
335 control.setLayoutData(data);
340 protected TemplatePersistenceData[] getTemplateOfCategory(boolean isComment) {
341 ArrayList res = new ArrayList();
342 TemplatePersistenceData[] templates = fTemplates.getTemplateData(false);
343 for (int i = 0; i < templates.length; i++) {
344 TemplatePersistenceData curr = templates[i];
345 if (isComment == curr.getTemplate().getName().endsWith(
346 CodeTemplateContextType.COMMENT_SUFFIX)) {
350 return (TemplatePersistenceData[]) res
351 .toArray(new TemplatePersistenceData[res.size()]);
354 protected static boolean canEdit(List selected) {
355 return selected.size() == 1
356 && (selected.get(0) instanceof TemplatePersistenceData);
359 protected void updateSourceViewerInput(List selection) {
360 if (fPatternViewer == null
361 || fPatternViewer.getTextWidget().isDisposed()) {
364 if (selection.size() == 1
365 && selection.get(0) instanceof TemplatePersistenceData) {
366 TemplatePersistenceData data = (TemplatePersistenceData) selection
368 Template template = data.getTemplate();
369 TemplateContextType type = PHPeclipsePlugin.getDefault()
370 .getCodeTemplateContextRegistry().getContextType(
371 template.getContextTypeId());
372 fTemplateProcessor.setContextType(type);
373 fPatternViewer.getDocument().set(template.getPattern());
375 fPatternViewer.getDocument().set(""); //$NON-NLS-1$
379 protected void doButtonPressed(int buttonIndex, List selected) {
380 if (buttonIndex == IDX_EDIT) {
381 edit((TemplatePersistenceData) selected.get(0));
382 } else if (buttonIndex == IDX_EXPORT) {
384 } else if (buttonIndex == IDX_EXPORTALL) {
386 } else if (buttonIndex == IDX_IMPORT) {
391 private void edit(TemplatePersistenceData data) {
392 Template newTemplate = new Template(data.getTemplate());
393 EditTemplateDialog dialog = new EditTemplateDialog(getShell(),
394 newTemplate, true, false, PHPeclipsePlugin.getDefault()
395 .getCodeTemplateContextRegistry());
396 if (dialog.open() == Window.OK) {
398 data.setTemplate(newTemplate);
399 fCodeTemplateTree.refresh(data);
400 fCodeTemplateTree.selectElements(new StructuredSelection(data));
404 private void import_() {
405 FileDialog dialog = new FileDialog(getShell());
406 dialog.setText(PreferencesMessages
407 .getString("CodeTemplateBlock.import.title")); //$NON-NLS-1$
408 dialog.setFilterExtensions(new String[] { PreferencesMessages
409 .getString("CodeTemplateBlock.import.extension") }); //$NON-NLS-1$
410 String path = dialog.open();
416 TemplateReaderWriter reader = new TemplateReaderWriter();
417 File file = new File(path);
419 InputStream input = new BufferedInputStream(
420 new FileInputStream(file));
421 TemplatePersistenceData[] datas = reader.read(input, null);
422 for (int i = 0; i < datas.length; i++) {
423 updateTemplate(datas[i]);
427 fCodeTemplateTree.refresh();
428 updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
430 } catch (FileNotFoundException e) {
431 openReadErrorDialog(e);
432 } catch (IOException e) {
433 openReadErrorDialog(e);
438 private void updateTemplate(TemplatePersistenceData data) {
439 TemplatePersistenceData[] datas = fTemplates.getTemplateData(true);
440 for (int i = 0; i < datas.length; i++) {
441 String id = datas[i].getId();
442 if (id != null && id.equals(data.getId())) {
443 datas[i].setTemplate(data.getTemplate());
449 private void exportAll() {
450 export(fTemplates.getTemplateData(false));
453 private void export(List selected) {
454 List datas = new ArrayList();
455 for (int i = 0; i < selected.size(); i++) {
456 Object curr = selected.get(i);
457 if (curr instanceof TemplatePersistenceData) {
460 TemplatePersistenceData[] cat = getTemplateOfCategory(curr == COMMENT_NODE);
461 datas.addAll(Arrays.asList(cat));
464 export((TemplatePersistenceData[]) datas
465 .toArray(new TemplatePersistenceData[datas.size()]));
468 private void export(TemplatePersistenceData[] templates) {
469 FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
471 .setText(PreferencesMessages
473 "CodeTemplateBlock.export.title", String.valueOf(templates.length))); //$NON-NLS-1$
474 dialog.setFilterExtensions(new String[] { PreferencesMessages
475 .getString("CodeTemplateBlock.export.extension") }); //$NON-NLS-1$
476 dialog.setFileName(PreferencesMessages
477 .getString("CodeTemplateBlock.export.filename")); //$NON-NLS-1$
478 String path = dialog.open();
483 File file = new File(path);
485 if (file.isHidden()) {
486 String title = PreferencesMessages
487 .getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$
488 String message = PreferencesMessages
490 "CodeTemplateBlock.export.error.hidden", file.getAbsolutePath()); //$NON-NLS-1$
491 MessageDialog.openError(getShell(), title, message);
495 if (file.exists() && !file.canWrite()) {
496 String title = PreferencesMessages
497 .getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$
498 String message = PreferencesMessages
500 "CodeTemplateBlock.export.error.canNotWrite", file.getAbsolutePath()); //$NON-NLS-1$
501 MessageDialog.openError(getShell(), title, message);
505 if (!file.exists() || confirmOverwrite(file)) {
507 OutputStream output = new BufferedOutputStream(
508 new FileOutputStream(file));
509 TemplateReaderWriter writer = new TemplateReaderWriter();
510 writer.save(templates, output);
511 } catch (IOException e) {
512 openWriteErrorDialog(e);
518 private boolean confirmOverwrite(File file) {
523 .getString("CodeTemplateBlock.export.exists.title"), //$NON-NLS-1$
526 "CodeTemplateBlock.export.exists.message", file.getAbsolutePath())); //$NON-NLS-1$
529 public void performDefaults() {
530 IPreferenceStore prefs = PHPeclipsePlugin.getDefault()
531 .getPreferenceStore();
532 fCreateJavaDocComments.setSelection(prefs
533 .getDefaultBoolean(PREF_JAVADOC_STUBS));
535 fTemplates.restoreDefaults();
538 fCodeTemplateTree.refresh();
539 updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
542 public boolean performOk(boolean enabled) {
543 IPreferenceStore prefs = PreferenceConstants.getPreferenceStore();
544 prefs.setValue(PREF_JAVADOC_STUBS, fCreateJavaDocComments.isSelected());
545 PHPeclipsePlugin.getDefault().savePluginPreferences();
549 } catch (IOException e) {
550 PHPeclipsePlugin.log(e);
551 openWriteErrorDialog(e);
556 public void performCancel() {
559 } catch (IOException e) {
560 openReadErrorDialog(e);
564 private void openReadErrorDialog(Exception e) {
565 String title = PreferencesMessages
566 .getString("CodeTemplateBlock.error.read.title"); //$NON-NLS-1$
568 String message = e.getLocalizedMessage();
570 message = PreferencesMessages.getFormattedString(
571 "CodeTemplateBlock.error.parse.message", message); //$NON-NLS-1$
573 message = PreferencesMessages
574 .getString("CodeTemplateBlock.error.read.message"); //$NON-NLS-1$
575 MessageDialog.openError(getShell(), title, message);
578 private void openWriteErrorDialog(Exception e) {
579 String title = PreferencesMessages
580 .getString("CodeTemplateBlock.error.write.title"); //$NON-NLS-1$
581 String message = PreferencesMessages
582 .getString("CodeTemplateBlock.error.write.message"); //$NON-NLS-1$
583 MessageDialog.openError(getShell(), title, message);