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
{
40 * Force the update of all widgets associated with a provider. While not the Android way of doing things,
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
];
63 * A helper to reliably turn a string into an int, returning 0 on any failure condition.
67 public static int safeToInt( String intThing
) {
68 if ( intThing
== null ) return 0;
70 int ret
= Integer
.parseInt(intThing
);
73 catch ( Exception e
) {
78 public static String
randomColorString() {
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 ) {
90 colours
[1] = colours
[2];
94 if ( Math
.random() < 0.5 ) {
96 colours
[0] = colours
[2];
100 if ( Math
.random() < 0.5 ) {
101 int tmp
= colours
[0];
102 colours
[0] = colours
[1];
106 for (int i
= 0; i
<3; i
++) {
107 ret
+= Integer
.toHexString(colours
[i
]) + Integer
.toHexString(colours
[i
]);
113 * Capitalise words in a sentence, apart from some specifically excepted ones.
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
);
122 if ( m
.group().matches("(de|von|to|for|of|vom)") )
123 m
.appendReplacement(capped
, m
.group());
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
137 public static String
toHexString( byte[] raw
) {
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.
160 * @return the trimmed string.
162 public static String
rTrim( String toTrim
) {
163 int pos
= toTrim
.length();
166 char ch
= toTrim
.charAt(pos
-1);
167 if ( ch
== '\n' || ch
== '\r' || ch
== ' ' ) {
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
);
188 case '%': escaped
.append("%25"); break;
189 case '\'': escaped
.append("%27"); break;
190 case '#': escaped
.append("%23"); break;
191 case '?': escaped
.append("%3f"); break;
194 escaped
.append("<p>");
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
209 public static void writeNullableLong( Parcel dest
, Long l
) {
210 dest
.writeByte((byte) (l
== null ?
'N' : '+'));
211 if ( l
== null ) return;
216 * Sometimes we are reading Long values which may be null from parcels
217 * @param dest The Parcel
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.
230 * @param defaultValue
233 public static boolean toBoolean( Integer zeroIsFalse
, boolean defaultValue
) {
234 if ( zeroIsFalse
== null ) return defaultValue
;
235 else if ( zeroIsFalse
== 0 ) return false;
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.
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
) {
262 res
.addAll(getViewsInside(sv
,likeThis
));