Various fixes to Journal Editing.
[acal.git] / src / com / morphoss / acal / StaticHelpers.java
blob466c95d378bab53f6264fe825f01460d2c6f7c77
1 /*
2 * Copyright (C) 2011 Morphoss Ltd
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 package com.morphoss.acal;
21 import java.util.ArrayList;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
25 import android.appwidget.AppWidgetManager;
26 import android.appwidget.AppWidgetProvider;
27 import android.content.ComponentName;
28 import android.content.ContentValues;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.os.Parcel;
32 import android.view.View;
34 import com.morphoss.acal.desktop.ShowUpcomingWidgetProvider;
37 public final class StaticHelpers {
39 /**
40 * Force the update of all widgets associated with a provider. While not the Android way of doing things,
41 * its bloody useful.
42 * @param context - A context - must belong to the aCal package!
43 * @param provider - An App Widget Provider - MUST extend AppWidget Provider
45 public static void updateWidgets(Context context, Class<? extends AppWidgetProvider> provider) {
46 AppWidgetManager man = AppWidgetManager.getInstance(context);
47 int[] ids = man.getAppWidgetIds(new ComponentName(context,provider));
48 Intent updateIntent = new Intent();
49 updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
50 updateIntent.putExtra(ShowUpcomingWidgetProvider.SHOW_UPCOMING_WIDGET_IDS_KEY, ids);
51 context.sendBroadcast(updateIntent);
54 public static String[] mergeArrays(String[] first, String[] second) {
55 String[] result = new String[first.length+second.length];
56 for (int i = 0; i < first.length; i++) result[i] = first[i];
57 for (int i = 0; i < second.length; i++) result[first.length+i] = second[i];
58 return result;
62 /**
63 * A helper to reliably turn a string into an int, returning 0 on any failure condition.
64 * @param intThing
65 * @return
67 public static int safeToInt( String intThing ) {
68 if ( intThing == null ) return 0;
69 try {
70 int ret = Integer.parseInt(intThing);
71 return ret;
73 catch ( Exception e ) {
74 return 0;
78 public static String randomColorString() {
79 String ret = "#";
80 int colours[] = new int[3];
81 int startpos = (int) (Math.random() * 3);
82 colours[startpos] = (int) (Math.random() * 5.0) + 3;
83 if ( ++startpos > 2 ) startpos -= 2;
84 colours[startpos] = (int) (Math.random() * 9.0) + 3;
85 if ( ++startpos > 2 ) startpos -= 2;
86 colours[startpos] = (int) (Math.random() * 7.0) + 3;
88 if ( Math.random() < 0.5 ) {
89 int tmp = colours[1];
90 colours[1] = colours[2];
91 colours[2] = tmp;
94 if ( Math.random() < 0.5 ) {
95 int tmp = colours[0];
96 colours[0] = colours[2];
97 colours[2] = tmp;
100 if ( Math.random() < 0.5 ) {
101 int tmp = colours[0];
102 colours[0] = colours[1];
103 colours[1] = tmp;
106 for (int i = 0; i<3; i++) {
107 ret += Integer.toHexString(colours[i]) + Integer.toHexString(colours[i]);
109 return ret;
113 * Capitalise words in a sentence, apart from some specifically excepted ones.
114 * @param boring
115 * @return
117 public static String capitaliseWords( String boring ) {
118 final Pattern wordSplitter = Pattern.compile("\\b(\\w+)\\b", Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
119 StringBuffer capped = new StringBuffer();
120 Matcher m = wordSplitter.matcher(boring);
121 while( m.find() ) {
122 if ( m.group().matches("(de|von|to|for|of|vom)") )
123 m.appendReplacement(capped, m.group());
124 else
125 m.appendReplacement(capped, m.group().substring(0,1).toUpperCase() + m.group().substring(1));
127 m.appendTail(capped);
128 return capped.toString();
131 static final char[] HEXES = new char[] {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
133 * Convert a byte array into a hex string
134 * @param raw
135 * @return
137 public static String toHexString( byte[] raw ) {
138 if (raw == null) {
139 return null;
141 final StringBuilder hex = new StringBuilder(2 * raw.length);
142 for (final byte b : raw) {
143 hex.append(HEXES[(b & 0xF0) >> 4]).append(HEXES[(b & 0x0F)]);
145 return hex.toString();
149 public static void copyContentValue(ContentValues cloned, ContentValues serverData, String columnName) {
150 String aValue = serverData.getAsString(columnName);
151 if ( aValue != null ) cloned.put(columnName, aValue);
156 * Trim spaces, newlines & carriage-returns from the RHS of the string.
158 * @param toTrim
159 * @param toStrip
160 * @return the trimmed string.
162 public static String rTrim( String toTrim ) {
163 int pos = toTrim.length();
165 while( pos >= 0 ) {
166 char ch = toTrim.charAt(pos-1);
167 if ( ch == '\n' || ch == '\r' || ch == ' ' ) {
168 pos--;
169 continue;
171 break;
173 return toTrim.substring(0,pos);
178 * URL escape things in the string.
179 * @param toEscape The String to be escaped
180 * @param makeParas set to true if you want \n => <p> conversion as well.
181 * @return The urlescaped string.
183 public static String urlescape( String toEscape, boolean makeParas ) {
184 StringBuilder escaped = new StringBuilder();
185 for (int i = 0; i < toEscape.length(); i++) {
186 char chr = toEscape.charAt(i);
187 switch (chr) {
188 case '%': escaped.append("%25"); break;
189 case '\'': escaped.append("%27"); break;
190 case '#': escaped.append("%23"); break;
191 case '?': escaped.append("%3f"); break;
192 case '\n':
193 if ( makeParas ) {
194 escaped.append("<p>");
195 break;
197 default: escaped.append(chr);
200 return escaped.toString();
205 * Sometimes we are writing Long values which may be null into parcels
206 * @param dest The Parcel
207 * @param l The Long
209 public static void writeNullableLong( Parcel dest, Long l) {
210 dest.writeByte((byte) (l == null ? 'N' : '+'));
211 if ( l == null ) return;
212 dest.writeLong(l);
216 * Sometimes we are reading Long values which may be null from parcels
217 * @param dest The Parcel
218 * @param l The Long
220 public static Long readNullableLong( Parcel src ) {
221 byte b = src.readByte();
222 if ( b == 'N' ) return null;
223 return src.readLong();
227 * Since ContentValues and SQlite don't play well with booleans it's useful to have this
228 * to convert stuff from a number that's really a boolean.
229 * @param zeroIsFalse
230 * @param defaultValue
231 * @return
233 public static boolean toBoolean( Integer zeroIsFalse, boolean defaultValue ) {
234 if ( zeroIsFalse == null ) return defaultValue;
235 else if ( zeroIsFalse == 0 ) return false;
236 else return true;
240 * Strip any leading protocol://server.domain:port from the incoming URL.
241 * @param stripFromUrl
242 * @return The URL which is the bare pathname
244 public static String pathOnServer( String stripFromUrl ) {
245 Matcher m = Constants.matchProtocolServerPort.matcher(stripFromUrl);
246 return m.replaceAll("");
250 * Get all of the views inside this which are of a particular type.
251 * @param v
252 * @param likeThis
253 * @return
255 public static ArrayList<View> getViewsInside( View v, Class<?> likeThis ) {
256 ArrayList<View> res = new ArrayList<View>();
257 for( View sv : v.getFocusables(0)) {
258 if ( sv.getClass() == likeThis ) {
259 res.add(sv);
261 else {
262 res.addAll(getViewsInside(sv,likeThis));
265 return res;