1 /******************************************************************************* 2 * Copyright (c) 2000, 2014 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.internal.ui.refactoring; 15 16 import java.util.HashMap; 17 import java.util.Map; 18 19 import org.eclipse.swt.SWT; 20 import org.eclipse.swt.custom.StyledText; 21 import org.eclipse.swt.events.DisposeEvent; 22 import org.eclipse.swt.events.DisposeListener; 23 import org.eclipse.swt.graphics.Color; 24 import org.eclipse.swt.graphics.Image; 25 import org.eclipse.swt.graphics.RGB; 26 import org.eclipse.swt.widgets.Composite; 27 import org.eclipse.swt.widgets.Control; 28 import org.eclipse.swt.widgets.Display; 29 30 import org.eclipse.core.runtime.IAdaptable; 31 32 import org.eclipse.jface.dialogs.Dialog; 33 import org.eclipse.jface.preference.IPreferenceStore; 34 import org.eclipse.jface.preference.PreferenceConverter; 35 import org.eclipse.jface.resource.ImageDescriptor; 36 import org.eclipse.jface.resource.JFaceResources; 37 38 import org.eclipse.jface.text.Document; 39 import org.eclipse.jface.text.IDocument; 40 import org.eclipse.jface.text.source.IVerticalRuler; 41 import org.eclipse.jface.text.source.SourceViewer; 42 import org.eclipse.jface.text.source.SourceViewerConfiguration; 43 44 import org.eclipse.ui.model.IWorkbenchAdapter; 45 46 import org.eclipse.ui.texteditor.AbstractTextEditor; 47 48 import org.eclipse.ui.editors.text.EditorsUI; 49 50 import org.eclipse.ltk.core.refactoring.Change; 51 import org.eclipse.ltk.ui.refactoring.ChangePreviewViewerInput; 52 import org.eclipse.ltk.ui.refactoring.IChangePreviewViewer; 53 54 import org.eclipse.jdt.internal.corext.refactoring.nls.changes.CreateTextFileChange; 55 56 import org.eclipse.jdt.ui.PreferenceConstants; 57 import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration; 58 import org.eclipse.jdt.ui.text.JavaTextTools; 59 60 import org.eclipse.jdt.internal.ui.JavaPlugin; 61 import org.eclipse.jdt.internal.ui.propertiesfileeditor.IPropertiesFilePartitions; 62 import org.eclipse.jdt.internal.ui.propertiesfileeditor.PropertiesFileDocumentSetupParticipant; 63 import org.eclipse.jdt.internal.ui.propertiesfileeditor.PropertiesFileSourceViewerConfiguration; 64 import org.eclipse.jdt.internal.ui.util.ViewerPane; 65 66 /** 67 * Change preview viewer for <code>CreateTextFileChange</code> objects. 68 */ 69 public final class CreateTextFileChangePreviewViewer implements IChangePreviewViewer { 70 71 private static class CreateTextFilePreviewer extends ViewerPane { 72 73 private ImageDescriptor fDescriptor; 74 75 private Image fImage; 76 CreateTextFilePreviewer(Composite parent, int style)77 public CreateTextFilePreviewer(Composite parent, int style) { 78 super(parent, style); 79 addDisposeListener(new DisposeListener() { 80 @Override 81 public void widgetDisposed(DisposeEvent e) { 82 disposeImage(); 83 } 84 }); 85 } 86 disposeImage()87 /*package*/ void disposeImage() { 88 if (fImage != null) { 89 fImage.dispose(); 90 } 91 } 92 setImageDescriptor(ImageDescriptor imageDescriptor)93 public void setImageDescriptor(ImageDescriptor imageDescriptor) { 94 fDescriptor= imageDescriptor; 95 } 96 97 @Override setText(String text)98 public void setText(String text) { 99 super.setText(text); 100 Image current= null; 101 if (fDescriptor != null) { 102 current= fImage; 103 fImage= fDescriptor.createImage(); 104 } else { 105 current= fImage; 106 fImage= null; 107 } 108 setImage(fImage); 109 if (current != null) { 110 current.dispose(); 111 } 112 } 113 114 } 115 116 private static class FileChangeSourceViewer extends SourceViewer { 117 118 private final Map<String, Color> customColors= new HashMap<>(); 119 FileChangeSourceViewer(Composite parent, IVerticalRuler ruler, int styles)120 public FileChangeSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { 121 super(parent, ruler, styles); 122 setColors(); 123 StyledText textWidget= getTextWidget(); 124 textWidget.setEditable(false); 125 textWidget.setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)); 126 } 127 128 @Override handleDispose()129 protected void handleDispose() { 130 for (Color color : customColors.values()) { 131 if (color != null) { 132 color.dispose(); 133 } 134 } 135 customColors.clear(); 136 super.handleDispose(); 137 } 138 setColors()139 private void setColors() { 140 IPreferenceStore store= EditorsUI.getPreferenceStore(); 141 StyledText styledText= getTextWidget(); 142 setColor(styledText, store, 143 AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND, 144 store.getBoolean( 145 AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT)); 146 setColor(styledText, store, 147 AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, 148 store.getBoolean( 149 AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)); 150 setColor(styledText, store, 151 AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND, 152 store.getBoolean( 153 AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND_SYSTEM_DEFAULT)); 154 setColor(styledText, store, 155 AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND, 156 store.getBoolean( 157 AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT)); 158 } 159 setColor(StyledText styledText, IPreferenceStore store, String key, boolean useDefault)160 private void setColor(StyledText styledText, IPreferenceStore store, 161 String key, boolean useDefault) { 162 Color newColor= useDefault 163 ? null 164 : createColor(styledText.getDisplay(), store, key); 165 switch (key) { 166 case AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND: 167 styledText.setForeground(newColor); 168 break; 169 case AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND: 170 styledText.setBackground(newColor); 171 break; 172 case AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND: 173 styledText.setSelectionForeground(newColor); 174 break; 175 case AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND: 176 styledText.setSelectionBackground(newColor); 177 break; 178 default: 179 return; 180 } 181 Color oldColor= customColors.remove(key); 182 if (oldColor != null) { 183 oldColor.dispose(); 184 } 185 customColors.put(key, newColor); 186 } 187 createColor(Display display, IPreferenceStore store, String key)188 private static Color createColor(Display display, IPreferenceStore store, 189 String key) { 190 RGB rgb= null; 191 if (store.contains(key)) { 192 if (store.isDefault(key)) { 193 rgb= PreferenceConverter.getDefaultColor(store, key); 194 } else { 195 rgb= PreferenceConverter.getColor(store, key); 196 } 197 if (rgb != null) { 198 return new Color(display, rgb); 199 } 200 } 201 return null; 202 } 203 } 204 205 private CreateTextFilePreviewer fPane; 206 207 private SourceViewer fSourceViewer; 208 209 @Override createControl(Composite parent)210 public void createControl(Composite parent) { 211 fPane= new CreateTextFilePreviewer(parent, SWT.BORDER | SWT.FLAT); 212 Dialog.applyDialogFont(fPane); 213 214 fSourceViewer= new FileChangeSourceViewer(fPane, null, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); 215 fPane.setContent(fSourceViewer.getControl()); 216 } 217 218 @Override getControl()219 public Control getControl() { 220 return fPane; 221 } 222 refresh()223 public void refresh() { 224 fSourceViewer.refresh(); 225 } 226 227 228 @Override setInput(ChangePreviewViewerInput input)229 public void setInput(ChangePreviewViewerInput input) { 230 Change change= input.getChange(); 231 if (change != null) { 232 Object element= change.getModifiedElement(); 233 if (element instanceof IAdaptable) { 234 IAdaptable adaptable= (IAdaptable) element; 235 IWorkbenchAdapter workbenchAdapter= adaptable.getAdapter(IWorkbenchAdapter.class); 236 if (workbenchAdapter != null) { 237 fPane.setImageDescriptor(workbenchAdapter.getImageDescriptor(element)); 238 } else { 239 fPane.setImageDescriptor(null); 240 } 241 } else { 242 fPane.setImageDescriptor(null); 243 } 244 } 245 if (!(change instanceof CreateTextFileChange)) { 246 fSourceViewer.setInput(null); 247 fPane.setText(""); //$NON-NLS-1$ 248 return; 249 } 250 CreateTextFileChange textFileChange= (CreateTextFileChange) change; 251 fPane.setText(textFileChange.getName()); 252 IDocument document= new Document(textFileChange.getPreview()); 253 // This is a temporary work around until we get the 254 // source viewer registry. 255 fSourceViewer.unconfigure(); 256 String textType= textFileChange.getTextType(); 257 JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools(); 258 IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore(); 259 boolean nomatch= false; 260 if (textType != null) switch (textType) { 261 case "java": //$NON-NLS-1$ 262 textTools.setupJavaDocumentPartitioner(document); 263 fSourceViewer.configure(new JavaSourceViewerConfiguration(textTools.getColorManager(), store, null, null)); 264 fSourceViewer.getTextWidget().setOrientation(SWT.LEFT_TO_RIGHT); 265 break; 266 case "properties": //$NON-NLS-1$ 267 PropertiesFileDocumentSetupParticipant.setupDocument(document); 268 fSourceViewer.configure(new PropertiesFileSourceViewerConfiguration(textTools.getColorManager(), store, null, IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING)); 269 fSourceViewer.getTextWidget().setOrientation(SWT.LEFT_TO_RIGHT); 270 break; 271 default: 272 nomatch= true; 273 break; 274 } 275 if (nomatch) { 276 fSourceViewer.configure(new SourceViewerConfiguration()); 277 fSourceViewer.getTextWidget().setOrientation(fSourceViewer.getTextWidget().getParent().getOrientation()); 278 } 279 fSourceViewer.setInput(document); 280 } 281 } 282