1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.ide.eclipse.adt.internal.lint; 17 18import static com.android.SdkConstants.UNIT_PX; 19import static com.android.SdkConstants.VALUE_N_DP; 20 21import com.android.ide.eclipse.adt.AdtPlugin; 22 23import org.eclipse.core.resources.IMarker; 24import org.eclipse.jface.dialogs.IInputValidator; 25import org.eclipse.jface.text.IDocument; 26import org.eclipse.jface.window.Window; 27import org.eclipse.swt.graphics.Image; 28import org.eclipse.swt.widgets.Shell; 29import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; 30import org.w3c.dom.Attr; 31import org.w3c.dom.Element; 32import org.w3c.dom.NamedNodeMap; 33import org.w3c.dom.Node; 34 35import java.util.regex.Matcher; 36import java.util.regex.Pattern; 37 38@SuppressWarnings("restriction") // DOM model 39final class ConvertToDpFix extends DocumentFix implements IInputValidator { 40 private ConvertToDpFix(String id, IMarker marker) { 41 super(id, marker); 42 } 43 44 @Override 45 public boolean needsFocus() { 46 return false; 47 } 48 49 @Override 50 public boolean isCancelable() { 51 return true; 52 } 53 54 @Override 55 protected void apply(IDocument document, IStructuredModel model, Node node, int start, 56 int end) { 57 Shell shell = AdtPlugin.getDisplay().getActiveShell(); 58 InputDensityDialog densityDialog = new InputDensityDialog(shell); 59 if (densityDialog.open() == Window.OK) { 60 int dpi = densityDialog.getDensity(); 61 Element element = (Element) node; 62 Pattern pattern = Pattern.compile("(\\d+)px"); //$NON-NLS-1$ 63 NamedNodeMap attributes = element.getAttributes(); 64 for (int i = 0, n = attributes.getLength(); i < n; i++) { 65 Attr attribute = (Attr) attributes.item(i); 66 String value = attribute.getValue(); 67 if (value.endsWith(UNIT_PX)) { 68 Matcher matcher = pattern.matcher(value); 69 if (matcher.matches()) { 70 String numberString = matcher.group(1); 71 try { 72 int px = Integer.parseInt(numberString); 73 int dp = px * 160 / dpi; 74 String newValue = String.format(VALUE_N_DP, dp); 75 attribute.setNodeValue(newValue); 76 } catch (NumberFormatException nufe) { 77 AdtPlugin.log(nufe, null); 78 } 79 } 80 } 81 } 82 } 83 } 84 85 @Override 86 public String getDisplayString() { 87 return "Convert to \"dp\"..."; 88 } 89 90 @Override 91 public Image getImage() { 92 return AdtPlugin.getAndroidLogo(); 93 } 94 95 // ---- Implements IInputValidator ---- 96 97 @Override 98 public String isValid(String input) { 99 if (input == null || input.length() == 0) 100 return " "; //$NON-NLS-1$ 101 102 try { 103 int i = Integer.parseInt(input); 104 if (i <= 0 || i > 1000) { 105 return "Invalid range"; 106 } 107 } catch (NumberFormatException x) { 108 return "Enter a valid number"; 109 } 110 111 return null; 112 } 113} 114