diff --git a/app/build.gradle b/app/build.gradle index 98fb9be0..5d4f42ed 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,8 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 29 - buildToolsVersion '28.0.3' - useLibrary 'org.apache.http.legacy' + buildToolsVersion '29.0.3' defaultConfig { minSdkVersion 15 @@ -20,6 +19,7 @@ android { } } } + signingConfigs { releaseConfig { def propsFile = rootProject.file('keystore.properties') @@ -35,6 +35,7 @@ android { } } } + buildTypes { debug { minifyEnabled false @@ -46,6 +47,7 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + flavorDimensions "version" productFlavors { full { @@ -59,30 +61,44 @@ android { resValue "string", "search_history_authority", applicationId + ".search.SearchHistoryProvider" } } + lintOptions { disable 'MissingTranslation', 'ExtraTranslation', 'StringFormatInvalid', 'ValidFragment', 'Registered' } + + compileOptions { + encoding = 'UTF-8' + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + useLibrary 'org.apache.http.legacy' } dependencies { +// Android support + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.preference:preference:1.1.1' + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' + implementation 'com.google.android.material:material:1.1.0' + +// Other implementation 'org.androidannotations:androidannotations-api:4.7.0' implementation 'org.androidannotations:ormlite-api:4.7.0' - implementation 'com.j256.ormlite:ormlite-core:4.48' - implementation 'com.j256.ormlite:ormlite-android:4.48' + implementation 'com.j256.ormlite:ormlite-core:5.1' + implementation 'com.j256.ormlite:ormlite-android:5.1' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support:recyclerview-v7:28.0.0' - implementation 'com.android.support:support-annotations:28.0.0' - implementation 'com.android.support:design:28.0.0' - implementation 'com.android.support:support-v4:28.0.0' implementation 'com.getbase:floatingactionbutton:1.10.1' implementation 'com.nispok:snackbar:2.11.0' implementation 'com.github.aegnor:rencode-java:cb628e824e' + implementation 'org.apache.openjpa:openjpa-lib:3.1.1' + implementation 'net.iharder:base64:2.3.9' + //implementation 'fr.turri:aXMLRPC:1.12.0' implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') { transitive = true } implementation 'com.evernote:android-job:1.2.6' + annotationProcessor 'org.androidannotations:androidannotations:4.7.0' annotationProcessor 'org.androidannotations:ormlite:4.7.0' } - diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/ByteArrayPartSource.java b/app/src/main/java/com/android/internalcopy/http/multipart/ByteArrayPartSource.java deleted file mode 100644 index b143b57e..00000000 --- a/app/src/main/java/com/android/internalcopy/http/multipart/ByteArrayPartSource.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/ByteArrayPartSource.java,v 1.7 2004/04/18 23:51:37 jsdever Exp $ - * $Revision: 480424 $ - * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package com.android.internalcopy.http.multipart; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -/** - * A PartSource that reads from a byte array. This class should be used when - * the data to post is already loaded into memory. - * - * @author Michael Becke - * - * @since 2.0 - */ -public class ByteArrayPartSource implements PartSource { - - /** Name of the source file. */ - private String fileName; - - /** Byte array of the source file. */ - private byte[] bytes; - - /** - * Constructor for ByteArrayPartSource. - * - * @param fileName the name of the file these bytes represent - * @param bytes the content of this part - */ - public ByteArrayPartSource(String fileName, byte[] bytes) { - - this.fileName = fileName; - this.bytes = bytes; - - } - - /** - * @see PartSource#getLength() - */ - public long getLength() { - return bytes.length; - } - - /** - * @see PartSource#getFileName() - */ - public String getFileName() { - return fileName; - } - - /** - * @see PartSource#createInputStream() - */ - public InputStream createInputStream() { - return new ByteArrayInputStream(bytes); - } - -} diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/FilePart.java b/app/src/main/java/com/android/internalcopy/http/multipart/FilePart.java deleted file mode 100644 index 43f050c1..00000000 --- a/app/src/main/java/com/android/internalcopy/http/multipart/FilePart.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $ - * $Revision: 480424 $ - * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package com.android.internalcopy.http.multipart; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import org.apache.http.util.EncodingUtils; - -/** - * This class implements a part of a Multipart post object that - * consists of a file. - * - * @author Matthew Albright - * @author Jeff Dever - * @author Adrian Sutton - * @author Michael Becke - * @author Mark Diggory - * @author Mike Bowler - * @author Oleg Kalnichevski - * - * @since 2.0 - * - */ -public class FilePart extends PartBase { - - /** Default content encoding of file attachments. */ - public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream"; - - /** Default charset of file attachments. */ - public static final String DEFAULT_CHARSET = "ISO-8859-1"; - - /** Default transfer encoding of file attachments. */ - public static final String DEFAULT_TRANSFER_ENCODING = "binary"; - - /** Attachment's file name */ - protected static final String FILE_NAME = "; filename="; - - /** Attachment's file name as a byte array */ - private static final byte[] FILE_NAME_BYTES = - EncodingUtils.getAsciiBytes(FILE_NAME); - - /** Source of the file part. */ - private PartSource source; - - /** - * FilePart Constructor. - * - * @param name the name for this part - * @param partSource the source for this part - * @param contentType the content type for this part, if null the - * {@link #DEFAULT_CONTENT_TYPE default} is used - * @param charset the charset encoding for this part, if null the - * {@link #DEFAULT_CHARSET default} is used - */ - public FilePart(String name, PartSource partSource, String contentType, String charset) { - - super( - name, - contentType == null ? DEFAULT_CONTENT_TYPE : contentType, - charset == null ? "ISO-8859-1" : charset, - DEFAULT_TRANSFER_ENCODING - ); - - if (partSource == null) { - throw new IllegalArgumentException("Source may not be null"); - } - this.source = partSource; - } - - /** - * FilePart Constructor. - * - * @param name the name for this part - * @param partSource the source for this part - */ - public FilePart(String name, PartSource partSource) { - this(name, partSource, null, null); - } - - /** - * FilePart Constructor. - * - * @param name the name of the file part - * @param file the file to post - * - * @throws FileNotFoundException if the file is not a normal - * file or if it is not readable. - */ - public FilePart(String name, File file) - throws FileNotFoundException { - this(name, new FilePartSource(file), null, null); - } - - /** - * FilePart Constructor. - * - * @param name the name of the file part - * @param file the file to post - * @param contentType the content type for this part, if null the - * {@link #DEFAULT_CONTENT_TYPE default} is used - * @param charset the charset encoding for this part, if null the - * {@link #DEFAULT_CHARSET default} is used - * - * @throws FileNotFoundException if the file is not a normal - * file or if it is not readable. - */ - public FilePart(String name, File file, String contentType, String charset) - throws FileNotFoundException { - this(name, new FilePartSource(file), contentType, charset); - } - - /** - * FilePart Constructor. - * - * @param name the name of the file part - * @param fileName the file name - * @param file the file to post - * - * @throws FileNotFoundException if the file is not a normal - * file or if it is not readable. - */ - public FilePart(String name, String fileName, File file) - throws FileNotFoundException { - this(name, new FilePartSource(fileName, file), null, null); - } - - /** - * FilePart Constructor. - * - * @param name the name of the file part - * @param fileName the file name - * @param file the file to post - * @param contentType the content type for this part, if null the - * {@link #DEFAULT_CONTENT_TYPE default} is used - * @param charset the charset encoding for this part, if null the - * {@link #DEFAULT_CHARSET default} is used - * - * @throws FileNotFoundException if the file is not a normal - * file or if it is not readable. - */ - public FilePart(String name, String fileName, File file, String contentType, String charset) - throws FileNotFoundException { - this(name, new FilePartSource(fileName, file), contentType, charset); - } - - /** - * Write the disposition header to the output stream - * @param out The output stream - * @throws IOException If an IO problem occurs - * @see Part#sendDispositionHeader(OutputStream) - */ - @Override - protected void sendDispositionHeader(OutputStream out) - throws IOException { - super.sendDispositionHeader(out); - String filename = this.source.getFileName(); - if (filename != null) { - out.write(FILE_NAME_BYTES); - out.write(QUOTE_BYTES); - out.write(EncodingUtils.getAsciiBytes(filename)); - out.write(QUOTE_BYTES); - } - } - - /** - * Write the data in "source" to the specified stream. - * @param out The output stream. - * @throws IOException if an IO problem occurs. - * @see Part#sendData(OutputStream) - */ - @Override - protected void sendData(OutputStream out) throws IOException { - if (lengthOfData() == 0) { - - // this file contains no data, so there is nothing to send. - // we don't want to create a zero length buffer as this will - // cause an infinite loop when reading. - return; - } - - byte[] tmp = new byte[4096]; - InputStream instream = source.createInputStream(); - try { - int len; - while ((len = instream.read(tmp)) >= 0) { - out.write(tmp, 0, len); - } - } finally { - // we're done with the stream, close it - instream.close(); - } - } - - /** - * Returns the source of the file part. - * - * @return The source. - */ - protected PartSource getSource() { - return this.source; - } - - /** - * Return the length of the data. - * @return The length. - * @see Part#lengthOfData() - */ - @Override - protected long lengthOfData() { - return source.getLength(); - } - -} diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/FilePartSource.java b/app/src/main/java/com/android/internalcopy/http/multipart/FilePartSource.java deleted file mode 100644 index 813ccbf3..00000000 --- a/app/src/main/java/com/android/internalcopy/http/multipart/FilePartSource.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePartSource.java,v 1.10 2004/04/18 23:51:37 jsdever Exp $ - * $Revision: 480424 $ - * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package com.android.internalcopy.http.multipart; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - -/** - * A PartSource that reads from a File. - * - * @author Michael Becke - * @author Mark Diggory - * @author Mike Bowler - * - * @since 2.0 - */ -public class FilePartSource implements PartSource { - - /** File part file. */ - private File file = null; - - /** File part file name. */ - private String fileName = null; - - /** - * Constructor for FilePartSource. - * - * @param file the FilePart source File. - * - * @throws FileNotFoundException if the file does not exist or - * cannot be read - */ - public FilePartSource(File file) throws FileNotFoundException { - this.file = file; - if (file != null) { - if (!file.isFile()) { - throw new FileNotFoundException("File is not a normal file."); - } - if (!file.canRead()) { - throw new FileNotFoundException("File is not readable."); - } - this.fileName = file.getName(); - } - } - - /** - * Constructor for FilePartSource. - * - * @param fileName the file name of the FilePart - * @param file the source File for the FilePart - * - * @throws FileNotFoundException if the file does not exist or - * cannot be read - */ - public FilePartSource(String fileName, File file) - throws FileNotFoundException { - this(file); - if (fileName != null) { - this.fileName = fileName; - } - } - - /** - * Return the length of the file - * @return the length of the file. - * @see PartSource#getLength() - */ - public long getLength() { - if (this.file != null) { - return this.file.length(); - } else { - return 0; - } - } - - /** - * Return the current filename - * @return the filename. - * @see PartSource#getFileName() - */ - public String getFileName() { - return (fileName == null) ? "noname" : fileName; - } - - /** - * Return a new {@link FileInputStream} for the current filename. - * @return the new input stream. - * @throws IOException If an IO problem occurs. - * @see PartSource#createInputStream() - */ - public InputStream createInputStream() throws IOException { - if (this.file != null) { - return new FileInputStream(this.file); - } else { - return new ByteArrayInputStream(new byte[] {}); - } - } - -} diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/MultipartEntity.java b/app/src/main/java/com/android/internalcopy/http/multipart/MultipartEntity.java deleted file mode 100644 index 9af47175..00000000 --- a/app/src/main/java/com/android/internalcopy/http/multipart/MultipartEntity.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/MultipartRequestEntity.java,v 1.1 2004/10/06 03:39:59 mbecke Exp $ - * $Revision: 502647 $ - * $Date: 2007-02-02 17:22:54 +0100 (Fri, 02 Feb 2007) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package com.android.internalcopy.http.multipart; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Random; - -import org.apache.http.Header; -import org.apache.http.entity.AbstractHttpEntity; -import org.apache.http.message.BasicHeader; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.HTTP; -import org.apache.http.util.EncodingUtils; - -/** - * Implements a request entity suitable for an HTTP multipart POST method. - *

- * The HTTP multipart POST method is defined in section 3.3 of - * RFC1867: - *

- * The media-type multipart/form-data follows the rules of all multipart - * MIME data streams as outlined in RFC 1521. The multipart/form-data contains - * a series of parts. Each part is expected to contain a content-disposition - * header where the value is "form-data" and a name attribute specifies - * the field name within the form, e.g., 'content-disposition: form-data; - * name="xxxxx"', where xxxxx is the field name corresponding to that field. - * Field names originally in non-ASCII character sets may be encoded using - * the method outlined in RFC 1522. - *
- *

- *

This entity is designed to be used in conjunction with the - * {@link org.apache.http.HttpRequest} to provide - * multipart posts. Example usage:

- *
- *  File f = new File("/path/fileToUpload.txt");
- *  HttpRequest request = new HttpRequest("http://host/some_path");
- *  Part[] parts = {
- *      new StringPart("param_name", "value"),
- *      new FilePart(f.getName(), f)
- *  };
- *  filePost.setEntity(
- *      new MultipartRequestEntity(parts, filePost.getParams())
- *      );
- *  HttpClient client = new HttpClient();
- *  int status = client.executeMethod(filePost);
- * 
- * - * @since 3.0 - */ -public class MultipartEntity extends AbstractHttpEntity { - - /** The Content-Type for multipart/form-data. */ - private static final String MULTIPART_FORM_CONTENT_TYPE = "multipart/form-data"; - - /** - * Sets the value to use as the multipart boundary. - *

- * This parameter expects a value if type {@link String}. - *

- */ - public static final String MULTIPART_BOUNDARY = "http.method.multipart.boundary"; - - /** - * The pool of ASCII chars to be used for generating a multipart boundary. - */ - private static byte[] MULTIPART_CHARS = EncodingUtils.getAsciiBytes( - "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); - - /** - * Generates a random multipart boundary string. - */ - private static byte[] generateMultipartBoundary() { - Random rand = new Random(); - byte[] bytes = new byte[rand.nextInt(11) + 30]; // a random size from 30 to 40 - for (int i = 0; i < bytes.length; i++) { - bytes[i] = MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]; - } - return bytes; - } - - /** The MIME parts as set by the constructor */ - protected Part[] parts; - - private byte[] multipartBoundary; - - private HttpParams params; - - private boolean contentConsumed = false; - - /** - * Creates a new multipart entity containing the given parts. - * @param parts The parts to include. - * @param params The params of the HttpMethod using this entity. - */ - public MultipartEntity(Part[] parts, HttpParams params) { - if (parts == null) { - throw new IllegalArgumentException("parts cannot be null"); - } - if (params == null) { - throw new IllegalArgumentException("params cannot be null"); - } - this.parts = parts; - this.params = params; - } - - public MultipartEntity(Part[] parts) { - setContentType(MULTIPART_FORM_CONTENT_TYPE); - if (parts == null) { - throw new IllegalArgumentException("parts cannot be null"); - } - this.parts = parts; - this.params = null; - } - - /** - * Returns the MIME boundary string that is used to demarcate boundaries of - * this part. The first call to this method will implicitly create a new - * boundary string. To create a boundary string first the - * HttpMethodParams.MULTIPART_BOUNDARY parameter is considered. Otherwise - * a random one is generated. - * - * @return The boundary string of this entity in ASCII encoding. - */ - protected byte[] getMultipartBoundary() { - if (multipartBoundary == null) { - String temp = null; - if (params != null) { - temp = (String) params.getParameter(MULTIPART_BOUNDARY); - } - if (temp != null) { - multipartBoundary = EncodingUtils.getAsciiBytes(temp); - } else { - multipartBoundary = generateMultipartBoundary(); - } - } - return multipartBoundary; - } - - /** - * Returns true if all parts are repeatable, false otherwise. - */ - public boolean isRepeatable() { - for (int i = 0; i < parts.length; i++) { - if (!parts[i].isRepeatable()) { - return false; - } - } - return true; - } - - /* (non-Javadoc) - */ - public void writeTo(OutputStream out) throws IOException { - Part.sendParts(out, parts, getMultipartBoundary()); - } - /* (non-Javadoc) - * @see org.apache.commons.http.AbstractHttpEntity.#getContentType() - */ - @Override - public Header getContentType() { - StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE); - buffer.append("; boundary="); - buffer.append(EncodingUtils.getAsciiString(getMultipartBoundary())); - return new BasicHeader(HTTP.CONTENT_TYPE, buffer.toString()); - - } - - /* (non-Javadoc) - */ - public long getContentLength() { - try { - return Part.getLengthOfParts(parts, getMultipartBoundary()); - } catch (Exception e) { - return 0; - } - } - - public InputStream getContent() throws IOException, IllegalStateException { - if(!isRepeatable() && this.contentConsumed ) { - throw new IllegalStateException("Content has been consumed"); - } - this.contentConsumed = true; - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Part.sendParts(baos, this.parts, this.multipartBoundary); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - return bais; - } - - public boolean isStreaming() { - return false; - } -} diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/Part.java b/app/src/main/java/com/android/internalcopy/http/multipart/Part.java deleted file mode 100644 index aa667715..00000000 --- a/app/src/main/java/com/android/internalcopy/http/multipart/Part.java +++ /dev/null @@ -1,425 +0,0 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/Part.java,v 1.16 2005/01/14 21:16:40 olegk Exp $ - * $Revision: 480424 $ - * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package com.android.internalcopy.http.multipart; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.http.util.EncodingUtils; - -/** - * Abstract class for one Part of a multipart post object. - * - * @author Matthew Albright - * @author Jeff Dever - * @author Adrian Sutton - * @author Mike Bowler - * @author Oleg Kalnichevski - * - * @since 2.0 - */ -public abstract class Part { - - /** - * The boundary - * @deprecated use {@link org.apache.http.client.methods.multipart#MULTIPART_BOUNDARY} - */ - protected static final String BOUNDARY = "----------------314159265358979323846"; - - /** - * The boundary as a byte array. - * @deprecated - */ - protected static final byte[] BOUNDARY_BYTES = EncodingUtils.getAsciiBytes(BOUNDARY); - - /** - * The default boundary to be used if {@link #setPartBoundary(byte[])} has not - * been called. - */ - private static final byte[] DEFAULT_BOUNDARY_BYTES = BOUNDARY_BYTES; - - /** Carriage return/linefeed */ - protected static final String CRLF = "\r\n"; - - /** Carriage return/linefeed as a byte array */ - protected static final byte[] CRLF_BYTES = EncodingUtils.getAsciiBytes(CRLF); - - /** Content dispostion characters */ - protected static final String QUOTE = "\""; - - /** Content dispostion as a byte array */ - protected static final byte[] QUOTE_BYTES = - EncodingUtils.getAsciiBytes(QUOTE); - - /** Extra characters */ - protected static final String EXTRA = "--"; - - /** Extra characters as a byte array */ - protected static final byte[] EXTRA_BYTES = - EncodingUtils.getAsciiBytes(EXTRA); - - /** Content dispostion characters */ - protected static final String CONTENT_DISPOSITION = "Content-Disposition: form-data; name="; - - /** Content dispostion as a byte array */ - protected static final byte[] CONTENT_DISPOSITION_BYTES = - EncodingUtils.getAsciiBytes(CONTENT_DISPOSITION); - - /** Content type header */ - protected static final String CONTENT_TYPE = "Content-Type: "; - - /** Content type header as a byte array */ - protected static final byte[] CONTENT_TYPE_BYTES = - EncodingUtils.getAsciiBytes(CONTENT_TYPE); - - /** Content charset */ - protected static final String CHARSET = "; charset="; - - /** Content charset as a byte array */ - protected static final byte[] CHARSET_BYTES = - EncodingUtils.getAsciiBytes(CHARSET); - - /** Content type header */ - protected static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding: "; - - /** Content type header as a byte array */ - protected static final byte[] CONTENT_TRANSFER_ENCODING_BYTES = - EncodingUtils.getAsciiBytes(CONTENT_TRANSFER_ENCODING); - - /** - * Return the boundary string. - * @return the boundary string - * @deprecated uses a constant string. Rather use {@link #getPartBoundary} - */ - public static String getBoundary() { - return BOUNDARY; - } - - /** - * The ASCII bytes to use as the multipart boundary. - */ - private byte[] boundaryBytes; - - /** - * Return the name of this part. - * @return The name. - */ - public abstract String getName(); - - /** - * Returns the content type of this part. - * @return the content type, or null to exclude the content type header - */ - public abstract String getContentType(); - - /** - * Return the character encoding of this part. - * @return the character encoding, or null to exclude the character - * encoding header - */ - public abstract String getCharSet(); - - /** - * Return the transfer encoding of this part. - * @return the transfer encoding, or null to exclude the transfer encoding header - */ - public abstract String getTransferEncoding(); - - /** - * Gets the part boundary to be used. - * @return the part boundary as an array of bytes. - * - * @since 3.0 - */ - protected byte[] getPartBoundary() { - if (boundaryBytes == null) { - // custom boundary bytes have not been set, use the default. - return DEFAULT_BOUNDARY_BYTES; - } else { - return boundaryBytes; - } - } - - /** - * Sets the part boundary. Only meant to be used by - * {@link Part#sendParts(OutputStream, Part[], byte[])} - * and {@link Part#getLengthOfParts(Part[], byte[])} - * @param boundaryBytes An array of ASCII bytes. - * @since 3.0 - */ - void setPartBoundary(byte[] boundaryBytes) { - this.boundaryBytes = boundaryBytes; - } - - /** - * Tests if this part can be sent more than once. - * @return true if {@link #sendData(OutputStream)} can be successfully called - * more than once. - * @since 3.0 - */ - public boolean isRepeatable() { - return true; - } - - /** - * Write the start to the specified output stream - * @param out The output stream - * @throws IOException If an IO problem occurs. - */ - protected void sendStart(OutputStream out) throws IOException { - out.write(EXTRA_BYTES); - out.write(getPartBoundary()); - out.write(CRLF_BYTES); - } - - /** - * Write the content disposition header to the specified output stream - * - * @param out The output stream - * @throws IOException If an IO problem occurs. - */ - protected void sendDispositionHeader(OutputStream out) throws IOException { - out.write(CONTENT_DISPOSITION_BYTES); - out.write(QUOTE_BYTES); - out.write(EncodingUtils.getAsciiBytes(getName())); - out.write(QUOTE_BYTES); - } - - /** - * Write the content type header to the specified output stream - * @param out The output stream - * @throws IOException If an IO problem occurs. - */ - protected void sendContentTypeHeader(OutputStream out) throws IOException { - String contentType = getContentType(); - if (contentType != null) { - out.write(CRLF_BYTES); - out.write(CONTENT_TYPE_BYTES); - out.write(EncodingUtils.getAsciiBytes(contentType)); - String charSet = getCharSet(); - if (charSet != null) { - out.write(CHARSET_BYTES); - out.write(EncodingUtils.getAsciiBytes(charSet)); - } - } - } - - /** - * Write the content transfer encoding header to the specified - * output stream - * - * @param out The output stream - * @throws IOException If an IO problem occurs. - */ - protected void sendTransferEncodingHeader(OutputStream out) throws IOException { - String transferEncoding = getTransferEncoding(); - if (transferEncoding != null) { - out.write(CRLF_BYTES); - out.write(CONTENT_TRANSFER_ENCODING_BYTES); - out.write(EncodingUtils.getAsciiBytes(transferEncoding)); - } - } - - /** - * Write the end of the header to the output stream - * @param out The output stream - * @throws IOException If an IO problem occurs. - */ - protected void sendEndOfHeader(OutputStream out) throws IOException { - out.write(CRLF_BYTES); - out.write(CRLF_BYTES); - } - - /** - * Write the data to the specified output stream - * @param out The output stream - * @throws IOException If an IO problem occurs. - */ - protected abstract void sendData(OutputStream out) throws IOException; - - /** - * Return the length of the main content - * - * @return long The length. - * @throws IOException If an IO problem occurs - */ - protected abstract long lengthOfData() throws IOException; - - /** - * Write the end data to the output stream. - * @param out The output stream - * @throws IOException If an IO problem occurs. - */ - protected void sendEnd(OutputStream out) throws IOException { - out.write(CRLF_BYTES); - } - - /** - * Write all the data to the output stream. - * If you override this method make sure to override - * #length() as well - * - * @param out The output stream - * @throws IOException If an IO problem occurs. - */ - public void send(OutputStream out) throws IOException { - sendStart(out); - sendDispositionHeader(out); - sendContentTypeHeader(out); - sendTransferEncodingHeader(out); - sendEndOfHeader(out); - sendData(out); - sendEnd(out); - } - - - /** - * Return the full length of all the data. - * If you override this method make sure to override - * #send(OutputStream) as well - * - * @return long The length. - * @throws IOException If an IO problem occurs - */ - public long length() throws IOException { - if (lengthOfData() < 0) { - return -1; - } - ByteArrayOutputStream overhead = new ByteArrayOutputStream(); - sendStart(overhead); - sendDispositionHeader(overhead); - sendContentTypeHeader(overhead); - sendTransferEncodingHeader(overhead); - sendEndOfHeader(overhead); - sendEnd(overhead); - return overhead.size() + lengthOfData(); - } - - /** - * Return a string representation of this object. - * @return A string representation of this object. - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return this.getName(); - } - - /** - * Write all parts and the last boundary to the specified output stream. - * - * @param out The stream to write to. - * @param parts The parts to write. - * - * @throws IOException If an I/O error occurs while writing the parts. - */ - public static void sendParts(OutputStream out, final Part[] parts) - throws IOException { - sendParts(out, parts, DEFAULT_BOUNDARY_BYTES); - } - - /** - * Write all parts and the last boundary to the specified output stream. - * - * @param out The stream to write to. - * @param parts The parts to write. - * @param partBoundary The ASCII bytes to use as the part boundary. - * - * @throws IOException If an I/O error occurs while writing the parts. - * - * @since 3.0 - */ - public static void sendParts(OutputStream out, Part[] parts, byte[] partBoundary) - throws IOException { - - if (parts == null) { - throw new IllegalArgumentException("Parts may not be null"); - } - if (partBoundary == null || partBoundary.length == 0) { - throw new IllegalArgumentException("partBoundary may not be empty"); - } - for (int i = 0; i < parts.length; i++) { - // set the part boundary before the part is sent - parts[i].setPartBoundary(partBoundary); - parts[i].send(out); - } - out.write(EXTRA_BYTES); - out.write(partBoundary); - out.write(EXTRA_BYTES); - out.write(CRLF_BYTES); - } - - /** - * Return the total sum of all parts and that of the last boundary - * - * @param parts The parts. - * @return The total length - * - * @throws IOException If an I/O error occurs while writing the parts. - */ - public static long getLengthOfParts(Part[] parts) - throws IOException { - return getLengthOfParts(parts, DEFAULT_BOUNDARY_BYTES); - } - - /** - * Gets the length of the multipart message including the given parts. - * - * @param parts The parts. - * @param partBoundary The ASCII bytes to use as the part boundary. - * @return The total length - * - * @throws IOException If an I/O error occurs while writing the parts. - * - * @since 3.0 - */ - public static long getLengthOfParts(Part[] parts, byte[] partBoundary) throws IOException { - if (parts == null) { - throw new IllegalArgumentException("Parts may not be null"); - } - long total = 0; - for (int i = 0; i < parts.length; i++) { - // set the part boundary before we calculate the part's length - parts[i].setPartBoundary(partBoundary); - long l = parts[i].length(); - if (l < 0) { - return -1; - } - total += l; - } - total += EXTRA_BYTES.length; - total += partBoundary.length; - total += EXTRA_BYTES.length; - total += CRLF_BYTES.length; - return total; - } -} diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/PartBase.java b/app/src/main/java/com/android/internalcopy/http/multipart/PartBase.java deleted file mode 100644 index 82896472..00000000 --- a/app/src/main/java/com/android/internalcopy/http/multipart/PartBase.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/PartBase.java,v 1.5 2004/04/18 23:51:37 jsdever Exp $ - * $Revision: 480424 $ - * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package com.android.internalcopy.http.multipart; - - -/** - * Provides setters and getters for the basic Part properties. - * - * @author Michael Becke - */ -public abstract class PartBase extends Part { - - /** Name of the file part. */ - private String name; - - /** Content type of the file part. */ - private String contentType; - - /** Content encoding of the file part. */ - private String charSet; - - /** The transfer encoding. */ - private String transferEncoding; - - /** - * Constructor. - * - * @param name The name of the part - * @param contentType The content type, or null - * @param charSet The character encoding, or null - * @param transferEncoding The transfer encoding, or null - */ - public PartBase(String name, String contentType, String charSet, String transferEncoding) { - - if (name == null) { - throw new IllegalArgumentException("Name must not be null"); - } - this.name = name; - this.contentType = contentType; - this.charSet = charSet; - this.transferEncoding = transferEncoding; - } - - /** - * Returns the name. - * @return The name. - * @see Part#getName() - */ - @Override - public String getName() { - return this.name; - } - - /** - * Returns the content type of this part. - * @return String The name. - */ - @Override - public String getContentType() { - return this.contentType; - } - - /** - * Return the character encoding of this part. - * @return String The name. - */ - @Override - public String getCharSet() { - return this.charSet; - } - - /** - * Returns the transfer encoding of this part. - * @return String The name. - */ - @Override - public String getTransferEncoding() { - return transferEncoding; - } - - /** - * Sets the character encoding. - * - * @param charSet the character encoding, or null to exclude the character - * encoding header - */ - public void setCharSet(String charSet) { - this.charSet = charSet; - } - - /** - * Sets the content type. - * - * @param contentType the content type, or null to exclude the content type header - */ - public void setContentType(String contentType) { - this.contentType = contentType; - } - - /** - * Sets the part name. - * - * @param name - */ - public void setName(String name) { - if (name == null) { - throw new IllegalArgumentException("Name must not be null"); - } - this.name = name; - } - - /** - * Sets the transfer encoding. - * - * @param transferEncoding the transfer encoding, or null to exclude the - * transfer encoding header - */ - public void setTransferEncoding(String transferEncoding) { - this.transferEncoding = transferEncoding; - } - -} diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/PartSource.java b/app/src/main/java/com/android/internalcopy/http/multipart/PartSource.java deleted file mode 100644 index 8fec3aa9..00000000 --- a/app/src/main/java/com/android/internalcopy/http/multipart/PartSource.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/PartSource.java,v 1.6 2004/04/18 23:51:37 jsdever Exp $ - * $Revision: 480424 $ - * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package com.android.internalcopy.http.multipart; - -import java.io.IOException; -import java.io.InputStream; - -/** - * An interface for providing access to data when posting MultiPart messages. - * - * @see FilePart - * - * @author Michael Becke - * - * @since 2.0 - */ -public interface PartSource { - - /** - * Gets the number of bytes contained in this source. - * - * @return a value >= 0 - */ - long getLength(); - - /** - * Gets the name of the file this source represents. - * - * @return the fileName used for posting a MultiPart file part - */ - String getFileName(); - - /** - * Gets a new InputStream for reading this source. This method can be - * called more than once and should therefore return a new stream every - * time. - * - * @return a new InputStream - * - * @throws IOException if an error occurs when creating the InputStream - */ - InputStream createInputStream() throws IOException; - -} diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/StringPart.java b/app/src/main/java/com/android/internalcopy/http/multipart/StringPart.java deleted file mode 100644 index c613c771..00000000 --- a/app/src/main/java/com/android/internalcopy/http/multipart/StringPart.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/StringPart.java,v 1.11 2004/04/18 23:51:37 jsdever Exp $ - * $Revision: 480424 $ - * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package com.android.internalcopy.http.multipart; - -import java.io.OutputStream; -import java.io.IOException; - -import org.apache.http.util.EncodingUtils; - -/** - * Simple string parameter for a multipart post - * - * @author Matthew Albright - * @author Jeff Dever - * @author Mike Bowler - * @author Oleg Kalnichevski - * - * @since 2.0 - */ -public class StringPart extends PartBase { - - /** Default content encoding of string parameters. */ - public static final String DEFAULT_CONTENT_TYPE = "text/plain"; - - /** Default charset of string parameters*/ - public static final String DEFAULT_CHARSET = "US-ASCII"; - - /** Default transfer encoding of string parameters*/ - public static final String DEFAULT_TRANSFER_ENCODING = "8bit"; - - /** Contents of this StringPart. */ - private byte[] content; - - /** The String value of this part. */ - private String value; - - /** - * Constructor. - * - * @param name The name of the part - * @param value the string to post - * @param charset the charset to be used to encode the string, if null - * the {@link #DEFAULT_CHARSET default} is used - */ - public StringPart(String name, String value, String charset) { - - super( - name, - DEFAULT_CONTENT_TYPE, - charset == null ? DEFAULT_CHARSET : charset, - DEFAULT_TRANSFER_ENCODING - ); - if (value == null) { - throw new IllegalArgumentException("Value may not be null"); - } - if (value.indexOf(0) != -1) { - // See RFC 2048, 2.8. "8bit Data" - throw new IllegalArgumentException("NULs may not be present in string parts"); - } - this.value = value; - } - - /** - * Constructor. - * - * @param name The name of the part - * @param value the string to post - */ - public StringPart(String name, String value) { - this(name, value, null); - } - - /** - * Gets the content in bytes. Bytes are lazily created to allow the charset to be changed - * after the part is created. - * - * @return the content in bytes - */ - private byte[] getContent() { - if (content == null) { - content = EncodingUtils.getBytes(value, getCharSet()); - } - return content; - } - - /** - * Writes the data to the given OutputStream. - * @param out the OutputStream to write to - * @throws IOException if there is a write error - */ - @Override - protected void sendData(OutputStream out) throws IOException { - out.write(getContent()); - } - - /** - * Return the length of the data. - * @return The length of the data. - * @see Part#lengthOfData() - */ - @Override - protected long lengthOfData() { - return getContent().length; - } - - /* (non-Javadoc) - * @see org.apache.commons.httpclient.methods.multipart.BasePart#setCharSet(java.lang.String) - */ - @Override - public void setCharSet(String charSet) { - super.setCharSet(charSet); - this.content = null; - } - -} diff --git a/app/src/main/java/de/timroes/axmlrpc/Call.java b/app/src/main/java/de/timroes/axmlrpc/Call.java index de393ec5..26bfabe4 100644 --- a/app/src/main/java/de/timroes/axmlrpc/Call.java +++ b/app/src/main/java/de/timroes/axmlrpc/Call.java @@ -16,13 +16,14 @@ public class Call { private String method; private Object[] params; + private final SerializerHandler serializerHandler; /** * Create a new method call with the given name and no parameters. * @param method The method to be called. */ - public Call(String method) { - this(method, null); + public Call(SerializerHandler serializerHandler, String method) { + this(serializerHandler, method, null); } /** @@ -30,9 +31,10 @@ public class Call { * @param method The method to be called. * @param params An array of parameters for the method. */ - public Call(String method, Object[] params) { + public Call(SerializerHandler serializerHandler, String method, Object[] params) { this.method = method; this.params = params; + this.serializerHandler = serializerHandler; } /** @@ -57,11 +59,11 @@ public class Call { methodCall.addChildren(methodName); if(params != null && params.length > 0) { - XmlElement params = new XmlElement(XMLRPCClient.PARAMS); - methodCall.addChildren(params); + XmlElement callParams = new XmlElement(XMLRPCClient.PARAMS); + methodCall.addChildren(callParams); for(Object o : this.params) { - params.addChildren(getXMLParam(o)); + callParams.addChildren(getXMLParam(o)); } } @@ -79,7 +81,7 @@ public class Call { XmlElement param = new XmlElement(XMLRPCClient.PARAM); XmlElement value = new XmlElement(XMLRPCClient.VALUE); param.addChildren(value); - value.addChildren(SerializerHandler.getDefault().serialize(o)); + value.addChildren(serializerHandler.serialize(o)); return param; } diff --git a/app/src/main/java/de/timroes/axmlrpc/ResponseParser.java b/app/src/main/java/de/timroes/axmlrpc/ResponseParser.java index c58b13d3..c47d2240 100644 --- a/app/src/main/java/de/timroes/axmlrpc/ResponseParser.java +++ b/app/src/main/java/de/timroes/axmlrpc/ResponseParser.java @@ -16,7 +16,7 @@ import org.xmlpull.v1.XmlPullParserFactory; * * @author Tim Roes */ -class ResponseParser { +public class ResponseParser { private static final String FAULT_CODE = "faultCode"; private static final String FAULT_STRING = "faultString"; @@ -71,13 +71,13 @@ class ResponseParser { pullParser.nextTag(); // TAG_VALUE () // no parser.require() here since its called in XMLRPCSerializer.deserialize() below // deserialize result - Object obj = SerializerHandler.getDefault().deserialize(pullParser); + Object obj = SerializerHandler.deserialize(pullParser); consumeHttpEntity(response, entity); return obj; } else if (tag.equals(XMLRPCClient.FAULT)) { // fault response pullParser.nextTag(); // TAG_VALUE () - Map map = (Map) SerializerHandler.getDefault().deserialize(pullParser); + Map map = (Map) SerializerHandler.deserialize(pullParser); consumeHttpEntity(response, entity); //Check that required tags are in the response @@ -92,12 +92,11 @@ class ResponseParser { } catch (XmlPullParserException ex) { consumeHttpEntity(response, entity); throw new XMLRPCException("Error parsing response.", ex); + } catch(XMLRPCServerException e) { + throw e; } catch (Exception ex) { consumeHttpEntity(response, entity); - if(ex instanceof XMLRPCServerException) - throw (XMLRPCServerException)ex; - else - throw new XMLRPCException("Error getting result from server.", ex); + throw new XMLRPCException("Error getting result from server.", ex); } } -} \ No newline at end of file +} diff --git a/app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java b/app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java index f6003f87..317e3e07 100644 --- a/app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java +++ b/app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java @@ -127,6 +127,11 @@ public class XMLRPCClient { */ public static final int FLAGS_NO_STRING_ENCODE = 0x1000; + /** + * Accepts response containing eg: + */ + public static final int FLAGS_ACCEPT_NULL_DATES = 0x4000; + /** * This flag should be used if the server is an apache ws xmlrpc server. * This will set some flags, so that the not standard conform behavior @@ -140,28 +145,30 @@ public class XMLRPCClient { private final int flags; private DefaultHttpClient httpclient; - + private String url; private Map backgroundCalls = new ConcurrentHashMap(); private ResponseParser responseParser; + private final SerializerHandler serializerHandler; + /** * Create a new XMLRPC client for the given URL. - * + * * @param httpclient The already-initialized Apache HttpClient to use for connection. * @param url The URL to send the requests to. * @param flags A combination of flags to be set. */ public XMLRPCClient(DefaultHttpClient httpclient, String url, int flags) { - SerializerHandler.initialize(flags); + this.serializerHandler = new SerializerHandler(flags); this.httpclient = httpclient; this.url = url; this.flags = flags; - + // Create a parser for the http responses. responseParser = new ResponseParser(); @@ -260,7 +267,7 @@ public class XMLRPCClient { throw new XMLRPCRuntimeException("Method name must only contain A-Z a-z . : _ / "); } - return new Call(method, params); + return new Call(serializerHandler, method, params); } @@ -368,7 +375,7 @@ public class XMLRPCClient { try { Call c = createCall(methodName, params); - + // Prepare POST request // FIXME: where creating a new HttpPost so calling #cancel isn't going to do anything HttpPost post = new HttpPost(url); @@ -377,10 +384,10 @@ public class XMLRPCClient { StringEntity entity = new StringEntity(c.getXML(), HTTP.UTF_8); entity.setContentType(TYPE_XML); post.setEntity(entity); - + HttpResponse response = httpclient.execute(post); int statusCode = response.getStatusLine().getStatusCode(); - + InputStream istream; // If status code was 401 or 403 throw exception or if appropriate @@ -406,7 +413,7 @@ public class XMLRPCClient { || statusCode == HttpURLConnection.HTTP_MOVED_TEMP) { // ... do either a foward if(isFlagSet(FLAGS_FORWARD)) { - boolean temporaryForward = (statusCode == HttpURLConnection.HTTP_MOVED_TEMP); + boolean temporaryForward = statusCode == HttpURLConnection.HTTP_MOVED_TEMP; // Get new location from header field. String newLocation = response.getFirstHeader("Location").getValue(); @@ -440,10 +447,8 @@ public class XMLRPCClient { } // Check for strict parameters - if(isFlagSet(FLAGS_STRICT)) { - if(!response.getFirstHeader("Content-Type").getValue().startsWith(TYPE_XML)) { + if(isFlagSet(FLAGS_STRICT) && !response.getFirstHeader("Content-Type").getValue().startsWith(TYPE_XML)) { throw new XMLRPCException("The Content-Type of the response must be text/xml."); - } } return responseParser.parse(istream, entity); @@ -462,9 +467,9 @@ public class XMLRPCClient { } } - + } - + public static class CancelException extends Exception { private static final long serialVersionUID = 9125122307255855136L; } @@ -475,5 +480,5 @@ public class XMLRPCClient { public UnauthorizdException(int statusCode) { this.statusCode = statusCode; } public int getStatusCode() { return statusCode; } } - + } diff --git a/app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java b/app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java index 0b403e93..20bccca2 100644 --- a/app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java +++ b/app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java @@ -8,7 +8,7 @@ package de.timroes.axmlrpc; */ public class XMLRPCServerException extends XMLRPCException { - private int errornr; + private final int errornr; public XMLRPCServerException(String ex, int errnr) { super(ex); diff --git a/app/src/main/java/de/timroes/axmlrpc/XMLUtil.java b/app/src/main/java/de/timroes/axmlrpc/XMLUtil.java index 7e444591..6cc97643 100644 --- a/app/src/main/java/de/timroes/axmlrpc/XMLUtil.java +++ b/app/src/main/java/de/timroes/axmlrpc/XMLUtil.java @@ -9,6 +9,8 @@ import de.timroes.axmlrpc.xmlcreator.XmlElement; */ public class XMLUtil { + private XMLUtil() {} + /** * Creates an xml tag with a given type and content. * @@ -22,4 +24,4 @@ public class XMLUtil { return xml; } -} \ No newline at end of file +} diff --git a/app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java b/app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java index d1b054fe..8789fa3d 100644 --- a/app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java +++ b/app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java @@ -3,6 +3,7 @@ package de.timroes.axmlrpc.serializer; import de.timroes.axmlrpc.XMLRPCException; import de.timroes.axmlrpc.XMLRPCRuntimeException; import de.timroes.axmlrpc.xmlcreator.XmlElement; +import java.util.Arrays; /** * @@ -12,10 +13,20 @@ public class ArraySerializer implements Serializer { private static final String ARRAY_DATA = "data"; private static final String ARRAY_VALUE = "value"; + private final SerializerHandler serializerHandler; + + public ArraySerializer(SerializerHandler serializerHandler){ + this.serializerHandler = serializerHandler; + } public XmlElement serialize(Object object) { - Iterable iter = (Iterable)object; + Iterable iter; + if ( object instanceof Iterable){ + iter = (Iterable)object; + } else { + iter = Arrays.asList((Object[]) object); + } XmlElement array = new XmlElement(SerializerHandler.TYPE_ARRAY); XmlElement data = new XmlElement(ARRAY_DATA); array.addChildren(data); @@ -25,7 +36,7 @@ public class ArraySerializer implements Serializer { XmlElement e; for(Object obj : iter) { e = new XmlElement(ARRAY_VALUE); - e.addChildren(SerializerHandler.getDefault().serialize(obj)); + e.addChildren(serializerHandler.serialize(obj)); data.addChildren(e); } @@ -37,4 +48,4 @@ public class ArraySerializer implements Serializer { } -} \ No newline at end of file +} diff --git a/app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java b/app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java index f64a7f4e..c85162cd 100644 --- a/app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java +++ b/app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java @@ -11,7 +11,7 @@ public class BooleanSerializer implements Serializer { public XmlElement serialize(Object object) { return XMLUtil.makeXmlTag(SerializerHandler.TYPE_BOOLEAN, - ((Boolean)object == true) ? "1" : "0"); + (Boolean) object ? "1" : "0"); } -} \ No newline at end of file +} diff --git a/app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java b/app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java index 8c19f0f3..7cb67c6e 100644 --- a/app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java +++ b/app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java @@ -10,9 +10,15 @@ import java.text.SimpleDateFormat; */ public class DateTimeSerializer implements Serializer { - public static final String DATETIME_FORMAT = "yyyyMMdd'T'HH:mm:ss"; + public static final String DATETIME_FORMAT = "yyyyMMdd'T'HHmmss"; public static final SimpleDateFormat DATE_FORMATER = new SimpleDateFormat(DATETIME_FORMAT); + public final boolean accepts_null_input; + + public DateTimeSerializer(boolean accepts_null_input) { + this.accepts_null_input = accepts_null_input; + } + public XmlElement serialize(Object object) { return XMLUtil.makeXmlTag(SerializerHandler.TYPE_DATETIME, DATE_FORMATER.format(object)); diff --git a/app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java b/app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java index 8666183e..9f15e556 100644 --- a/app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java +++ b/app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java @@ -2,7 +2,6 @@ package de.timroes.axmlrpc.serializer; import de.timroes.axmlrpc.XMLRPCClient; import de.timroes.axmlrpc.XMLRPCException; -import de.timroes.axmlrpc.XMLRPCRuntimeException; import de.timroes.axmlrpc.xmlcreator.XmlElement; import java.io.BufferedReader; @@ -60,54 +59,29 @@ public class SerializerHandler { public static final String TYPE_BASE64 = "base64"; public static final String TYPE_NULL = "nil"; - private static SerializerHandler instance; - - /** - * Initialize the serialization handler. This method must be called before - * the get method returns any object. - * - * @param flags The flags that has been set in the XMLRPCClient. - * @see XMLRPCClient - */ - public static void initialize(int flags) { - instance = new SerializerHandler(flags); - } - - /** - * Return the instance of the SerializerHandler. - * It must have been initialized with initialize() before. - * - * @return The instance of the SerializerHandler. - */ - public static SerializerHandler getDefault() { - if(instance == null) { - throw new XMLRPCRuntimeException("The SerializerHandler has not been initialized."); - } - return instance; - } - private StringSerializer string; private BooleanSerializer bool = new BooleanSerializer(); private IntSerializer integer = new IntSerializer(); private LongSerializer long8 = new LongSerializer(); - private StructSerializer struct = new StructSerializer(); + private StructSerializer struct; private DoubleSerializer floating = new DoubleSerializer(); - private DateTimeSerializer datetime = new DateTimeSerializer(); - private ArraySerializer array = new ArraySerializer(); + private DateTimeSerializer datetime; + public static boolean accepts_null_input; + public SerializerHandler(boolean accepts_null_input) { + SerializerHandler.accepts_null_input = accepts_null_input; + } + private ArraySerializer array; private Base64Serializer base64 = new Base64Serializer(); private NullSerializer nil = new NullSerializer(); - + private int flags; - /** - * Generates the SerializerHandler. - * This method can only called from within the class (the initialize method). - * - * @param flags The flags to use. - */ - private SerializerHandler(int flags) { + public SerializerHandler(int flags) { this.flags = flags; string = new StringSerializer((flags & XMLRPCClient.FLAGS_NO_STRING_ENCODE) == 0); + struct = new StructSerializer(this); + array = new ArraySerializer(this); + datetime = new DateTimeSerializer((flags & XMLRPCClient.FLAGS_ACCEPT_NULL_DATES) != 0); } /** @@ -152,8 +126,12 @@ public class SerializerHandler { obj = parser.nextText(); } else if (typeNodeName.equals(TYPE_DATE_TIME_ISO8601)) { + dateFormat.setCalendar(cal); String value = parser.nextText(); + if (accepts_null_input && (value==null || value.trim().length()==0)) { + return null; + } try { obj = dateFormat.parseObject(value); } catch (ParseException e) { @@ -232,7 +210,7 @@ public class SerializerHandler { */ public XmlElement serialize(Object object) throws XMLRPCException { - Serializer s = null; + Serializer s; if((flags & XMLRPCClient.FLAGS_NIL) != 0 && object == null) { s = nil; @@ -277,7 +255,7 @@ public class SerializerHandler { s = base64; } else if(object instanceof Byte[]) { s = base64; - } else if(object instanceof Iterable) { + } else if(object instanceof Iterable || object instanceof Object[]) { s = array; } else { throw new XMLRPCException("No serializer found for type '" @@ -288,4 +266,4 @@ public class SerializerHandler { } -} \ No newline at end of file +} diff --git a/app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java b/app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java index 823edad6..c16daff2 100644 --- a/app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java +++ b/app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java @@ -19,9 +19,12 @@ public class StringSerializer implements Serializer { public XmlElement serialize(Object object) { String content = object.toString(); if(encodeStrings) { - content = content.replaceAll("&", "&").replaceAll("<", "<"); + content = content + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll("]]>", "]]>"); } return XMLUtil.makeXmlTag(SerializerHandler.TYPE_STRING, content); } -} \ No newline at end of file +} diff --git a/app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java b/app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java index 722f54a3..34ee8c0d 100644 --- a/app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java +++ b/app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java @@ -15,6 +15,12 @@ public class StructSerializer implements Serializer { private static final String STRUCT_NAME = "name"; private static final String STRUCT_VALUE = "value"; + private final SerializerHandler serializerHandler; + + public StructSerializer(SerializerHandler serializerHandler) { + this.serializerHandler = serializerHandler; + } + public XmlElement serialize(Object object) { XmlElement struct = new XmlElement(SerializerHandler.TYPE_STRUCT); @@ -33,7 +39,7 @@ public class StructSerializer implements Serializer { name = new XmlElement(STRUCT_NAME); value = new XmlElement(STRUCT_VALUE); name.setContent(member.getKey()); - value.addChildren(SerializerHandler.getDefault().serialize(member.getValue())); + value.addChildren(serializerHandler.serialize(member.getValue())); entry.addChildren(name); entry.addChildren(value); struct.addChildren(entry); @@ -46,4 +52,4 @@ public class StructSerializer implements Serializer { return struct; } -} \ No newline at end of file +} diff --git a/app/src/main/java/de/timroes/base64/Base64.java b/app/src/main/java/de/timroes/base64/Base64.java index 24612791..68bc1f35 100644 --- a/app/src/main/java/de/timroes/base64/Base64.java +++ b/app/src/main/java/de/timroes/base64/Base64.java @@ -14,6 +14,8 @@ public class Base64 { private static final HashMap map = new HashMap(); + private Base64() {} + static { for(int i = 0; i < code.length; i++) { map.put(code[i], (byte)i); @@ -44,10 +46,10 @@ public class Base64 { int outi = 0; int b1, b2, b3, b4; for(int i = 0; i < input.length; i+=4) { - b1 = (map.get(input[i]) - 1); - b2 = (map.get(input[i+1]) - 1); - b3 = (map.get(input[i+2]) - 1); - b4 = (map.get(input[i+3]) - 1); + b1 = map.get(input[i]) - 1; + b2 = map.get(input[i+1]) - 1; + b3 = map.get(input[i+2]) - 1; + b4 = map.get(input[i+3]) - 1; out[outi++] = (byte)(b1 << 2 | b2 >>> 4); out[outi++] = (byte)((b2 & 0x0F) << 4 | b3 >>> 2); out[outi++] = (byte)((b3 & 0x03) << 6 | (b4 & 0x3F)); @@ -158,4 +160,4 @@ public class Base64 { return out; } -} \ No newline at end of file +} diff --git a/app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java b/app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java index dbd04276..c31dad08 100644 --- a/app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java +++ b/app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java @@ -14,6 +14,8 @@ * limitations under the License. */ +// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6 + package net.margaritov.preference.colorpicker; import android.graphics.Bitmap; @@ -28,101 +30,102 @@ import android.graphics.drawable.Drawable; * This drawable that draws a simple white and gray chessboard pattern. * It's pattern you will often see as a background behind a * partly transparent image in many applications. + * * @author Daniel Nilsson */ public class AlphaPatternDrawable extends Drawable { - private int mRectangleSize = 10; + private int mRectangleSize = 10; - private Paint mPaint = new Paint(); - private Paint mPaintWhite = new Paint(); - private Paint mPaintGray = new Paint(); + private Paint mPaint = new Paint(); + private Paint mPaintWhite = new Paint(); + private Paint mPaintGray = new Paint(); - private int numRectanglesHorizontal; - private int numRectanglesVertical; + private int numRectanglesHorizontal; + private int numRectanglesVertical; - /** - * Bitmap in which the pattern will be cahched. - */ - private Bitmap mBitmap; + /** + * Bitmap in which the pattern will be cahched. + */ + private Bitmap mBitmap; - public AlphaPatternDrawable(int rectangleSize) { - mRectangleSize = rectangleSize; - mPaintWhite.setColor(0xffffffff); - mPaintGray.setColor(0xffcbcbcb); - } + public AlphaPatternDrawable(int rectangleSize) { + mRectangleSize = rectangleSize; + mPaintWhite.setColor(0xffffffff); + mPaintGray.setColor(0xffcbcbcb); + } - @Override - public void draw(Canvas canvas) { - canvas.drawBitmap(mBitmap, null, getBounds(), mPaint); - } + @Override + public void draw(Canvas canvas) { + canvas.drawBitmap(mBitmap, null, getBounds(), mPaint); + } - @Override - public int getOpacity() { - return 0; - } + @Override + public int getOpacity() { + return 0; + } - @Override - public void setAlpha(int alpha) { - throw new UnsupportedOperationException("Alpha is not supported by this drawwable."); - } + @Override + public void setAlpha(int alpha) { + throw new UnsupportedOperationException("Alpha is not supported by this drawwable."); + } - @Override - public void setColorFilter(ColorFilter cf) { - throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable."); - } + @Override + public void setColorFilter(ColorFilter cf) { + throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable."); + } - @Override - protected void onBoundsChange(Rect bounds) { - super.onBoundsChange(bounds); + @Override + protected void onBoundsChange(Rect bounds) { + super.onBoundsChange(bounds); - int height = bounds.height(); - int width = bounds.width(); + int height = bounds.height(); + int width = bounds.width(); - numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize)); - numRectanglesVertical = (int) Math.ceil(height / mRectangleSize); + numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize)); + numRectanglesVertical = (int) Math.ceil(height / mRectangleSize); - generatePatternBitmap(); + generatePatternBitmap(); - } + } - /** - * This will generate a bitmap with the pattern - * as big as the rectangle we were allow to draw on. - * We do this to chache the bitmap so we don't need to - * recreate it each time draw() is called since it - * takes a few milliseconds. - */ - private void generatePatternBitmap() { + /** + * This will generate a bitmap with the pattern + * as big as the rectangle we were allow to draw on. + * We do this to chache the bitmap so we don't need to + * recreate it each time draw() is called since it + * takes a few milliseconds. + */ + private void generatePatternBitmap() { - if (getBounds().width() <= 0 || getBounds().height() <= 0) { - return; - } + if (getBounds().width() <= 0 || getBounds().height() <= 0) { + return; + } - mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888); - Canvas canvas = new Canvas(mBitmap); + mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888); + Canvas canvas = new Canvas(mBitmap); - Rect r = new Rect(); - boolean verticalStartWhite = true; - for (int i = 0; i <= numRectanglesVertical; i++) { + Rect r = new Rect(); + boolean verticalStartWhite = true; + for (int i = 0; i <= numRectanglesVertical; i++) { - boolean isWhite = verticalStartWhite; - for (int j = 0; j <= numRectanglesHorizontal; j++) { + boolean isWhite = verticalStartWhite; + for (int j = 0; j <= numRectanglesHorizontal; j++) { - r.top = i * mRectangleSize; - r.left = j * mRectangleSize; - r.bottom = r.top + mRectangleSize; - r.right = r.left + mRectangleSize; + r.top = i * mRectangleSize; + r.left = j * mRectangleSize; + r.bottom = r.top + mRectangleSize; + r.right = r.left + mRectangleSize; - canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray); + canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray); - isWhite = !isWhite; - } + isWhite = !isWhite; + } - verticalStartWhite = !verticalStartWhite; + verticalStartWhite = !verticalStartWhite; - } + } - } + } -} \ No newline at end of file +} diff --git a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java index fddf6984..aa0e96fb 100644 --- a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java +++ b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java @@ -14,123 +14,240 @@ * limitations under the License. */ +// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6 + package net.margaritov.preference.colorpicker; -import android.app.Dialog; import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.Color; import android.graphics.PixelFormat; import android.os.Bundle; +import android.text.InputFilter; +import android.text.InputType; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; +import android.view.ViewTreeObserver; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; import android.widget.LinearLayout; +import android.widget.TextView; -import org.transdroid.R; - -public class ColorPickerDialog extends Dialog implements ColorPickerView.OnColorChangedListener, View.OnClickListener { - - private ColorPickerView mColorPicker; - - private ColorPickerPanelView mOldColor; - private ColorPickerPanelView mNewColor; - - private OnColorChangedListener mListener; - - public interface OnColorChangedListener { - public void onColorChanged(int color); - } - - public ColorPickerDialog(Context context, int initialColor) { - super(context); - - init(initialColor); - } - - private void init(int color) { - // To fight color banding. - getWindow().setFormat(PixelFormat.RGBA_8888); - - setUp(color); - - } +import androidx.appcompat.app.AppCompatDialog; - private void setUp(int color) { - - LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - View layout = inflater.inflate(R.layout.dialog_color_picker, null); - - setContentView(layout); - - setTitle(R.string.dialog_color_picker); - - mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view); - mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel); - mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel); - - ((LinearLayout) mOldColor.getParent()) - .setPadding(Math.round(mColorPicker.getDrawingOffset()), 0, Math.round(mColorPicker.getDrawingOffset()), - 0); - - mOldColor.setOnClickListener(this); - mNewColor.setOnClickListener(this); - mColorPicker.setOnColorChangedListener(this); - mOldColor.setColor(color); - mColorPicker.setColor(color, true); - - } - - @Override - public void onColorChanged(int color) { +import org.transdroid.R; - mNewColor.setColor(color); +import java.util.Locale; + +public class ColorPickerDialog + extends + AppCompatDialog + implements + ColorPickerView.OnColorChangedListener, + View.OnClickListener, ViewTreeObserver.OnGlobalLayoutListener { + + private ColorPickerView mColorPicker; + + private ColorPickerPanelView mOldColor; + private ColorPickerPanelView mNewColor; + + private EditText mHexVal; + private boolean mHexValueEnabled = false; + private ColorStateList mHexDefaultTextColor; + + private OnColorChangedListener mListener; + private int mOrientation; + private View mLayout; + + private String mTitle; + + @Override + public void onGlobalLayout() { + if (getContext().getResources().getConfiguration().orientation != mOrientation) { + final int oldcolor = mOldColor.getColor(); + final int newcolor = mNewColor.getColor(); + mLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); + setUp(oldcolor); + mNewColor.setColor(newcolor); + mColorPicker.setColor(newcolor); + } + } + + public interface OnColorChangedListener { + public void onColorChanged(int color); + } + + public ColorPickerDialog(Context context, int initialColor, String title) { + super(context); + + mTitle = title; + init(initialColor); + } + + private void init(int color) { + // To fight color banding. + getWindow().setFormat(PixelFormat.RGBA_8888); + + setUp(color); + + } + + private void setUp(int color) { + + LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + mLayout = inflater.inflate(R.layout.dialog_color_picker, null); + mLayout.getViewTreeObserver().addOnGlobalLayoutListener(this); + + mOrientation = getContext().getResources().getConfiguration().orientation; + setContentView(mLayout); + + setTitle(mTitle); + + mColorPicker = (ColorPickerView) mLayout.findViewById(R.id.color_picker_view); + mOldColor = (ColorPickerPanelView) mLayout.findViewById(R.id.old_color_panel); + mNewColor = (ColorPickerPanelView) mLayout.findViewById(R.id.new_color_panel); + + mHexVal = (EditText) mLayout.findViewById(R.id.hex_val); + mHexVal.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + mHexDefaultTextColor = mHexVal.getTextColors(); + + mHexVal.setOnEditorActionListener(new TextView.OnEditorActionListener() { + + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(v.getWindowToken(), 0); + String s = mHexVal.getText().toString(); + if (s.length() > 5 || s.length() < 10) { + try { + int c = ColorPickerPreference.convertToColorInt(s.toString()); + mColorPicker.setColor(c, true); + mHexVal.setTextColor(mHexDefaultTextColor); + } catch (IllegalArgumentException e) { + mHexVal.setTextColor(Color.RED); + } + } else { + mHexVal.setTextColor(Color.RED); + } + return true; + } + return false; + } + }); + + ((LinearLayout) mOldColor.getParent()).setPadding( + Math.round(mColorPicker.getDrawingOffset()), + 0, + Math.round(mColorPicker.getDrawingOffset()), + 0 + ); + + mOldColor.setOnClickListener(this); + mNewColor.setOnClickListener(this); + mColorPicker.setOnColorChangedListener(this); + mOldColor.setColor(color); + mColorPicker.setColor(color, true); + + } + + @Override + public void onColorChanged(int color) { + + mNewColor.setColor(color); + + if (mHexValueEnabled) + updateHexValue(color); /* - if (mListener != null) { + if (mListener != null) { mListener.onColorChanged(color); } */ - } - - public void setAlphaSliderVisible(boolean visible) { - mColorPicker.setAlphaSliderVisible(visible); - } - - /** - * Set a OnColorChangedListener to get notified when the color - * selected by the user has changed. - * @param listener - */ - public void setOnColorChangedListener(OnColorChangedListener listener) { - mListener = listener; - } - - public int getColor() { - return mColorPicker.getColor(); - } - - @Override - public void onClick(View v) { - if (v.getId() == R.id.new_color_panel) { - if (mListener != null) { - mListener.onColorChanged(mNewColor.getColor()); - } - } - dismiss(); - } - - @Override - public Bundle onSaveInstanceState() { - Bundle state = super.onSaveInstanceState(); - state.putInt("old_color", mOldColor.getColor()); - state.putInt("new_color", mNewColor.getColor()); - return state; - } - - @Override - public void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - mOldColor.setColor(savedInstanceState.getInt("old_color")); - mColorPicker.setColor(savedInstanceState.getInt("new_color"), true); - } + } + + public void setHexValueEnabled(boolean enable) { + mHexValueEnabled = enable; + if (enable) { + mHexVal.setVisibility(View.VISIBLE); + updateHexLengthFilter(); + updateHexValue(getColor()); + } else + mHexVal.setVisibility(View.GONE); + } + + public boolean getHexValueEnabled() { + return mHexValueEnabled; + } + + private void updateHexLengthFilter() { + if (getAlphaSliderVisible()) + mHexVal.setFilters(new InputFilter[]{new InputFilter.LengthFilter(9)}); + else + mHexVal.setFilters(new InputFilter[]{new InputFilter.LengthFilter(7)}); + } + + private void updateHexValue(int color) { + if (getAlphaSliderVisible()) { + mHexVal.setText(ColorPickerPreference.convertToARGB(color).toUpperCase(Locale.getDefault())); + } else { + mHexVal.setText(ColorPickerPreference.convertToRGB(color).toUpperCase(Locale.getDefault())); + } + mHexVal.setTextColor(mHexDefaultTextColor); + } + + public void setAlphaSliderVisible(boolean visible) { + mColorPicker.setAlphaSliderVisible(visible); + if (mHexValueEnabled) { + updateHexLengthFilter(); + updateHexValue(getColor()); + } + } + + public boolean getAlphaSliderVisible() { + return mColorPicker.getAlphaSliderVisible(); + } + + /** + * Set a OnColorChangedListener to get notified when the color + * selected by the user has changed. + * + * @param listener + */ + public void setOnColorChangedListener(OnColorChangedListener listener) { + mListener = listener; + } + + public int getColor() { + return mColorPicker.getColor(); + } + + @Override + public void onClick(View v) { + if (v.getId() == R.id.new_color_panel) { + if (mListener != null) { + mListener.onColorChanged(mNewColor.getColor()); + } + } + dismiss(); + } + + @Override + public Bundle onSaveInstanceState() { + Bundle state = super.onSaveInstanceState(); + state.putInt("old_color", mOldColor.getColor()); + state.putInt("new_color", mNewColor.getColor()); + return state; + } + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + mOldColor.setColor(savedInstanceState.getInt("old_color")); + mColorPicker.setColor(savedInstanceState.getInt("new_color"), true); + } } diff --git a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java index 4b305793..60716e6d 100644 --- a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java +++ b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java @@ -14,6 +14,8 @@ * limitations under the License. */ +// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6 + package net.margaritov.preference.colorpicker; import android.content.Context; @@ -27,140 +29,148 @@ import android.view.View; * This class draws a panel which which will be filled with a color which can be set. * It can be used to show the currently selected color which you will get from * the {@link ColorPickerView}. + * * @author Daniel Nilsson */ public class ColorPickerPanelView extends View { - /** - * The width in pixels of the border - * surrounding the color panel. - */ - private final static float BORDER_WIDTH_PX = 1; - - private float mDensity = 1f; - - private int mBorderColor = 0xff6E6E6E; - private int mColor = 0xff000000; + /** + * The width in pixels of the border + * surrounding the color panel. + */ + private final static float BORDER_WIDTH_PX = 1; - private Paint mBorderPaint; - private Paint mColorPaint; + private float mDensity = 1f; - private RectF mDrawingRect; - private RectF mColorRect; + private int mBorderColor = 0xff6E6E6E; + private int mColor = 0xff000000; - private AlphaPatternDrawable mAlphaPattern; + private Paint mBorderPaint; + private Paint mColorPaint; + private RectF mDrawingRect; + private RectF mColorRect; - public ColorPickerPanelView(Context context) { - this(context, null); - } + private AlphaPatternDrawable mAlphaPattern; - public ColorPickerPanelView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } + public ColorPickerPanelView(Context context) { + this(context, null); + } - private void init() { - mBorderPaint = new Paint(); - mColorPaint = new Paint(); - mDensity = getContext().getResources().getDisplayMetrics().density; - } + public ColorPickerPanelView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } - @Override - protected void onDraw(Canvas canvas) { + private void init() { + mBorderPaint = new Paint(); + mColorPaint = new Paint(); + mDensity = getContext().getResources().getDisplayMetrics().density; + } - final RectF rect = mColorRect; - if (BORDER_WIDTH_PX > 0) { - mBorderPaint.setColor(mBorderColor); - canvas.drawRect(mDrawingRect, mBorderPaint); - } + @Override + protected void onDraw(Canvas canvas) { - if (mAlphaPattern != null) { - mAlphaPattern.draw(canvas); - } + final RectF rect = mColorRect; - mColorPaint.setColor(mColor); + if (BORDER_WIDTH_PX > 0) { + mBorderPaint.setColor(mBorderColor); + canvas.drawRect(mDrawingRect, mBorderPaint); + } - canvas.drawRect(rect, mColorPaint); - } + if (mAlphaPattern != null) { + mAlphaPattern.draw(canvas); + } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + mColorPaint.setColor(mColor); - int width = MeasureSpec.getSize(widthMeasureSpec); - int height = MeasureSpec.getSize(heightMeasureSpec); + canvas.drawRect(rect, mColorPaint); + } - setMeasuredDimension(width, height); - } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); + int width = MeasureSpec.getSize(widthMeasureSpec); + int height = MeasureSpec.getSize(heightMeasureSpec); - mDrawingRect = new RectF(); - mDrawingRect.left = getPaddingLeft(); - mDrawingRect.right = w - getPaddingRight(); - mDrawingRect.top = getPaddingTop(); - mDrawingRect.bottom = h - getPaddingBottom(); + setMeasuredDimension(width, height); + } - setUpColorRect(); + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); - } + mDrawingRect = new RectF(); + mDrawingRect.left = getPaddingLeft(); + mDrawingRect.right = w - getPaddingRight(); + mDrawingRect.top = getPaddingTop(); + mDrawingRect.bottom = h - getPaddingBottom(); - private void setUpColorRect() { - final RectF dRect = mDrawingRect; + setUpColorRect(); - float left = dRect.left + BORDER_WIDTH_PX; - float top = dRect.top + BORDER_WIDTH_PX; - float bottom = dRect.bottom - BORDER_WIDTH_PX; - float right = dRect.right - BORDER_WIDTH_PX; + } - mColorRect = new RectF(left, top, right, bottom); + private void setUpColorRect() { + final RectF dRect = mDrawingRect; - mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity)); + float left = dRect.left + BORDER_WIDTH_PX; + float top = dRect.top + BORDER_WIDTH_PX; + float bottom = dRect.bottom - BORDER_WIDTH_PX; + float right = dRect.right - BORDER_WIDTH_PX; - mAlphaPattern.setBounds(Math.round(mColorRect.left), Math.round(mColorRect.top), Math.round(mColorRect.right), - Math.round(mColorRect.bottom)); + mColorRect = new RectF(left, top, right, bottom); - } + mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity)); - /** - * Set the color that should be shown by this view. - * @param color - */ - public void setColor(int color) { - mColor = color; - invalidate(); - } + mAlphaPattern.setBounds( + Math.round(mColorRect.left), + Math.round(mColorRect.top), + Math.round(mColorRect.right), + Math.round(mColorRect.bottom) + ); - /** - * Get the color currently show by this view. - * @return - */ - public int getColor() { - return mColor; - } + } - /** - * Set the color of the border surrounding the panel. - * @param color - */ - public void setBorderColor(int color) { - mBorderColor = color; - invalidate(); - } + /** + * Set the color that should be shown by this view. + * + * @param color + */ + public void setColor(int color) { + mColor = color; + invalidate(); + } - /** - * Get the color of the border surrounding the panel. - */ - public int getBorderColor() { - return mBorderColor; - } + /** + * Get the color currently show by this view. + * + * @return + */ + public int getColor() { + return mColor; + } + + /** + * Set the color of the border surrounding the panel. + * + * @param color + */ + public void setBorderColor(int color) { + mBorderColor = color; + invalidate(); + } + + /** + * Get the color of the border surrounding the panel. + */ + public int getBorderColor() { + return mBorderColor; + } -} \ No newline at end of file +} diff --git a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java index da9a50fe..ca211059 100644 --- a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java +++ b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java @@ -14,6 +14,8 @@ * limitations under the License. */ +// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6 + package net.margaritov.preference.colorpicker; import android.content.Context; @@ -24,259 +26,312 @@ import android.graphics.Color; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.preference.Preference; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + /** - * A preference type that allows a user to choose a time + * A preference type that allows a user to choose a color + * * @author Sergey Margaritov */ -public class ColorPickerPreference extends Preference - implements Preference.OnPreferenceClickListener, ColorPickerDialog.OnColorChangedListener { - - View mView; - ColorPickerDialog mDialog; - private int mValue = Color.BLACK; - private float mDensity = 0; - private boolean mAlphaSliderEnabled = false; - - public ColorPickerPreference(Context context) { - super(context); - init(context, null); - } - - public ColorPickerPreference(Context context, AttributeSet attrs) { - super(context, attrs); - init(context, attrs); - } - - public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(context, attrs); - } - - @Override - protected Object onGetDefaultValue(TypedArray a, int index) { - return a.getColor(index, Color.BLACK); - } - - @Override - protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { - onColorChanged(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue); - } - - private void init(Context context, AttributeSet attrs) { - mDensity = getContext().getResources().getDisplayMetrics().density; - setOnPreferenceClickListener(this); - if (attrs != null) { - mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false); - } - } - - @Override - protected void onBindView(View view) { - super.onBindView(view); - mView = view; - setPreviewColor(); - } - - private void setPreviewColor() { - if (mView == null) { - return; - } - ImageView iView = new ImageView(getContext()); - LinearLayout widgetFrameView = ((LinearLayout) mView.findViewById(android.R.id.widget_frame)); - if (widgetFrameView == null) { - return; - } - widgetFrameView.setVisibility(View.VISIBLE); - widgetFrameView - .setPadding(widgetFrameView.getPaddingLeft(), widgetFrameView.getPaddingTop(), (int) (mDensity * 8), - widgetFrameView.getPaddingBottom()); - // remove already create preview image - int count = widgetFrameView.getChildCount(); - if (count > 0) { - widgetFrameView.removeViews(0, count); - } - widgetFrameView.addView(iView); - widgetFrameView.setMinimumWidth(0); - iView.setBackgroundDrawable(new AlphaPatternDrawable((int) (5 * mDensity))); - iView.setImageBitmap(getPreviewBitmap()); - } - - private Bitmap getPreviewBitmap() { - int d = (int) (mDensity * 31); //30dip - int color = mValue; - Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888); - int w = bm.getWidth(); - int h = bm.getHeight(); - int c = color; - for (int i = 0; i < w; i++) { - for (int j = i; j < h; j++) { - c = (i <= 1 || j <= 1 || i >= w - 2 || j >= h - 2) ? Color.GRAY : color; - bm.setPixel(i, j, c); - if (i != j) { - bm.setPixel(j, i, c); - } - } - } - - return bm; - } - - @Override - public void onColorChanged(int color) { - if (isPersistent()) { - persistInt(color); - } - mValue = color; - setPreviewColor(); - try { - getOnPreferenceChangeListener().onPreferenceChange(this, color); - } catch (NullPointerException e) { - - } - } - - public boolean onPreferenceClick(Preference preference) { - showDialog(null); - return false; - } - - protected void showDialog(Bundle state) { - mDialog = new ColorPickerDialog(getContext(), mValue); - mDialog.setOnColorChangedListener(this); - if (mAlphaSliderEnabled) { - mDialog.setAlphaSliderVisible(true); - } - if (state != null) { - mDialog.onRestoreInstanceState(state); - } - mDialog.show(); - } - - /** - * Toggle Alpha Slider visibility (by default it's disabled) - * @param enable - */ - public void setAlphaSliderEnabled(boolean enable) { - mAlphaSliderEnabled = enable; - } - - /** - * For custom purposes. Not used by ColorPickerPreferrence - * @param color - * @author Unknown - */ - public static String convertToARGB(int color) { - String alpha = Integer.toHexString(Color.alpha(color)); - String red = Integer.toHexString(Color.red(color)); - String green = Integer.toHexString(Color.green(color)); - String blue = Integer.toHexString(Color.blue(color)); - - if (alpha.length() == 1) { - alpha = "0" + alpha; - } - - if (red.length() == 1) { - red = "0" + red; - } - - if (green.length() == 1) { - green = "0" + green; - } - - if (blue.length() == 1) { - blue = "0" + blue; - } - - return "#" + alpha + red + green + blue; - } - - /** - * For custom purposes. Not used by ColorPickerPreferrence - * @param argb - * @throws NumberFormatException - * @author Unknown - */ - public static int convertToColorInt(String argb) throws NumberFormatException { - - if (argb.startsWith("#")) { - argb = argb.replace("#", ""); - } - - int alpha = -1, red = -1, green = -1, blue = -1; - - if (argb.length() == 8) { - alpha = Integer.parseInt(argb.substring(0, 2), 16); - red = Integer.parseInt(argb.substring(2, 4), 16); - green = Integer.parseInt(argb.substring(4, 6), 16); - blue = Integer.parseInt(argb.substring(6, 8), 16); - } else if (argb.length() == 6) { - alpha = 255; - red = Integer.parseInt(argb.substring(0, 2), 16); - green = Integer.parseInt(argb.substring(2, 4), 16); - blue = Integer.parseInt(argb.substring(4, 6), 16); - } - - return Color.argb(alpha, red, green, blue); - } - - @Override - protected Parcelable onSaveInstanceState() { - final Parcelable superState = super.onSaveInstanceState(); - if (mDialog == null || !mDialog.isShowing()) { - return superState; - } - - final SavedState myState = new SavedState(superState); - myState.dialogBundle = mDialog.onSaveInstanceState(); - return myState; - } - - @Override - protected void onRestoreInstanceState(Parcelable state) { - if (state == null || !(state instanceof SavedState)) { - // Didn't save state for us in onSaveInstanceState - super.onRestoreInstanceState(state); - return; - } - - SavedState myState = (SavedState) state; - super.onRestoreInstanceState(myState.getSuperState()); - showDialog(myState.dialogBundle); - } - - private static class SavedState extends BaseSavedState { - Bundle dialogBundle; - - public SavedState(Parcel source) { - super(source); - dialogBundle = source.readBundle(); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeBundle(dialogBundle); - } - - public SavedState(Parcelable superState) { - super(superState); - } - - @SuppressWarnings("unused") - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } -} \ No newline at end of file +public class ColorPickerPreference + extends + Preference + implements + Preference.OnPreferenceClickListener, + ColorPickerDialog.OnColorChangedListener { + + View mView; + ColorPickerDialog mDialog; + private int mValue = Color.BLACK; + private float mDensity = 0; + private boolean mAlphaSliderEnabled = false; + private boolean mHexValueEnabled = false; + + public ColorPickerPreference(Context context) { + super(context); + init(context, null); + } + + public ColorPickerPreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context, attrs); + } + + /**Method edited by + * @author Anna Berkovitch + * added functionality to accept hex string as defaultValue + * and to properly persist resources reference string, such as @color/someColor + * previously persisted 0*/ + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + int colorInt; + String mHexDefaultValue = a.getString(index); + if (mHexDefaultValue != null && mHexDefaultValue.startsWith("#")) { + colorInt = convertToColorInt(mHexDefaultValue); + return colorInt; + + } else { + return a.getColor(index, Color.BLACK); + } + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + onColorChanged(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue); + } + + private void init(Context context, AttributeSet attrs) { + mDensity = getContext().getResources().getDisplayMetrics().density; + setOnPreferenceClickListener(this); + if (attrs != null) { + mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false); + mHexValueEnabled = attrs.getAttributeBooleanValue(null, "hexValue", false); + } + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + mView = holder.itemView; + setPreviewColor(); + } + + private void setPreviewColor() { + if (mView == null) return; + ImageView iView = new ImageView(getContext()); + LinearLayout widgetFrameView = ((LinearLayout) mView.findViewById(android.R.id.widget_frame)); + if (widgetFrameView == null) return; + widgetFrameView.setVisibility(View.VISIBLE); + widgetFrameView.setPadding( + widgetFrameView.getPaddingLeft(), + widgetFrameView.getPaddingTop(), + (int) (mDensity * 8), + widgetFrameView.getPaddingBottom() + ); + // remove already create preview image + int count = widgetFrameView.getChildCount(); + if (count > 0) { + widgetFrameView.removeViews(0, count); + } + widgetFrameView.addView(iView); + widgetFrameView.setMinimumWidth(0); + iView.setBackgroundDrawable(new AlphaPatternDrawable((int) (5 * mDensity))); + iView.setImageBitmap(getPreviewBitmap()); + } + + private Bitmap getPreviewBitmap() { + int d = (int) (mDensity * 31); //30dip + int color = mValue; + Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888); + int w = bm.getWidth(); + int h = bm.getHeight(); + int c = color; + for (int i = 0; i < w; i++) { + for (int j = i; j < h; j++) { + c = (i <= 1 || j <= 1 || i >= w - 2 || j >= h - 2) ? Color.GRAY : color; + bm.setPixel(i, j, c); + if (i != j) { + bm.setPixel(j, i, c); + } + } + } + + return bm; + } + + @Override + public void onColorChanged(int color) { + if (isPersistent()) { + persistInt(color); + } + mValue = color; + setPreviewColor(); + try { + getOnPreferenceChangeListener().onPreferenceChange(this, color); + } catch (NullPointerException e) { + + } + } + + public boolean onPreferenceClick(Preference preference) { + showDialog(null); + return false; + } + + protected void showDialog(Bundle state) { + mDialog = new ColorPickerDialog(getContext(), mValue, getTitle().toString()); + mDialog.setOnColorChangedListener(this); + if (mAlphaSliderEnabled) { + mDialog.setAlphaSliderVisible(true); + } + if (mHexValueEnabled) { + mDialog.setHexValueEnabled(true); + } + if (state != null) { + mDialog.onRestoreInstanceState(state); + } + mDialog.show(); + } + + /** + * Toggle Alpha Slider visibility (by default it's disabled) + * + * @param enable + */ + public void setAlphaSliderEnabled(boolean enable) { + mAlphaSliderEnabled = enable; + } + + /** + * Toggle Hex Value visibility (by default it's disabled) + * + * @param enable + */ + public void setHexValueEnabled(boolean enable) { + mHexValueEnabled = enable; + } + + /** + * For custom purposes. Not used by ColorPickerPreferrence + * + * @param color + * @author Unknown + */ + public static String convertToARGB(int color) { + String alpha = Integer.toHexString(Color.alpha(color)); + String red = Integer.toHexString(Color.red(color)); + String green = Integer.toHexString(Color.green(color)); + String blue = Integer.toHexString(Color.blue(color)); + + if (alpha.length() == 1) { + alpha = "0" + alpha; + } + + if (red.length() == 1) { + red = "0" + red; + } + + if (green.length() == 1) { + green = "0" + green; + } + + if (blue.length() == 1) { + blue = "0" + blue; + } + + return "#" + alpha + red + green + blue; + } + + /** + * Method currently used by onGetDefaultValue method to + * convert hex string provided in android:defaultValue to color integer. + * + * @param color + * @return A string representing the hex value of color, + * without the alpha value + * @author Charles Rosaaen + */ + public static String convertToRGB(int color) { + String red = Integer.toHexString(Color.red(color)); + String green = Integer.toHexString(Color.green(color)); + String blue = Integer.toHexString(Color.blue(color)); + + if (red.length() == 1) { + red = "0" + red; + } + + if (green.length() == 1) { + green = "0" + green; + } + + if (blue.length() == 1) { + blue = "0" + blue; + } + + return "#" + red + green + blue; + } + + /** + * For custom purposes. Not used by ColorPickerPreferrence + * + * @param argb + * @throws NumberFormatException + * @author Unknown + */ + public static int convertToColorInt(String argb) throws IllegalArgumentException { + + if (!argb.startsWith("#")) { + argb = "#" + argb; + } + + return Color.parseColor(argb); + } + + @Override + protected Parcelable onSaveInstanceState() { + final Parcelable superState = super.onSaveInstanceState(); + if (mDialog == null || !mDialog.isShowing()) { + return superState; + } + + final SavedState myState = new SavedState(superState); + myState.dialogBundle = mDialog.onSaveInstanceState(); + return myState; + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + if (state == null || !(state instanceof SavedState)) { + // Didn't save state for us in onSaveInstanceState + super.onRestoreInstanceState(state); + return; + } + + SavedState myState = (SavedState) state; + super.onRestoreInstanceState(myState.getSuperState()); + showDialog(myState.dialogBundle); + } + + private static class SavedState extends BaseSavedState { + Bundle dialogBundle; + + public SavedState(Parcel source) { + super(source); + dialogBundle = source.readBundle(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeBundle(dialogBundle); + } + + public SavedState(Parcelable superState) { + super(superState); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } +} diff --git a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java index 48d18d61..f2824cfc 100644 --- a/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java +++ b/app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java @@ -14,6 +14,8 @@ * limitations under the License. */ +// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6 + package net.margaritov.preference.colorpicker; import android.content.Context; @@ -38,895 +40,908 @@ import android.view.View; * to select a color. A slider for the alpha channel is * also available. Enable it by setting * setAlphaSliderVisible(boolean) to true. + * * @author Daniel Nilsson */ public class ColorPickerView extends View { - private final static int PANEL_SAT_VAL = 0; - private final static int PANEL_HUE = 1; - private final static int PANEL_ALPHA = 2; - - /** - * The width in pixels of the border - * surrounding all color panels. - */ - private final static float BORDER_WIDTH_PX = 1; - - /** - * The width in dp of the hue panel. - */ - private float HUE_PANEL_WIDTH = 30f; - /** - * The height in dp of the alpha panel - */ - private float ALPHA_PANEL_HEIGHT = 20f; - /** - * The distance in dp between the different - * color panels. - */ - private float PANEL_SPACING = 10f; - /** - * The radius in dp of the color palette tracker circle. - */ - private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f; - /** - * The dp which the tracker of the hue or alpha panel - * will extend outside of its bounds. - */ - private float RECTANGLE_TRACKER_OFFSET = 2f; - - - private float mDensity = 1f; - - private OnColorChangedListener mListener; - - private Paint mSatValPaint; - private Paint mSatValTrackerPaint; - - private Paint mHuePaint; - private Paint mHueTrackerPaint; - - private Paint mAlphaPaint; - private Paint mAlphaTextPaint; - - private Paint mBorderPaint; - - private Shader mValShader; - private Shader mSatShader; - private Shader mHueShader; - private Shader mAlphaShader; - - private int mAlpha = 0xff; - private float mHue = 360f; - private float mSat = 0f; - private float mVal = 0f; - - private String mAlphaSliderText = ""; - private int mSliderTrackerColor = 0xff1c1c1c; - private int mBorderColor = 0xff6E6E6E; - private boolean mShowAlphaPanel = false; - - /* - * To remember which panel that has the "focus" when - * processing hardware button data. - */ - private int mLastTouchedPanel = PANEL_SAT_VAL; - - /** - * Offset from the edge we must have or else - * the finger tracker will get clipped when - * it is drawn outside of the view. - */ - private float mDrawingOffset; - - - /* - * Distance form the edges of the view - * of where we are allowed to draw. - */ - private RectF mDrawingRect; - - private RectF mSatValRect; - private RectF mHueRect; - private RectF mAlphaRect; - - private AlphaPatternDrawable mAlphaPattern; - - private Point mStartTouchPoint = null; + private final static int PANEL_SAT_VAL = 0; + private final static int PANEL_HUE = 1; + private final static int PANEL_ALPHA = 2; + + /** + * The width in pixels of the border + * surrounding all color panels. + */ + private final static float BORDER_WIDTH_PX = 1; + + /** + * The width in dp of the hue panel. + */ + private float HUE_PANEL_WIDTH = 30f; + /** + * The height in dp of the alpha panel + */ + private float ALPHA_PANEL_HEIGHT = 20f; + /** + * The distance in dp between the different + * color panels. + */ + private float PANEL_SPACING = 10f; + /** + * The radius in dp of the color palette tracker circle. + */ + private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f; + /** + * The dp which the tracker of the hue or alpha panel + * will extend outside of its bounds. + */ + private float RECTANGLE_TRACKER_OFFSET = 2f; + + + private float mDensity = 1f; + + private OnColorChangedListener mListener; + + private Paint mSatValPaint; + private Paint mSatValTrackerPaint; + + private Paint mHuePaint; + private Paint mHueTrackerPaint; + + private Paint mAlphaPaint; + private Paint mAlphaTextPaint; + + private Paint mBorderPaint; + + private Shader mValShader; + private Shader mSatShader; + private Shader mHueShader; + private Shader mAlphaShader; + + private int mAlpha = 0xff; + private float mHue = 360f; + private float mSat = 0f; + private float mVal = 0f; + + private String mAlphaSliderText = ""; + private int mSliderTrackerColor = 0xff1c1c1c; + private int mBorderColor = 0xff6E6E6E; + private boolean mShowAlphaPanel = false; + + /* + * To remember which panel that has the "focus" when + * processing hardware button data. + */ + private int mLastTouchedPanel = PANEL_SAT_VAL; + + /** + * Offset from the edge we must have or else + * the finger tracker will get clipped when + * it is drawn outside of the view. + */ + private float mDrawingOffset; - public interface OnColorChangedListener { - public void onColorChanged(int color); - } - public ColorPickerView(Context context) { - this(context, null); - } + /* + * Distance form the edges of the view + * of where we are allowed to draw. + */ + private RectF mDrawingRect; - public ColorPickerView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } + private RectF mSatValRect; + private RectF mHueRect; + private RectF mAlphaRect; - public ColorPickerView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } + private AlphaPatternDrawable mAlphaPattern; - private void init() { - mDensity = getContext().getResources().getDisplayMetrics().density; - PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity; - RECTANGLE_TRACKER_OFFSET *= mDensity; - HUE_PANEL_WIDTH *= mDensity; - ALPHA_PANEL_HEIGHT *= mDensity; - PANEL_SPACING = PANEL_SPACING * mDensity; + private Point mStartTouchPoint = null; - mDrawingOffset = calculateRequiredOffset(); + public interface OnColorChangedListener { + public void onColorChanged(int color); + } - initPaintTools(); + public ColorPickerView(Context context) { + this(context, null); + } - //Needed for receiving trackball motion events. - setFocusable(true); - setFocusableInTouchMode(true); - } + public ColorPickerView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } - private void initPaintTools() { + public ColorPickerView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } - mSatValPaint = new Paint(); - mSatValTrackerPaint = new Paint(); - mHuePaint = new Paint(); - mHueTrackerPaint = new Paint(); - mAlphaPaint = new Paint(); - mAlphaTextPaint = new Paint(); - mBorderPaint = new Paint(); + private void init() { + mDensity = getContext().getResources().getDisplayMetrics().density; + PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity; + RECTANGLE_TRACKER_OFFSET *= mDensity; + HUE_PANEL_WIDTH *= mDensity; + ALPHA_PANEL_HEIGHT *= mDensity; + PANEL_SPACING = PANEL_SPACING * mDensity; + mDrawingOffset = calculateRequiredOffset(); - mSatValTrackerPaint.setStyle(Style.STROKE); - mSatValTrackerPaint.setStrokeWidth(2f * mDensity); - mSatValTrackerPaint.setAntiAlias(true); + initPaintTools(); - mHueTrackerPaint.setColor(mSliderTrackerColor); - mHueTrackerPaint.setStyle(Style.STROKE); - mHueTrackerPaint.setStrokeWidth(2f * mDensity); - mHueTrackerPaint.setAntiAlias(true); + //Needed for receiving trackball motion events. + setFocusable(true); + setFocusableInTouchMode(true); + } - mAlphaTextPaint.setColor(0xff1c1c1c); - mAlphaTextPaint.setTextSize(14f * mDensity); - mAlphaTextPaint.setAntiAlias(true); - mAlphaTextPaint.setTextAlign(Align.CENTER); - mAlphaTextPaint.setFakeBoldText(true); + private void initPaintTools() { + mSatValPaint = new Paint(); + mSatValTrackerPaint = new Paint(); + mHuePaint = new Paint(); + mHueTrackerPaint = new Paint(); + mAlphaPaint = new Paint(); + mAlphaTextPaint = new Paint(); + mBorderPaint = new Paint(); - } - private float calculateRequiredOffset() { - float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET); - offset = Math.max(offset, BORDER_WIDTH_PX * mDensity); + mSatValTrackerPaint.setStyle(Style.STROKE); + mSatValTrackerPaint.setStrokeWidth(2f * mDensity); + mSatValTrackerPaint.setAntiAlias(true); - return offset * 1.5f; - } + mHueTrackerPaint.setColor(mSliderTrackerColor); + mHueTrackerPaint.setStyle(Style.STROKE); + mHueTrackerPaint.setStrokeWidth(2f * mDensity); + mHueTrackerPaint.setAntiAlias(true); - private int[] buildHueColorArray() { + mAlphaTextPaint.setColor(0xff1c1c1c); + mAlphaTextPaint.setTextSize(14f * mDensity); + mAlphaTextPaint.setAntiAlias(true); + mAlphaTextPaint.setTextAlign(Align.CENTER); + mAlphaTextPaint.setFakeBoldText(true); - int[] hue = new int[361]; - int count = 0; - for (int i = hue.length - 1; i >= 0; i--, count++) { - hue[count] = Color.HSVToColor(new float[]{i, 1f, 1f}); - } + } - return hue; - } + private float calculateRequiredOffset() { + float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET); + offset = Math.max(offset, BORDER_WIDTH_PX * mDensity); + return offset * 1.5f; + } - @Override - protected void onDraw(Canvas canvas) { + private int[] buildHueColorArray() { - if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) { - return; - } + int[] hue = new int[361]; - drawSatValPanel(canvas); - drawHuePanel(canvas); - drawAlphaPanel(canvas); + int count = 0; + for (int i = hue.length - 1; i >= 0; i--, count++) { + hue[count] = Color.HSVToColor(new float[]{i, 1f, 1f}); + } - } + return hue; + } - private void drawSatValPanel(Canvas canvas) { - final RectF rect = mSatValRect; + @Override + protected void onDraw(Canvas canvas) { - if (BORDER_WIDTH_PX > 0) { - mBorderPaint.setColor(mBorderColor); - canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, - rect.bottom + BORDER_WIDTH_PX, mBorderPaint); - } + if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) return; - if (mValShader == null) { - mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, 0xffffffff, 0xff000000, - TileMode.CLAMP); - } + drawSatValPanel(canvas); + drawHuePanel(canvas); + drawAlphaPanel(canvas); - int rgb = Color.HSVToColor(new float[]{mHue, 1f, 1f}); + } - mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, 0xffffffff, rgb, TileMode.CLAMP); - ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY); - mSatValPaint.setShader(mShader); + private void drawSatValPanel(Canvas canvas) { - canvas.drawRect(rect, mSatValPaint); + final RectF rect = mSatValRect; - Point p = satValToPoint(mSat, mVal); + if (BORDER_WIDTH_PX > 0) { + mBorderPaint.setColor(mBorderColor); + canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint); + } - mSatValTrackerPaint.setColor(0xff000000); - canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint); + if (mValShader == null) { + mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, + 0xffffffff, 0xff000000, TileMode.CLAMP); + } - mSatValTrackerPaint.setColor(0xffdddddd); - canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint); + int rgb = Color.HSVToColor(new float[]{mHue, 1f, 1f}); - } + mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, + 0xffffffff, rgb, TileMode.CLAMP); + ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY); + mSatValPaint.setShader(mShader); - private void drawHuePanel(Canvas canvas) { + canvas.drawRect(rect, mSatValPaint); - final RectF rect = mHueRect; + Point p = satValToPoint(mSat, mVal); - if (BORDER_WIDTH_PX > 0) { - mBorderPaint.setColor(mBorderColor); - canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, - rect.bottom + BORDER_WIDTH_PX, mBorderPaint); - } + mSatValTrackerPaint.setColor(0xff000000); + canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint); - if (mHueShader == null) { - mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, - TileMode.CLAMP); - mHuePaint.setShader(mHueShader); - } + mSatValTrackerPaint.setColor(0xffdddddd); + canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint); - canvas.drawRect(rect, mHuePaint); + } - float rectHeight = 4 * mDensity / 2; + private void drawHuePanel(Canvas canvas) { - Point p = hueToPoint(mHue); + final RectF rect = mHueRect; - RectF r = new RectF(); - r.left = rect.left - RECTANGLE_TRACKER_OFFSET; - r.right = rect.right + RECTANGLE_TRACKER_OFFSET; - r.top = p.y - rectHeight; - r.bottom = p.y + rectHeight; + if (BORDER_WIDTH_PX > 0) { + mBorderPaint.setColor(mBorderColor); + canvas.drawRect(rect.left - BORDER_WIDTH_PX, + rect.top - BORDER_WIDTH_PX, + rect.right + BORDER_WIDTH_PX, + rect.bottom + BORDER_WIDTH_PX, + mBorderPaint); + } + if (mHueShader == null) { + mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP); + mHuePaint.setShader(mHueShader); + } - canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint); + canvas.drawRect(rect, mHuePaint); - } + float rectHeight = 4 * mDensity / 2; - private void drawAlphaPanel(Canvas canvas) { + Point p = hueToPoint(mHue); - if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) { - return; - } + RectF r = new RectF(); + r.left = rect.left - RECTANGLE_TRACKER_OFFSET; + r.right = rect.right + RECTANGLE_TRACKER_OFFSET; + r.top = p.y - rectHeight; + r.bottom = p.y + rectHeight; - final RectF rect = mAlphaRect; - if (BORDER_WIDTH_PX > 0) { - mBorderPaint.setColor(mBorderColor); - canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, - rect.bottom + BORDER_WIDTH_PX, mBorderPaint); - } + canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint); + } - mAlphaPattern.draw(canvas); + private void drawAlphaPanel(Canvas canvas) { - float[] hsv = new float[]{mHue, mSat, mVal}; - int color = Color.HSVToColor(hsv); - int acolor = Color.HSVToColor(0, hsv); + if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) return; - mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, color, acolor, TileMode.CLAMP); + final RectF rect = mAlphaRect; + if (BORDER_WIDTH_PX > 0) { + mBorderPaint.setColor(mBorderColor); + canvas.drawRect(rect.left - BORDER_WIDTH_PX, + rect.top - BORDER_WIDTH_PX, + rect.right + BORDER_WIDTH_PX, + rect.bottom + BORDER_WIDTH_PX, + mBorderPaint); + } - mAlphaPaint.setShader(mAlphaShader); - canvas.drawRect(rect, mAlphaPaint); + mAlphaPattern.draw(canvas); - if (mAlphaSliderText != null && mAlphaSliderText != "") { - canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint); - } + float[] hsv = new float[]{mHue, mSat, mVal}; + int color = Color.HSVToColor(hsv); + int acolor = Color.HSVToColor(0, hsv); - float rectWidth = 4 * mDensity / 2; + mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, + color, acolor, TileMode.CLAMP); - Point p = alphaToPoint(mAlpha); - RectF r = new RectF(); - r.left = p.x - rectWidth; - r.right = p.x + rectWidth; - r.top = rect.top - RECTANGLE_TRACKER_OFFSET; - r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET; + mAlphaPaint.setShader(mAlphaShader); - canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint); + canvas.drawRect(rect, mAlphaPaint); - } + if (mAlphaSliderText != null && mAlphaSliderText != "") { + canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint); + } + float rectWidth = 4 * mDensity / 2; - private Point hueToPoint(float hue) { + Point p = alphaToPoint(mAlpha); - final RectF rect = mHueRect; - final float height = rect.height(); + RectF r = new RectF(); + r.left = p.x - rectWidth; + r.right = p.x + rectWidth; + r.top = rect.top - RECTANGLE_TRACKER_OFFSET; + r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET; - Point p = new Point(); + canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint); - p.y = (int) (height - (hue * height / 360f) + rect.top); - p.x = (int) rect.left; + } - return p; - } - private Point satValToPoint(float sat, float val) { + private Point hueToPoint(float hue) { - final RectF rect = mSatValRect; - final float height = rect.height(); - final float width = rect.width(); + final RectF rect = mHueRect; + final float height = rect.height(); - Point p = new Point(); + Point p = new Point(); - p.x = (int) (sat * width + rect.left); - p.y = (int) ((1f - val) * height + rect.top); + p.y = (int) (height - (hue * height / 360f) + rect.top); + p.x = (int) rect.left; - return p; - } + return p; + } - private Point alphaToPoint(int alpha) { + private Point satValToPoint(float sat, float val) { - final RectF rect = mAlphaRect; - final float width = rect.width(); + final RectF rect = mSatValRect; + final float height = rect.height(); + final float width = rect.width(); - Point p = new Point(); + Point p = new Point(); - p.x = (int) (width - (alpha * width / 0xff) + rect.left); - p.y = (int) rect.top; + p.x = (int) (sat * width + rect.left); + p.y = (int) ((1f - val) * height + rect.top); - return p; + return p; + } - } + private Point alphaToPoint(int alpha) { - private float[] pointToSatVal(float x, float y) { + final RectF rect = mAlphaRect; + final float width = rect.width(); - final RectF rect = mSatValRect; - float[] result = new float[2]; + Point p = new Point(); - float width = rect.width(); - float height = rect.height(); + p.x = (int) (width - (alpha * width / 0xff) + rect.left); + p.y = (int) rect.top; - if (x < rect.left) { - x = 0f; - } else if (x > rect.right) { - x = width; - } else { - x = x - rect.left; - } + return p; - if (y < rect.top) { - y = 0f; - } else if (y > rect.bottom) { - y = height; - } else { - y = y - rect.top; - } + } + private float[] pointToSatVal(float x, float y) { - result[0] = 1.f / width * x; - result[1] = 1.f - (1.f / height * y); + final RectF rect = mSatValRect; + float[] result = new float[2]; - return result; - } + float width = rect.width(); + float height = rect.height(); - private float pointToHue(float y) { + if (x < rect.left) { + x = 0f; + } else if (x > rect.right) { + x = width; + } else { + x = x - rect.left; + } - final RectF rect = mHueRect; + if (y < rect.top) { + y = 0f; + } else if (y > rect.bottom) { + y = height; + } else { + y = y - rect.top; + } - float height = rect.height(); - if (y < rect.top) { - y = 0f; - } else if (y > rect.bottom) { - y = height; - } else { - y = y - rect.top; - } + result[0] = 1.f / width * x; + result[1] = 1.f - (1.f / height * y); - return 360f - (y * 360f / height); - } + return result; + } - private int pointToAlpha(int x) { + private float pointToHue(float y) { - final RectF rect = mAlphaRect; - final int width = (int) rect.width(); + final RectF rect = mHueRect; - if (x < rect.left) { - x = 0; - } else if (x > rect.right) { - x = width; - } else { - x = x - (int) rect.left; - } + float height = rect.height(); - return 0xff - (x * 0xff / width); + if (y < rect.top) { + y = 0f; + } else if (y > rect.bottom) { + y = height; + } else { + y = y - rect.top; + } - } + return 360f - (y * 360f / height); + } + private int pointToAlpha(int x) { - @Override - public boolean onTrackballEvent(MotionEvent event) { + final RectF rect = mAlphaRect; + final int width = (int) rect.width(); - float x = event.getX(); - float y = event.getY(); + if (x < rect.left) { + x = 0; + } else if (x > rect.right) { + x = width; + } else { + x = x - (int) rect.left; + } - boolean update = false; + return 0xff - (x * 0xff / width); + } - if (event.getAction() == MotionEvent.ACTION_MOVE) { - switch (mLastTouchedPanel) { + @Override + public boolean onTrackballEvent(MotionEvent event) { - case PANEL_SAT_VAL: + float x = event.getX(); + float y = event.getY(); - float sat, val; + boolean update = false; - sat = mSat + x / 50f; - val = mVal - y / 50f; - if (sat < 0f) { - sat = 0f; - } else if (sat > 1f) { - sat = 1f; - } + if (event.getAction() == MotionEvent.ACTION_MOVE) { - if (val < 0f) { - val = 0f; - } else if (val > 1f) { - val = 1f; - } + switch (mLastTouchedPanel) { - mSat = sat; - mVal = val; + case PANEL_SAT_VAL: - update = true; + float sat, val; - break; + sat = mSat + x / 50f; + val = mVal - y / 50f; - case PANEL_HUE: + if (sat < 0f) { + sat = 0f; + } else if (sat > 1f) { + sat = 1f; + } - float hue = mHue - y * 10f; + if (val < 0f) { + val = 0f; + } else if (val > 1f) { + val = 1f; + } - if (hue < 0f) { - hue = 0f; - } else if (hue > 360f) { - hue = 360f; - } + mSat = sat; + mVal = val; - mHue = hue; + update = true; - update = true; + break; - break; + case PANEL_HUE: - case PANEL_ALPHA: + float hue = mHue - y * 10f; - if (!mShowAlphaPanel || mAlphaRect == null) { - update = false; - } else { + if (hue < 0f) { + hue = 0f; + } else if (hue > 360f) { + hue = 360f; + } - int alpha = (int) (mAlpha - x * 10); + mHue = hue; - if (alpha < 0) { - alpha = 0; - } else if (alpha > 0xff) { - alpha = 0xff; - } + update = true; - mAlpha = alpha; + break; + case PANEL_ALPHA: - update = true; - } + if (!mShowAlphaPanel || mAlphaRect == null) { + update = false; + } else { - break; - } + int alpha = (int) (mAlpha - x * 10); + if (alpha < 0) { + alpha = 0; + } else if (alpha > 0xff) { + alpha = 0xff; + } - } + mAlpha = alpha; - if (update) { + update = true; + } - if (mListener != null) { - mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal})); - } + break; + } - invalidate(); - return true; - } + } - return super.onTrackballEvent(event); - } - @Override - public boolean onTouchEvent(MotionEvent event) { + if (update) { - boolean update = false; + if (mListener != null) { + mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal})); + } - switch (event.getAction()) { + invalidate(); + return true; + } - case MotionEvent.ACTION_DOWN: - mStartTouchPoint = new Point((int) event.getX(), (int) event.getY()); + return super.onTrackballEvent(event); + } - update = moveTrackersIfNeeded(event); + @Override + public boolean onTouchEvent(MotionEvent event) { - break; + boolean update = false; - case MotionEvent.ACTION_MOVE: + switch (event.getAction()) { - update = moveTrackersIfNeeded(event); + case MotionEvent.ACTION_DOWN: - break; + mStartTouchPoint = new Point((int) event.getX(), (int) event.getY()); - case MotionEvent.ACTION_UP: + update = moveTrackersIfNeeded(event); - mStartTouchPoint = null; + break; - update = moveTrackersIfNeeded(event); + case MotionEvent.ACTION_MOVE: - break; + update = moveTrackersIfNeeded(event); - } + break; - if (update) { + case MotionEvent.ACTION_UP: - if (mListener != null) { - mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal})); - } + mStartTouchPoint = null; - invalidate(); - return true; - } + update = moveTrackersIfNeeded(event); + break; - return super.onTouchEvent(event); - } + } - private boolean moveTrackersIfNeeded(MotionEvent event) { + if (update) { - if (mStartTouchPoint == null) { - return false; - } + if (mListener != null) { + mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal})); + } - boolean update = false; + invalidate(); + return true; + } - int startX = mStartTouchPoint.x; - int startY = mStartTouchPoint.y; + return super.onTouchEvent(event); + } - if (mHueRect.contains(startX, startY)) { - mLastTouchedPanel = PANEL_HUE; + private boolean moveTrackersIfNeeded(MotionEvent event) { - mHue = pointToHue(event.getY()); + if (mStartTouchPoint == null) return false; - update = true; - } else if (mSatValRect.contains(startX, startY)) { + boolean update = false; - mLastTouchedPanel = PANEL_SAT_VAL; + int startX = mStartTouchPoint.x; + int startY = mStartTouchPoint.y; - float[] result = pointToSatVal(event.getX(), event.getY()); - mSat = result[0]; - mVal = result[1]; + if (mHueRect.contains(startX, startY)) { + mLastTouchedPanel = PANEL_HUE; - update = true; - } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) { + mHue = pointToHue(event.getY()); - mLastTouchedPanel = PANEL_ALPHA; + update = true; + } else if (mSatValRect.contains(startX, startY)) { - mAlpha = pointToAlpha((int) event.getX()); + mLastTouchedPanel = PANEL_SAT_VAL; - update = true; - } + float[] result = pointToSatVal(event.getX(), event.getY()); + mSat = result[0]; + mVal = result[1]; - return update; - } + update = true; + } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) { - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + mLastTouchedPanel = PANEL_ALPHA; - int width = 0; - int height = 0; + mAlpha = pointToAlpha((int) event.getX()); - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - int heightMode = MeasureSpec.getMode(heightMeasureSpec); + update = true; + } - int widthAllowed = MeasureSpec.getSize(widthMeasureSpec); - int heightAllowed = MeasureSpec.getSize(heightMeasureSpec); - widthAllowed = chooseWidth(widthMode, widthAllowed); - heightAllowed = chooseHeight(heightMode, heightAllowed); + return update; + } - if (!mShowAlphaPanel) { + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH); + int width = 0; + int height = 0; - //If calculated height (based on the width) is more than the allowed height. - if (height > heightAllowed || getTag().equals("landscape")) { - height = heightAllowed; - width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH); - } else { - width = widthAllowed; - } - } else { + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int heightMode = MeasureSpec.getMode(heightMeasureSpec); - width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH); + int widthAllowed = MeasureSpec.getSize(widthMeasureSpec); + int heightAllowed = MeasureSpec.getSize(heightMeasureSpec); - if (width > widthAllowed) { - width = widthAllowed; - height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT); - } else { - height = heightAllowed; - } + widthAllowed = chooseWidth(widthMode, widthAllowed); + heightAllowed = chooseHeight(heightMode, heightAllowed); - } + if (!mShowAlphaPanel) { - setMeasuredDimension(width, height); - } + height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH); - private int chooseWidth(int mode, int size) { - if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) { - return size; - } else { // (mode == MeasureSpec.UNSPECIFIED) - return getPrefferedWidth(); - } - } + //If calculated height (based on the width) is more than the allowed height. + if (height > heightAllowed || getTag().equals("landscape")) { + height = heightAllowed; + width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH); + } else { + width = widthAllowed; + } + } else { - private int chooseHeight(int mode, int size) { - if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) { - return size; - } else { // (mode == MeasureSpec.UNSPECIFIED) - return getPrefferedHeight(); - } - } + width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH); - private int getPrefferedWidth() { + if (width > widthAllowed) { + width = widthAllowed; + height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT); + } else { + height = heightAllowed; + } - int width = getPrefferedHeight(); + } - if (mShowAlphaPanel) { - width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT); - } + setMeasuredDimension(width, height); + } + private int chooseWidth(int mode, int size) { + if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) { + return size; + } else { // (mode == MeasureSpec.UNSPECIFIED) + return getPrefferedWidth(); + } + } - return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING); + private int chooseHeight(int mode, int size) { + if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) { + return size; + } else { // (mode == MeasureSpec.UNSPECIFIED) + return getPrefferedHeight(); + } + } - } + private int getPrefferedWidth() { - private int getPrefferedHeight() { + int width = getPrefferedHeight(); - int height = (int) (200 * mDensity); + if (mShowAlphaPanel) { + width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT); + } - if (mShowAlphaPanel) { - height += PANEL_SPACING + ALPHA_PANEL_HEIGHT; - } - return height; - } + return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING); + } - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); + private int getPrefferedHeight() { - mDrawingRect = new RectF(); - mDrawingRect.left = mDrawingOffset + getPaddingLeft(); - mDrawingRect.right = w - mDrawingOffset - getPaddingRight(); - mDrawingRect.top = mDrawingOffset + getPaddingTop(); - mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom(); + int height = (int) (200 * mDensity); - setUpSatValRect(); - setUpHueRect(); - setUpAlphaRect(); - } + if (mShowAlphaPanel) { + height += PANEL_SPACING + ALPHA_PANEL_HEIGHT; + } - private void setUpSatValRect() { + return height; + } - final RectF dRect = mDrawingRect; - float panelSide = dRect.height() - BORDER_WIDTH_PX * 2; - if (mShowAlphaPanel) { - panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT; - } + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); - float left = dRect.left + BORDER_WIDTH_PX; - float top = dRect.top + BORDER_WIDTH_PX; - float bottom = top + panelSide; - float right = left + panelSide; + mDrawingRect = new RectF(); + mDrawingRect.left = mDrawingOffset + getPaddingLeft(); + mDrawingRect.right = w - mDrawingOffset - getPaddingRight(); + mDrawingRect.top = mDrawingOffset + getPaddingTop(); + mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom(); - mSatValRect = new RectF(left, top, right, bottom); - } + setUpSatValRect(); + setUpHueRect(); + setUpAlphaRect(); + } - private void setUpHueRect() { - final RectF dRect = mDrawingRect; + private void setUpSatValRect() { - float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX; - float top = dRect.top + BORDER_WIDTH_PX; - float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0); - float right = dRect.right - BORDER_WIDTH_PX; - - mHueRect = new RectF(left, top, right, bottom); - } - - private void setUpAlphaRect() { - - if (!mShowAlphaPanel) { - return; - } - - final RectF dRect = mDrawingRect; - - float left = dRect.left + BORDER_WIDTH_PX; - float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX; - float bottom = dRect.bottom - BORDER_WIDTH_PX; - float right = dRect.right - BORDER_WIDTH_PX; - - mAlphaRect = new RectF(left, top, right, bottom); - - mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity)); - mAlphaPattern.setBounds(Math.round(mAlphaRect.left), Math.round(mAlphaRect.top), Math.round(mAlphaRect.right), - Math.round(mAlphaRect.bottom)); - - } - - - /** - * Set a OnColorChangedListener to get notified when the color - * selected by the user has changed. - * @param listener - */ - public void setOnColorChangedListener(OnColorChangedListener listener) { - mListener = listener; - } + final RectF dRect = mDrawingRect; + float panelSide = dRect.height() - BORDER_WIDTH_PX * 2; + + if (mShowAlphaPanel) { + panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT; + } + + float left = dRect.left + BORDER_WIDTH_PX; + float top = dRect.top + BORDER_WIDTH_PX; + float bottom = top + panelSide; + float right = left + panelSide; - /** - * Set the color of the border surrounding all panels. - * @param color - */ - public void setBorderColor(int color) { - mBorderColor = color; - invalidate(); - } + mSatValRect = new RectF(left, top, right, bottom); + } - /** - * Get the color of the border surrounding all panels. - */ - public int getBorderColor() { - return mBorderColor; - } - - /** - * Get the current color this view is showing. - * @return the current color. - */ - public int getColor() { - return Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}); - } - - /** - * Set the color the view should show. - * @param color The color that should be selected. - */ - public void setColor(int color) { - setColor(color, false); - } - - /** - * Set the color this view should show. - * @param color The color that should be selected. - * @param callback If you want to get a callback to - * your OnColorChangedListener. - */ - public void setColor(int color, boolean callback) { - - int alpha = Color.alpha(color); - int red = Color.red(color); - int blue = Color.blue(color); - int green = Color.green(color); - - float[] hsv = new float[3]; - - Color.RGBToHSV(red, green, blue, hsv); - - mAlpha = alpha; - mHue = hsv[0]; - mSat = hsv[1]; - mVal = hsv[2]; - - if (callback && mListener != null) { - mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal})); - } - - invalidate(); - } - - /** - * Get the drawing offset of the color picker view. - * The drawing offset is the distance from the side of - * a panel to the side of the view minus the padding. - * Useful if you want to have your own panel below showing - * the currently selected color and want to align it perfectly. - * @return The offset in pixels. - */ - public float getDrawingOffset() { - return mDrawingOffset; - } - - /** - * Set if the user is allowed to adjust the alpha panel. Default is false. - * If it is set to false no alpha will be set. - * @param visible - */ - public void setAlphaSliderVisible(boolean visible) { - - if (mShowAlphaPanel != visible) { - mShowAlphaPanel = visible; + private void setUpHueRect() { + final RectF dRect = mDrawingRect; + + float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX; + float top = dRect.top + BORDER_WIDTH_PX; + float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0); + float right = dRect.right - BORDER_WIDTH_PX; + + mHueRect = new RectF(left, top, right, bottom); + } + + private void setUpAlphaRect() { + + if (!mShowAlphaPanel) return; + + final RectF dRect = mDrawingRect; + + float left = dRect.left + BORDER_WIDTH_PX; + float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX; + float bottom = dRect.bottom - BORDER_WIDTH_PX; + float right = dRect.right - BORDER_WIDTH_PX; + + mAlphaRect = new RectF(left, top, right, bottom); + + mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity)); + mAlphaPattern.setBounds( + Math.round(mAlphaRect.left), + Math.round(mAlphaRect.top), + Math.round(mAlphaRect.right), + Math.round(mAlphaRect.bottom) + ); + + } + + + /** + * Set a OnColorChangedListener to get notified when the color + * selected by the user has changed. + * + * @param listener + */ + public void setOnColorChangedListener(OnColorChangedListener listener) { + mListener = listener; + } + + /** + * Set the color of the border surrounding all panels. + * + * @param color + */ + public void setBorderColor(int color) { + mBorderColor = color; + invalidate(); + } + + /** + * Get the color of the border surrounding all panels. + */ + public int getBorderColor() { + return mBorderColor; + } + + /** + * Get the current color this view is showing. + * + * @return the current color. + */ + public int getColor() { + return Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}); + } + + /** + * Set the color the view should show. + * + * @param color The color that should be selected. + */ + public void setColor(int color) { + setColor(color, false); + } + + /** + * Set the color this view should show. + * + * @param color The color that should be selected. + * @param callback If you want to get a callback to + * your OnColorChangedListener. + */ + public void setColor(int color, boolean callback) { + + int alpha = Color.alpha(color); + + float[] hsv = new float[3]; + + Color.colorToHSV(color, hsv); + + mAlpha = alpha; + mHue = hsv[0]; + mSat = hsv[1]; + mVal = hsv[2]; + + if (callback && mListener != null) { + mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal})); + } + + invalidate(); + } + + /** + * Get the drawing offset of the color picker view. + * The drawing offset is the distance from the side of + * a panel to the side of the view minus the padding. + * Useful if you want to have your own panel below showing + * the currently selected color and want to align it perfectly. + * + * @return The offset in pixels. + */ + public float getDrawingOffset() { + return mDrawingOffset; + } + + /** + * Set if the user is allowed to adjust the alpha panel. Default is false. + * If it is set to false no alpha will be set. + * + * @param visible + */ + public void setAlphaSliderVisible(boolean visible) { + + if (mShowAlphaPanel != visible) { + mShowAlphaPanel = visible; /* - * Reset all shader to force a recreation. + * Reset all shader to force a recreation. * Otherwise they will not look right after * the size of the view has changed. */ - mValShader = null; - mSatShader = null; - mHueShader = null; - mAlphaShader = null; - ; - - requestLayout(); - } - - } - - public void setSliderTrackerColor(int color) { - mSliderTrackerColor = color; - - mHueTrackerPaint.setColor(mSliderTrackerColor); - - invalidate(); - } - - public int getSliderTrackerColor() { - return mSliderTrackerColor; - } - - /** - * Set the text that should be shown in the - * alpha slider. Set to null to disable text. - * @param res string resource id. - */ - public void setAlphaSliderText(int res) { - String text = getContext().getString(res); - setAlphaSliderText(text); - } - - /** - * Set the text that should be shown in the - * alpha slider. Set to null to disable text. - * @param text Text that should be shown. - */ - public void setAlphaSliderText(String text) { - mAlphaSliderText = text; - invalidate(); - } - - /** - * Get the current value of the text - * that will be shown in the alpha - * slider. - * @return - */ - public String getAlphaSliderText() { - return mAlphaSliderText; - } -} \ No newline at end of file + mValShader = null; + mSatShader = null; + mHueShader = null; + mAlphaShader = null; + + requestLayout(); + } + + } + + public boolean getAlphaSliderVisible() { + return mShowAlphaPanel; + } + + public void setSliderTrackerColor(int color) { + mSliderTrackerColor = color; + + mHueTrackerPaint.setColor(mSliderTrackerColor); + + invalidate(); + } + + public int getSliderTrackerColor() { + return mSliderTrackerColor; + } + + /** + * Set the text that should be shown in the + * alpha slider. Set to null to disable text. + * + * @param res string resource id. + */ + public void setAlphaSliderText(int res) { + String text = getContext().getString(res); + setAlphaSliderText(text); + } + + /** + * Set the text that should be shown in the + * alpha slider. Set to null to disable text. + * + * @param text Text that should be shown. + */ + public void setAlphaSliderText(String text) { + mAlphaSliderText = text; + invalidate(); + } + + /** + * Get the current value of the text + * that will be shown in the alpha + * slider. + * + * @return + */ + public String getAlphaSliderText() { + return mAlphaSliderText; + } +} diff --git a/app/src/main/java/org/apache/openjpa/lib/util/Base16Encoder.java b/app/src/main/java/org/apache/openjpa/lib/util/Base16Encoder.java deleted file mode 100644 index 51c301b1..00000000 --- a/app/src/main/java/org/apache/openjpa/lib/util/Base16Encoder.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.openjpa.lib.util; - -/** - * Base 16 encoder. - * - * @author Marc Prud'hommeaux - * @nojavadoc - */ -public class Base16Encoder { - - private final static char[] HEX = new char[]{ - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - - /** - * Convert bytes to a base16 string. - */ - public static String encode(byte[] byteArray) { - StringBuffer hexBuffer = new StringBuffer(byteArray.length * 2); - for (int i = 0; i < byteArray.length; i++) - for (int j = 1; j >= 0; j--) - hexBuffer.append(HEX[(byteArray[i] >> (j * 4)) & 0xF]); - return hexBuffer.toString(); - } - - /** - * Convert a base16 string into a byte array. - */ - public static byte[] decode(String s) { - int len = s.length(); - byte[] r = new byte[len / 2]; - for (int i = 0; i < r.length; i++) { - int digit1 = s.charAt(i * 2), digit2 = s.charAt(i * 2 + 1); - if (digit1 >= '0' && digit1 <= '9') - digit1 -= '0'; - else if (digit1 >= 'A' && digit1 <= 'F') - digit1 -= 'A' - 10; - if (digit2 >= '0' && digit2 <= '9') - digit2 -= '0'; - else if (digit2 >= 'A' && digit2 <= 'F') - digit2 -= 'A' - 10; - - r[i] = (byte) ((digit1 << 4) + digit2); - } - return r; - } -} diff --git a/app/src/main/java/org/base64/android/Base64.java b/app/src/main/java/org/base64/android/Base64.java deleted file mode 100644 index e4d3ec79..00000000 --- a/app/src/main/java/org/base64/android/Base64.java +++ /dev/null @@ -1,1998 +0,0 @@ -package org.base64.android; - -/** - *

Encodes and decodes to and from Base64 notation. Released as Public Domain software.

- *

Homepage: http://iharder.net/base64.

- * - *

Example:

- * - * String encoded = Base64.encode( myByteArray ); - *
- * byte[] myByteArray = Base64.decode( encoded ); - * - *

The options parameter, which appears in a few places, is used to pass - * several pieces of information to the encoder. In the "higher level" methods such as - * encodeBytes( bytes, options ) the options parameter can be used to indicate such - * things as first gzipping the bytes before encoding them, not inserting linefeeds, - * and encoding using the URL-safe and Ordered dialects.

- * - *

Note, according to RFC3548, - * Section 2.1, implementations should not add line feeds unless explicitly told - * to do so. I've got Base64 set to this behavior now, although earlier versions - * broke lines by default.

- * - *

The constants defined in Base64 can be OR-ed together to combine options, so you - * might make a call like this:

- * - * String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DO_BREAK_LINES ); - *

to compress the data before encoding it and then making the output have newline characters.

- *

Also...

- * String encoded = Base64.encodeBytes( crazyString.getBytes() ); - * - * - * - *

- * Change Log: - *

- *
    - *
  • v2.3.3 - Changed default char encoding to US-ASCII which reduces the internal Java - * footprint with its CharEncoders and so forth. Fixed some javadocs that were - * inconsistent. Removed imports and specified things like java.io.IOException - * explicitly inline.
  • - *
  • v2.3.2 - Reduced memory footprint! Finally refined the "guessing" of how big the - * final encoded data will be so that the code doesn't have to create two output - * arrays: an oversized initial one and then a final, exact-sized one. Big win - * when using the {@link #encodeBytesToBytes(byte[])} family of methods (and not - * using the gzip options which uses a different mechanism with streams and stuff).
  • - *
  • v2.3.1 - Added {@link #encodeBytesToBytes(byte[], int, int, int)} and some - * similar helper methods to be more efficient with memory by not returning a - * String but just a byte array.
  • - *
  • v2.3 - This is not a drop-in replacement! This is two years of comments - * and bug fixes queued up and finally executed. Thanks to everyone who sent - * me stuff, and I'm sorry I wasn't able to distribute your fixes to everyone else. - * Much bad coding was cleaned up including throwing exceptions where necessary - * instead of returning null values or something similar. Here are some changes - * that may affect you: - *
      - *
    • Does not break lines, by default. This is to keep in compliance with - * RFC3548.
    • - *
    • Throws exceptions instead of returning null values. Because some operations - * (especially those that may permit the GZIP option) use IO streams, there - * is a possiblity of an java.io.IOException being thrown. After some discussion and - * thought, I've changed the behavior of the methods to throw java.io.IOExceptions - * rather than return null if ever there's an error. I think this is more - * appropriate, though it will require some changes to your code. Sorry, - * it should have been done this way to begin with.
    • - *
    • Removed all references to System.out, System.err, and the like. - * Shame on me. All I can say is sorry they were ever there.
    • - *
    • Throws NullPointerExceptions and IllegalArgumentExceptions as needed - * such as when passed arrays are null or offsets are invalid.
    • - *
    • Cleaned up as much javadoc as I could to avoid any javadoc warnings. - * This was especially annoying before for people who were thorough in their - * own projects and then had gobs of javadoc warnings on this file.
    • - *
    - *
  • v2.2.1 - Fixed bug using URL_SAFE and ORDERED encodings. Fixed bug - * when using very small files (~< 40 bytes).
  • - *
  • v2.2 - Added some helper methods for encoding/decoding directly from - * one file to the next. Also added a main() method to support command line - * encoding/decoding from one file to the next. Also added these Base64 dialects: - *
      - *
    1. The default is RFC3548 format.
    2. - *
    3. Calling Base64.setFormat(Base64.BASE64_FORMAT.URLSAFE_FORMAT) generates - * URL and file name friendly format as described in Section 4 of RFC3548. - * http://www.faqs.org/rfcs/rfc3548.html
    4. - *
    5. Calling Base64.setFormat(Base64.BASE64_FORMAT.ORDERED_FORMAT) generates - * URL and file name friendly format that preserves lexical ordering as described - * in http://www.faqs.org/qa/rfcc-1940.html
    6. - *
    - * Special thanks to Jim Kellerman at http://www.powerset.com/ - * for contributing the new Base64 dialects. - *
  • - * - *
  • v2.1 - Cleaned up javadoc comments and unused variables and methods. Added - * some convenience methods for reading and writing to and from files.
  • - *
  • v2.0.2 - Now specifies UTF-8 encoding in places where the code fails on systems - * with other encodings (like EBCDIC).
  • - *
  • v2.0.1 - Fixed an error when decoding a single byte, that is, when the - * encoded data was a single byte.
  • - *
  • v2.0 - I got rid of methods that used booleans to set options. - * Now everything is more consolidated and cleaner. The code now detects - * when data that's being decoded is gzip-compressed and will decompress it - * automatically. Generally things are cleaner. You'll probably have to - * change some method calls that you were making to support the new - * options format (ints that you "OR" together).
  • - *
  • v1.5.1 - Fixed bug when decompressing and decoding to a - * byte[] using decode( String s, boolean gzipCompressed ). - * Added the ability to "suspend" encoding in the Output Stream so - * you can turn on and off the encoding if you need to embed base64 - * data in an otherwise "normal" stream (like an XML file).
  • - *
  • v1.5 - Output stream pases on flush() command but doesn't do anything itself. - * This helps when using GZIP streams. - * Added the ability to GZip-compress objects before encoding them.
  • - *
  • v1.4 - Added helper methods to read/write files.
  • - *
  • v1.3.6 - Fixed OutputStream.flush() so that 'position' is reset.
  • - *
  • v1.3.5 - Added flag to turn on and off line breaks. Fixed bug in input stream - * where last buffer being read, if not completely full, was not returned.
  • - *
  • v1.3.4 - Fixed when "improperly padded stream" error was thrown at the wrong time.
  • - *
  • v1.3.3 - Fixed I/O streams which were totally messed up.
  • - *
- * - *

- * I am placing this code in the Public Domain. Do with it as you will. - * This software comes with no guarantees or warranties but with - * plenty of well-wishing instead! - * Please visit http://iharder.net/base64 - * periodically to check for updates or to contribute improvements. - *

- * - * @author Robert Harder - * @author rob@iharder.net - * @version 2.3.3 - */ -public class Base64 -{ - -/* ******** P U B L I C F I E L D S ******** */ - - - /** No options specified. Value is zero. */ - public final static int NO_OPTIONS = 0; - - /** Specify encoding in first bit. Value is one. */ - public final static int ENCODE = 1; - - - /** Specify decoding in first bit. Value is zero. */ - public final static int DECODE = 0; - - - /** Specify that data should be gzip-compressed in second bit. Value is two. */ - public final static int GZIP = 2; - - - /** Do break lines when encoding. Value is 8. */ - public final static int DO_BREAK_LINES = 8; - - /** - * Encode using Base64-like encoding that is URL- and Filename-safe as described - * in Section 4 of RFC3548: - * http://www.faqs.org/rfcs/rfc3548.html. - * It is important to note that data encoded this way is not officially valid Base64, - * or at the very least should not be called Base64 without also specifying that is - * was encoded using the URL- and Filename-safe dialect. - */ - public final static int URL_SAFE = 16; - - - /** - * Encode using the special "ordered" dialect of Base64 described here: - * http://www.faqs.org/qa/rfcc-1940.html. - */ - public final static int ORDERED = 32; - - -/* ******** P R I V A T E F I E L D S ******** */ - - - /** Maximum line length (76) of Base64 output. */ - private final static int MAX_LINE_LENGTH = 76; - - - /** The equals sign (=) as a byte. */ - private final static byte EQUALS_SIGN = (byte)'='; - - - /** The new line character (\n) as a byte. */ - private final static byte NEW_LINE = (byte)'\n'; - - - /** Preferred encoding. */ - private final static String PREFERRED_ENCODING = "US-ASCII"; - - - private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding - private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding - - -/* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ - - /** The 64 valid Base64 values. */ - /* Host platform me be something funny like EBCDIC, so we hardcode these values. */ - private final static byte[] _STANDARD_ALPHABET = { - (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', - (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', - (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', - (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', - (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', - (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', - (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', - (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' - }; - - - /** - * Translates a Base64 value to either its 6-bit reconstruction value - * or a negative number indicating some other meaning. - **/ - private final static byte[] _STANDARD_DECODABET = { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - 62, // Plus sign at decimal 43 - -9,-9,-9, // Decimal 44 - 46 - 63, // Slash at decimal 47 - 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' - 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' - -9,-9,-9,-9,-9,-9, // Decimal 91 - 96 - 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' - 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' - -9,-9,-9,-9 // Decimal 123 - 126 - /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ - }; - - -/* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ - - /** - * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548: - * http://www.faqs.org/rfcs/rfc3548.html. - * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash." - */ - private final static byte[] _URL_SAFE_ALPHABET = { - (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', - (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', - (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', - (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', - (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', - (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', - (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', - (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_' - }; - - /** - * Used in decoding URL- and Filename-safe dialects of Base64. - */ - private final static byte[] _URL_SAFE_DECODABET = { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - -9, // Plus sign at decimal 43 - -9, // Decimal 44 - 62, // Minus sign at decimal 45 - -9, // Decimal 46 - -9, // Slash at decimal 47 - 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' - 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' - -9,-9,-9,-9, // Decimal 91 - 94 - 63, // Underscore at decimal 95 - -9, // Decimal 96 - 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' - 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' - -9,-9,-9,-9 // Decimal 123 - 126 - /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ - }; - - - -/* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ - - /** - * I don't get the point of this technique, but someone requested it, - * and it is described here: - * http://www.faqs.org/qa/rfcc-1940.html. - */ - private final static byte[] _ORDERED_ALPHABET = { - (byte)'-', - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', - (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', - (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', - (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', - (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', - (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', - (byte)'_', - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', - (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', - (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', - (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z' - }; - - /** - * Used in decoding the "ordered" dialect of Base64. - */ - private final static byte[] _ORDERED_DECODABET = { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - -9, // Plus sign at decimal 43 - -9, // Decimal 44 - 0, // Minus sign at decimal 45 - -9, // Decimal 46 - -9, // Slash at decimal 47 - 1,2,3,4,5,6,7,8,9,10, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 11,12,13,14,15,16,17,18,19,20,21,22,23, // Letters 'A' through 'M' - 24,25,26,27,28,29,30,31,32,33,34,35,36, // Letters 'N' through 'Z' - -9,-9,-9,-9, // Decimal 91 - 94 - 37, // Underscore at decimal 95 - -9, // Decimal 96 - 38,39,40,41,42,43,44,45,46,47,48,49,50, // Letters 'a' through 'm' - 51,52,53,54,55,56,57,58,59,60,61,62,63, // Letters 'n' through 'z' - -9,-9,-9,-9 // Decimal 123 - 126 - /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ - }; - - -/* ******** D E T E R M I N E W H I C H A L H A B E T ******** */ - - - /** - * Returns one of the _SOMETHING_ALPHABET byte arrays depending on - * the options specified. - * It's possible, though silly, to specify ORDERED and URLSAFE - * in which case one of them will be picked, though there is - * no guarantee as to which one will be picked. - */ - private final static byte[] getAlphabet( int options ) { - if ((options & URL_SAFE) == URL_SAFE) { - return _URL_SAFE_ALPHABET; - } else if ((options & ORDERED) == ORDERED) { - return _ORDERED_ALPHABET; - } else { - return _STANDARD_ALPHABET; - } - } // end getAlphabet - - - /** - * Returns one of the _SOMETHING_DECODABET byte arrays depending on - * the options specified. - * It's possible, though silly, to specify ORDERED and URL_SAFE - * in which case one of them will be picked, though there is - * no guarantee as to which one will be picked. - */ - private final static byte[] getDecodabet( int options ) { - if( (options & URL_SAFE) == URL_SAFE) { - return _URL_SAFE_DECODABET; - } else if ((options & ORDERED) == ORDERED) { - return _ORDERED_DECODABET; - } else { - return _STANDARD_DECODABET; - } - } // end getAlphabet - - - - /** Defeats instantiation. */ - private Base64(){} - - - - -/* ******** E N C O D I N G M E T H O D S ******** */ - - - /** - * Encodes up to the first three bytes of array threeBytes - * and returns a four-byte array in Base64 notation. - * The actual number of significant bytes in your array is - * given by numSigBytes. - * The array threeBytes needs only be as big as - * numSigBytes. - * Code can reuse a byte array by passing a four-byte array as b4. - * - * @param b4 A reusable byte array to reduce array instantiation - * @param threeBytes the array to convert - * @param numSigBytes the number of significant bytes in your array - * @return four byte array in Base64 notation. - * @since 1.5.1 - */ - private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes, int options ) { - encode3to4( threeBytes, 0, numSigBytes, b4, 0, options ); - return b4; - } // end encode3to4 - - - /** - *

Encodes up to three bytes of the array source - * and writes the resulting four Base64 bytes to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accomodate srcOffset + 3 for - * the source array or destOffset + 4 for - * the destination array. - * The actual number of significant bytes in your array is - * given by numSigBytes.

- *

This is the lowest level of the encoding methods with - * all possible parameters.

- * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param numSigBytes the number of significant bytes in your array - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @return the destination array - * @since 1.3 - */ - private static byte[] encode3to4( - byte[] source, int srcOffset, int numSigBytes, - byte[] destination, int destOffset, int options ) { - - byte[] ALPHABET = getAlphabet( options ); - - // 1 2 3 - // 01234567890123456789012345678901 Bit position - // --------000000001111111122222222 Array position from threeBytes - // --------| || || || | Six bit groups to index ALPHABET - // >>18 >>12 >> 6 >> 0 Right shift necessary - // 0x3f 0x3f 0x3f Additional AND - - // Create buffer with zero-padding if there are only one or two - // significant bytes passed in the array. - // We have to shift left 24 in order to flush out the 1's that appear - // when Java treats a value as negative that is cast from a byte to an int. - int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 ) - | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 ) - | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 ); - - switch( numSigBytes ) - { - case 3: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; - destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ]; - return destination; - - case 2: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; - destination[ destOffset + 3 ] = EQUALS_SIGN; - return destination; - - case 1: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = EQUALS_SIGN; - destination[ destOffset + 3 ] = EQUALS_SIGN; - return destination; - - default: - return destination; - } // end switch - } // end encode3to4 - - - - /** - * Performs Base64 encoding on the raw ByteBuffer, - * writing it to the encoded ByteBuffer. - * This is an experimental feature. Currently it does not - * pass along any options (such as {@link #DO_BREAK_LINES} - * or {@link #GZIP}. - * - * @param raw input buffer - * @param encoded output buffer - * @since 2.3 - */ - public static void encode( java.nio.ByteBuffer raw, java.nio.ByteBuffer encoded ){ - byte[] raw3 = new byte[3]; - byte[] enc4 = new byte[4]; - - while( raw.hasRemaining() ){ - int rem = Math.min(3,raw.remaining()); - raw.get(raw3,0,rem); - Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS ); - encoded.put(enc4); - } // end input remaining - } - - - /** - * Performs Base64 encoding on the raw ByteBuffer, - * writing it to the encoded CharBuffer. - * This is an experimental feature. Currently it does not - * pass along any options (such as {@link #DO_BREAK_LINES} - * or {@link #GZIP}. - * - * @param raw input buffer - * @param encoded output buffer - * @since 2.3 - */ - public static void encode( java.nio.ByteBuffer raw, java.nio.CharBuffer encoded ){ - byte[] raw3 = new byte[3]; - byte[] enc4 = new byte[4]; - - while( raw.hasRemaining() ){ - int rem = Math.min(3,raw.remaining()); - raw.get(raw3,0,rem); - Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS ); - for( int i = 0; i < 4; i++ ){ - encoded.put( (char)(enc4[i] & 0xFF) ); - } - } // end input remaining - } - - - - - /** - * Serializes an object and returns the Base64-encoded - * version of that serialized object. - * - *

As of v 2.3, if the object - * cannot be serialized or there is another error, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned a null value, but - * in retrospect that's a pretty poor way to handle it.

- * - * The object is not GZip-compressed before being encoded. - * - * @param serializableObject The object to encode - * @return The Base64-encoded object - * @throws java.io.IOException if there is an error - * @throws NullPointerException if serializedObject is null - * @since 1.4 - */ - public static String encodeObject( java.io.Serializable serializableObject ) - throws java.io.IOException { - return encodeObject( serializableObject, NO_OPTIONS ); - } // end encodeObject - - - - /** - * Serializes an object and returns the Base64-encoded - * version of that serialized object. - * - *

As of v 2.3, if the object - * cannot be serialized or there is another error, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned a null value, but - * in retrospect that's a pretty poor way to handle it.

- * - * The object is not GZip-compressed before being encoded. - *

- * Example options:

-     *   GZIP: gzip-compresses object before encoding it.
-     *   DO_BREAK_LINES: break lines at 76 characters
-     * 
- *

- * Example: encodeObject( myObj, Base64.GZIP ) or - *

- * Example: encodeObject( myObj, Base64.GZIP | Base64.DO_BREAK_LINES ) - * - * @param serializableObject The object to encode - * @param options Specified options - * @return The Base64-encoded object - * @see Base64#GZIP - * @see Base64#DO_BREAK_LINES - * @throws java.io.IOException if there is an error - * @since 2.0 - */ - public static String encodeObject( java.io.Serializable serializableObject, int options ) - throws java.io.IOException { - - if( serializableObject == null ){ - throw new NullPointerException( "Cannot serialize a null object." ); - } // end if: null - - // Streams - java.io.ByteArrayOutputStream baos = null; - java.io.OutputStream b64os = null; - java.io.ObjectOutputStream oos = null; - - - try { - // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream - // Note that the optional GZIPping is handled by Base64.OutputStream. - baos = new java.io.ByteArrayOutputStream(); - b64os = new Base64.OutputStream( baos, ENCODE | options ); - oos = new java.io.ObjectOutputStream( b64os ); - oos.writeObject( serializableObject ); - } // end try - catch( java.io.IOException e ) { - // Catch it and then throw it immediately so that - // the finally{} block is called for cleanup. - throw e; - } // end catch - finally { - try{ oos.close(); } catch( Exception e ){} - try{ b64os.close(); } catch( Exception e ){} - try{ baos.close(); } catch( Exception e ){} - } // end finally - - // Return value according to relevant encoding. - try { - return new String( baos.toByteArray(), PREFERRED_ENCODING ); - } // end try - catch (java.io.UnsupportedEncodingException uue){ - // Fall back to some Java default - return new String( baos.toByteArray() ); - } // end catch - - } // end encode - - - - /** - * Encodes a byte array into Base64 notation. - * Does not GZip-compress data. - * - * @param source The data to convert - * @return The data in Base64-encoded form - * @throws NullPointerException if source array is null - * @since 1.4 - */ - public static String encodeBytes( byte[] source ) { - // Since we're not going to have the GZIP encoding turned on, - // we're not going to have an java.io.IOException thrown, so - // we should not force the user to have to catch it. - String encoded = null; - try { - encoded = encodeBytes(source, 0, source.length, NO_OPTIONS); - } catch (java.io.IOException ex) { - assert false : ex.getMessage(); - } // end catch - assert encoded != null; - return encoded; - } // end encodeBytes - - - - /** - * Encodes a byte array into Base64 notation. - *

- * Example options:

-     *   GZIP: gzip-compresses object before encoding it.
-     *   DO_BREAK_LINES: break lines at 76 characters
-     *     Note: Technically, this makes your encoding non-compliant.
-     * 
- *

- * Example: encodeBytes( myData, Base64.GZIP ) or - *

- * Example: encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES ) - * - * - *

As of v 2.3, if there is an error with the GZIP stream, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned a null value, but - * in retrospect that's a pretty poor way to handle it.

- * - * - * @param source The data to convert - * @param options Specified options - * @return The Base64-encoded data as a String - * @see Base64#GZIP - * @see Base64#DO_BREAK_LINES - * @throws java.io.IOException if there is an error - * @throws NullPointerException if source array is null - * @since 2.0 - */ - public static String encodeBytes( byte[] source, int options ) throws java.io.IOException { - return encodeBytes( source, 0, source.length, options ); - } // end encodeBytes - - - /** - * Encodes a byte array into Base64 notation. - * Does not GZip-compress data. - * - *

As of v 2.3, if there is an error, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned a null value, but - * in retrospect that's a pretty poor way to handle it.

- * - * - * @param source The data to convert - * @param off Offset in array where conversion should begin - * @param len Length of data to convert - * @return The Base64-encoded data as a String - * @throws NullPointerException if source array is null - * @throws IllegalArgumentException if source array, offset, or length are invalid - * @since 1.4 - */ - public static String encodeBytes( byte[] source, int off, int len ) { - // Since we're not going to have the GZIP encoding turned on, - // we're not going to have an java.io.IOException thrown, so - // we should not force the user to have to catch it. - String encoded = null; - try { - encoded = encodeBytes( source, off, len, NO_OPTIONS ); - } catch (java.io.IOException ex) { - assert false : ex.getMessage(); - } // end catch - assert encoded != null; - return encoded; - } // end encodeBytes - - - - /** - * Encodes a byte array into Base64 notation. - *

- * Example options:

-     *   GZIP: gzip-compresses object before encoding it.
-     *   DO_BREAK_LINES: break lines at 76 characters
-     *     Note: Technically, this makes your encoding non-compliant.
-     * 
- *

- * Example: encodeBytes( myData, Base64.GZIP ) or - *

- * Example: encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES ) - * - * - *

As of v 2.3, if there is an error with the GZIP stream, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned a null value, but - * in retrospect that's a pretty poor way to handle it.

- * - * - * @param source The data to convert - * @param off Offset in array where conversion should begin - * @param len Length of data to convert - * @param options Specified options - * @return The Base64-encoded data as a String - * @see Base64#GZIP - * @see Base64#DO_BREAK_LINES - * @throws java.io.IOException if there is an error - * @throws NullPointerException if source array is null - * @throws IllegalArgumentException if source array, offset, or length are invalid - * @since 2.0 - */ - public static String encodeBytes( byte[] source, int off, int len, int options ) throws java.io.IOException { - byte[] encoded = encodeBytesToBytes( source, off, len, options ); - - // Return value according to relevant encoding. - try { - return new String( encoded, PREFERRED_ENCODING ); - } // end try - catch (java.io.UnsupportedEncodingException uue) { - return new String( encoded ); - } // end catch - - } // end encodeBytes - - - - - /** - * Similar to {@link #encodeBytes(byte[])} but returns - * a byte array instead of instantiating a String. This is more efficient - * if you're working with I/O streams and have large data sets to encode. - * - * - * @param source The data to convert - * @return The Base64-encoded data as a byte[] (of ASCII characters) - * @throws NullPointerException if source array is null - * @since 2.3.1 - */ - public static byte[] encodeBytesToBytes( byte[] source ) { - byte[] encoded = null; - try { - encoded = encodeBytesToBytes( source, 0, source.length, Base64.NO_OPTIONS ); - } catch( java.io.IOException ex ) { - assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage(); - } - return encoded; - } - - - /** - * Similar to {@link #encodeBytes(byte[], int, int, int)} but returns - * a byte array instead of instantiating a String. This is more efficient - * if you're working with I/O streams and have large data sets to encode. - * - * - * @param source The data to convert - * @param off Offset in array where conversion should begin - * @param len Length of data to convert - * @param options Specified options - * @return The Base64-encoded data as a String - * @see Base64#GZIP - * @see Base64#DO_BREAK_LINES - * @throws java.io.IOException if there is an error - * @throws NullPointerException if source array is null - * @throws IllegalArgumentException if source array, offset, or length are invalid - * @since 2.3.1 - */ - public static byte[] encodeBytesToBytes( byte[] source, int off, int len, int options ) throws java.io.IOException { - - if( source == null ){ - throw new NullPointerException( "Cannot serialize a null array." ); - } // end if: null - - if( off < 0 ){ - throw new IllegalArgumentException( "Cannot have negative offset: " + off ); - } // end if: off < 0 - - if( len < 0 ){ - throw new IllegalArgumentException( "Cannot have length offset: " + len ); - } // end if: len < 0 - - if( off + len > source.length ){ - throw new IllegalArgumentException( - String.format( "Cannot have offset of %d and length of %d with array of length %d", off,len,source.length)); - } // end if: off < 0 - - - - // Compress? - if( (options & GZIP) > 0 ) { - java.io.ByteArrayOutputStream baos = null; - java.util.zip.GZIPOutputStream gzos = null; - Base64.OutputStream b64os = null; - - try { - // GZip -> Base64 -> ByteArray - baos = new java.io.ByteArrayOutputStream(); - b64os = new Base64.OutputStream( baos, ENCODE | options ); - gzos = new java.util.zip.GZIPOutputStream( b64os ); - - gzos.write( source, off, len ); - gzos.close(); - } // end try - catch( java.io.IOException e ) { - // Catch it and then throw it immediately so that - // the finally{} block is called for cleanup. - throw e; - } // end catch - finally { - try{ gzos.close(); } catch( Exception e ){} - try{ b64os.close(); } catch( Exception e ){} - try{ baos.close(); } catch( Exception e ){} - } // end finally - - return baos.toByteArray(); - } // end if: compress - - // Else, don't compress. Better not to use streams at all then. - else { - boolean breakLines = (options & DO_BREAK_LINES) > 0; - - //int len43 = len * 4 / 3; - //byte[] outBuff = new byte[ ( len43 ) // Main 4:3 - // + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding - // + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines - // Try to determine more precisely how big the array needs to be. - // If we get it right, we don't have to do an array copy, and - // we save a bunch of memory. - int encLen = ( len / 3 ) * 4 + ( len % 3 > 0 ? 4 : 0 ); // Bytes needed for actual encoding - if( breakLines ){ - encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters - } - byte[] outBuff = new byte[ encLen ]; - - - int d = 0; - int e = 0; - int len2 = len - 2; - int lineLength = 0; - for( ; d < len2; d+=3, e+=4 ) { - encode3to4( source, d+off, 3, outBuff, e, options ); - - lineLength += 4; - if( breakLines && lineLength >= MAX_LINE_LENGTH ) - { - outBuff[e+4] = NEW_LINE; - e++; - lineLength = 0; - } // end if: end of line - } // en dfor: each piece of array - - if( d < len ) { - encode3to4( source, d+off, len - d, outBuff, e, options ); - e += 4; - } // end if: some padding needed - - - // Only resize array if we didn't guess it right. - if( e < outBuff.length - 1 ){ - byte[] finalOut = new byte[e]; - System.arraycopy(outBuff,0, finalOut,0,e); - //System.err.println("Having to resize array from " + outBuff.length + " to " + e ); - return finalOut; - } else { - //System.err.println("No need to resize array."); - return outBuff; - } - - } // end else: don't compress - - } // end encodeBytesToBytes - - - - - -/* ******** D E C O D I N G M E T H O D S ******** */ - - - /** - * Decodes four bytes from array source - * and writes the resulting bytes (up to three of them) - * to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accomodate srcOffset + 4 for - * the source array or destOffset + 3 for - * the destination array. - * This method returns the actual number of bytes that - * were converted from the Base64 encoding. - *

This is the lowest level of the decoding methods with - * all possible parameters.

- * - * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @param options alphabet type is pulled from this (standard, url-safe, ordered) - * @return the number of decoded bytes converted - * @throws NullPointerException if source or destination arrays are null - * @throws IllegalArgumentException if srcOffset or destOffset are invalid - * or there is not enough room in the array. - * @since 1.3 - */ - private static int decode4to3( - byte[] source, int srcOffset, - byte[] destination, int destOffset, int options ) { - - // Lots of error checking and exception throwing - if( source == null ){ - throw new NullPointerException( "Source array was null." ); - } // end if - if( destination == null ){ - throw new NullPointerException( "Destination array was null." ); - } // end if - if( srcOffset < 0 || srcOffset + 3 >= source.length ){ - throw new IllegalArgumentException( String.format( - "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset ) ); - } // end if - if( destOffset < 0 || destOffset +2 >= destination.length ){ - throw new IllegalArgumentException( String.format( - "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset ) ); - } // end if - - - byte[] DECODABET = getDecodabet( options ); - - // Example: Dk== - if( source[ srcOffset + 2] == EQUALS_SIGN ) { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); - return 1; - } - - // Example: DkL= - else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); - return 2; - } - - // Example: DkLE - else { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) - // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) - | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); - - - destination[ destOffset ] = (byte)( outBuff >> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); - destination[ destOffset + 2 ] = (byte)( outBuff ); - - return 3; - } - } // end decodeToBytes - - - - - - /** - * Low-level access to decoding ASCII characters in - * the form of a byte array. Ignores GUNZIP option, if - * it's set. This is not generally a recommended method, - * although it is used internally as part of the decoding process. - * Special case: if len = 0, an empty array is returned. Still, - * if you need more speed and reduced memory footprint (and aren't - * gzipping), consider this method. - * - * @param source The Base64 encoded data - * @return decoded data - * @since 2.3.1 - */ - public static byte[] decode( byte[] source ){ - byte[] decoded = null; - try { - decoded = decode( source, 0, source.length, Base64.NO_OPTIONS ); - } catch( java.io.IOException ex ) { - assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage(); - } - return decoded; - } - - - - /** - * Low-level access to decoding ASCII characters in - * the form of a byte array. Ignores GUNZIP option, if - * it's set. This is not generally a recommended method, - * although it is used internally as part of the decoding process. - * Special case: if len = 0, an empty array is returned. Still, - * if you need more speed and reduced memory footprint (and aren't - * gzipping), consider this method. - * - * @param source The Base64 encoded data - * @param off The offset of where to begin decoding - * @param len The length of characters to decode - * @param options Can specify options such as alphabet type to use - * @return decoded data - * @throws java.io.IOException If bogus characters exist in source data - * @since 1.3 - */ - public static byte[] decode( byte[] source, int off, int len, int options ) - throws java.io.IOException { - - // Lots of error checking and exception throwing - if( source == null ){ - throw new NullPointerException( "Cannot decode null source array." ); - } // end if - if( off < 0 || off + len > source.length ){ - throw new IllegalArgumentException( String.format( - "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len ) ); - } // end if - - if( len == 0 ){ - return new byte[0]; - }else if( len < 4 ){ - throw new IllegalArgumentException( - "Base64-encoded string must have at least four characters, but length specified was " + len ); - } // end if - - byte[] DECODABET = getDecodabet( options ); - - int len34 = len * 3 / 4; // Estimate on array size - byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output - int outBuffPosn = 0; // Keep track of where we're writing - - byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space - int b4Posn = 0; // Keep track of four byte input buffer - int i = 0; // Source array counter - byte sbiCrop = 0; // Low seven bits (ASCII) of input - byte sbiDecode = 0; // Special value from DECODABET - - for( i = off; i < off+len; i++ ) { // Loop through source - - sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits - sbiDecode = DECODABET[ sbiCrop ]; // Special value - - // White space, Equals sign, or legit Base64 character - // Note the values such as -5 and -9 in the - // DECODABETs at the top of the file. - if( sbiDecode >= WHITE_SPACE_ENC ) { - if( sbiDecode >= EQUALS_SIGN_ENC ) { - b4[ b4Posn++ ] = sbiCrop; // Save non-whitespace - if( b4Posn > 3 ) { // Time to decode? - outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options ); - b4Posn = 0; - - // If that was the equals sign, break out of 'for' loop - if( sbiCrop == EQUALS_SIGN ) { - break; - } // end if: equals sign - } // end if: quartet built - } // end if: equals sign or better - } // end if: white space, equals sign or better - else { - // There's a bad input character in the Base64 stream. - throw new java.io.IOException( String.format( - "Bad Base64 input character '%c' in array position %d", source[i], i ) ); - } // end else: - } // each input character - - byte[] out = new byte[ outBuffPosn ]; - System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); - return out; - } // end decode - - - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @return the decoded data - * @throws java.io.IOException If there is a problem - * @since 1.4 - */ - public static byte[] decode( String s ) throws java.io.IOException { - return decode( s, NO_OPTIONS ); - } - - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @param options encode options such as URL_SAFE - * @return the decoded data - * @throws java.io.IOException if there is an error - * @throws NullPointerException if s is null - * @since 1.4 - */ - public static byte[] decode( String s, int options ) throws java.io.IOException { - - if( s == null ){ - throw new NullPointerException( "Input string was null." ); - } // end if - - byte[] bytes; - try { - bytes = s.getBytes( PREFERRED_ENCODING ); - } // end try - catch( java.io.UnsupportedEncodingException uee ) { - bytes = s.getBytes(); - } // end catch - // - - // Decode - bytes = decode( bytes, 0, bytes.length, options ); - - - // Check to see if it's gzip-compressed - // GZIP Magic Two-Byte Number: 0x8b1f (35615) - if( bytes != null && bytes.length >= 4 ) { - - int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); - if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head ) { - java.io.ByteArrayInputStream bais = null; - java.util.zip.GZIPInputStream gzis = null; - java.io.ByteArrayOutputStream baos = null; - byte[] buffer = new byte[2048]; - int length = 0; - - try { - baos = new java.io.ByteArrayOutputStream(); - bais = new java.io.ByteArrayInputStream( bytes ); - gzis = new java.util.zip.GZIPInputStream( bais ); - - while( ( length = gzis.read( buffer ) ) >= 0 ) { - baos.write(buffer,0,length); - } // end while: reading input - - // No error? Get new bytes. - bytes = baos.toByteArray(); - - } // end try - catch( java.io.IOException e ) { - // Just return originally-decoded bytes - } // end catch - finally { - try{ baos.close(); } catch( Exception e ){} - try{ gzis.close(); } catch( Exception e ){} - try{ bais.close(); } catch( Exception e ){} - } // end finally - - } // end if: gzipped - } // end if: bytes.length >= 2 - - return bytes; - } // end decode - - - - /** - * Attempts to decode Base64 data and deserialize a Java - * Object within. Returns null if there was an error. - * - * @param encodedObject The Base64 data to decode - * @return The decoded and deserialized object - * @throws NullPointerException if encodedObject is null - * @throws java.io.IOException if there is a general error - * @throws ClassNotFoundException if the decoded object is of a - * class that cannot be found by the JVM - * @since 1.5 - */ - public static Object decodeToObject( String encodedObject ) - throws java.io.IOException, java.lang.ClassNotFoundException { - - // Decode and gunzip if necessary - byte[] objBytes = decode( encodedObject ); - - java.io.ByteArrayInputStream bais = null; - java.io.ObjectInputStream ois = null; - Object obj = null; - - try { - bais = new java.io.ByteArrayInputStream( objBytes ); - ois = new java.io.ObjectInputStream( bais ); - - obj = ois.readObject(); - } // end try - catch( java.io.IOException e ) { - throw e; // Catch and throw in order to execute finally{} - } // end catch - catch( java.lang.ClassNotFoundException e ) { - throw e; // Catch and throw in order to execute finally{} - } // end catch - finally { - try{ bais.close(); } catch( Exception e ){} - try{ ois.close(); } catch( Exception e ){} - } // end finally - - return obj; - } // end decodeObject - - - - /** - * Convenience method for encoding data to a file. - * - *

As of v 2.3, if there is a error, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned false, but - * in retrospect that's a pretty poor way to handle it.

- * - * @param dataToEncode byte array of data to encode in base64 form - * @param filename Filename for saving encoded data - * @throws java.io.IOException if there is an error - * @throws NullPointerException if dataToEncode is null - * @since 2.1 - */ - public static void encodeToFile( byte[] dataToEncode, String filename ) - throws java.io.IOException { - - if( dataToEncode == null ){ - throw new NullPointerException( "Data to encode was null." ); - } // end iff - - Base64.OutputStream bos = null; - try { - bos = new Base64.OutputStream( - new java.io.FileOutputStream( filename ), Base64.ENCODE ); - bos.write( dataToEncode ); - } // end try - catch( java.io.IOException e ) { - throw e; // Catch and throw to execute finally{} block - } // end catch: java.io.IOException - finally { - try{ bos.close(); } catch( Exception e ){} - } // end finally - - } // end encodeToFile - - - /** - * Convenience method for decoding data to a file. - * - *

As of v 2.3, if there is a error, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned false, but - * in retrospect that's a pretty poor way to handle it.

- * - * @param dataToDecode Base64-encoded data as a string - * @param filename Filename for saving decoded data - * @throws java.io.IOException if there is an error - * @since 2.1 - */ - public static void decodeToFile( String dataToDecode, String filename ) - throws java.io.IOException { - - Base64.OutputStream bos = null; - try{ - bos = new Base64.OutputStream( - new java.io.FileOutputStream( filename ), Base64.DECODE ); - bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) ); - } // end try - catch( java.io.IOException e ) { - throw e; // Catch and throw to execute finally{} block - } // end catch: java.io.IOException - finally { - try{ bos.close(); } catch( Exception e ){} - } // end finally - - } // end decodeToFile - - - - - /** - * Convenience method for reading a base64-encoded - * file and decoding it. - * - *

As of v 2.3, if there is a error, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned false, but - * in retrospect that's a pretty poor way to handle it.

- * - * @param filename Filename for reading encoded data - * @return decoded byte array - * @throws java.io.IOException if there is an error - * @since 2.1 - */ - public static byte[] decodeFromFile( String filename ) - throws java.io.IOException { - - byte[] decodedData = null; - Base64.InputStream bis = null; - try - { - // Set up some useful variables - java.io.File file = new java.io.File( filename ); - byte[] buffer = null; - int length = 0; - int numBytes = 0; - - // Check for size of file - if( file.length() > Integer.MAX_VALUE ) - { - throw new java.io.IOException( "File is too big for this convenience method (" + file.length() + " bytes)." ); - } // end if: file too big for int index - buffer = new byte[ (int)file.length() ]; - - // Open a stream - bis = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( file ) ), Base64.DECODE ); - - // Read until done - while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) { - length += numBytes; - } // end while - - // Save in a variable to return - decodedData = new byte[ length ]; - System.arraycopy( buffer, 0, decodedData, 0, length ); - - } // end try - catch( java.io.IOException e ) { - throw e; // Catch and release to execute finally{} - } // end catch: java.io.IOException - finally { - try{ bis.close(); } catch( Exception e) {} - } // end finally - - return decodedData; - } // end decodeFromFile - - - - /** - * Convenience method for reading a binary file - * and base64-encoding it. - * - *

As of v 2.3, if there is a error, - * the method will throw an java.io.IOException. This is new to v2.3! - * In earlier versions, it just returned false, but - * in retrospect that's a pretty poor way to handle it.

- * - * @param filename Filename for reading binary data - * @return base64-encoded string - * @throws java.io.IOException if there is an error - * @since 2.1 - */ - public static String encodeFromFile( String filename ) - throws java.io.IOException { - - String encodedData = null; - Base64.InputStream bis = null; - try - { - // Set up some useful variables - java.io.File file = new java.io.File( filename ); - byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4),40) ]; // Need max() for math on small files (v2.2.1) - int length = 0; - int numBytes = 0; - - // Open a stream - bis = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( file ) ), Base64.ENCODE ); - - // Read until done - while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) { - length += numBytes; - } // end while - - // Save in a variable to return - encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING ); - - } // end try - catch( java.io.IOException e ) { - throw e; // Catch and release to execute finally{} - } // end catch: java.io.IOException - finally { - try{ bis.close(); } catch( Exception e) {} - } // end finally - - return encodedData; - } // end encodeFromFile - - /** - * Reads infile and encodes it to outfile. - * - * @param infile Input file - * @param outfile Output file - * @throws java.io.IOException if there is an error - * @since 2.2 - */ - public static void encodeFileToFile( String infile, String outfile ) - throws java.io.IOException { - - String encoded = Base64.encodeFromFile( infile ); - java.io.OutputStream out = null; - try{ - out = new java.io.BufferedOutputStream( - new java.io.FileOutputStream( outfile ) ); - out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output. - } // end try - catch( java.io.IOException e ) { - throw e; // Catch and release to execute finally{} - } // end catch - finally { - try { out.close(); } - catch( Exception ex ){} - } // end finally - } // end encodeFileToFile - - - /** - * Reads infile and decodes it to outfile. - * - * @param infile Input file - * @param outfile Output file - * @throws java.io.IOException if there is an error - * @since 2.2 - */ - public static void decodeFileToFile( String infile, String outfile ) - throws java.io.IOException { - - byte[] decoded = Base64.decodeFromFile( infile ); - java.io.OutputStream out = null; - try{ - out = new java.io.BufferedOutputStream( - new java.io.FileOutputStream( outfile ) ); - out.write( decoded ); - } // end try - catch( java.io.IOException e ) { - throw e; // Catch and release to execute finally{} - } // end catch - finally { - try { out.close(); } - catch( Exception ex ){} - } // end finally - } // end decodeFileToFile - - - /* ******** I N N E R C L A S S I N P U T S T R E A M ******** */ - - - - /** - * A {@link Base64.InputStream} will read data from another - * java.io.InputStream, given in the constructor, - * and encode/decode to/from Base64 notation on the fly. - * - * @see Base64 - * @since 1.3 - */ - public static class InputStream extends java.io.FilterInputStream { - - private boolean encode; // Encoding or decoding - private int position; // Current position in the buffer - private byte[] buffer; // Small buffer holding converted data - private int bufferLength; // Length of buffer (3 or 4) - private int numSigBytes; // Number of meaningful bytes in the buffer - private int lineLength; - private boolean breakLines; // Break lines at less than 80 characters - private int options; // Record options used to create the stream. - private byte[] decodabet; // Local copies to avoid extra method calls - - - /** - * Constructs a {@link Base64.InputStream} in DECODE mode. - * - * @param in the java.io.InputStream from which to read data. - * @since 1.3 - */ - public InputStream( java.io.InputStream in ) { - this( in, DECODE ); - } // end constructor - - - /** - * Constructs a {@link Base64.InputStream} in - * either ENCODE or DECODE mode. - *

- * Valid options:

-         *   ENCODE or DECODE: Encode or Decode as data is read.
-         *   DO_BREAK_LINES: break lines at 76 characters
-         *     (only meaningful when encoding)
-         * 
- *

- * Example: new Base64.InputStream( in, Base64.DECODE ) - * - * - * @param in the java.io.InputStream from which to read data. - * @param options Specified options - * @see Base64#ENCODE - * @see Base64#DECODE - * @see Base64#DO_BREAK_LINES - * @since 2.0 - */ - public InputStream( java.io.InputStream in, int options ) { - - super( in ); - this.options = options; // Record for later - this.breakLines = (options & DO_BREAK_LINES) > 0; - this.encode = (options & ENCODE) > 0; - this.bufferLength = encode ? 4 : 3; - this.buffer = new byte[ bufferLength ]; - this.position = -1; - this.lineLength = 0; - this.decodabet = getDecodabet(options); - } // end constructor - - /** - * Reads enough of the input stream to convert - * to/from Base64 and returns the next byte. - * - * @return next byte - * @since 1.3 - */ - @Override - public int read() throws java.io.IOException { - - // Do we need to get data? - if( position < 0 ) { - if( encode ) { - byte[] b3 = new byte[3]; - int numBinaryBytes = 0; - for( int i = 0; i < 3; i++ ) { - int b = in.read(); - - // If end of stream, b is -1. - if( b >= 0 ) { - b3[i] = (byte)b; - numBinaryBytes++; - } else { - break; // out of for loop - } // end else: end of stream - - } // end for: each needed input byte - - if( numBinaryBytes > 0 ) { - encode3to4( b3, 0, numBinaryBytes, buffer, 0, options ); - position = 0; - numSigBytes = 4; - } // end if: got data - else { - return -1; // Must be end of stream - } // end else - } // end if: encoding - - // Else decoding - else { - byte[] b4 = new byte[4]; - int i = 0; - for( i = 0; i < 4; i++ ) { - // Read four "meaningful" bytes: - int b = 0; - do{ b = in.read(); } - while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC ); - - if( b < 0 ) { - break; // Reads a -1 if end of stream - } // end if: end of stream - - b4[i] = (byte)b; - } // end for: each needed input byte - - if( i == 4 ) { - numSigBytes = decode4to3( b4, 0, buffer, 0, options ); - position = 0; - } // end if: got four characters - else if( i == 0 ){ - return -1; - } // end else if: also padded correctly - else { - // Must have broken out from above. - throw new java.io.IOException( "Improperly padded Base64 input." ); - } // end - - } // end else: decode - } // end else: get data - - // Got data? - if( position >= 0 ) { - // End of relevant data? - if( /*!encode &&*/ position >= numSigBytes ){ - return -1; - } // end if: got data - - if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) { - lineLength = 0; - return '\n'; - } // end if - else { - lineLength++; // This isn't important when decoding - // but throwing an extra "if" seems - // just as wasteful. - - int b = buffer[ position++ ]; - - if( position >= bufferLength ) { - position = -1; - } // end if: end - - return b & 0xFF; // This is how you "cast" a byte that's - // intended to be unsigned. - } // end else - } // end if: position >= 0 - - // Else error - else { - throw new java.io.IOException( "Error in Base64 code reading stream." ); - } // end else - } // end read - - - /** - * Calls {@link #read()} repeatedly until the end of stream - * is reached or len bytes are read. - * Returns number of bytes read into array or -1 if - * end of stream is encountered. - * - * @param dest array to hold values - * @param off offset for array - * @param len max number of bytes to read into array - * @return bytes read into array or -1 if end of stream is encountered. - * @since 1.3 - */ - @Override - public int read( byte[] dest, int off, int len ) - throws java.io.IOException { - int i; - int b; - for( i = 0; i < len; i++ ) { - b = read(); - - if( b >= 0 ) { - dest[off + i] = (byte) b; - } - else if( i == 0 ) { - return -1; - } - else { - break; // Out of 'for' loop - } // Out of 'for' loop - } // end for: each byte read - return i; - } // end read - - } // end inner class InputStream - - - - - - - /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */ - - - - /** - * A {@link Base64.OutputStream} will write data to another - * java.io.OutputStream, given in the constructor, - * and encode/decode to/from Base64 notation on the fly. - * - * @see Base64 - * @since 1.3 - */ - public static class OutputStream extends java.io.FilterOutputStream { - - private boolean encode; - private int position; - private byte[] buffer; - private int bufferLength; - private int lineLength; - private boolean breakLines; - private byte[] b4; // Scratch used in a few places - private boolean suspendEncoding; - private int options; // Record for later - private byte[] decodabet; // Local copies to avoid extra method calls - - /** - * Constructs a {@link Base64.OutputStream} in ENCODE mode. - * - * @param out the java.io.OutputStream to which data will be written. - * @since 1.3 - */ - public OutputStream( java.io.OutputStream out ) { - this( out, ENCODE ); - } // end constructor - - - /** - * Constructs a {@link Base64.OutputStream} in - * either ENCODE or DECODE mode. - *

- * Valid options:

-         *   ENCODE or DECODE: Encode or Decode as data is read.
-         *   DO_BREAK_LINES: don't break lines at 76 characters
-         *     (only meaningful when encoding)
-         * 
- *

- * Example: new Base64.OutputStream( out, Base64.ENCODE ) - * - * @param out the java.io.OutputStream to which data will be written. - * @param options Specified options. - * @see Base64#ENCODE - * @see Base64#DECODE - * @see Base64#DO_BREAK_LINES - * @since 1.3 - */ - public OutputStream( java.io.OutputStream out, int options ) { - super( out ); - this.breakLines = (options & DO_BREAK_LINES) > 0; - this.encode = (options & ENCODE) > 0; - this.bufferLength = encode ? 3 : 4; - this.buffer = new byte[ bufferLength ]; - this.position = 0; - this.lineLength = 0; - this.suspendEncoding = false; - this.b4 = new byte[4]; - this.options = options; - this.decodabet = getDecodabet(options); - } // end constructor - - - /** - * Writes the byte to the output stream after - * converting to/from Base64 notation. - * When encoding, bytes are buffered three - * at a time before the output stream actually - * gets a write() call. - * When decoding, bytes are buffered four - * at a time. - * - * @param theByte the byte to write - * @since 1.3 - */ - @Override - public void write(int theByte) - throws java.io.IOException { - // Encoding suspended? - if( suspendEncoding ) { - super.out.write( theByte ); - return; - } // end if: supsended - - // Encode? - if( encode ) { - buffer[ position++ ] = (byte)theByte; - if( position >= bufferLength ) { // Enough to encode. - - out.write( encode3to4( b4, buffer, bufferLength, options ) ); - - lineLength += 4; - if( breakLines && lineLength >= MAX_LINE_LENGTH ) { - out.write( NEW_LINE ); - lineLength = 0; - } // end if: end of line - - position = 0; - } // end if: enough to output - } // end if: encoding - - // Else, Decoding - else { - // Meaningful Base64 character? - if( decodabet[ theByte & 0x7f ] > WHITE_SPACE_ENC ) { - buffer[ position++ ] = (byte)theByte; - if( position >= bufferLength ) { // Enough to output. - - int len = Base64.decode4to3( buffer, 0, b4, 0, options ); - out.write( b4, 0, len ); - position = 0; - } // end if: enough to output - } // end if: meaningful base64 character - else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC ) { - throw new java.io.IOException( "Invalid character in Base64 data." ); - } // end else: not white space either - } // end else: decoding - } // end write - - - - /** - * Calls {@link #write(int)} repeatedly until len - * bytes are written. - * - * @param theBytes array from which to read bytes - * @param off offset for array - * @param len max number of bytes to read into array - * @since 1.3 - */ - @Override - public void write( byte[] theBytes, int off, int len ) - throws java.io.IOException { - // Encoding suspended? - if( suspendEncoding ) { - super.out.write( theBytes, off, len ); - return; - } // end if: supsended - - for( int i = 0; i < len; i++ ) { - write( theBytes[ off + i ] ); - } // end for: each byte written - - } // end write - - - - /** - * Method added by PHIL. [Thanks, PHIL. -Rob] - * This pads the buffer without closing the stream. - * @throws java.io.IOException if there's an error. - */ - public void flushBase64() throws java.io.IOException { - if( position > 0 ) { - if( encode ) { - out.write( encode3to4( b4, buffer, position, options ) ); - position = 0; - } // end if: encoding - else { - throw new java.io.IOException( "Base64 input not properly padded." ); - } // end else: decoding - } // end if: buffer partially full - - } // end flush - - /** - * Flushes the stream (and the enclosing streams). - * @throws java.io.IOException - * @since 2.3 - */ - @Override - public void flush() throws java.io.IOException { - flushBase64(); - super.flush(); - } - - /** - * Flushes and closes (I think, in the superclass) the stream. - * - * @since 1.3 - */ - @Override - public void close() throws java.io.IOException { - // 1. Ensure that pending characters are written - flush(); - - // 2. Actually close the stream - // Base class both flushes and closes. - super.close(); - - buffer = null; - out = null; - } // end close - - - - /** - * Suspends encoding of the stream. - * May be helpful if you need to embed a piece of - * base64-encoded data in a stream. - * - * @throws java.io.IOException if there's an error flushing - * @since 1.5.1 - */ - public void suspendEncoding() throws java.io.IOException { - flushBase64(); - this.suspendEncoding = true; - } // end suspendEncoding - - - /** - * Resumes encoding of the stream. - * May be helpful if you need to embed a piece of - * base64-encoded data in a stream. - * - * @since 1.5.1 - */ - public void resumeEncoding() { - this.suspendEncoding = false; - } // end resumeEncoding - - - - } // end inner class OutputStream - - -} // end class Base64 diff --git a/app/src/main/java/org/transdroid/core/app/settings/SettingsUtils.java b/app/src/main/java/org/transdroid/core/app/settings/SettingsUtils.java index 79989549..1c5a2834 100644 --- a/app/src/main/java/org/transdroid/core/app/settings/SettingsUtils.java +++ b/app/src/main/java/org/transdroid/core/app/settings/SettingsUtils.java @@ -2,8 +2,8 @@ package org.transdroid.core.app.settings; import android.content.Context; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.app.AppCompatDelegate; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDelegate; import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.Theme; diff --git a/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java b/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java index 2ec7ee0e..2dc28601 100644 --- a/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java @@ -20,8 +20,8 @@ import android.annotation.TargetApi; import android.content.Intent; import android.os.Build; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import com.nispok.snackbar.Snackbar; import com.nispok.snackbar.SnackbarManager; diff --git a/app/src/main/java/org/transdroid/core/gui/DetailsFragment.java b/app/src/main/java/org/transdroid/core/gui/DetailsFragment.java index d701d54e..c4b8baf2 100644 --- a/app/src/main/java/org/transdroid/core/gui/DetailsFragment.java +++ b/app/src/main/java/org/transdroid/core/gui/DetailsFragment.java @@ -23,9 +23,9 @@ import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.ActionMenuView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.ActionMenuView; import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; diff --git a/app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java b/app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java index dd7c5036..297dec6c 100644 --- a/app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java +++ b/app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java @@ -16,8 +16,8 @@ */ package org.transdroid.core.gui; -import android.support.v7.widget.ActionMenuView; -import android.support.v7.widget.Toolbar; +import androidx.appcompat.widget.ActionMenuView; +import androidx.appcompat.widget.Toolbar; import org.transdroid.daemon.Priority; import org.transdroid.daemon.Torrent; diff --git a/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java b/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java index 054f140a..0d67a33f 100644 --- a/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java @@ -24,14 +24,14 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.view.MenuItemCompat; -import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.ActionBarDrawerToggle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.ActionMenuView; -import android.support.v7.widget.SearchView; -import android.support.v7.widget.Toolbar; +import androidx.annotation.NonNull; +import androidx.core.view.MenuItemCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.ActionMenuView; +import androidx.appcompat.widget.SearchView; +import androidx.appcompat.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; diff --git a/app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java b/app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java index 9553e107..9e2dccd0 100644 --- a/app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java +++ b/app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java @@ -18,10 +18,10 @@ package org.transdroid.core.gui; import android.app.Fragment; import android.content.Context; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.ActionMenuView; -import android.support.v7.widget.Toolbar; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.ActionMenuView; +import androidx.appcompat.widget.Toolbar; import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; diff --git a/app/src/main/java/org/transdroid/core/gui/TransdroidApp.java b/app/src/main/java/org/transdroid/core/gui/TransdroidApp.java index 54c5088e..0f8299b0 100644 --- a/app/src/main/java/org/transdroid/core/gui/TransdroidApp.java +++ b/app/src/main/java/org/transdroid/core/gui/TransdroidApp.java @@ -17,8 +17,8 @@ package org.transdroid.core.gui; import android.app.Application; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.evernote.android.job.JobConfig; import com.evernote.android.job.JobManager; import com.evernote.android.job.util.JobLogger; diff --git a/app/src/main/java/org/transdroid/core/gui/log/DatabaseHelper.java b/app/src/main/java/org/transdroid/core/gui/log/DatabaseHelper.java index 448a3df9..dda98570 100644 --- a/app/src/main/java/org/transdroid/core/gui/log/DatabaseHelper.java +++ b/app/src/main/java/org/transdroid/core/gui/log/DatabaseHelper.java @@ -20,7 +20,7 @@ import java.sql.SQLException; import android.content.Context; import android.database.sqlite.SQLiteDatabase; -import android.support.annotation.Keep; +import androidx.annotation.Keep; import android.util.Log; import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper; diff --git a/app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java b/app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java index 2051c814..c7018530 100644 --- a/app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java +++ b/app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java @@ -26,9 +26,9 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; -import android.support.annotation.NonNull; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; +import androidx.annotation.NonNull; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; import android.text.Spannable; import android.text.SpannableString; import android.text.style.TypefaceSpan; diff --git a/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java index 43cb2e87..088292c8 100644 --- a/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java +++ b/app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java @@ -17,7 +17,7 @@ package org.transdroid.core.gui.remoterss; -import android.support.v4.app.Fragment; +import androidx.fragment.app.Fragment; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; diff --git a/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java b/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java index 06035b47..c5eba827 100644 --- a/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java @@ -22,13 +22,13 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Parcel; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.design.widget.TabLayout; -import android.support.v4.view.PagerAdapter; -import android.support.v4.view.ViewPager; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.google.android.material.tabs.TabLayout; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsFragment.java b/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsFragment.java index 894bf4f0..f60acf9f 100644 --- a/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsFragment.java +++ b/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsFragment.java @@ -16,7 +16,7 @@ */ package org.transdroid.core.gui.rss; -import android.support.v4.app.Fragment; +import androidx.fragment.app.Fragment; import android.view.Menu; import android.view.MenuItem; import android.view.View; diff --git a/app/src/main/java/org/transdroid/core/gui/rss/RssItemsActivity.java b/app/src/main/java/org/transdroid/core/gui/rss/RssItemsActivity.java index 46e9a7aa..7f9794da 100644 --- a/app/src/main/java/org/transdroid/core/gui/rss/RssItemsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/rss/RssItemsActivity.java @@ -20,8 +20,8 @@ import android.annotation.TargetApi; import android.content.Intent; import android.os.Build; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.EActivity; diff --git a/app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java b/app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java index e14c42cf..48133995 100644 --- a/app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java +++ b/app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java @@ -23,8 +23,8 @@ import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.support.v4.app.Fragment; -import android.support.v7.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.appcompat.app.AppCompatActivity; import android.text.TextUtils; import android.view.ActionMode; import android.view.Menu; diff --git a/app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java b/app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java index d7f85bf4..254840fe 100644 --- a/app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java @@ -23,9 +23,9 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.SearchRecentSuggestions; -import android.support.v4.view.MenuItemCompat; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import androidx.core.view.MenuItemCompat; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; diff --git a/app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java b/app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java index 696d43b0..59d19702 100644 --- a/app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java +++ b/app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java @@ -20,7 +20,7 @@ import android.app.Fragment; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.text.TextUtils; import android.view.ActionMode; import android.view.Menu; diff --git a/app/src/main/java/org/transdroid/core/gui/settings/InterceptableEditTextPreference.java b/app/src/main/java/org/transdroid/core/gui/settings/InterceptableEditTextPreference.java index 71e48b96..c0b49954 100644 --- a/app/src/main/java/org/transdroid/core/gui/settings/InterceptableEditTextPreference.java +++ b/app/src/main/java/org/transdroid/core/gui/settings/InterceptableEditTextPreference.java @@ -3,7 +3,7 @@ package org.transdroid.core.gui.settings; import android.content.Context; import android.os.Build; import android.preference.EditTextPreference; -import android.support.annotation.RequiresApi; +import androidx.annotation.RequiresApi; import android.util.AttributeSet; public class InterceptableEditTextPreference extends EditTextPreference { diff --git a/app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java b/app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java index 6553f068..8cd67c2d 100644 --- a/app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java @@ -3,11 +3,11 @@ package org.transdroid.core.gui.settings; import android.content.res.Configuration; import android.os.Bundle; import android.preference.PreferenceActivity; -import android.support.annotation.Nullable; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatCallback; -import android.support.v7.app.AppCompatDelegate; -import android.support.v7.view.ActionMode; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatCallback; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.view.ActionMode; public class PreferenceCompatActivity extends PreferenceActivity implements AppCompatCallback { diff --git a/app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java b/app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java index 8d3c4727..e8b85992 100644 --- a/app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java @@ -28,7 +28,7 @@ import android.os.Bundle; import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.PreferenceManager; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.EActivity; import org.androidannotations.annotations.OptionsItem; diff --git a/app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java b/app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java index ebc1e066..2995086d 100644 --- a/app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java @@ -28,7 +28,7 @@ import android.os.Bundle; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceManager; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import android.text.TextUtils; import com.nispok.snackbar.Snackbar; diff --git a/app/src/main/java/org/transdroid/core/service/AppUpdateJob.java b/app/src/main/java/org/transdroid/core/service/AppUpdateJob.java index 62197eec..cf50c4c7 100644 --- a/app/src/main/java/org/transdroid/core/service/AppUpdateJob.java +++ b/app/src/main/java/org/transdroid/core/service/AppUpdateJob.java @@ -17,7 +17,7 @@ package org.transdroid.core.service; import android.content.Context; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.evernote.android.job.Job; import com.evernote.android.job.JobManager; import com.evernote.android.job.JobRequest; diff --git a/app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java b/app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java index ce41ddb9..23afcd45 100644 --- a/app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java +++ b/app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java @@ -23,7 +23,7 @@ import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; -import android.support.v4.app.NotificationCompat; +import androidx.core.app.NotificationCompat; import com.evernote.android.job.Job; diff --git a/app/src/main/java/org/transdroid/core/service/ConnectivityHelper.java b/app/src/main/java/org/transdroid/core/service/ConnectivityHelper.java index 4e532d36..ad0497c4 100644 --- a/app/src/main/java/org/transdroid/core/service/ConnectivityHelper.java +++ b/app/src/main/java/org/transdroid/core/service/ConnectivityHelper.java @@ -23,9 +23,9 @@ import android.content.DialogInterface; import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AlertDialog; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.appcompat.app.AlertDialog; import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EBean.Scope; import org.androidannotations.annotations.SystemService; diff --git a/app/src/main/java/org/transdroid/core/service/RssCheckerJob.java b/app/src/main/java/org/transdroid/core/service/RssCheckerJob.java index 85bf6479..066ce99a 100644 --- a/app/src/main/java/org/transdroid/core/service/RssCheckerJob.java +++ b/app/src/main/java/org/transdroid/core/service/RssCheckerJob.java @@ -17,7 +17,7 @@ package org.transdroid.core.service; import android.content.Context; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.evernote.android.job.Job; import com.evernote.android.job.JobManager; import com.evernote.android.job.JobRequest; diff --git a/app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java b/app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java index 910c90da..f1343a96 100644 --- a/app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java +++ b/app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java @@ -20,7 +20,7 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.support.v4.app.NotificationCompat; +import androidx.core.app.NotificationCompat; import com.evernote.android.job.Job; diff --git a/app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java b/app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java index 450aeacf..01f8c0f4 100644 --- a/app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java +++ b/app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java @@ -16,8 +16,8 @@ */ package org.transdroid.core.service; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.evernote.android.job.Job; import com.evernote.android.job.JobCreator; diff --git a/app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java b/app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java index a0f05bba..218bc129 100644 --- a/app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java +++ b/app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java @@ -17,7 +17,7 @@ package org.transdroid.core.service; import android.content.Context; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.evernote.android.job.Job; import com.evernote.android.job.JobManager; import com.evernote.android.job.JobRequest; diff --git a/app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java b/app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java index 8573dfae..094ef47f 100644 --- a/app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java +++ b/app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java @@ -20,7 +20,7 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.support.v4.app.NotificationCompat; +import androidx.core.app.NotificationCompat; import android.text.TextUtils; import com.evernote.android.job.Job; import org.androidannotations.annotations.Bean; diff --git a/app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java b/app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java index 73f806bb..e4d7d68d 100644 --- a/app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java +++ b/app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java @@ -22,8 +22,8 @@ import android.appwidget.AppWidgetManager; import android.content.Intent; import android.os.Build; import android.os.Bundle; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; import android.view.View; import android.view.View.OnClickListener; import android.widget.CheckBox; diff --git a/app/src/main/java/org/transdroid/core/widget/ListWidgetProvider.java b/app/src/main/java/org/transdroid/core/widget/ListWidgetProvider.java index 2ef2b471..efc38d58 100644 --- a/app/src/main/java/org/transdroid/core/widget/ListWidgetProvider.java +++ b/app/src/main/java/org/transdroid/core/widget/ListWidgetProvider.java @@ -24,7 +24,7 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import android.widget.RemoteViews; import org.androidannotations.annotations.Bean; diff --git a/app/src/main/java/org/transdroid/daemon/Aria2c/Aria2Adapter.java b/app/src/main/java/org/transdroid/daemon/Aria2c/Aria2Adapter.java index 1e02ef9e..d7806e80 100644 --- a/app/src/main/java/org/transdroid/daemon/Aria2c/Aria2Adapter.java +++ b/app/src/main/java/org/transdroid/daemon/Aria2c/Aria2Adapter.java @@ -1,19 +1,19 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.Aria2c; @@ -25,7 +25,7 @@ import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; -import org.base64.android.Base64; +import net.iharder.Base64; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -360,27 +360,27 @@ public class Aria2Adapter implements IDaemonAdapter { } // @formatter:off torrents.add(new Torrent( - j, - tor.getString("gid"), - name, - status, - tor.getString("dir"), + j, + tor.getString("gid"), + name, + status, + tor.getString("dir"), downloadSpeed, - tor.getInt("uploadSpeed"), - tor.getInt("connections"), - numSeeders , - tor.getInt("connections"), - numSeeders, - (downloadSpeed > 0? (int) (totalLength / downloadSpeed): -1), - completedLength, + tor.getInt("uploadSpeed"), + tor.getInt("connections"), + numSeeders , + tor.getInt("connections"), + numSeeders, + (downloadSpeed > 0? (int) (totalLength / downloadSpeed): -1), + completedLength, tor.getLong("uploadLength"), - totalLength, + totalLength, completedLength / (float) totalLength, // Percentage to [0..1] 0f, // Not available null, // Not available null, // Not available null, // Not available - error, + error, settings.getType())); // @formatter:on @@ -403,12 +403,12 @@ public class Aria2Adapter implements IDaemonAdapter { } // @formatter:off files.add(new TorrentFile( - Integer.toString(file.getInt("index")), - rel, - rel, - file.getString("path"), + Integer.toString(file.getInt("index")), + rel, + rel, + file.getString("path"), file.getLong("length"), - file.getLong("completedLength"), + file.getLong("completedLength"), file.getBoolean("selected") ? Priority.Normal : Priority.Off)); // @formatter:on diff --git a/app/src/main/java/org/transdroid/daemon/BitComet/BitCometAdapter.java b/app/src/main/java/org/transdroid/daemon/BitComet/BitCometAdapter.java index ba313bf7..3d758188 100644 --- a/app/src/main/java/org/transdroid/daemon/BitComet/BitCometAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/BitComet/BitCometAdapter.java @@ -1,26 +1,26 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.BitComet; -import com.android.internalcopy.http.multipart.BitCometFilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; -import com.android.internalcopy.http.multipart.Utf8StringPart; +import org.transdroid.multipart.BitCometFilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; +import org.transdroid.multipart.Utf8StringPart; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; diff --git a/app/src/main/java/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java b/app/src/main/java/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java index e054db1a..80211e74 100644 --- a/app/src/main/java/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java @@ -1,25 +1,25 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.BuffaloNas; -import com.android.internalcopy.http.multipart.FilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; +import com.android.internal.http.multipart.FilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -108,8 +108,8 @@ public class BuffaloNasAdapter implements IDaemonAdapter { // Request to add a torrent by URL String url = ((AddByUrlTask) task).getUrl(); // @formatter:off - makeRequest(log, "/api/torrent-add", - new BasicNameValuePair("url", url), + makeRequest(log, "/api/torrent-add", + new BasicNameValuePair("url", url), new BasicNameValuePair("start", "yes")); // @formatter:on return new DaemonTaskSuccessResult(task); @@ -119,9 +119,9 @@ public class BuffaloNasAdapter implements IDaemonAdapter { // Remove a torrent RemoveTask removeTask = (RemoveTask) task; // @formatter:off - makeRequest(log, "/api/torrent-remove", - new BasicNameValuePair("hash", removeTask.getTargetTorrent().getUniqueID()), - new BasicNameValuePair("delete-torrent", "yes"), + makeRequest(log, "/api/torrent-remove", + new BasicNameValuePair("hash", removeTask.getTargetTorrent().getUniqueID()), + new BasicNameValuePair("delete-torrent", "yes"), new BasicNameValuePair("delete-data", (removeTask.includingData() ? "yes" : "no"))); // @formatter:on return new DaemonTaskSuccessResult(task); @@ -149,9 +149,9 @@ public class BuffaloNasAdapter implements IDaemonAdapter { String ul = Integer.toString( (ratesTask.getUploadRate() == null ? -1 : ratesTask.getUploadRate() * 1024)); // @formatter:off - makeRequest(log, "/api/app-settings-set", + makeRequest(log, "/api/app-settings-set", new BasicNameValuePair("auto_bandwidth_management", "0"), - new BasicNameValuePair("max_dl_rate", dl), + new BasicNameValuePair("max_dl_rate", dl), new BasicNameValuePair("max_ul_rate", ul), new BasicNameValuePair("max_ul_rate_seed", ul)); // @formatter:on diff --git a/app/src/main/java/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java b/app/src/main/java/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java index fab3d6fb..8cf3c74e 100644 --- a/app/src/main/java/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java @@ -1,25 +1,25 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.DLinkRouterBT; -import com.android.internalcopy.http.multipart.FilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; +import com.android.internal.http.multipart.FilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -358,23 +358,23 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { // @formatter:off Torrent new_t = new Torrent( - i, - tor.getString(BT_HASH), - tor.getString(BT_CAPTION), + i, + tor.getString(BT_HASH), + tor.getString(BT_CAPTION), status, null, // Not supported? - tor.getInt(BT_DOWNLOAD_RATE), - tor.getInt(BT_UPLOAD_RATE), - tor.getInt(BT_PEERS_CONNECTED), - tor.getInt(BT_PEERS_TOTAL), - tor.getInt(BT_SEEDS_CONNECTED), + tor.getInt(BT_DOWNLOAD_RATE), + tor.getInt(BT_UPLOAD_RATE), + tor.getInt(BT_PEERS_CONNECTED), + tor.getInt(BT_PEERS_TOTAL), + tor.getInt(BT_SEEDS_CONNECTED), tor.getInt(BT_SEEDS_TOTAL), eta, - tor.getLong(BT_DONE), - tor.getLong(BT_PAYLOAD_UPLOAD), - tor.getLong(BT_SIZE), + tor.getLong(BT_DONE), + tor.getLong(BT_PAYLOAD_UPLOAD), + tor.getLong(BT_SIZE), tor.getLong(BT_DONE) / (float) tor.getLong(BT_SIZE), - Float.parseFloat(tor.getString(BT_COPYS)), + Float.parseFloat(tor.getString(BT_COPYS)), null, null, null, @@ -402,11 +402,11 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { // @formatter:off torrentfiles.add(new TorrentFile( String.valueOf(i), - file.getString(BT_FILE_NAME), - file.getString(BT_FILE_NAME), + file.getString(BT_FILE_NAME), + file.getString(BT_FILE_NAME), null, // Not supported? - file.getLong(BT_FILE_SIZE), - file.getLong(BT_FILE_DONE), + file.getLong(BT_FILE_SIZE), + file.getLong(BT_FILE_DONE), convertTransmissionPriority(file.getInt(BT_FILE_PRIORITY)))); // @formatter:on } diff --git a/app/src/main/java/org/transdroid/daemon/DaemonException.java b/app/src/main/java/org/transdroid/daemon/DaemonException.java index ca367540..29040814 100644 --- a/app/src/main/java/org/transdroid/daemon/DaemonException.java +++ b/app/src/main/java/org/transdroid/daemon/DaemonException.java @@ -18,7 +18,7 @@ package org.transdroid.daemon; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; /** * An exception thrown when an error occurs inside a server daemon adapter. diff --git a/app/src/main/java/org/transdroid/daemon/Deluge/DelugeAdapter.java b/app/src/main/java/org/transdroid/daemon/Deluge/DelugeAdapter.java index cc62339b..61180a7a 100644 --- a/app/src/main/java/org/transdroid/daemon/Deluge/DelugeAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/Deluge/DelugeAdapter.java @@ -17,9 +17,9 @@ */ package org.transdroid.daemon.Deluge; -import com.android.internalcopy.http.multipart.FilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; +import com.android.internal.http.multipart.FilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -418,7 +418,7 @@ public class DelugeAdapter implements IDaemonAdapter { return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.FileAccessError, e.toString())); } } - + /*private JSONArray buildSetTorrentOptions(String torrent, String key, String value) throws JSONException { JSONArray params = new JSONArray(); params.put(new JSONArray().put(torrent)); // torrent_id diff --git a/app/src/main/java/org/transdroid/daemon/Deluge/DelugeCommon.java b/app/src/main/java/org/transdroid/daemon/Deluge/DelugeCommon.java index 73622761..fdb76964 100644 --- a/app/src/main/java/org/transdroid/daemon/Deluge/DelugeCommon.java +++ b/app/src/main/java/org/transdroid/daemon/Deluge/DelugeCommon.java @@ -17,7 +17,7 @@ */ package org.transdroid.daemon.Deluge; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import org.transdroid.daemon.Priority; import org.transdroid.daemon.TorrentStatus; diff --git a/app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcAdapter.java b/app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcAdapter.java index 252cab19..31e371f3 100644 --- a/app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcAdapter.java @@ -17,8 +17,8 @@ */ package org.transdroid.daemon.Deluge; -import android.support.annotation.NonNull; -import org.base64.android.Base64; +import androidx.annotation.NonNull; +import net.iharder.Base64; import org.transdroid.core.gui.log.Log; import org.transdroid.core.gui.remoterss.data.RemoteRssChannel; import org.transdroid.core.gui.remoterss.data.RemoteRssItem; diff --git a/app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java b/app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java index 9906d560..47069f04 100644 --- a/app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java +++ b/app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java @@ -17,7 +17,7 @@ */ package org.transdroid.daemon.Deluge; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import org.transdroid.daemon.DaemonException; import org.transdroid.daemon.DaemonException.ExceptionType; import org.transdroid.daemon.DaemonSettings; diff --git a/app/src/main/java/org/transdroid/daemon/Ktorrent/KtorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/Ktorrent/KtorrentAdapter.java index 4455b051..287a93e3 100644 --- a/app/src/main/java/org/transdroid/daemon/Ktorrent/KtorrentAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/Ktorrent/KtorrentAdapter.java @@ -1,25 +1,25 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.Ktorrent; -import com.android.internalcopy.http.multipart.FilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; +import com.android.internal.http.multipart.FilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; diff --git a/app/src/main/java/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java index 2b81edfe..83bb4407 100644 --- a/app/src/main/java/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java @@ -17,9 +17,9 @@ */ package org.transdroid.daemon.Qbittorrent; -import com.android.internalcopy.http.multipart.FilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; +import com.android.internal.http.multipart.FilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; diff --git a/app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java b/app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java index dca623f1..4bc720e7 100644 --- a/app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java @@ -1,26 +1,26 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.Synology; -import com.android.internalcopy.http.multipart.FilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; -import com.android.internalcopy.http.multipart.Utf8StringPart; +import com.android.internal.http.multipart.FilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; +import org.transdroid.multipart.Utf8StringPart; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; diff --git a/app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java b/app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java index ddfa5bed..f75ac761 100644 --- a/app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java @@ -1,19 +1,19 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.Tfb4rt; @@ -47,9 +47,9 @@ import org.transdroid.daemon.task.RemoveTask; import org.transdroid.daemon.task.RetrieveTask; import org.transdroid.daemon.task.RetrieveTaskSuccessResult; import org.transdroid.daemon.util.HttpHelper; -import com.android.internalcopy.http.multipart.FilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; +import com.android.internal.http.multipart.FilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; /** * An adapter that allows for easy access to Torrentflux-b4rt installs. Communication is handled via HTTP GET requests diff --git a/app/src/main/java/org/transdroid/daemon/Transmission/TransmissionAdapter.java b/app/src/main/java/org/transdroid/daemon/Transmission/TransmissionAdapter.java index 2cf42baf..7acc1e85 100644 --- a/app/src/main/java/org/transdroid/daemon/Transmission/TransmissionAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/Transmission/TransmissionAdapter.java @@ -22,8 +22,8 @@ import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; -import org.base64.android.Base64; -import org.base64.android.Base64.InputStream; +import net.iharder.Base64; +import net.iharder.Base64.InputStream; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -192,7 +192,7 @@ public class TransmissionAdapter implements IDaemonAdapter { // Encode the .torrent file's data InputStream in = - new Base64.InputStream(new FileInputStream(new File(URI.create(file))), Base64.ENCODE); + new InputStream(new FileInputStream(new File(URI.create(file))), Base64.ENCODE); StringWriter writer = new StringWriter(); int c; while ((c = in.read()) != -1) { diff --git a/app/src/main/java/org/transdroid/daemon/Ttorrent/TtorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/Ttorrent/TtorrentAdapter.java index 53fa05d3..3f4ea1de 100644 --- a/app/src/main/java/org/transdroid/daemon/Ttorrent/TtorrentAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/Ttorrent/TtorrentAdapter.java @@ -1,25 +1,25 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.Ttorrent; -import com.android.internalcopy.http.multipart.FilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; +import com.android.internal.http.multipart.FilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; diff --git a/app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java index 5f2e7b7e..ed43d52e 100644 --- a/app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java @@ -1,25 +1,25 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.Utorrent; -import com.android.internalcopy.http.multipart.FilePart; -import com.android.internalcopy.http.multipart.MultipartEntity; -import com.android.internalcopy.http.multipart.Part; +import com.android.internal.http.multipart.FilePart; +import com.android.internal.http.multipart.MultipartEntity; +import com.android.internal.http.multipart.Part; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; diff --git a/app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java b/app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java index 67eec402..8bfc8b74 100644 --- a/app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java +++ b/app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java @@ -1,19 +1,19 @@ /* * This file is part of Transdroid - * + * * Transdroid is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * Transdroid is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Transdroid. If not, see . - * + * */ package org.transdroid.daemon.Vuze; @@ -43,7 +43,7 @@ import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; -import org.base64.android.Base64; +import net.iharder.Base64; import org.transdroid.daemon.DaemonException; import org.transdroid.daemon.DaemonSettings; import org.transdroid.daemon.DaemonException.ExceptionType; @@ -56,16 +56,16 @@ import org.xmlpull.v1.XmlSerializer; import android.util.Xml; /** - * Implements an XML-RPC-like client that build and parses XML following + * Implements an XML-RPC-like client that build and parses XML following * Vuze's XML over HTTP plug-in (which unfortunately is incompatible with * the default XML-RPC protocol). - * + * * The documentation can be found at http://azureus.sourceforge.net/plugin_details.php?plugin=xml_http_if&docu=1#1 * and some stuff is at http://wiki.vuze.com/index.php/XML_over_HTTP - * + * * A lot of it is copied from the org.xmlrpc.android library's XMLRPCClient * as can be found at http://code.google.com/p/android-xmlrpc - * + * * @author erickok * */ @@ -87,7 +87,7 @@ public class VuzeXmlOverHttpClient { private final static String TAG_ANNOUNCE = "announce_result"; private final static String TAG_SCRAPE = "scrape_result"; private final static String TAG_CACHED_PROPERTY_NAMES = "cached_property_names"; - + private DefaultHttpClient client; private HttpPost postMethod; private Random random; @@ -105,14 +105,14 @@ public class VuzeXmlOverHttpClient { postMethod.addHeader("Content-Type", "text/xml"); // WARNING - // I had to disable "Expect: 100-Continue" header since I had - // two second delay between sending http POST request and POST body + // I had to disable "Expect: 100-Continue" header since I had + // two second delay between sending http POST request and POST body HttpParams httpParams = postMethod.getParams(); HttpProtocolParams.setUseExpectContinue(httpParams, false); HttpConnectionParams.setConnectionTimeout(httpParams, settings.getTimeoutInMilliseconds()); - HttpConnectionParams.setSoTimeout(httpParams, settings.getTimeoutInMilliseconds()); - + HttpConnectionParams.setSoTimeout(httpParams, settings.getTimeoutInMilliseconds()); + SchemeRegistry registry = new SchemeRegistry(); SocketFactory httpsSocketFactory; if (settings.getSslTrustKey() != null) { @@ -124,7 +124,7 @@ public class VuzeXmlOverHttpClient { } registry.register(new Scheme("http", new PlainSocketFactory(), 80)); registry.register(new Scheme("https", httpsSocketFactory, 443)); - + client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams); if (settings.shouldUseAuthentication()) { if (settings.getUsername() == null || settings.getPassword() == null) { @@ -137,11 +137,11 @@ public class VuzeXmlOverHttpClient { new UsernamePasswordCredentials(username, password)); } } - + random = new Random(); random.nextInt(); } - + /** * Convenience constructor. Creates new instance based on server String address * @param settings The server connection settings @@ -151,23 +151,23 @@ public class VuzeXmlOverHttpClient { public VuzeXmlOverHttpClient(DaemonSettings settings, String url) throws DaemonException { this(settings, URI.create(url)); } - + protected Map callXMLRPC(Long object, String method, Object[] params, Long connectionID, boolean paramsAreVuzeObjects) throws DaemonException { try { - + // prepare POST body XmlSerializer serializer = Xml.newSerializer(); StringWriter bodyWriter = new StringWriter(); serializer.setOutput(bodyWriter); serializer.startDocument(null, null); serializer.startTag(null, TAG_REQUEST); - + // set object if (object != null) { serializer.startTag(null, TAG_OBJECT).startTag(null, TAG_OBJECT_ID) .text(object.toString()).endTag(null, TAG_OBJECT_ID).endTag(null, TAG_OBJECT); } - + // set method serializer.startTag(null, TAG_METHOD).text(method).endTag(null, TAG_METHOD); if (params != null && params.length != 0) { @@ -188,7 +188,7 @@ public class VuzeXmlOverHttpClient { } serializer.endTag(null, TAG_PARAMS); } - + // set connection id if (connectionID != null) { serializer.startTag(null, TAG_CONNECTION_ID).text(connectionID.toString()).endTag(null, TAG_CONNECTION_ID); @@ -199,16 +199,16 @@ public class VuzeXmlOverHttpClient { serializer.endTag(null, TAG_REQUEST); serializer.endDocument(); - + // set POST body HttpEntity entity = new StringEntity(bodyWriter.toString()); postMethod.setEntity(entity); - + // Force preemptive authentication - // This makes sure there is an 'Authentication: ' header being send before trying and failing and retrying + // This makes sure there is an 'Authentication: ' header being send before trying and failing and retrying // by the basic authentication mechanism of DefaultHttpClient postMethod.addHeader("Authorization", "Basic " + Base64.encodeBytes((username + ":" + password).getBytes())); - + // execute HTTP POST request HttpResponse response = client.execute(postMethod); @@ -225,33 +225,33 @@ public class VuzeXmlOverHttpClient { // setup pull parser XmlPullParser pullParser = XmlPullParserFactory.newInstance().newPullParser(); entity = response.getEntity(); - //String temp = HttpHelper.ConvertStreamToString(entity.getContent()); + //String temp = HttpHelper.ConvertStreamToString(entity.getContent()); //Reader reader = new StringReader(temp); Reader reader = new InputStreamReader(entity.getContent()); pullParser.setInput(reader); - + // lets start pulling... pullParser.nextTag(); pullParser.require(XmlPullParser.START_TAG, null, TAG_RESPONSE); - + // build list of returned values int next = pullParser.nextTag(); // skip to first start tag in list String name = pullParser.getName(); // get name of the first start tag - + // Empty response? if (next == XmlPullParser.END_TAG && name.equals(TAG_RESPONSE)) { - + return null; - + } else if (name.equals(TAG_ERROR)) { - + // Error String errorText = pullParser.nextText(); // the value of the ERROR entity.consumeContent(); throw new DaemonException(ExceptionType.ConnectionError, errorText); - + } else { - + // Consume a list of ENTRYs? if (name.equals(TAG_ENTRY)) { @@ -262,15 +262,15 @@ public class VuzeXmlOverHttpClient { } entity.consumeContent(); return entries; - + } else { - + // Only a single object was returned, not an entry listing return consumeObject(pullParser); } - + } - + } catch (IOException e) { throw new DaemonException(ExceptionType.ConnectionError, e.toString()); } catch (XmlPullParserException e) { @@ -282,11 +282,11 @@ public class VuzeXmlOverHttpClient { int next = pullParser.nextTag(); String name = pullParser.getName(); - + // Consume the ENTRY objects Map returnValues = new HashMap(); while (next == XmlPullParser.START_TAG) { - + if (name.equals(TAG_TORRENT) || name.equals(TAG_ANNOUNCE) || name.equals(TAG_SCRAPE) || name.equals(TAG_STATS)) { // One of the objects contained inside an entry pullParser.nextTag(); @@ -297,21 +297,21 @@ public class VuzeXmlOverHttpClient { } next = pullParser.nextTag(); // skip to next start tag name = pullParser.getName(); // get name of the new start tag - + } - + // Consume ENTRY ending pullParser.nextTag(); - + return returnValues; - + } private Map consumeObject(XmlPullParser pullParser) throws XmlPullParserException, IOException { int next = XmlPullParser.START_TAG; String name = pullParser.getName(); - + // Consume bottom-level (contains no objects of its own) object Map returnValues = new HashMap(); while (next == XmlPullParser.START_TAG && !(name.equals(TAG_CACHED_PROPERTY_NAMES))) { @@ -326,11 +326,11 @@ public class VuzeXmlOverHttpClient { } next = pullParser.nextTag(); // skip to next start tag name = pullParser.getName(); // get name of the new start tag - + } - + return returnValues; - + } private String serialize(Object value) { @@ -344,7 +344,7 @@ public class VuzeXmlOverHttpClient { return null; } - /* For now cast all integers as Long; this prevents casting problems later on when + /* For now cast all integers as Long; this prevents casting problems later on when * we know it's a long but the value was small so it is casted to an Integer here // Integer? try { @@ -353,7 +353,7 @@ public class VuzeXmlOverHttpClient { } catch (NumberFormatException e) { // Just continue trying the next type }*/ - + // Long? try { Long longnum = Long.parseLong(rawText); @@ -361,7 +361,7 @@ public class VuzeXmlOverHttpClient { } catch (NumberFormatException e) { // Just continue trying the next type } - + // Double? try { Double doublenum = Double.parseDouble(rawText); @@ -369,9 +369,9 @@ public class VuzeXmlOverHttpClient { } catch (NumberFormatException e) { // Just continue trying the next type } - + // String otherwise return rawText; } - + } diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/BitCometFilePart.java b/app/src/main/java/org/transdroid/multipart/BitCometFilePart.java similarity index 89% rename from app/src/main/java/com/android/internalcopy/http/multipart/BitCometFilePart.java rename to app/src/main/java/org/transdroid/multipart/BitCometFilePart.java index bc75ef38..d20cea0e 100644 --- a/app/src/main/java/com/android/internalcopy/http/multipart/BitCometFilePart.java +++ b/app/src/main/java/org/transdroid/multipart/BitCometFilePart.java @@ -1,238 +1,242 @@ -/* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $ - * $Revision: 480424 $ - * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package com.android.internalcopy.http.multipart; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import org.apache.http.util.EncodingUtils; - -/** - * This class implements a part of a Multipart post object that - * consists of a file. - * - * @author Matthew Albright - * @author Jeff Dever - * @author Adrian Sutton - * @author Michael Becke - * @author Mark Diggory - * @author Mike Bowler - * @author Oleg Kalnichevski - * - * @since 2.0 - * - */ -public class BitCometFilePart extends PartBase { - - /** Default content encoding of file attachments. */ - public static final String DEFAULT_CONTENT_TYPE = "application/x-bittorrent"; - - /** Attachment's file name */ - protected static final String FILE_NAME = "; filename="; - - /** Attachment's file name as a byte array */ - private static final byte[] FILE_NAME_BYTES = - EncodingUtils.getAsciiBytes(FILE_NAME); - - /** Source of the file part. */ - private PartSource source; - - /** - * FilePart Constructor. - * - * @param name the name for this part - * @param partSource the source for this part - * @param contentType the content type for this part, if null the - * {@link #DEFAULT_CONTENT_TYPE default} is used - * @param charset the charset encoding for this part, if null the - * {@link #DEFAULT_CHARSET default} is used - */ - public BitCometFilePart(String name, PartSource partSource, String contentType, String charset) { - - super( - name, - contentType == null ? DEFAULT_CONTENT_TYPE : contentType, - charset == null ? "ISO-8859-1" : charset, - null - ); - - if (partSource == null) { - throw new IllegalArgumentException("Source may not be null"); - } - this.source = partSource; - } - - /** - * FilePart Constructor. - * - * @param name the name for this part - * @param partSource the source for this part - */ - public BitCometFilePart(String name, PartSource partSource) { - this(name, partSource, null, null); - } - - /** - * FilePart Constructor. - * - * @param name the name of the file part - * @param file the file to post - * - * @throws FileNotFoundException if the file is not a normal - * file or if it is not readable. - */ - public BitCometFilePart(String name, File file) - throws FileNotFoundException { - this(name, new FilePartSource(file), null, null); - } - - /** - * FilePart Constructor. - * - * @param name the name of the file part - * @param file the file to post - * @param contentType the content type for this part, if null the - * {@link #DEFAULT_CONTENT_TYPE default} is used - * @param charset the charset encoding for this part, if null the - * {@link #DEFAULT_CHARSET default} is used - * - * @throws FileNotFoundException if the file is not a normal - * file or if it is not readable. - */ - public BitCometFilePart(String name, File file, String contentType, String charset) - throws FileNotFoundException { - this(name, new FilePartSource(file), contentType, charset); - } - - /** - * FilePart Constructor. - * - * @param name the name of the file part - * @param fileName the file name - * @param file the file to post - * - * @throws FileNotFoundException if the file is not a normal - * file or if it is not readable. - */ - public BitCometFilePart(String name, String fileName, File file) - throws FileNotFoundException { - this(name, new FilePartSource(fileName, file), null, null); - } - - /** - * FilePart Constructor. - * - * @param name the name of the file part - * @param fileName the file name - * @param file the file to post - * @param contentType the content type for this part, if null the - * {@link #DEFAULT_CONTENT_TYPE default} is used - * @param charset the charset encoding for this part, if null the - * {@link #DEFAULT_CHARSET default} is used - * - * @throws FileNotFoundException if the file is not a normal - * file or if it is not readable. - */ - public BitCometFilePart(String name, String fileName, File file, String contentType, String charset) - throws FileNotFoundException { - this(name, new FilePartSource(fileName, file), contentType, charset); - } - - /** - * Write the disposition header to the output stream - * @param out The output stream - * @throws IOException If an IO problem occurs - * @see Part#sendDispositionHeader(OutputStream) - */ - @Override - protected void sendDispositionHeader(OutputStream out) - throws IOException { - super.sendDispositionHeader(out); - String filename = this.source.getFileName(); - if (filename != null) { - out.write(FILE_NAME_BYTES); - out.write(QUOTE_BYTES); - out.write(EncodingUtils.getAsciiBytes(filename)); - out.write(QUOTE_BYTES); - } - } - - /** - * Write the data in "source" to the specified stream. - * @param out The output stream. - * @throws IOException if an IO problem occurs. - * @see Part#sendData(OutputStream) - */ - @Override - protected void sendData(OutputStream out) throws IOException { - if (lengthOfData() == 0) { - - // this file contains no data, so there is nothing to send. - // we don't want to create a zero length buffer as this will - // cause an infinite loop when reading. - return; - } - - byte[] tmp = new byte[4096]; - InputStream instream = source.createInputStream(); - try { - int len; - while ((len = instream.read(tmp)) >= 0) { - out.write(tmp, 0, len); - } - } finally { - // we're done with the stream, close it - instream.close(); - } - } - - /** - * Returns the source of the file part. - * - * @return The source. - */ - protected PartSource getSource() { - return this.source; - } - - /** - * Return the length of the data. - * @return The length. - * @see Part#lengthOfData() - */ - @Override - protected long lengthOfData() { - return source.getLength(); - } - -} +/* + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $ + * $Revision: 480424 $ + * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ + * + * ==================================================================== + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.transdroid.multipart; + +import com.android.internal.http.multipart.FilePartSource; +import com.android.internal.http.multipart.PartBase; +import com.android.internal.http.multipart.PartSource; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import org.apache.http.util.EncodingUtils; + +/** + * This class implements a part of a Multipart post object that + * consists of a file. + * + * @author Matthew Albright + * @author Jeff Dever + * @author Adrian Sutton + * @author Michael Becke + * @author Mark Diggory + * @author Mike Bowler + * @author Oleg Kalnichevski + * + * @since 2.0 + * + */ +public class BitCometFilePart extends PartBase { + + /** Default content encoding of file attachments. */ + public static final String DEFAULT_CONTENT_TYPE = "application/x-bittorrent"; + + /** Attachment's file name */ + protected static final String FILE_NAME = "; filename="; + + /** Attachment's file name as a byte array */ + private static final byte[] FILE_NAME_BYTES = + EncodingUtils.getAsciiBytes(FILE_NAME); + + /** Source of the file part. */ + private PartSource source; + + /** + * FilePart Constructor. + * + * @param name the name for this part + * @param partSource the source for this part + * @param contentType the content type for this part, if null the + * {@link #DEFAULT_CONTENT_TYPE default} is used + * @param charset the charset encoding for this part, if null the + * {@link #DEFAULT_CHARSET default} is used + */ + public BitCometFilePart(String name, PartSource partSource, String contentType, String charset) { + + super( + name, + contentType == null ? DEFAULT_CONTENT_TYPE : contentType, + charset == null ? "ISO-8859-1" : charset, + null + ); + + if (partSource == null) { + throw new IllegalArgumentException("Source may not be null"); + } + this.source = partSource; + } + + /** + * FilePart Constructor. + * + * @param name the name for this part + * @param partSource the source for this part + */ + public BitCometFilePart(String name, PartSource partSource) { + this(name, partSource, null, null); + } + + /** + * FilePart Constructor. + * + * @param name the name of the file part + * @param file the file to post + * + * @throws FileNotFoundException if the file is not a normal + * file or if it is not readable. + */ + public BitCometFilePart(String name, File file) + throws FileNotFoundException { + this(name, new FilePartSource(file), null, null); + } + + /** + * FilePart Constructor. + * + * @param name the name of the file part + * @param file the file to post + * @param contentType the content type for this part, if null the + * {@link #DEFAULT_CONTENT_TYPE default} is used + * @param charset the charset encoding for this part, if null the + * {@link #DEFAULT_CHARSET default} is used + * + * @throws FileNotFoundException if the file is not a normal + * file or if it is not readable. + */ + public BitCometFilePart(String name, File file, String contentType, String charset) + throws FileNotFoundException { + this(name, new FilePartSource(file), contentType, charset); + } + + /** + * FilePart Constructor. + * + * @param name the name of the file part + * @param fileName the file name + * @param file the file to post + * + * @throws FileNotFoundException if the file is not a normal + * file or if it is not readable. + */ + public BitCometFilePart(String name, String fileName, File file) + throws FileNotFoundException { + this(name, new FilePartSource(fileName, file), null, null); + } + + /** + * FilePart Constructor. + * + * @param name the name of the file part + * @param fileName the file name + * @param file the file to post + * @param contentType the content type for this part, if null the + * {@link #DEFAULT_CONTENT_TYPE default} is used + * @param charset the charset encoding for this part, if null the + * {@link #DEFAULT_CHARSET default} is used + * + * @throws FileNotFoundException if the file is not a normal + * file or if it is not readable. + */ + public BitCometFilePart(String name, String fileName, File file, String contentType, String charset) + throws FileNotFoundException { + this(name, new FilePartSource(fileName, file), contentType, charset); + } + + /** + * Write the disposition header to the output stream + * @param out The output stream + * @throws IOException If an IO problem occurs + * @see Part#sendDispositionHeader(OutputStream) + */ + @Override + protected void sendDispositionHeader(OutputStream out) + throws IOException { + super.sendDispositionHeader(out); + String filename = this.source.getFileName(); + if (filename != null) { + out.write(FILE_NAME_BYTES); + out.write(QUOTE_BYTES); + out.write(EncodingUtils.getAsciiBytes(filename)); + out.write(QUOTE_BYTES); + } + } + + /** + * Write the data in "source" to the specified stream. + * @param out The output stream. + * @throws IOException if an IO problem occurs. + * @see Part#sendData(OutputStream) + */ + @Override + protected void sendData(OutputStream out) throws IOException { + if (lengthOfData() == 0) { + + // this file contains no data, so there is nothing to send. + // we don't want to create a zero length buffer as this will + // cause an infinite loop when reading. + return; + } + + byte[] tmp = new byte[4096]; + InputStream instream = source.createInputStream(); + try { + int len; + while ((len = instream.read(tmp)) >= 0) { + out.write(tmp, 0, len); + } + } finally { + // we're done with the stream, close it + instream.close(); + } + } + + /** + * Returns the source of the file part. + * + * @return The source. + */ + protected PartSource getSource() { + return this.source; + } + + /** + * Return the length of the data. + * @return The length. + * @see Part#lengthOfData() + */ + @Override + protected long lengthOfData() { + return source.getLength(); + } + +} diff --git a/app/src/main/java/com/android/internalcopy/http/multipart/Utf8StringPart.java b/app/src/main/java/org/transdroid/multipart/Utf8StringPart.java similarity index 89% rename from app/src/main/java/com/android/internalcopy/http/multipart/Utf8StringPart.java rename to app/src/main/java/org/transdroid/multipart/Utf8StringPart.java index 3a2f28ba..6b4c3ab6 100644 --- a/app/src/main/java/com/android/internalcopy/http/multipart/Utf8StringPart.java +++ b/app/src/main/java/org/transdroid/multipart/Utf8StringPart.java @@ -1,43 +1,45 @@ -package com.android.internalcopy.http.multipart; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.http.util.EncodingUtils; - -public class Utf8StringPart extends PartBase { - - /** Contents of this StringPart. */ - private byte[] content; - - /** The String value of this part. */ - private String value; - - public Utf8StringPart(String name, String value) { - super(name, null, null, null); - this.value = value; - } - - /** - * Gets the content in bytes. Bytes are lazily created to allow the charset to be changed - * after the part is created. - * - * @return the content in bytes - */ - private byte[] getContent() { - if (content == null) { - content = EncodingUtils.getBytes(value, "utf-8"); - } - return content; - } - - @Override - protected void sendData(OutputStream out) throws IOException { - out.write(getContent()); - } - - @Override - protected long lengthOfData() throws IOException { - return getContent().length; - } -} +package org.transdroid.multipart; + +import com.android.internal.http.multipart.PartBase; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.http.util.EncodingUtils; + +public class Utf8StringPart extends PartBase { + + /** Contents of this StringPart. */ + private byte[] content; + + /** The String value of this part. */ + private String value; + + public Utf8StringPart(String name, String value) { + super(name, null, null, null); + this.value = value; + } + + /** + * Gets the content in bytes. Bytes are lazily created to allow the charset to be changed + * after the part is created. + * + * @return the content in bytes + */ + private byte[] getContent() { + if (content == null) { + content = EncodingUtils.getBytes(value, "utf-8"); + } + return content; + } + + @Override + protected void sendData(OutputStream out) throws IOException { + out.write(getContent()); + } + + @Override + protected long lengthOfData() throws IOException { + return getContent().length; + } +} diff --git a/app/src/main/res/layout-land/dialog_color_picker.xml b/app/src/main/res/layout-land/dialog_color_picker.xml index cf567016..f7a2264d 100644 --- a/app/src/main/res/layout-land/dialog_color_picker.xml +++ b/app/src/main/res/layout-land/dialog_color_picker.xml @@ -1,77 +1,82 @@ - - - - - - - - - + android:paddingRight="5dp"> + + + + + + + + + + + + + + + - - - - - - - - - \ No newline at end of file + diff --git a/app/src/main/res/layout-w600dp/activity_search.xml b/app/src/main/res/layout-w600dp/activity_search.xml index cf882efe..149c511f 100644 --- a/app/src/main/res/layout-w600dp/activity_search.xml +++ b/app/src/main/res/layout-w600dp/activity_search.xml @@ -23,7 +23,7 @@ android:orientation="horizontal" tools:context=".core.gui.search.SearchActivity_"> - - - - - - - - @@ -79,6 +79,6 @@ android:layout_height="match_parent" tools:layout="@layout/fragment_torrents" /> - + diff --git a/app/src/main/res/layout-w900dp/activity_torrents.xml b/app/src/main/res/layout-w900dp/activity_torrents.xml index daadda61..04d54f77 100644 --- a/app/src/main/res/layout-w900dp/activity_torrents.xml +++ b/app/src/main/res/layout-w900dp/activity_torrents.xml @@ -30,7 +30,7 @@ android:focusable="true" android:focusableInTouchMode="true"/> - - - - - - - - - @@ -73,6 +73,6 @@ tools:layout="@layout/fragment_torrents" /> - + diff --git a/app/src/main/res/layout/activity_rssitems.xml b/app/src/main/res/layout/activity_rssitems.xml index 1350234e..1b7df4a9 100644 --- a/app/src/main/res/layout/activity_rssitems.xml +++ b/app/src/main/res/layout/activity_rssitems.xml @@ -21,7 +21,7 @@ android:layout_height="match_parent" tools:context=".core.gui.rss.RssItemsActivity_"> - - - + . --> - - - - - - + diff --git a/app/src/main/res/layout/dialog_color_picker.xml b/app/src/main/res/layout/dialog_color_picker.xml index 2ddbca41..a5fbaaf2 100644 --- a/app/src/main/res/layout/dialog_color_picker.xml +++ b/app/src/main/res/layout/dialog_color_picker.xml @@ -1,77 +1,88 @@ - - - - - - - - - + android:paddingRight="5dp"> + + + + + + + + + + + + + + + + + + - - - - - - - - - \ No newline at end of file + diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml index f6f5af5c..3470e821 100644 --- a/app/src/main/res/layout/fragment_details.xml +++ b/app/src/main/res/layout/fragment_details.xml @@ -23,7 +23,7 @@ android:layout_height="match_parent" tools:context=".core.gui.DetailsActivity_"> - - - - + - @@ -36,7 +36,7 @@ tools:listitem="@layout/list_item_torrent" tools:visibility="visible" /> - + \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +64,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,33 +75,14 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -90,7 +106,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -110,10 +126,12 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -138,27 +156,30 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index aec99730..a9f778a7 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -8,14 +24,17 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +65,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,17 +78,13 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%