1d6124a176326169bc87cb29823ca2dc906689680Tor Norbye/* 2d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * Copyright (C) 2012 The Android Open Source Project 3d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * 4d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * you may not use this file except in compliance with the License. 6d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * You may obtain a copy of the License at 7d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * 8d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * http://www.eclipse.org/org/documents/epl-v10.php 9d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * 10d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * Unless required by applicable law or agreed to in writing, software 11d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * distributed under the License is distributed on an "AS IS" BASIS, 12d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * See the License for the specific language governing permissions and 14d6124a176326169bc87cb29823ca2dc906689680Tor Norbye * limitations under the License. 15d6124a176326169bc87cb29823ca2dc906689680Tor Norbye */ 16d6124a176326169bc87cb29823ca2dc906689680Tor Norbyepackage com.android.ide.eclipse.adt.internal.lint; 17d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 1812d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ANDROID_URI; 19d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 20d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport com.android.ide.eclipse.adt.AdtPlugin; 21d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport com.android.ide.eclipse.adt.AdtUtils; 22d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; 2385e4a1a9dd133abb879ec211ce8dd385004edf22Xavier Ducrohetimport com.android.utils.XmlUtils; 24d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 25d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.core.resources.IFile; 26d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.core.resources.IMarker; 27d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.jface.text.IDocument; 28d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.jface.text.Region; 29d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.swt.graphics.Image; 30d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.ui.IEditorPart; 31d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.ui.ISharedImages; 32d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.ui.PartInitException; 33d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.ui.PlatformUI; 34d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; 35d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; 36d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.w3c.dom.Attr; 37d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.w3c.dom.Element; 38d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeimport org.w3c.dom.Node; 39d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 40d6124a176326169bc87cb29823ca2dc906689680Tor Norbye@SuppressWarnings("restriction") // DOM model 41d6124a176326169bc87cb29823ca2dc906689680Tor Norbyeabstract class SetPropertyFix extends DocumentFix { 42d6124a176326169bc87cb29823ca2dc906689680Tor Norbye private Region mSelect; 43d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 44d6124a176326169bc87cb29823ca2dc906689680Tor Norbye protected SetPropertyFix(String id, IMarker marker) { 45d6124a176326169bc87cb29823ca2dc906689680Tor Norbye super(id, marker); 46d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 47d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 48d6124a176326169bc87cb29823ca2dc906689680Tor Norbye /** Attribute to be added */ 49d6124a176326169bc87cb29823ca2dc906689680Tor Norbye protected abstract String getAttribute(); 50d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 519a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye /** Whether it's in the android: namespace */ 529a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye protected abstract boolean isAndroidAttribute(); 539a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye 5417f39d1945df1ec1d8eb6dee329aa6403c9e8b99Tor Norbye protected String getProposal(Element element) { 55d6124a176326169bc87cb29823ca2dc906689680Tor Norbye return invokeCodeCompletion() ? "" : "TODO"; //$NON-NLS-1$ 56d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 57d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 58d6124a176326169bc87cb29823ca2dc906689680Tor Norbye protected boolean invokeCodeCompletion() { 59d6124a176326169bc87cb29823ca2dc906689680Tor Norbye return false; 60d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 61d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 62d6124a176326169bc87cb29823ca2dc906689680Tor Norbye @Override 63d6124a176326169bc87cb29823ca2dc906689680Tor Norbye public boolean isCancelable() { 64d6124a176326169bc87cb29823ca2dc906689680Tor Norbye return false; 65d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 66d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 67d6124a176326169bc87cb29823ca2dc906689680Tor Norbye @Override 68d6124a176326169bc87cb29823ca2dc906689680Tor Norbye protected void apply(IDocument document, IStructuredModel model, Node node, int start, 69d6124a176326169bc87cb29823ca2dc906689680Tor Norbye int end) { 70d6124a176326169bc87cb29823ca2dc906689680Tor Norbye mSelect = null; 71d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 72d6124a176326169bc87cb29823ca2dc906689680Tor Norbye if (node instanceof Element) { 73d6124a176326169bc87cb29823ca2dc906689680Tor Norbye Element element = (Element) node; 7417f39d1945df1ec1d8eb6dee329aa6403c9e8b99Tor Norbye String proposal = getProposal(element); 75d6124a176326169bc87cb29823ca2dc906689680Tor Norbye String localAttribute = getAttribute(); 769a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye String prefix = null; 779a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye if (isAndroidAttribute()) { 789a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye prefix = XmlUtils.lookupNamespacePrefix(node, ANDROID_URI); 799a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye } 80d6124a176326169bc87cb29823ca2dc906689680Tor Norbye String attribute = prefix != null ? prefix + ':' + localAttribute : localAttribute; 81d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 82d6124a176326169bc87cb29823ca2dc906689680Tor Norbye // This does not work even though it should: it does not include the prefix 83d6124a176326169bc87cb29823ca2dc906689680Tor Norbye //element.setAttributeNS(ANDROID_URI, localAttribute, proposal); 84d6124a176326169bc87cb29823ca2dc906689680Tor Norbye // So workaround instead: 85d6124a176326169bc87cb29823ca2dc906689680Tor Norbye element.setAttribute(attribute, proposal); 86d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 879a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye Attr attr = null; 889a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye if (isAndroidAttribute()) { 899a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye attr = element.getAttributeNodeNS(ANDROID_URI, localAttribute); 909a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye } else { 919a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye attr = element.getAttributeNode(localAttribute); 929a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye } 93d6124a176326169bc87cb29823ca2dc906689680Tor Norbye if (attr instanceof IndexedRegion) { 94d6124a176326169bc87cb29823ca2dc906689680Tor Norbye IndexedRegion region = (IndexedRegion) attr; 95d6124a176326169bc87cb29823ca2dc906689680Tor Norbye int offset = region.getStartOffset(); 96d6124a176326169bc87cb29823ca2dc906689680Tor Norbye // We only want to select the value part inside the quotes, 97d6124a176326169bc87cb29823ca2dc906689680Tor Norbye // so skip the attribute and =" parts added by WST: 98d6124a176326169bc87cb29823ca2dc906689680Tor Norbye offset += attribute.length() + 2; 999a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye if (selectValue()) { 1009a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye mSelect = new Region(offset, proposal.length()); 1019a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye } 102d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 103d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 104d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 105d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 1069a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye protected boolean selectValue() { 1079a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye return true; 1089a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye } 1099a666a7cf24a78455482b79b4fbe4c1eba0481ceTor Norbye 110d6124a176326169bc87cb29823ca2dc906689680Tor Norbye @Override 111d6124a176326169bc87cb29823ca2dc906689680Tor Norbye public void apply(IDocument document) { 112d6124a176326169bc87cb29823ca2dc906689680Tor Norbye try { 113d6124a176326169bc87cb29823ca2dc906689680Tor Norbye IFile file = (IFile) mMarker.getResource(); 114d6124a176326169bc87cb29823ca2dc906689680Tor Norbye super.apply(document); 115d6124a176326169bc87cb29823ca2dc906689680Tor Norbye AdtPlugin.openFile(file, mSelect, true); 116d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } catch (PartInitException e) { 117d6124a176326169bc87cb29823ca2dc906689680Tor Norbye AdtPlugin.log(e, null); 118d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 119d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 120d6124a176326169bc87cb29823ca2dc906689680Tor Norbye // Invoke code assist 121d6124a176326169bc87cb29823ca2dc906689680Tor Norbye if (invokeCodeCompletion()) { 122d6124a176326169bc87cb29823ca2dc906689680Tor Norbye IEditorPart editor = AdtUtils.getActiveEditor(); 123d6124a176326169bc87cb29823ca2dc906689680Tor Norbye if (editor instanceof AndroidXmlEditor) { 124d6124a176326169bc87cb29823ca2dc906689680Tor Norbye ((AndroidXmlEditor) editor).invokeContentAssist(-1); 125d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 126d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 127d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 128d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 129d6124a176326169bc87cb29823ca2dc906689680Tor Norbye @Override 130d6124a176326169bc87cb29823ca2dc906689680Tor Norbye public boolean needsFocus() { 131d6124a176326169bc87cb29823ca2dc906689680Tor Norbye // Because we need to show the editor with text selected 132d6124a176326169bc87cb29823ca2dc906689680Tor Norbye return true; 133d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 134d6124a176326169bc87cb29823ca2dc906689680Tor Norbye 135d6124a176326169bc87cb29823ca2dc906689680Tor Norbye @Override 136d6124a176326169bc87cb29823ca2dc906689680Tor Norbye public Image getImage() { 137d6124a176326169bc87cb29823ca2dc906689680Tor Norbye ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages(); 138d6124a176326169bc87cb29823ca2dc906689680Tor Norbye return sharedImages.getImage(ISharedImages.IMG_OBJ_ADD); 139d6124a176326169bc87cb29823ca2dc906689680Tor Norbye } 140a881b0b34678ad76c9f5eba62fac7a00a22ac606Tor Norbye} 141