/******************************************************************************* * Copyright (c) 2005, 2012 eBay Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ /** * */ package org.eclipse.vjet.eclipse.internal.ui.preferences.codestyle; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.vjet.eclipse.core.VjoNature; import org.eclipse.vjet.eclipse.ui.VjetUIPlugin; import org.eclipse.core.resources.IProject; import org.eclipse.dltk.mod.internal.ui.editor.ScriptSourceViewer; import org.eclipse.dltk.mod.internal.ui.preferences.ScriptSourcePreviewerUpdater; import org.eclipse.dltk.mod.internal.ui.wizards.dialogfields.DialogField; import org.eclipse.dltk.mod.internal.ui.wizards.dialogfields.IDialogFieldListener; import org.eclipse.dltk.mod.internal.ui.wizards.dialogfields.ITreeListAdapter; import org.eclipse.dltk.mod.internal.ui.wizards.dialogfields.LayoutUtil; import org.eclipse.dltk.mod.internal.ui.wizards.dialogfields.TreeListDialogField; import org.eclipse.dltk.mod.ui.DLTKUILanguageManager; import org.eclipse.dltk.mod.ui.IDLTKUILanguageToolkit; import org.eclipse.dltk.mod.ui.text.ScriptSourceViewerConfiguration; import org.eclipse.dltk.mod.ui.text.ScriptTextTools; import org.eclipse.dltk.mod.ui.util.PixelConverter; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.text.templates.Template; import org.eclipse.jface.text.templates.TemplateContextType; import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData; import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; /** * code template block * * * */ public class CodeTemplateBlock { private class CodeTemplateAdapter extends ViewerSorter implements ITreeListAdapter, IDialogFieldListener { private final Object[] NO_CHILDREN= new Object[0]; public void customButtonPressed(TreeListDialogField field, int index) { doButtonPressed(index, field.getSelectedElements()); } public void selectionChanged(TreeListDialogField field) { List selected= field.getSelectedElements(); field.enableButton(IDX_EDIT, canEdit(selected)); field.enableButton(IDX_EXPORT, !selected.isEmpty()); updateSourceViewerInput(selected); } public void doubleClicked(TreeListDialogField field) { List selected= field.getSelectedElements(); if (canEdit(selected)) { doButtonPressed(IDX_EDIT, selected); } } public Object[] getChildren(TreeListDialogField field, Object element) { if (element == COMMENT_NODE) { return getTemplateOfCategory(element == COMMENT_NODE); } return NO_CHILDREN; } public Object getParent(TreeListDialogField field, Object element) { if (element instanceof TemplatePersistenceData) { TemplatePersistenceData data= (TemplatePersistenceData) element; if (data.getTemplate().getName().endsWith(CodeTemplateContextType.COMMENT_SUFFIX)) { return COMMENT_NODE; } } return null; } public boolean hasChildren(TreeListDialogField field, Object element) { return (element == COMMENT_NODE); } public void dialogFieldChanged(DialogField field) { } public void keyPressed(TreeListDialogField field, KeyEvent event) { } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ViewerSorter#category(java.lang.Object) */ public int category(Object element) { if (element == COMMENT_NODE) { return 1; } TemplatePersistenceData data= (TemplatePersistenceData) element; String id= data.getId(); if (CodeTemplateContextType.CTYPE_ID.equals(id)) { return 101; } else if (CodeTemplateContextType.INTERFACE_ID.equals(id)) { return 101; } return 1000; } } private static class CodeTemplateLabelProvider extends LabelProvider { /* (non-Javadoc) * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) */ public Image getImage(Object element) { return null; } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) */ public String getText(Object element) { if (element == COMMENT_NODE) { return (String) element; } TemplatePersistenceData data= (TemplatePersistenceData) element; String id=data.getId(); if (CodeTemplateContextType.CTYPE_ID.equals(id)) { return "Ctype"; } else if (CodeTemplateContextType.INTERFACE_ID.equals(id)) { return "Interface"; } return data.getTemplate().getDescription(); } } private final static int IDX_EDIT= 0; private final static int IDX_IMPORT= 2; private final static int IDX_EXPORT= 3; private final static int IDX_EXPORTALL= 4; protected final static Object COMMENT_NODE= "Comment"; private TreeListDialogField fCodeTemplateTree; protected ProjectTemplateStore fTemplateStore; private PixelConverter fPixelConverter; private SourceViewer fPatternViewer; private Control fSWTWidget; private TemplateVariableProcessor fTemplateProcessor; private final org.eclipse.core.resources.IProject fProject; public CodeTemplateBlock(IProject project) { fProject= project; fTemplateStore= new ProjectTemplateStore(project); try { fTemplateStore.load(); } catch (IOException e) { e.printStackTrace(); } fTemplateProcessor= new TemplateVariableProcessor(); CodeTemplateAdapter adapter= new CodeTemplateAdapter(); String[] buttonLabels= new String[] { "Edit", /* */ null, "Import", "Export", "Export All" }; fCodeTemplateTree= new TreeListDialogField(adapter, buttonLabels, new CodeTemplateLabelProvider()); fCodeTemplateTree.setDialogFieldListener(adapter); fCodeTemplateTree.setLabelText("Code Template Block"); fCodeTemplateTree.setViewerSorter(adapter); fCodeTemplateTree.enableButton(IDX_EXPORT, false); fCodeTemplateTree.enableButton(IDX_EDIT, false); fCodeTemplateTree.addElement(COMMENT_NODE); fCodeTemplateTree.selectFirstElement(); } public void postSetSelection(Object element) { fCodeTemplateTree.postSetSelection(new StructuredSelection(element)); } public boolean hasProjectSpecificOptions(IProject project) { if (project != null) { return ProjectTemplateStore.hasProjectSpecificTempates(project); } return false; } protected Control createContents(Composite parent) { fPixelConverter= new PixelConverter(parent); fSWTWidget= parent; Composite composite= new Composite(parent, SWT.NONE); composite.setFont(parent.getFont()); GridLayout layout= new GridLayout(); layout.marginHeight= 0; layout.marginWidth= 0; layout.numColumns= 2; composite.setLayout(layout); fCodeTemplateTree.doFillIntoGrid(composite, 3); LayoutUtil.setHorizontalSpan(fCodeTemplateTree.getLabelControl(null), 2); LayoutUtil.setHorizontalGrabbing(fCodeTemplateTree.getTreeControl(null)); fPatternViewer= createViewer(composite, 2); return composite; } private Shell getShell() { if (fSWTWidget != null) { return fSWTWidget.getShell(); } return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); } private SourceViewer createViewer(Composite parent, int nColumns) { Label label= new Label(parent, SWT.NONE); label.setText("pattern"); GridData data= new GridData(); data.horizontalSpan= nColumns; label.setLayoutData(data); IDocument document= new Document(); IDLTKUILanguageToolkit toolkit = DLTKUILanguageManager.getLanguageToolkit(VjoNature.NATURE_ID); ScriptTextTools textTools = toolkit.getTextTools(); textTools.setupDocumentPartitioner(document, toolkit.getPartitioningId()); IPreferenceStore store = toolkit.getPreferenceStore(); ScriptSourceViewer viewer = new ScriptSourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store); ScriptSourceViewerConfiguration configuration = toolkit.createSourceViewerConfiguration(); viewer.configure(configuration); viewer.setEditable(false); viewer.setDocument(document); new ScriptSourcePreviewerUpdater(viewer, configuration, store); Control control= viewer.getControl(); data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL); data.horizontalSpan= nColumns; data.heightHint= fPixelConverter.convertHeightInCharsToPixels(5); control.setLayoutData(data); return viewer; } protected TemplatePersistenceData[] getTemplateOfCategory(boolean isComment) { ArrayList res= new ArrayList(); TemplatePersistenceData[] templates= fTemplateStore.getTemplateData(); for (int i= 0; i < templates.length; i++) { TemplatePersistenceData curr= templates[i]; if (isComment == curr.getTemplate().getName().endsWith(CodeTemplateContextType.COMMENT_SUFFIX)) { res.add(curr); } } return (TemplatePersistenceData[]) res.toArray(new TemplatePersistenceData[res.size()]); } protected static boolean canEdit(List selected) { return selected.size() == 1 && (selected.get(0) instanceof TemplatePersistenceData); } protected void updateSourceViewerInput(List selection) { if (fPatternViewer == null || fPatternViewer.getTextWidget().isDisposed()) { return; } if (selection.size() == 1 && selection.get(0) instanceof TemplatePersistenceData) { TemplatePersistenceData data= (TemplatePersistenceData) selection.get(0); Template template= data.getTemplate(); TemplateContextType type= VjetUIPlugin.getDefault().getCodeTemplateContextRegistry().getContextType(template.getContextTypeId()); fTemplateProcessor.setContextType(type); fPatternViewer.getDocument().set(template.getPattern()); } else { fPatternViewer.getDocument().set(""); //$NON-NLS-1$ } } protected void doButtonPressed(int buttonIndex, List selected) { if (buttonIndex == IDX_EDIT) { edit((TemplatePersistenceData) selected.get(0)); } else if (buttonIndex == IDX_EXPORT) { export(selected); } else if (buttonIndex == IDX_EXPORTALL) { exportAll(); } else if (buttonIndex == IDX_IMPORT) { import_(); } } private void edit(TemplatePersistenceData data) { // Template newTemplate= new Template(data.getTemplate()); // EditTemplateDialog dialog= new EditTemplateDialog(getShell(), newTemplate, true, false, JavaPlugin.getDefault().getCodeTemplateContextRegistry()); // if (dialog.open() == Window.OK) { // // changed // data.setTemplate(dialog.getTemplate()); // fCodeTemplateTree.refresh(data); // fCodeTemplateTree.selectElements(new StructuredSelection(data)); // } } private void import_() { FileDialog dialog= new FileDialog(getShell()); dialog.setText("Import Template"); String path= dialog.open(); if (path == null) return; try { TemplateReaderWriter reader= new TemplateReaderWriter(); File file= new File(path); if (file.exists()) { InputStream input= new BufferedInputStream(new FileInputStream(file)); try { TemplatePersistenceData[] datas= reader.read(input, null); for (int i= 0; i < datas.length; i++) { updateTemplate(datas[i]); } } finally { try { input.close(); } catch (IOException x) { } } } fCodeTemplateTree.refresh(); updateSourceViewerInput(fCodeTemplateTree.getSelectedElements()); } catch (FileNotFoundException e) { openReadErrorDialog(e); } catch (IOException e) { openReadErrorDialog(e); } } private void updateTemplate(TemplatePersistenceData data) { TemplatePersistenceData[] datas= fTemplateStore.getTemplateData(); for (int i= 0; i < datas.length; i++) { String id= datas[i].getId(); if (id != null && id.equals(data.getId())) { datas[i].setTemplate(data.getTemplate()); break; } } } private void exportAll() { export(fTemplateStore.getTemplateData()); } private void export(List selected) { Set datas= new HashSet(); for (int i= 0; i < selected.size(); i++) { Object curr= selected.get(i); if (curr instanceof TemplatePersistenceData) { datas.add(curr); } else { TemplatePersistenceData[] cat= getTemplateOfCategory(curr == COMMENT_NODE); datas.addAll(Arrays.asList(cat)); } } export((TemplatePersistenceData[]) datas.toArray(new TemplatePersistenceData[datas.size()])); } private void export(TemplatePersistenceData[] templates) { FileDialog dialog= new FileDialog(getShell(), SWT.SAVE); dialog.setText("Export Template"); dialog.setFileName("template.xml"); String path= dialog.open(); if (path == null) return; File file= new File(path); if (file.isHidden()) { String title= "Export failed"; String message= "Export failed"; MessageDialog.openError(getShell(), title, message); return; } if (file.exists() && !file.canWrite()) { String title= "Export Failed"; String message= "file is readonly"; MessageDialog.openError(getShell(), title, message); return; } if (!file.exists() || confirmOverwrite(file)) { OutputStream output= null; try { output= new BufferedOutputStream(new FileOutputStream(file)); TemplateReaderWriter writer= new TemplateReaderWriter(); writer.save(templates, output); output.close(); } catch (IOException e) { if (output != null) { try { output.close(); } catch (IOException e2) { // ignore } } openWriteErrorDialog(e); } } } private boolean confirmOverwrite(File file) { return MessageDialog.openQuestion(getShell(), "Already exists, overwrite?", "Already exsits"); } public void performDefaults() { fTemplateStore.restoreDefaults(); // refresh fCodeTemplateTree.refresh(); updateSourceViewerInput(fCodeTemplateTree.getSelectedElements()); } public boolean performOk(boolean enabled) { if (fProject != null) { TemplatePersistenceData[] templateData= fTemplateStore.getTemplateData(); for (int i= 0; i < templateData.length; i++) { fTemplateStore.setProjectSpecific(templateData[i].getId(), enabled); } } try { fTemplateStore.save(); } catch (IOException e) { openWriteErrorDialog(e); } return true; } public void performCancel() { try { fTemplateStore.revertChanges(); } catch (IOException e) { openReadErrorDialog(e); } } private void openReadErrorDialog(Exception e) { String title= "read error"; String message= e.getLocalizedMessage(); MessageDialog.openError(getShell(), title, message); } private void openWriteErrorDialog(Exception e) { String title= "write error"; String message= "write error"; MessageDialog.openError(getShell(), title, message); } }