private IProject guessProject(IStructuredSelection selection) { if (selection == null) { return null; } for (Object element : selection.toList()) { if (element instanceof IAdaptable) { IResource res = (IResource) ((IAdaptable) element).getAdapter(IResource.class); IProject project = res != null ? res.getProject() : null; // Is this an Android project? try { if (project == null || !project.hasNature(AdtConstants.NATURE_DEFAULT)) { continue; } } catch (CoreException e) { // checking the nature failed, ignore this resource continue; } return project; } else if (element instanceof Pair<?, ?>) { // Pair of Project/String @SuppressWarnings("unchecked") Pair<IProject, String> pair = (Pair<IProject, String>) element; return pair.getFirst(); } } // Try to figure out the project from the active editor IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) { IWorkbenchPage page = window.getActivePage(); if (page != null) { IEditorPart activeEditor = page.getActiveEditor(); if (activeEditor instanceof AndroidXmlEditor) { Object input = ((AndroidXmlEditor) activeEditor).getEditorInput(); if (input instanceof FileEditorInput) { FileEditorInput fileInput = (FileEditorInput) input; return fileInput.getFile().getProject(); } } } } IJavaProject[] projects = BaseProjectHelper.getAndroidProjects( new IProjectFilter() { public boolean accept(IProject project) { return project.isAccessible(); } }); if (projects != null && projects.length == 1) { return projects[0].getProject(); } return null; }
/** * Displays a prompt message to the user and read two values, login/password. * * <p><i>Asks user for login/password information.</i> * * <p>This method shows a question in the standard output, asking for login and password.</br> * <b>Method Output:</b></br> Title</br> Message</br> Login: (Wait for user input)</br> * Password: (Wait for user input)</br> * * <p> * * @param title The title of the iteration. * @param message The message to be displayed. * @return A {@link Pair} holding the entered login and password. The <b>first element</b> is * always the <b>Login</b>, and the <b>second element</b> is always the <b>Password</b>. * This method will never return null, in case of error the pair will be filled with empty * strings. * @see ITaskMonitor#displayLoginPasswordPrompt(String, String) */ public Pair<String, String> displayLoginPasswordPrompt(String title, String message) { String login = ""; // $NON-NLS-1$ String password = ""; // $NON-NLS-1$ mSdkLog.printf("\n%1$s\n%2$s", title, message); byte[] readBuffer = new byte[2048]; try { mSdkLog.printf("\nLogin: "******"\nPassword: "******""; // $NON-NLS-1$ password = ""; // $NON-NLS-1$ // Just print the error to console. mSdkLog.printf("\nError occurred during login/pass query: %s\n", e.getMessage()); } return Pair.of(login, password); }
/** * Returns a pair of (tag-balance,bracket-balance) for the range textStart to offset. * * @param doc the document * @param start the offset of the starting character (inclusive) * @param end the offset of the ending character (exclusive) * @return the balance of tags and brackets */ private static Pair<Integer, Integer> getBalance(IStructuredDocument doc, int start, int end) { // Balance of open and closing tags // <foo></foo> has tagBalance = 0, <foo> has tagBalance = 1 int tagBalance = 0; // Balance of open and closing brackets // <foo attr1="value1"> has bracketBalance = 1, <foo has bracketBalance = 1 int bracketBalance = 0; IStructuredDocumentRegion region = doc.getRegionAtCharacterOffset(start); if (region != null) { boolean inOpenTag = true; while (region != null && region.getStartOffset() < end) { int regionStart = region.getStartOffset(); ITextRegionList subRegions = region.getRegions(); for (int i = 0, n = subRegions.size(); i < n; i++) { ITextRegion subRegion = subRegions.get(i); int subRegionStart = regionStart + subRegion.getStart(); int subRegionEnd = regionStart + subRegion.getEnd(); if (subRegionEnd < start || subRegionStart >= end) { continue; } String type = subRegion.getType(); if (XML_TAG_OPEN.equals(type)) { bracketBalance++; inOpenTag = true; } else if (XML_TAG_CLOSE.equals(type)) { bracketBalance--; if (inOpenTag) { tagBalance++; } else { tagBalance--; } } else if (XML_END_TAG_OPEN.equals(type)) { bracketBalance++; inOpenTag = false; } else if (XML_EMPTY_TAG_CLOSE.equals(type)) { bracketBalance--; } } region = region.getNext(); } } return Pair.of(tagBalance, bracketBalance); }
/** * Computes the minimum SDK and target SDK versions for the project * * @param project the project to look up the versions for * @return a pair of (minimum SDK, target SDK) versions, never null */ @NonNull public static Pair<Integer, Integer> computeSdkVersions(IProject project) { int mMinSdkVersion = 1; int mTargetSdkVersion = 1; IAbstractFile manifestFile = AndroidManifest.getManifest(new IFolderWrapper(project)); if (manifestFile != null) { try { Object value = AndroidManifest.getMinSdkVersion(manifestFile); mMinSdkVersion = 1; // Default case if missing if (value instanceof Integer) { mMinSdkVersion = ((Integer) value).intValue(); } else if (value instanceof String) { // handle codename, only if we can resolve it. if (Sdk.getCurrent() != null) { IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString("android-" + value); // $NON-NLS-1$ if (target != null) { // codename future API level is current api + 1 mMinSdkVersion = target.getVersion().getApiLevel() + 1; } } } Integer i = AndroidManifest.getTargetSdkVersion(manifestFile); if (i == null) { mTargetSdkVersion = mMinSdkVersion; } else { mTargetSdkVersion = i.intValue(); } } catch (XPathExpressionException e) { // do nothing we'll use 1 below. } catch (StreamException e) { // do nothing we'll use 1 below. } } return Pair.of(mMinSdkVersion, mTargetSdkVersion); }
private Pair<List<String>, List<String>> findViews(final boolean layoutsOnly) { final Set<String> customViews = new HashSet<String>(); final Set<String> thirdPartyViews = new HashSet<String>(); ProjectState state = Sdk.getProjectState(mProject); final List<IProject> libraries = state != null ? state.getFullLibraryProjects() : Collections.<IProject>emptyList(); SearchRequestor requestor = new SearchRequestor() { @Override public void acceptSearchMatch(SearchMatch match) throws CoreException { // Ignore matches in comments if (match.isInsideDocComment()) { return; } Object element = match.getElement(); if (element instanceof ResolvedBinaryType) { // Third party view ResolvedBinaryType type = (ResolvedBinaryType) element; IPackageFragment fragment = type.getPackageFragment(); IPath path = fragment.getPath(); String last = path.lastSegment(); // Filter out android.jar stuff if (last.equals(FN_FRAMEWORK_LIBRARY)) { return; } if (!isValidView(type, layoutsOnly)) { return; } IProject matchProject = match.getResource().getProject(); if (mProject == matchProject || libraries.contains(matchProject)) { String fqn = type.getFullyQualifiedName(); thirdPartyViews.add(fqn); } } else if (element instanceof ResolvedSourceType) { // User custom view IProject matchProject = match.getResource().getProject(); if (mProject == matchProject || libraries.contains(matchProject)) { ResolvedSourceType type = (ResolvedSourceType) element; if (!isValidView(type, layoutsOnly)) { return; } String fqn = type.getFullyQualifiedName(); fqn = fqn.replace('$', '.'); customViews.add(fqn); } } } }; try { IJavaProject javaProject = BaseProjectHelper.getJavaProject(mProject); if (javaProject != null) { String className = layoutsOnly ? CLASS_VIEWGROUP : CLASS_VIEW; IType viewType = javaProject.findType(className); if (viewType != null) { IJavaSearchScope scope = SearchEngine.createHierarchyScope(viewType); SearchParticipant[] participants = new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}; int matchRule = SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE; SearchPattern pattern = SearchPattern.createPattern( "*", IJavaSearchConstants.CLASS, IJavaSearchConstants.IMPLEMENTORS, matchRule); SearchEngine engine = new SearchEngine(); engine.search(pattern, participants, scope, requestor, new NullProgressMonitor()); } } } catch (CoreException e) { AdtPlugin.log(e, null); } List<String> custom = new ArrayList<String>(customViews); List<String> thirdParty = new ArrayList<String>(thirdPartyViews); if (!layoutsOnly) { // Update our cached answers (unless we were filtered on only layouts) mCustomViews = custom; mThirdPartyViews = thirdParty; } return Pair.of(custom, thirdParty); }
public void customizeDocumentCommand(IDocument document, DocumentCommand c) { if (!isSmartInsertMode()) { return; } if (!(document instanceof IStructuredDocument)) { // This shouldn't happen unless this strategy is used on an invalid document return; } IStructuredDocument doc = (IStructuredDocument) document; // Handle newlines/indentation if (c.length == 0 && c.text != null && TextUtilities.endsWith(doc.getLegalLineDelimiters(), c.text) != -1) { IModelManager modelManager = StructuredModelManager.getModelManager(); IStructuredModel model = modelManager.getModelForRead(doc); if (model != null) { try { final int offset = c.offset; int lineStart = findLineStart(doc, offset); int textStart = findTextStart(doc, lineStart, offset); IStructuredDocumentRegion region = doc.getRegionAtCharacterOffset(textStart); if (region != null && region.getType().equals(XML_TAG_NAME)) { Pair<Integer, Integer> balance = getBalance(doc, textStart, offset); int tagBalance = balance.getFirst(); int bracketBalance = balance.getSecond(); String lineIndent = ""; // $NON-NLS-1$ if (textStart > lineStart) { lineIndent = doc.get(lineStart, textStart - lineStart); } // We only care if tag or bracket balance is greater than 0; // we never *dedent* on negative balances boolean addIndent = false; if (bracketBalance < 0) { // Handle // <foo // ></foo>^ // and // <foo // />^ ITextRegion left = getRegionAt(doc, offset, true /*biasLeft*/); if (left != null && (left.getType().equals(XML_TAG_CLOSE) || left.getType().equals(XML_EMPTY_TAG_CLOSE))) { // Find the corresponding open tag... // The org.eclipse.wst.xml.ui.gotoMatchingTag frequently // doesn't work, it just says "No matching brace found" // (or I would use that here). int targetBalance = 0; ITextRegion right = getRegionAt(doc, offset, false /*biasLeft*/); if (right != null && right.getType().equals(XML_END_TAG_OPEN)) { targetBalance = -1; } int openTag = AndroidXmlCharacterMatcher.findTagBackwards(doc, offset, targetBalance); if (openTag != -1) { // Look up the indentation of the given line lineIndent = AndroidXmlEditor.getIndentAtOffset(doc, openTag); } } } else if (tagBalance > 0 || bracketBalance > 0) { // Add indentation addIndent = true; } StringBuilder sb = new StringBuilder(c.text); sb.append(lineIndent); String oneIndentUnit = XmlFormatPreferences.create().getOneIndentUnit(); if (addIndent) { sb.append(oneIndentUnit); } // Handle // <foo>^</foo> // turning into // <foo> // ^ // </foo> ITextRegion left = getRegionAt(doc, offset, true /*biasLeft*/); ITextRegion right = getRegionAt(doc, offset, false /*biasLeft*/); if (left != null && right != null && left.getType().equals(XML_TAG_CLOSE) && right.getType().equals(XML_END_TAG_OPEN)) { // Move end tag if (tagBalance > 0 && bracketBalance < 0) { sb.append(oneIndentUnit); } c.caretOffset = offset + sb.length(); c.shiftsCaret = false; sb.append(TextUtilities.getDefaultLineDelimiter(doc)); sb.append(lineIndent); } c.text = sb.toString(); } else if (region != null && region.getType().equals(XML_CONTENT)) { // Indenting in text content. If you're in the middle of editing // text, just copy the current line indentation. // However, if you're editing in leading whitespace (e.g. you press // newline on a blank line following say an element) then figure // out the indentation as if the newline had been pressed at the // end of the element, and insert that amount of indentation. // In this case we need to also make sure to subtract any existing // whitespace on the current line such that if we have // // <foo> // ^ <bar/> // </foo> // // you end up with // // <foo> // // ^<bar/> // </foo> // String text = region.getText(); int regionStart = region.getStartOffset(); int delta = offset - regionStart; boolean inWhitespacePrefix = true; for (int i = 0, n = Math.min(delta, text.length()); i < n; i++) { char ch = text.charAt(i); if (!Character.isWhitespace(ch)) { inWhitespacePrefix = false; break; } } if (inWhitespacePrefix) { IStructuredDocumentRegion previous = region.getPrevious(); if (previous != null && previous.getType() == XML_TAG_NAME) { ITextRegionList subRegions = previous.getRegions(); ITextRegion last = subRegions.get(subRegions.size() - 1); if (last.getType() == XML_TAG_CLOSE || last.getType() == XML_EMPTY_TAG_CLOSE) { int begin = AndroidXmlCharacterMatcher.findTagBackwards( doc, previous.getStartOffset() + last.getStart(), 0); int prevLineStart = findLineStart(doc, begin); int prevTextStart = findTextStart(doc, prevLineStart, begin); String lineIndent = ""; // $NON-NLS-1$ if (prevTextStart > prevLineStart) { lineIndent = doc.get(prevLineStart, prevTextStart - prevLineStart); } StringBuilder sb = new StringBuilder(c.text); sb.append(lineIndent); String oneIndentUnit = XmlFormatPreferences.create().getOneIndentUnit(); // See if there is whitespace on the insert line that // we should also remove for (int i = delta, n = text.length(); i < n; i++) { char ch = text.charAt(i); if (ch == ' ') { c.length++; } else { break; } } boolean onClosingTagLine = false; if (text.indexOf('\n', delta) == -1) { IStructuredDocumentRegion next = region.getNext(); if (next != null && next.getType() == XML_TAG_NAME) { String nextType = next.getRegions().get(0).getType(); if (nextType == XML_END_TAG_OPEN) { onClosingTagLine = true; } } } boolean addIndent = (last.getType() == XML_TAG_CLOSE) && !onClosingTagLine; if (addIndent) { sb.append(oneIndentUnit); } c.text = sb.toString(); return; } } } copyPreviousLineIndentation(doc, c); } else { copyPreviousLineIndentation(doc, c); } } catch (BadLocationException e) { AdtPlugin.log(e, null); } finally { model.releaseFromRead(); } } } }
Map<String, Map<String, BufferedImage>> generateImages(boolean previewOnly) { // Map of ids to images: Preserve insertion order (the densities) Map<String, Map<String, BufferedImage>> categoryMap = new LinkedHashMap<String, Map<String, BufferedImage>>(); CreateAssetSetWizard wizard = (CreateAssetSetWizard) getWizard(); AssetType type = wizard.getAssetType(); boolean crop = mTrimCheckBox.getSelection(); BufferedImage sourceImage = null; if (mImageRadio.getSelection()) { // Load the image // TODO: Only do this when the source image type is image String path = mImagePathText.getText().trim(); if (path.length() == 0) { setErrorMessage("Enter a filename"); return Collections.emptyMap(); } File file = new File(path); if (!file.exists()) { setErrorMessage(String.format("%1$s does not exist", file.getPath())); return Collections.emptyMap(); } setErrorMessage(null); sourceImage = getImage(path, false); if (sourceImage != null) { if (crop) { sourceImage = ImageUtils.cropBlank(sourceImage, null, TYPE_INT_ARGB); } int padding = getPadding(); if (padding != 0) { sourceImage = Util.paddedImage(sourceImage, padding); } } } else if (mTextRadio.getSelection()) { String text = mText.getText(); TextRenderUtil.Options options = new TextRenderUtil.Options(); options.font = getSelectedFont(); int color; if (type.needsColors()) { color = 0xFF000000 | (mFgColor.red << 16) | (mFgColor.green << 8) | mFgColor.blue; } else { color = 0xFFFFFFFF; } options.foregroundColor = color; sourceImage = TextRenderUtil.renderTextImage(text, getPadding(), options); if (crop) { sourceImage = ImageUtils.cropBlank(sourceImage, null, TYPE_INT_ARGB); } int padding = getPadding(); if (padding != 0) { sourceImage = Util.paddedImage(sourceImage, padding); } } else { assert mClipartRadio.getSelection(); assert mSelectedClipart != null; try { sourceImage = GraphicGenerator.getClipartImage(mSelectedClipart); if (crop) { sourceImage = ImageUtils.cropBlank(sourceImage, null, TYPE_INT_ARGB); } if (type.needsColors()) { int color = 0xFF000000 | (mFgColor.red << 16) | (mFgColor.green << 8) | mFgColor.blue; Paint paint = new java.awt.Color(color); sourceImage = Util.filledImage(sourceImage, paint); } int padding = getPadding(); if (padding != 0) { sourceImage = Util.paddedImage(sourceImage, padding); } } catch (IOException e) { AdtPlugin.log(e, null); return categoryMap; } } GraphicGenerator generator = null; GraphicGenerator.Options options = null; switch (type) { case LAUNCHER: { generator = new LauncherIconGenerator(); LauncherIconGenerator.LauncherOptions launcherOptions = new LauncherIconGenerator.LauncherOptions(); launcherOptions.shape = mCircleButton.getSelection() ? GraphicGenerator.Shape.CIRCLE : GraphicGenerator.Shape.SQUARE; launcherOptions.crop = mCropRadio.getSelection(); if (SUPPORT_LAUNCHER_ICON_TYPES) { launcherOptions.style = mFancyRadio.getSelection() ? GraphicGenerator.Style.FANCY : mGlossyRadio.getSelection() ? GraphicGenerator.Style.GLOSSY : GraphicGenerator.Style.SIMPLE; } else { launcherOptions.style = GraphicGenerator.Style.SIMPLE; } int color = (mBgColor.red << 16) | (mBgColor.green << 8) | mBgColor.blue; launcherOptions.backgroundColor = color; // Flag which tells the generator iterator to include a web graphic launcherOptions.isWebGraphic = !previewOnly; options = launcherOptions; break; } case MENU: generator = new MenuIconGenerator(); options = new GraphicGenerator.Options(); break; case ACTIONBAR: { generator = new ActionBarIconGenerator(); ActionBarIconGenerator.ActionBarOptions actionBarOptions = new ActionBarIconGenerator.ActionBarOptions(); actionBarOptions.theme = mHoloDarkRadio.getSelection() ? ActionBarIconGenerator.Theme.HOLO_DARK : ActionBarIconGenerator.Theme.HOLO_LIGHT; options = actionBarOptions; break; } case NOTIFICATION: { generator = new NotificationIconGenerator(); NotificationIconGenerator.NotificationOptions notificationOptions = new NotificationIconGenerator.NotificationOptions(); notificationOptions.shape = mCircleButton.getSelection() ? GraphicGenerator.Shape.CIRCLE : GraphicGenerator.Shape.SQUARE; options = notificationOptions; break; } case TAB: generator = new TabIconGenerator(); options = new TabIconGenerator.TabOptions(); break; default: AdtPlugin.log(IStatus.ERROR, "Unsupported asset type: %1$s", type); return categoryMap; } options.sourceImage = sourceImage; IProject project = wizard.getProject(); Pair<Integer, Integer> v = ManifestInfo.computeSdkVersions(project); options.minSdk = v.getFirst(); String baseName = wizard.getBaseName(); generator.generate(null, categoryMap, this, options, baseName); return categoryMap; }
public void testDropZones() { List<Pair<Point, String[]>> zones = new ArrayList<Pair<Point, String[]>>(); zones.add( Pair.of( new Point(51 + 10, 181 + 10), new String[] {"above=@+id/Centered", "toLeftOf=@+id/Centered"})); zones.add( Pair.of( new Point(71 + 10, 181 + 10), new String[] {"above=@+id/Centered", "alignLeft=@+id/Centered"})); zones.add( Pair.of( new Point(104 + 10, 181 + 10), new String[] {"above=@+id/Centered", "alignRight=@+id/Centered"})); zones.add( Pair.of( new Point(137 + 10, 181 + 10), new String[] {"above=@+id/Centered", "alignRight=@+id/Centered"})); zones.add( Pair.of( new Point(170 + 10, 181 + 10), new String[] {"above=@+id/Centered", "toRightOf=@+id/Centered"})); zones.add( Pair.of( new Point(51 + 10, 279 + 10), new String[] {"below=@+id/Centered", "toLeftOf=@+id/Centered"})); zones.add( Pair.of( new Point(71 + 10, 279 + 10), new String[] {"below=@+id/Centered", "alignLeft=@+id/Centered"})); zones.add( Pair.of( new Point(104 + 10, 279 + 10), new String[] {"below=@+id/Centered", "alignLeft=@+id/Centered"})); zones.add( Pair.of( new Point(137 + 10, 279 + 10), new String[] {"below=@+id/Centered", "alignRight=@+id/Centered"})); zones.add( Pair.of( new Point(170 + 10, 279 + 10), new String[] {"below=@+id/Centered", "toRightOf=@+id/Centered"})); zones.add( Pair.of( new Point(51 + 10, 201 + 10), new String[] {"toLeftOf=@+id/Centered", "alignTop=@+id/Centered"})); zones.add( Pair.of( new Point(51 + 10, 227 + 10), new String[] {"toLeftOf=@+id/Centered", "alignTop=@+id/Centered"})); zones.add( Pair.of( new Point(170 + 10, 201 + 10), new String[] {"toRightOf=@+id/Centered", "alignTop=@+id/Centered"})); zones.add( Pair.of( new Point(51 + 10, 253 + 10), new String[] {"toLeftOf=@+id/Centered", "alignBottom=@+id/Centered"})); zones.add( Pair.of( new Point(170 + 10, 227 + 10), new String[] { "toRightOf=@+id/Centered", "alignTop=@+id/Centered", "alignBottom=@+id/Centered" })); zones.add( Pair.of( new Point(170 + 10, 253 + 10), new String[] {"toRightOf=@+id/Centered", "alignBottom=@+id/Centered"})); for (Pair<Point, String[]> zonePair : zones) { Point dropPoint = zonePair.getFirst(); String[] attachments = zonePair.getSecond(); // If we drag right into the button itself, not a valid drop position INode inserted = dragInto( new Rect(0, 0, 105, 80), new Point(120, 240), dropPoint, 1, -1, attachments, // Bounds rectangle "useStyle(DROP_RECIPIENT), drawRect(Rect[0,0,240,480])", // Drop zones "useStyle(DROP_ZONE), " + "drawRect(Rect[51,181,20,20]), drawRect(Rect[71,181,33,20]), " + "drawRect(Rect[104,181,33,20]), drawRect(Rect[137,181,33,20]), " + "drawRect(Rect[170,181,20,20]), drawRect(Rect[51,279,20,20]), " + "drawRect(Rect[71,279,33,20]), drawRect(Rect[104,279,33,20]), " + "drawRect(Rect[137,279,33,20]), drawRect(Rect[170,279,20,20]), " + "drawRect(Rect[51,201,20,26]), drawRect(Rect[51,227,20,26]), " + "drawRect(Rect[51,253,20,26]), drawRect(Rect[170,201,20,26]), " + "drawRect(Rect[170,227,20,26]), drawRect(Rect[170,253,20,26])"); for (String attachment : attachments) { String[] elements = attachment.split("="); String name = "layout_" + elements[0]; String value = elements[1]; assertEquals(value, inserted.getStringAttr(ANDROID_URI, name)); } } }