← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~trb143/openlp/android_03 into lp:openlp

 

Tim Bentley has proposed merging lp:~trb143/openlp/android_03 into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~trb143/openlp/android_03/+merge/87860

Updated string files and some translation files ready for the release
-- 
https://code.launchpad.net/~trb143/openlp/android_03/+merge/87860
Your team OpenLP Core is requested to review the proposed merge of lp:~trb143/openlp/android_03 into lp:openlp.
=== added file '.bzrignore'
--- .bzrignore	1970-01-01 00:00:00 +0000
+++ .bzrignore	2012-01-07 20:53:27 +0000
@@ -0,0 +1,13 @@
+bin/
+assets/
+gen/
+.idea
+out
+Openlp-android.iml
+Openlp-android-working.iml
+.classpath
+.settings
+Openlp-android-buildfilefix.iml
+build.xml
+local.properties
+build.properties

=== renamed file '.bzrignore' => '.bzrignore.moved'
=== added file '.classpath'
--- .classpath	1970-01-01 00:00:00 +0000
+++ .classpath	2012-01-07 20:53:27 +0000
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry kind="output" path="bin/classes"/>
+</classpath>

=== added file '.project'
--- .project	1970-01-01 00:00:00 +0000
+++ .project	2012-01-07 20:53:27 +0000
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>OpenlpRemote</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

=== added file 'AndroidManifest.xml'
--- AndroidManifest.xml	1970-01-01 00:00:00 +0000
+++ AndroidManifest.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+        xmlns:android="http://schemas.android.com/apk/res/android";
+		android:installLocation="auto"
+        package="org.openlp.android"
+        android:versionCode="1"
+        android:versionName="0.3"
+        >
+    <uses-sdk android:minSdkVersion="8"/>
+    <uses-permission android:name="android.permission.INTERNET"/>
+
+    <application
+            android:icon="@drawable/openlp_logo"
+            android:label="@string/app_name">
+        <activity
+                android:name=".OpenLP"
+                android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+        <activity
+                android:name=".activity.SearchableActivity"
+                android:label="@string/searchResults">
+            <intent-filter>
+                <action android:name="android.intent.action.SEARCH"/>
+            </intent-filter>
+            <meta-data
+                    android:name="android.app.searchable"
+                    android:resource="@xml/searchable"/>
+        </activity>
+
+        <activity android:name=".activity.Misc"/>
+        <activity android:name=".activity.Preferences" android:label="@string/preferences"/>
+        <activity android:name=".activity.Slide"/>
+        <activity android:name=".activity.Service"/>
+        <meta-data
+                android:name="android.app.default_searchable"
+                android:value=".activity.SearchableActivity"/>
+    </application>
+</manifest>
\ No newline at end of file

=== added file 'OpenLP.apk'
Binary files OpenLP.apk	1970-01-01 00:00:00 +0000 and OpenLP.apk	2012-01-07 20:53:27 +0000 differ
=== added directory 'assets'
=== added directory 'libs'
=== added file 'proguard.cfg'
--- proguard.cfg	1970-01-01 00:00:00 +0000
+++ proguard.cfg	2012-01-07 20:53:27 +0000
@@ -0,0 +1,36 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+-keepclasseswithmembernames class * {
+    public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembernames class * {
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+  public static final android.os.Parcelable$Creator *;
+}

=== added directory 'res'
=== added directory 'res/drawable-hdpi'
=== added file 'res/drawable-hdpi/icon.png'
Binary files res/drawable-hdpi/icon.png	1970-01-01 00:00:00 +0000 and res/drawable-hdpi/icon.png	2012-01-07 20:53:27 +0000 differ
=== added file 'res/drawable-hdpi/openlp_logo.png'
Binary files res/drawable-hdpi/openlp_logo.png	1970-01-01 00:00:00 +0000 and res/drawable-hdpi/openlp_logo.png	2012-01-07 20:53:27 +0000 differ
=== added directory 'res/drawable-ldpi'
=== added file 'res/drawable-ldpi/icon.png'
Binary files res/drawable-ldpi/icon.png	1970-01-01 00:00:00 +0000 and res/drawable-ldpi/icon.png	2012-01-07 20:53:27 +0000 differ
=== added file 'res/drawable-ldpi/openlp_logo.png'
Binary files res/drawable-ldpi/openlp_logo.png	1970-01-01 00:00:00 +0000 and res/drawable-ldpi/openlp_logo.png	2012-01-07 20:53:27 +0000 differ
=== added directory 'res/drawable-mdpi'
=== added file 'res/drawable-mdpi/icon.png'
Binary files res/drawable-mdpi/icon.png	1970-01-01 00:00:00 +0000 and res/drawable-mdpi/icon.png	2012-01-07 20:53:27 +0000 differ
=== added file 'res/drawable-mdpi/openlp_logo.png'
Binary files res/drawable-mdpi/openlp_logo.png	1970-01-01 00:00:00 +0000 and res/drawable-mdpi/openlp_logo.png	2012-01-07 20:53:27 +0000 differ
=== added directory 'res/layout'
=== added file 'res/layout/group_child.xml'
--- res/layout/group_child.xml	1970-01-01 00:00:00 +0000
+++ res/layout/group_child.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,14 @@
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android";
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+    <TextView
+            android:id="@+id/groupChildText"
+            android:layout_height="wrap_content"
+            android:layout_width="fill_parent"
+            android:paddingLeft="20dip"
+            android:gravity="center_vertical"
+            android:minLines="3"
+            />
+</LinearLayout>
\ No newline at end of file

=== added file 'res/layout/group_parent.xml'
--- res/layout/group_parent.xml	1970-01-01 00:00:00 +0000
+++ res/layout/group_parent.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android";
+	android:layout_width="fill_parent" 
+	android:baselineAligned="false"
+	android:orientation="horizontal" 
+	android:layout_height="wrap_content">
+	<TextView android:id="@+id/groupParentText"
+		android:layout_height="wrap_content" 
+		android:paddingLeft="5dip"
+		android:minLines="3" 
+		android:focusable="false" 
+		android:gravity="center_vertical|right"
+		android:layout_width="fill_parent"
+		android:layout_weight="1" />
+	<TextView android:id="@+id/parentChildCount" 
+		android:width="40dip"
+		android:paddingRight="5dip" 
+		android:layout_width="fill_parent"
+		android:layout_weight="1" 
+		android:layout_height="wrap_content"
+		android:gravity="center_vertical|right" />
+</LinearLayout>
\ No newline at end of file

=== added file 'res/layout/main.xml'
--- res/layout/main.xml	1970-01-01 00:00:00 +0000
+++ res/layout/main.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TabHost xmlns:android="http://schemas.android.com/apk/res/android";
+         android:id="@android:id/tabhost"
+         android:layout_width="fill_parent"
+         android:layout_height="fill_parent">
+    <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:padding="5dp">
+        <TabWidget
+                android:id="@android:id/tabs"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"/>
+        <FrameLayout
+                android:id="@android:id/tabcontent"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:padding="0dp"/>
+    </LinearLayout>
+</TabHost>
+

=== added file 'res/layout/misc.xml'
--- res/layout/misc.xml	1970-01-01 00:00:00 +0000
+++ res/layout/misc.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android";
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent">
+    <ToggleButton
+            android:id="@+id/toggleDisplayButton"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textOn="@string/displayBlankOn"
+            android:textOff="@string/displayBlankOff"/>
+    <TextView
+            android:text="@string/alert"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+    <EditText
+            android:id="@+id/alert"
+            android:layout_height="wrap_content"
+            android:text=""
+            android:inputType="textShortMessage"
+            android:layout_width="fill_parent"
+            android:hint="@string/alertHint"/>
+    <Button android:text="@string/send"
+            android:id="@+id/send"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+</LinearLayout>
+

=== added file 'res/layout/search.xml'
--- res/layout/search.xml	1970-01-01 00:00:00 +0000
+++ res/layout/search.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android";
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:orientation="vertical">
+    <TableLayout
+            android:id="@+id/tableLayout1"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent">
+        <ExpandableListView
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:id="@+id/list"
+                android:layout_width="wrap_content"
+                />
+    </TableLayout>
+</LinearLayout>

=== added file 'res/layout/service.xml'
--- res/layout/service.xml	1970-01-01 00:00:00 +0000
+++ res/layout/service.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android";
+        android:layout_width="fill_parent"
+        android:baselineAligned="false"
+        android:orientation="vertical"
+        android:layout_height="fill_parent">
+    <TableLayout
+            android:id="@+id/tableLayout1"
+            android:layout_width="fill_parent"
+            android:layout_gravity="fill"
+            android:layout_height="fill_parent">
+        <ListView
+                android:layout_gravity="top"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:id="@+id/list"
+                android:layout_width="fill_parent"/>
+        <LinearLayout
+                android:baselineAligned="false"
+                android:id="@+id/linearLayout1"
+                android:layout_width="fill_parent"
+                android:layout_gravity="fill"
+                android:layout_height="wrap_content"
+                android:layout_weight="0">
+            <Button
+                    android:text="@string/prev"
+                    android:layout_weight="1"
+                    android:id="@+id/prev"
+                    android:layout_height="wrap_content"
+                    android:layout_width="fill_parent"/>
+            <Button
+                    android:text="@string/next"
+                    android:layout_weight="1"
+                    android:id="@+id/next"
+                    android:layout_height="wrap_content"
+                    android:layout_width="fill_parent"/>
+        </LinearLayout>
+    </TableLayout>
+</LinearLayout>

=== added file 'res/layout/slide.xml'
--- res/layout/slide.xml	1970-01-01 00:00:00 +0000
+++ res/layout/slide.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android";
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:orientation="vertical">
+    <TableLayout
+            android:id="@+id/tableLayout1"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent">
+        <ListView
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:id="@+id/list"
+                android:layout_width="wrap_content"/>
+        <LinearLayout
+                android:layout_height="wrap_content"
+                android:id="@+id/linearLayout1"
+                android:layout_width="fill_parent">
+            <Button
+                    android:text="@string/prev"
+                    android:layout_weight="1"
+                    android:id="@+id/prev"
+                    android:layout_height="wrap_content"
+                    android:layout_width="fill_parent"
+                    android:layout_gravity="center_vertical"/>
+            <Button
+                    android:text="@string/next"
+                    android:layout_weight="1"
+                    android:id="@+id/next"
+                    android:layout_height="wrap_content"
+                    android:layout_width="fill_parent"
+                    android:layout_gravity="center"/>
+        </LinearLayout>
+    </TableLayout>
+
+</LinearLayout>

=== added file 'res/layout/slide_list_item.xml'
--- res/layout/slide_list_item.xml	1970-01-01 00:00:00 +0000
+++ res/layout/slide_list_item.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android";
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent">
+    <TextView
+            android:id="@+id/rowItemMarker"
+            android:layout_width="wrap_content"
+            android:layout_height="fill_parent"
+            android:gravity="center"
+            android:textStyle="bold"
+            android:textColor="@color/white"
+            />
+    <TextView
+            android:id="@+id/rowItemText"
+            android:layout_width="wrap_content"
+            android:layout_height="fill_parent"
+            android:gravity="center_vertical"
+            android:minLines="2"
+            android:textSize="8pt"/>
+</LinearLayout>
\ No newline at end of file

=== added directory 'res/menu'
=== added file 'res/menu/menu.xml'
--- res/menu/menu.xml	1970-01-01 00:00:00 +0000
+++ res/menu/menu.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android";>
+    <item android:enabled="true" android:titleCondensed="@string/settings" android:title="@string/settings"
+          android:id="@+id/preferences"/>
+	<item
+		android:id="@+id/menuSearch"
+		android:enabled="true"
+		android:title="Search"
+		android:titleCondensed="Search"/>
+</menu>

=== added directory 'res/value-el'
=== added file 'res/value-el/strings.xml'
--- res/value-el/strings.xml	1970-01-01 00:00:00 +0000
+++ res/value-el/strings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+  <string name="app_name">OpenLP</string>
+  <string name="settings">Ρυθμίσεις</string>
+  <string name="preferences">Προτιμήσεις</string>
+  <string name="exit">Έξοδος</string>
+  <string name="prev">Προηγούμενο</string>
+  <string name="next">Επόμενο</string>
+  <string name="previousServiceItem">Προηγούμενο Αντικείμενο</string>
+  <string name="nextServiceItem">Επόμενο Αντικείμενο</string>
+  <string name="previousSlide">Προηγούμενη Διαφάνεια</string>
+  <string name="nextSlide">Επόμενη Διαφάνεια</string>
+  <string name="blank">Κενό</string>
+  <string name="unblank">Μη Κενό</string>
+  <string name="alert">Ειδοποίηση:</string>
+  <string name="alertHint">Εισαγωγή μηνύματος ειδοποίησης</string>
+  <string name="alertTextNull">Παρακαλούμε εισάγετε ένα μήνυμα προς αποστολή.</string>
+  <string name="send">Αποστολή</string>
+  <string name="Slide">Διαφάνεια</string>
+  <string name="slides">Διαφάνειες</string>
+  <string name="Service">Λειτουργία</string>
+  <string name="misc">Διάφορα</string>
+  <string name="preferenceCategoryTitleServer">Server</string>
+  <string name="url">Server</string>
+  <string name="urlHint">Hostname ή διεύθυνση IP</string>
+  <string name="port">Θύρα</string>
+  <string name="enableCustomTimeouts">Ενεργοποίηση </string>
+  <string name="displayType">Εμφάνιση Τύπου Κενής Σελίδας</string>
+  <string name="displayBlankType">Εμφάνιση Τύπου Κενής Σελίδας</string>
+  <string name="displayBlankSummary">Επιλέξτε τον απαιτούμενο τύπο κενής σελίδας </string>
+  <string name="displayScreen">Οθόνη</string>
+  <string name="displayTheme">Θέμα</string>
+  <string name="displayDesktop">Επιφάνεια Εργασίας</string>
+  <string name="displayBlankOn">Επαναφορά εμφάνισης από</string>
+  <string name="displayBlankOff">Εμφάνιση Κενής Σελίδας στο</string>
+  <string name="customTimeoutsSummary">Επιλέξτε για τροποποίηση των ρυθμίσεων λήξης</string>
+  <string name="customTimeout">Τροποποιημένη Λήξη</string>
+  <string name="socketTimeout">Λήξη Socket</string>
+  <string name="socketTimeoutSummary">Επιλέξτε μια τιμή (milliseconds)</string>
+  <string name="connectionTimeout">Λήξη Σύνδεσης</string>
+  <string name="connectionTimedout">Η σύνδεση έληξε</string>
+  <string name="connectionTimeoutSummary">Επιλέξτε μια τιμή (milliseconds)</string>
+  <string name="save">Αποθήκευση</string>
+  <string name="unable">Μη δυνατή φόρτωση σελίδας -</string>
+  <string name="fail">Η σύνδεση απέτυχε</string>
+  <string name="jsonfail">JSON απέτυχε</string>
+  <string name="loading">Σύνδεση...</string>
+  <string name="searching">Αναζήτηση...</string>
+  <string name="loadingServiceItems">Φόρτωση Αντικειμένων Λειτουργίας...</string>
+  <string name="loadingSlideItems">Φόρτωση Αντικειμένων Διαφανειών...</string>
+  <string name="loadingStatusInfo">Φόρτωση Πληροφοριών Κατάστασης...</string>
+  <string name="searchHint">Αναζήτηση OpenLP</string>
+  <string name="searchResults">Αποτελέσματα Αναζήτησης</string>
+  <string name="showingResults">Εμφάνιση Αποτελεσμάτων για \'%s\'</string>
+</resources>

=== added directory 'res/values'
=== added directory 'res/values-af'
=== added directory 'res/values-cs'
=== added file 'res/values-cs/strings.xml'
--- res/values-cs/strings.xml	1970-01-01 00:00:00 +0000
+++ res/values-cs/strings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+  <string name="app_name">OpenLP</string>
+  <string name="settings">Nastavení</string>
+  <string name="preferences">Nastavení</string>
+  <string name="exit">Ukončit</string>
+  <string name="prev">Předchozí</string>
+  <string name="next">Další</string>
+  <string name="previousServiceItem">Předchozí položka</string>
+  <string name="nextServiceItem">Další položka</string>
+  <string name="previousSlide">Předchozí snímek</string>
+  <string name="nextSlide">Další snímek</string>
+  <string name="blank">Prázdný</string>
+  <string name="unblank">Neprázdný</string>
+  <string name="alert">Upozornění:</string>
+  <string name="alertHint">Zadat zprávu upozornění</string>
+  <string name="alertTextNull">Zadejte prosím zprávu k odeslání.</string>
+  <string name="send">Odeslat</string>
+  <string name="Slide">Snímek</string>
+  <string name="slides">Snímky</string>
+  <string name="Service">Služba</string>
+  <string name="misc">Různé</string>
+  <string name="preferenceCategoryTitleServer">Server</string>
+  <string name="url">Server</string>
+  <string name="urlHint">Jméno počítače nebo IP</string>
+  <string name="port">Port</string>
+  <string name="enableCustomTimeouts">Zapnout uživatelský časový limit</string>
+  <string name="displayType">Zobrazit prázdný typ</string>
+  <string name="displayBlankType">Zobrazit prázdný typ</string>
+  <string name="displayBlankSummary">Vybrat požadovaný prázdný typ</string>
+  <string name="displayScreen">Obrazovka</string>
+  <string name="displayTheme">Motiv</string>
+  <string name="displayDesktop">Pracovní plocha</string>
+  <string name="displayBlankOn">Obnovit zobrazení z</string>
+  <string name="displayBlankOff">Prázdné zobrazení na</string>
+  <string name="customTimeoutsSummary">Ověřit změny nastavení časového limitu</string>
+  <string name="customTimeout">Uživatelský časový limit</string>
+  <string name="socketTimeout">Časový limit socketu</string>
+  <string name="socketTimeoutSummary">Vybrat hodnotu (milisekundy)</string>
+  <string name="connectionTimeout">Časový limit spojení</string>
+  <string name="connectionTimedout">Spojení vypršelo</string>
+  <string name="connectionTimeoutSummary">Vybrat hodnotu (milisekundy)</string>
+  <string name="save">Uložit</string>
+  <string name="unable">Není možno načíst stránku -</string>
+  <string name="fail">Spojení selhalo</string>
+  <string name="jsonfail">JSON selhal</string>
+  <string name="loading">Připojuji se...</string>
+  <string name="searching">Hledám...</string>
+  <string name="loadingServiceItems">Načítám položky služby...</string>
+  <string name="loadingSlideItems">Načítám položky snímku...</string>
+  <string name="loadingStatusInfo">Načítám stavové info...</string>
+  <string name="searchHint">Hledat OpenLP</string>
+  <string name="searchResults">Výsledky hledání</string>
+  <string name="showingResults">Zobrazuji výsledky pro \'%s\'</string>
+</resources>

=== added directory 'res/values-de'
=== added file 'res/values-de/strings.xml'
--- res/values-de/strings.xml	1970-01-01 00:00:00 +0000
+++ res/values-de/strings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+  <string name="app_name">OpenLP</string>
+  <string name="settings"></string>
+  <string name="preferences"></string>
+  <string name="exit"></string>
+  <string name="prev"></string>
+  <string name="next"></string>
+  <string name="previousServiceItem"></string>
+  <string name="nextServiceItem"></string>
+  <string name="previousSlide"></string>
+  <string name="nextSlide"></string>
+  <string name="blank"></string>
+  <string name="unblank"></string>
+  <string name="alert">Hinweis:</string>
+  <string name="alertHint"></string>
+  <string name="alertTextNull"></string>
+  <string name="send"></string>
+  <string name="Slide">Folie</string>
+  <string name="slides">Folien</string>
+  <string name="Service">Ablauf</string>
+  <string name="misc"></string>
+  <string name="preferenceCategoryTitleServer">Server</string>
+  <string name="url">Server</string>
+  <string name="urlHint">Hostname oder IP</string>
+  <string name="port">Port</string>
+  <string name="enableCustomTimeouts"></string>
+  <string name="displayType"></string>
+  <string name="displayBlankType"></string>
+  <string name="displayBlankSummary"></string>
+  <string name="displayScreen"></string>
+  <string name="displayTheme">Design</string>
+  <string name="displayDesktop"></string>
+  <string name="displayBlankOn"></string>
+  <string name="displayBlankOff"></string>
+  <string name="customTimeoutsSummary"></string>
+  <string name="customTimeout"></string>
+  <string name="socketTimeout"></string>
+  <string name="socketTimeoutSummary"></string>
+  <string name="connectionTimeout"></string>
+  <string name="connectionTimedout"></string>
+  <string name="connectionTimeoutSummary"></string>
+  <string name="save">Speichern</string>
+  <string name="unable"></string>
+  <string name="fail"></string>
+  <string name="jsonfail"></string>
+  <string name="loading">Verbinde...</string>
+  <string name="searching">Suche...</string>
+  <string name="loadingServiceItems"></string>
+  <string name="loadingSlideItems"></string>
+  <string name="loadingStatusInfo"></string>
+  <string name="searchHint"></string>
+  <string name="searchResults"></string>
+  <string name="showingResults"></string>
+</resources>

=== added directory 'res/values-en-GB'
=== added file 'res/values-en-GB/strings.xml'
--- res/values-en-GB/strings.xml	1970-01-01 00:00:00 +0000
+++ res/values-en-GB/strings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+  <string name="app_name">OpenLP</string>
+  <string name="settings">Settings</string>
+  <string name="preferences">Preferences</string>
+  <string name="exit">Exit</string>
+  <string name="prev">Previous</string>
+  <string name="next">Next</string>
+  <string name="previousServiceItem">Previous Item</string>
+  <string name="nextServiceItem">Next Item</string>
+  <string name="previousSlide">Previous Slide</string>
+  <string name="nextSlide">Next Slide</string>
+  <string name="blank">Blank</string>
+  <string name="unblank">Unblank</string>
+  <string name="alert">Alert:</string>
+  <string name="alertHint">Enter alert message</string>
+  <string name="alertTextNull">Please enter a message to send.</string>
+  <string name="send">Send</string>
+  <string name="Slide">Slide</string>
+  <string name="slides">Slides</string>
+  <string name="Service">Service</string>
+  <string name="misc">Miscellaneous</string>
+  <string name="preferenceCategoryTitleServer">Server</string>
+  <string name="url">Server</string>
+  <string name="urlHint">Hostname or IP</string>
+  <string name="port">Port</string>
+  <string name="enableCustomTimeouts">Enable Custom Timeouts</string>
+  <string name="displayType">Display Blank Type</string>
+  <string name="displayBlankType">Display Blank Type</string>
+  <string name="displayBlankSummary">Select the required blank type</string>
+  <string name="displayScreen">Screen</string>
+  <string name="displayTheme">Theme</string>
+  <string name="displayDesktop">Desktop</string>
+  <string name="displayBlankOn">Reset display from</string>
+  <string name="displayBlankOff">Blank display to</string>
+  <string name="customTimeoutsSummary">Check to modify timeout settings</string>
+  <string name="customTimeout">Custom Timeout</string>
+  <string name="socketTimeout">Socket Timeout</string>
+  <string name="socketTimeoutSummary">Select a value (milliseconds)</string>
+  <string name="connectionTimeout">Connection Timeout</string>
+  <string name="connectionTimedout">Connection timed out</string>
+  <string name="connectionTimeoutSummary">Select a value (milliseconds)</string>
+  <string name="save">Save</string>
+  <string name="unable">Unable to load page -</string>
+  <string name="fail">Connection failed</string>
+  <string name="jsonfail">JSON failed</string>
+  <string name="loading">Connecting...</string>
+  <string name="searching">Searching...</string>
+  <string name="loadingServiceItems">Loading Service Items...</string>
+  <string name="loadingSlideItems">Loading Slide Items...</string>
+  <string name="loadingStatusInfo">Loading Status Info...</string>
+  <string name="searchHint">Search OpenLP</string>
+  <string name="searchResults">Search Results</string>
+  <string name="showingResults">Showing Results for \'%s\'</string>
+</resources>

=== added directory 'res/values-en-rZA'
=== added file 'res/values-en-rZA/strings.xml'
--- res/values-en-rZA/strings.xml	1970-01-01 00:00:00 +0000
+++ res/values-en-rZA/strings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+  <string name="app_name">OpenLP</string>
+  <string name="settings">Settings</string>
+  <string name="preferences">Preferences</string>
+  <string name="exit">Exit</string>
+  <string name="prev">Previous</string>
+  <string name="next">Next</string>
+  <string name="previousServiceItem">Previous Item</string>
+  <string name="nextServiceItem">Next Item</string>
+  <string name="previousSlide">Previous Slide</string>
+  <string name="nextSlide">Next Slide</string>
+  <string name="blank">Blank</string>
+  <string name="unblank">Unblank</string>
+  <string name="alert">Alert:</string>
+  <string name="alertHint">Enter alert message</string>
+  <string name="alertTextNull">Please enter a message to send.</string>
+  <string name="send">Send</string>
+  <string name="Slide">Slide</string>
+  <string name="slides">Slides</string>
+  <string name="Service">Service</string>
+  <string name="misc">Miscellaneous</string>
+  <string name="preferenceCategoryTitleServer">Server</string>
+  <string name="url">Server</string>
+  <string name="urlHint">Hostname or IP</string>
+  <string name="port">Port</string>
+  <string name="enableCustomTimeouts">Enable Custom Timeouts</string>
+  <string name="displayType">Display Blank Type</string>
+  <string name="displayBlankType">Display Blank Type</string>
+  <string name="displayBlankSummary">Select the required blank type</string>
+  <string name="displayScreen">Screen</string>
+  <string name="displayTheme">Theme</string>
+  <string name="displayDesktop">Desktop</string>
+  <string name="displayBlankOn">Reset display from</string>
+  <string name="displayBlankOff">Blank display to</string>
+  <string name="customTimeoutsSummary">Check to modify timeout settings</string>
+  <string name="customTimeout">Custom Timeout</string>
+  <string name="socketTimeout">Socket Timeout</string>
+  <string name="socketTimeoutSummary">Select a value (milliseconds)</string>
+  <string name="connectionTimeout">Connection Timeout</string>
+  <string name="connectionTimedout">Connection timed out</string>
+  <string name="connectionTimeoutSummary">Select a value (milliseconds)</string>
+  <string name="save">Save</string>
+  <string name="unable">Unable to load page -</string>
+  <string name="fail">Connection failed</string>
+  <string name="jsonfail">JSON failed</string>
+  <string name="loading">Connecting...</string>
+  <string name="searching">Searching...</string>
+  <string name="loadingServiceItems">Loading Service Items...</string>
+  <string name="loadingSlideItems">Loading Slide Items...</string>
+  <string name="loadingStatusInfo">Loading Status Info...</string>
+  <string name="searchHint">Search OpenLP</string>
+  <string name="searchResults">Search Results</string>
+  <string name="showingResults">Showing Results for \'%s\'</string>
+</resources>

=== added directory 'res/values-es'
=== added directory 'res/values-et'
=== added file 'res/values-et/strings.xml'
--- res/values-et/strings.xml	1970-01-01 00:00:00 +0000
+++ res/values-et/strings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+  <string name="app_name">OpenLP</string>
+  <string name="settings">Sätted</string>
+  <string name="preferences">Eelistused</string>
+  <string name="exit">Välju</string>
+  <string name="prev">Eelmine</string>
+  <string name="next">Järgmine</string>
+  <string name="previousServiceItem">Eelmine element</string>
+  <string name="nextServiceItem">Järgmine element</string>
+  <string name="previousSlide">Eelmine slaid</string>
+  <string name="nextSlide">Järgmine slaid</string>
+  <string name="blank">Tühjenda</string>
+  <string name="unblank">Näita</string>
+  <string name="alert">Teade:</string>
+  <string name="alertHint">Sisesta teade</string>
+  <string name="alertTextNull">Palun sisesta teade, mida saata.</string>
+  <string name="send">Saada</string>
+  <string name="Slide">Slaid</string>
+  <string name="slides">Slaidid</string>
+  <string name="Service">Teenistus</string>
+  <string name="misc">Muud</string>
+  <string name="preferenceCategoryTitleServer">Server</string>
+  <string name="url">Server</string>
+  <string name="urlHint">Hostinimi või IP</string>
+  <string name="port">Port</string>
+  <string name="enableCustomTimeouts">Kohandatud aegumisegade kasutamine</string>
+  <string name="displayType">Kuva tühjendamise liik</string>
+  <string name="displayBlankType">Kuva tühjendamise liik</string>
+  <string name="displayBlankSummary">Vali kuva tühjendamise liik</string>
+  <string name="displayScreen">Ekraan</string>
+  <string name="displayTheme">Kujundus</string>
+  <string name="displayDesktop">Töölaud</string>
+  <string name="displayBlankOn">Kuvavormi lähtestamine</string>
+  <string name="displayBlankOff">Kuva tühjendamisel kuvatakse</string>
+  <string name="customTimeoutsSummary">Märgi, et muuta aegumise sätteid</string>
+  <string name="customTimeout">Kohandatud aegumine</string>
+  <string name="socketTimeout">Pesa aegumine</string>
+  <string name="socketTimeoutSummary">Vali kestus (millisekundid)</string>
+  <string name="connectionTimeout">Ühenduse aegumine</string>
+  <string name="connectionTimedout">Ühendus aegus</string>
+  <string name="connectionTimeoutSummary">Vali kestus (millisekundid)</string>
+  <string name="save">Salvesta</string>
+  <string name="unable">Lehe laadimine pole võimalik -</string>
+  <string name="fail">Ühendus nurjus</string>
+  <string name="jsonfail">JSON nurjus</string>
+  <string name="loading">Ühendumine...</string>
+  <string name="searching">Otsimine...</string>
+  <string name="loadingServiceItems">Teenistuse elementide laadimine...</string>
+  <string name="loadingSlideItems">Slaidi elementide laadimine...</string>
+  <string name="loadingStatusInfo">Olekuinfo laadimine...</string>
+  <string name="searchHint">OpenLP otsing</string>
+  <string name="searchResults">Otsingu tulemused</string>
+  <string name="showingResults">Tulemused otsingule \'%s\' </string>
+</resources>

=== added directory 'res/values-fr'
=== added directory 'res/values-hu'
=== added file 'res/values-hu/strings.xml'
--- res/values-hu/strings.xml	1970-01-01 00:00:00 +0000
+++ res/values-hu/strings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+  <string name="app_name">OpenLP</string>
+  <string name="settings">Beállítások</string>
+  <string name="preferences">Beállítások</string>
+  <string name="exit">Kilépés</string>
+  <string name="prev">Előző</string>
+  <string name="next">Következő</string>
+  <string name="previousServiceItem">Előző elem</string>
+  <string name="nextServiceItem">Következő elem</string>
+  <string name="previousSlide">Előző dia</string>
+  <string name="nextSlide">Következő dia</string>
+  <string name="blank">Elsötétítés</string>
+  <string name="unblank">Elsötétítés visszavonása</string>
+  <string name="alert">Értesítés:</string>
+  <string name="alertHint">Értesítés megadása</string>
+  <string name="alertTextNull">Kérem, adj meg egy értesítő üzenetet.</string>
+  <string name="send">Küldés</string>
+  <string name="Slide">Dia</string>
+  <string name="slides">Diák</string>
+  <string name="Service">Sorrend</string>
+  <string name="misc">Egyebek</string>
+  <string name="preferenceCategoryTitleServer">Kiszolgáló</string>
+  <string name="url">Kiszolgáló</string>
+  <string name="urlHint">Gépnév vagy IP-cím</string>
+  <string name="port">Portszám</string>
+  <string name="enableCustomTimeouts">Egyéni időtúllépés engedélyezése</string>
+  <string name="displayType">Képernyő elsötétítési mód</string>
+  <string name="displayBlankType">Képernyő elsötétítési mód</string>
+  <string name="displayBlankSummary">Válaszd ki a kívánt elsötétítési módot</string>
+  <string name="displayScreen">Képernyő</string>
+  <string name="displayTheme">Téma</string>
+  <string name="displayDesktop">Asztalra</string>
+  <string name="displayBlankOn">Képernyő alaphelyzetbe állítása erről</string>
+  <string name="displayBlankOff">Képernyő elsötétítése erre</string>
+  <string name="customTimeoutsSummary">Jelöld be az időtúllépési beállítások módosításához</string>
+  <string name="customTimeout">Egyéni időtúllépés</string>
+  <string name="socketTimeout">Socket időtúllépés</string>
+  <string name="socketTimeoutSummary">Válassz egy értéket (milliszekundum)</string>
+  <string name="connectionTimeout">Kapcsolódási időtúllépés</string>
+  <string name="connectionTimedout">Időtúllépés miatt a kapcsolat megszakadt</string>
+  <string name="connectionTimeoutSummary">Válassz egy értéket (milliszekundum)</string>
+  <string name="save">Mentés</string>
+  <string name="unable">Az oldal nem tölthető be -</string>
+  <string name="fail">A kapcsolat megszakadt</string>
+  <string name="jsonfail">JSON feldolgozás sikertelen</string>
+  <string name="loading">Kapcsolódás…</string>
+  <string name="searching">Keresés…</string>
+  <string name="loadingServiceItems">Sorrend elemeinek betöltése…</string>
+  <string name="loadingSlideItems">Dia elemeinek betöltése…</string>
+  <string name="loadingStatusInfo">Állapotinformációk betöltése…</string>
+  <string name="searchHint">OpenLP keresés</string>
+  <string name="searchResults">Keresési eredmények</string>
+  <string name="showingResults">Keresési eredmények: %s </string>
+</resources>

=== added directory 'res/values-ja'
=== added directory 'res/values-ko'
=== added directory 'res/values-nb'
=== added directory 'res/values-nl'
=== added directory 'res/values-pt-rBR'
=== added directory 'res/values-ru'
=== added directory 'res/values-sv'
=== added file 'res/values-sv/strings.xml'
--- res/values-sv/strings.xml	1970-01-01 00:00:00 +0000
+++ res/values-sv/strings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">OpenLP</string>
+    <string name="settings">Inställningar</string>
+    <string name="exit">Avsluta</string>
+    <string name="prev">Föregående</string>
+    <string name="next">Nästa</string>
+    <string name="blank">Dölj</string>
+    <string name="unblank">Visa</string>
+    <string name="alert">Varning:</string>
+    <string name="send">Skicka</string>
+    <string name="Slide">Bild</string>
+    <string name="Service">Planering</string>
+    <string name="misc">Diverse</string>
+    <string name="url">Server</string>
+    <string name="port">Port</string>
+    <string name="save">Spara</string>
+    <string name="unable">Lyckas inte ladda sidan -</string>
+    <string name="fail">Anslutningen misslyckades</string>
+    <string name="jsonfail">JSON misslyckades</string>
+    <string name="loading">Ansluter...</string>
+</resources>

=== added directory 'res/values-zh-rCN'
=== added file 'res/values/colors.xml'
--- res/values/colors.xml	1970-01-01 00:00:00 +0000
+++ res/values/colors.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,4 @@
+<resources>
+    <color name="lightGreen">#ff66ff33</color>
+    <color name="white">#ffffffff</color>
+</resources>
\ No newline at end of file

=== added file 'res/values/defaultValues.xml'
--- res/values/defaultValues.xml	1970-01-01 00:00:00 +0000
+++ res/values/defaultValues.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,10 @@
+<resources>
+    <!-- STRING -->
+    <string name="hostDefaultValue">192.168.1.1</string>
+    <string name="portDefaultValue">4316</string>
+    <string name="displayTypeValue">@string/displayScreen</string>
+
+    <!-- INTEGER -->
+    <integer name="socketTimeoutDefaultValue">3000</integer>
+    <integer name="connectionTimeoutDefaultValue">3000</integer>
+</resources>
\ No newline at end of file

=== added file 'res/values/httpClientTimeoutValues.xml'
--- res/values/httpClientTimeoutValues.xml	1970-01-01 00:00:00 +0000
+++ res/values/httpClientTimeoutValues.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,16 @@
+<resources>
+    <string-array name="socketValueEntries">
+		<item>3000</item>
+		<item>4000</item>
+		<item>5000</item>
+		<item>8000</item>
+		<item>10000</item>
+	</string-array>
+	<string-array name="socketValues">
+		<item>3000</item>
+		<item>4000</item>
+		<item>5000</item>
+		<item>8000</item>
+		<item>10000</item>
+	</string-array>
+</resources>
\ No newline at end of file

=== added file 'res/values/keyStrings.xml'
--- res/values/keyStrings.xml	1970-01-01 00:00:00 +0000
+++ res/values/keyStrings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,9 @@
+<resources>
+    <string name="keyEnableCustomTimeout">enableCustomTimeout</string>
+    <string name="keyConnectionTimeout">connectionTimeout</string>
+    <string name="keyDisplayBlankType">blankType</string>    
+    <string name="keySocketTimeout">socketTimeout</string>
+    <string name="keyHost">keyHost</string>
+    <string name="keyPort">keyPort</string>
+    <string name="keySharedPreferences">keySharedPreferences</string>
+</resources>
\ No newline at end of file

=== added file 'res/values/misc.xml'
--- res/values/misc.xml	1970-01-01 00:00:00 +0000
+++ res/values/misc.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,12 @@
+<resources>
+    <string-array name="displayTypeValueEntries">
+		<item>@string/displayScreen</item>
+		<item>@string/displayTheme</item>
+		<item>@string/displayDesktop</item>
+	</string-array>
+    <string-array name="displayTypeValues">
+		<item>@string/displayScreen</item>
+		<item>@string/displayTheme</item>
+		<item>@string/displayDesktop</item>
+	</string-array>	
+</resources>
\ No newline at end of file

=== added file 'res/values/strings.xml'
--- res/values/strings.xml	1970-01-01 00:00:00 +0000
+++ res/values/strings.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">OpenLP</string>
+    <string name="settings">Settings</string>
+	<string name="preferences">Preferences</string>
+    <string name="exit">Exit</string>
+    <string name="prev">Previous</string>
+    <string name="next">Next</string>
+    <string name="previousServiceItem">Previous Item</string>
+    <string name="nextServiceItem">Next Item</string>
+    <string name="previousSlide">Previous Slide</string>
+    <string name="nextSlide">Next Slide</string>
+    <string name="blank">Blank</string>
+    <string name="unblank">Unblank</string>
+    <string name="alert">Alert:</string>
+    <string name="alertHint">Enter alert message</string>
+    <string name="alertTextNull">Please enter a message to send.</string>
+    <string name="send">Send</string>
+    <string name="Slide">Slide</string>
+    <string name="slides">Slides</string>
+    <string name="Service">Service</string>
+    <string name="misc">Miscellaneous</string>
+    <string name="preferenceCategoryTitleServer">Server</string>
+    <string name="url">Server</string>
+    <string name="urlHint">Hostname or IP</string>
+    <string name="port">Port</string>
+    <string name="enableCustomTimeouts">Enable Custom Timeouts</string>
+    <string name="displayType">Display Blank Type</string>
+    <string name="displayBlankType">Display Blank Type</string>
+    <string name="displayBlankSummary">Select the required blank type</string>
+    <string name="displayScreen">Screen</string>
+    <string name="displayTheme">Theme</string>
+    <string name="displayDesktop">Desktop</string>
+    <string name="displayBlankOn">Reset display from</string>
+    <string name="displayBlankOff">Blank display to</string>
+    <string name="customTimeoutsSummary">Check to modify timeout settings</string>
+    <string name="customTimeout">Custom Timeout</string>
+    <string name="socketTimeout">Socket Timeout</string>
+    <string name="socketTimeoutSummary">Select a value (milliseconds)</string>
+    <string name="connectionTimeout">Connection Timeout</string>
+    <string name="connectionTimedout">Connection timed out</string>
+    <string name="connectionTimeoutSummary">Select a value (milliseconds)</string>
+    <string name="save">Save</string>
+    <string name="unable">Unable to load page -</string>
+    <string name="fail">Connection failed</string>
+    <string name="jsonfail">JSON failed</string>
+    <string name="loading">Connecting...</string>
+    <string name="searching">Searching...</string>
+    <string name="loadingServiceItems">Loading Service Items...</string>
+    <string name="loadingSlideItems">Loading Slide Items...</string>
+    <string name="loadingStatusInfo">Loading Status Info...</string>
+	<string name="searchHint">Search OpenLP</string>
+    <string name="searchResults">Search Results</string>
+    <string name="showingResults">Showing Results for \'%s\'</string>
+
+</resources>

=== added directory 'res/xml'
=== added file 'res/xml/preferences.xml'
--- res/xml/preferences.xml	1970-01-01 00:00:00 +0000
+++ res/xml/preferences.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen
+        xmlns:android="http://schemas.android.com/apk/res/android";>
+    <PreferenceCategory
+            android:title="@string/displayType">
+        <ListPreference
+                android:title="@string/displayBlankType"
+                android:key="@string/keyDisplayBlankType"
+                android:summary="@string/displayBlankSummary"
+                android:entries="@array/displayTypeValueEntries"
+                android:entryValues="@array/displayTypeValues"
+                android:defaultValue="@string/displayTypeValue"/>  
+    </PreferenceCategory>
+    <PreferenceCategory
+            android:title="@string/preferenceCategoryTitleServer">
+        <EditTextPreference
+                android:title="@string/url"
+                android:key="@string/keyHost"
+                android:hint="@string/urlHint"
+                android:inputType="textUri"
+                android:name="@string/url"/>
+        <EditTextPreference
+                android:defaultValue="@string/portDefaultValue"
+                android:title="@string/port"
+                android:key="@string/keyPort"
+                android:name="@string/url"
+                android:inputType="number"/>
+    </PreferenceCategory>
+    <PreferenceCategory
+            android:title="@string/customTimeout">
+        <CheckBoxPreference
+                android:title="@string/enableCustomTimeouts"
+                android:key="@string/keyEnableCustomTimeout"
+                android:summary="@string/customTimeoutsSummary"/>
+        <ListPreference
+                android:title="@string/connectionTimeout"
+                android:key="@string/keyConnectionTimeout"
+                android:summary="@string/connectionTimeoutSummary"
+                android:dependency="@string/keyEnableCustomTimeout"
+                android:entries="@array/socketValueEntries"
+                android:entryValues="@array/socketValues"
+                android:defaultValue="@integer/connectionTimeoutDefaultValue"/>
+        <ListPreference
+                android:title="@string/socketTimeout"
+                android:key="@string/keySocketTimeout"
+                android:summary="@string/socketTimeoutSummary"
+                android:dependency="@string/keyEnableCustomTimeout"
+                android:entries="@array/socketValueEntries"
+                android:entryValues="@array/socketValues"
+                android:defaultValue="@integer/socketTimeoutDefaultValue"/>
+    </PreferenceCategory>
+</PreferenceScreen>

=== added file 'res/xml/searchable.xml'
--- res/xml/searchable.xml	1970-01-01 00:00:00 +0000
+++ res/xml/searchable.xml	2012-01-07 20:53:27 +0000
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<searchable
+		xmlns:android="http://schemas.android.com/apk/res/android";
+		android:label="@string/app_name"
+		android:hint="@string/searchHint"
+		>
+	
+</searchable>
\ No newline at end of file

=== added directory 'src'
=== added directory 'src/org'
=== added directory 'src/org/openlp'
=== added directory 'src/org/openlp/android'
=== added file 'src/org/openlp/android/OpenLP.java'
--- src/org/openlp/android/OpenLP.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/OpenLP.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,72 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android;
+
+import android.app.TabActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.TabHost;
+import org.openlp.android.activity.Misc;
+import org.openlp.android.activity.Preferences;
+import org.openlp.android.activity.Service;
+import org.openlp.android.activity.Slide;
+
+/**
+ * OpenLP-Android initialisation point.
+ */
+public class OpenLP extends TabActivity {
+    /**
+     * Called when the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+
+        if (getSharedPreferences(getString(R.string.keySharedPreferences), Context.MODE_PRIVATE)
+                .getString(getString(R.string.keyHost), "NONE").equals("NONE")
+                || getSharedPreferences(getString(R.string.keySharedPreferences), Context.MODE_PRIVATE).getString(getString(R.string.keyHost), null).equals(null)
+                ) {
+            Log.d(LOG_TAG, "URL preference not set. Starting preference activity...");
+            Intent preferenceIntent = new Intent(this, Preferences.class);
+            startActivity(preferenceIntent);
+        }
+        TabHost tabHost = getTabHost();
+
+        tabHost.addTab(tabHost.newTabSpec("albums")
+                .setIndicator("Service")
+                .setContent(new Intent(this, Service.class)));
+
+        tabHost.addTab(tabHost.newTabSpec("artists")
+                .setIndicator("Slide")
+                .setContent(new Intent(this, Slide.class)));
+
+        tabHost.addTab(tabHost.newTabSpec("albums")
+                .setIndicator("Misc")
+                .setContent(new Intent(this, Misc.class)));
+
+    }
+    private final String LOG_TAG = OpenLP.class.getName();
+}
\ No newline at end of file

=== added directory 'src/org/openlp/android/activity'
=== added file 'src/org/openlp/android/activity/Misc.java'
--- src/org/openlp/android/activity/Misc.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/activity/Misc.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,299 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.activity;
+
+import java.util.Arrays;
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+import android.widget.ToggleButton;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.openlp.android.R;
+import org.openlp.android.api.Api;
+import org.openlp.android.data.Poll;
+import org.openlp.android.utility.JSONHandler;
+import org.openlp.android.utility.OpenLPHttpClient;
+import org.openlp.android.utility.WebCallAsyncTask;
+
+
+public class Misc extends Activity implements Api {
+    private final Context context = this;
+    Misc misc = this;
+    SharedPreferences prefs;
+    String displayType;
+    
+    /*
+     * Process the Alert button 
+     */
+    public Button.OnClickListener mSend = new Button.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            EditText edittext = (EditText) findViewById(R.id.alert);
+            String alert;
+            try {
+                if (edittext.getText().toString().trim().length() > 0) {
+                    alert = JSONHandler.createRequestJSON("text", edittext.getText().toString());
+                    new WebCallAsyncTask(context, ALERT).execute(alert);
+                }
+                else {
+                    Toast.makeText(getBaseContext(), getString(R.string.alertTextNull), Toast.LENGTH_SHORT).show();
+                }
+            }
+            catch (JSONHandler.JSONHandlerException e) {
+                Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
+            }
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        Log.i(LOG_TAG, "onCreate");
+        setContentView(R.layout.misc);
+       
+        prefs = getApplicationContext().getSharedPreferences(getApplicationContext().getString(R.string.keySharedPreferences), Context.MODE_PRIVATE);
+        Log.d(LOG_TAG, prefs.getAll().toString());
+        displayType = prefs.getString(getApplicationContext().getString(R.string.keyDisplayBlankType), getApplicationContext().getString(R.string.displayTypeValue));        
+        Log.d(LOG_TAG, "Pref Display Type = " + displayType);
+        
+        final ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggleDisplayButton);
+
+        toggleButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                try {
+                    if (!toggleButton.isChecked()) {
+                        new WebCallAsyncTask(context).execute(DISPLAY_SHOW);
+                    }
+                    else {
+                    	Log.d(LOG_TAG, "onCLick Display Type = " + displayType);                    	
+                    	if (displayType.equals(getString(R.string.displayScreen))){
+                    		Log.d(LOG_TAG, "Blank matched");                    		
+                    		new WebCallAsyncTask(context).execute(DISPLAY_HIDE_SCREEN);
+                    	}
+                    	else if (displayType.equals(getString(R.string.displayTheme))){
+                    		Log.d(LOG_TAG, "Theme matched");                    		
+                    		new WebCallAsyncTask(context).execute(DISPLAY_HIDE_THEME);                    		
+                    	}
+                        else {                   
+                    		Log.d(LOG_TAG, "Desktop matched");                        	
+                    		new WebCallAsyncTask(context).execute(DISPLAY_HIDE_DESKTOP);                        	
+                    	}
+                    }
+                }
+                catch (Exception e) {
+                    Toast.makeText(context, String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage()),
+                            Toast.LENGTH_SHORT).show();
+                }
+                PollStatusTask poll = new PollStatusTask(misc);
+                poll.execute(POLL_STATUS);
+            }
+        });
+
+        findViewById(R.id.send).setOnClickListener(mSend);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log.d(LOG_TAG, "Resume");
+        new PollStatusTask(this).execute(POLL_STATUS);
+    }
+
+    /**
+     * Asynchronous task to Poll the status data.
+     */
+    class PollStatusTask extends AsyncTask<String, Void, Poll> {
+        Misc miscActivity;
+        ProgressDialog progressDialog;
+        String error;
+
+        PollStatusTask(Misc miscActivity) {
+            this.miscActivity = miscActivity;
+        }
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            progressDialog = ProgressDialog.show(Misc.this, getString(R.string.loading),
+                    getString(R.string.loadingStatusInfo));
+        }
+
+        @Override
+        protected Poll doInBackground(String... strings) {
+            OpenLPHttpClient httpClient = new OpenLPHttpClient(getApplicationContext());
+            HttpResponse response = null;
+            String returnString = "";
+
+            Log.d(LOG_TAG, "Processing:" + Arrays.asList(strings));
+            try {
+                httpClient.setUrl(strings[0]);
+                if (httpClient.getUrl().getHost().trim().length() <= 0) {
+                    startActivity(new Intent(miscActivity, Preferences.class));
+                }
+                else {
+                    response = httpClient.execute();
+                }
+
+                if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                    HttpEntity entity = response.getEntity();
+
+                    if (entity != null) {
+                        Poll poll = JSONHandler.parsePollResponseJSON(entity);
+                        Log.i(LOG_TAG, String.format("Service Items: %s", poll));
+                        return poll;
+                    }
+                }
+                else {
+                    returnString = String.format("%s %s", getString(R.string.unable), response);
+                }
+            }
+            catch (Exception e) {
+                try {
+                    throw new FetchItemsException(e);
+                }
+                catch (FetchItemsException e1) {
+                    returnString = String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage());
+                }
+            }
+
+            if (returnString.trim().length() > 0) {
+                error = returnString;
+                Log.e(LOG_TAG, returnString);
+            }
+            return null;
+        } 
+        
+        @Override
+        protected void onPostExecute(Poll poll) {
+            super.onPostExecute(poll);
+            final ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggleDisplayButton);
+            if (poll == null){
+            	toggleButton.setEnabled(false);
+            }
+            else {
+            	String onText = "";
+            	String offText = "";
+            	
+	            displayType = prefs.getString(getApplicationContext().getString(R.string.keyDisplayBlankType), getApplicationContext().getString(R.string.displayTypeValue));
+	            Log.d(LOG_TAG, "onPostExecute Display Type = " + displayType + " " + poll.isDisplayHidden());
+	            /*
+	             * Set display blanking to the preferences value
+	             */
+	            if (displayType.equals(getString(R.string.displayScreen))){
+	            	Log.d(LOG_TAG, "Blank called");	            	
+	            	onText = context.getString(R.string.displayScreen);
+	            	offText = context.getString(R.string.displayScreen);
+    			} 
+    			else if (displayType.equals(getString(R.string.displayTheme))){
+    				Log.d(LOG_TAG, "Theme called");    				
+    				onText = context.getString(R.string.displayTheme);
+    				offText = context.getString(R.string.displayTheme);    				
+    			}
+    			else {
+    				Log.d(LOG_TAG, "Desktop called");    				
+    				onText = context.getString(R.string.displayDesktop);
+    				offText = context.getString(R.string.displayDesktop);    				
+    			}
+	            /*
+	             * Set display blanked to the off value to that of the screen
+	             */
+	            if ( poll.isDisplayHidden()){
+		            if (poll.isBlankedDisplayed()){
+		            	Log.d(LOG_TAG, "Blank called");	            	
+		            	onText = context.getString(R.string.displayScreen);    				
+	    			} 
+	    			else if (poll.isThemeDisplayed()){
+	    				Log.d(LOG_TAG, "Theme called");    				
+	    				onText = context.getString(R.string.displayTheme);    				
+	    			}
+	    			else {
+	    				Log.d(LOG_TAG, "Desktop called");    				
+	    				onText = context.getString(R.string.displayDesktop);    				
+	    			}	            
+	            }
+	            toggleButton.setTextOn(context.getString(R.string.displayBlankOn) + " " + onText);
+	            toggleButton.setTextOff(context.getString(R.string.displayBlankOff) + " " + offText); 
+	        	toggleButton.setEnabled(true);	            
+	        	toggleButton.setChecked(false);
+	            if (poll.isDisplayHidden()){
+	            	toggleButton.setChecked(true);
+	            }	            
+            }
+            progressDialog.dismiss();
+            if (error != null && error.trim().length() > 0) {
+                Toast.makeText(context, error, Toast.LENGTH_LONG).show();
+            }
+        }
+
+        class FetchItemsException extends Exception {
+            /**
+			 * 
+			 */
+			private static final long serialVersionUID = -1527836134529641630L;
+
+			FetchItemsException(Throwable throwable) {
+                super(throwable);
+            }
+        }        
+    }
+    
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.menu, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle item selection
+        switch (item.getItemId()) {
+            case R.id.preferences:
+                startActivity(new Intent(this, Preferences.class));
+                return true;
+            case R.id.menuSearch:
+                onSearchRequested();
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+    private final String LOG_TAG = Misc.class.getName();
+}

=== added file 'src/org/openlp/android/activity/Preferences.java'
--- src/org/openlp/android/activity/Preferences.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/activity/Preferences.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.activity;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.util.Log;
+import org.openlp.android.R;
+
+/**
+ * Credits:
+ * http://www.kaloer.com/android-preferences
+ * http://androidpartaker.wordpress.com/2010/07/11/android-preferences/
+ */
+public class Preferences extends PreferenceActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.d(LOG_TAG, "Launching preferences");
+        getPreferenceManager().setSharedPreferencesName(getString(R.string.keySharedPreferences));
+        addPreferencesFromResource(R.xml.preferences);
+    }
+
+    private final String LOG_TAG = Preferences.class.getName();
+}

=== added file 'src/org/openlp/android/activity/SearchableActivity.java'
--- src/org/openlp/android/activity/SearchableActivity.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/activity/SearchableActivity.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,226 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.activity;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.app.SearchManager;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ExpandableListView;
+import android.widget.Toast;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.openlp.android.R;
+import org.openlp.android.api.Api;
+import org.openlp.android.utility.GroupExpandableListAdapter;
+import org.openlp.android.utility.JSONHandler;
+import org.openlp.android.utility.WebCallAsyncTask;
+import org.openlp.android.utility.WebCallReturningAsyncTask;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SearchableActivity extends Activity implements Api {
+    private Activity context;
+    private ExpandableListView listView;
+    private final int DIALOG_ITEM_OPTIONS = 0;
+    private Object dialogKey;
+    private JSONArray dialogValue;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search);
+        context = this;
+        listView = (ExpandableListView) findViewById(R.id.list);
+
+        listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
+            @SuppressWarnings({"unchecked"})
+            @Override
+            public boolean onChildClick(ExpandableListView expandableListView, View view, int parent,
+                                        int childPosition, long l) {
+                Map<String, JSONArray> child = (Map<String, JSONArray>) listView.getExpandableListAdapter()
+                        .getChild(parent, childPosition);
+                dialogKey = null;
+                dialogValue = null;
+                dialogKey = listView.getExpandableListAdapter().getGroup(parent);
+                dialogValue = child.get(dialogKey.toString());
+                showDialog(DIALOG_ITEM_OPTIONS);
+                return false;
+            }
+        });
+
+        Intent intent = getIntent();
+        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
+            String query = intent.getStringExtra(SearchManager.QUERY);
+            doSearch(query);
+        }
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+            case DIALOG_ITEM_OPTIONS:
+                AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
+                dialogBuilder.setTitle("Item Options:");
+                dialogBuilder.setNegativeButton("Send Live", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialogInterface, int i) {
+                        try {
+                            new WebCallAsyncTask(context, String.format(SEARCH_PLUGIN_LIVE, dialogKey))
+                                    .execute(JSONHandler.createRequestJSON("id", dialogValue.get(0).toString()));
+                        }
+                        catch (Exception e) {
+                            Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
+                        }
+                    }
+                });
+                dialogBuilder.setPositiveButton("Add to Service", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialogInterface, int i) {
+                        try {
+                            new WebCallAsyncTask(context, String.format(SEARCH_PLUGIN_ADD, dialogKey))
+                                    .execute(JSONHandler.createRequestJSON("id", dialogValue.get(0).toString()));
+                        }
+                        catch (Exception e) {
+                            Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
+                        }
+                        dialogInterface.cancel();
+                    }
+                });
+                return dialogBuilder.create();
+            default:
+                return null;
+        }
+    }
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        try {
+            dialog.setTitle(dialogValue.get(1).toString());
+        }
+        catch (JSONException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void doSearch(String search) {
+        new SearchAsync().execute(search);
+    }
+
+    class SearchAsync extends AsyncTask<String, Void, SearchResults> {
+        ProgressDialog progressDialog;
+        String query;
+
+        @Override
+        protected SearchResults doInBackground(String... strings) {
+            query = strings[0];
+            List<String> groups = new ArrayList<String>();
+            List<List<Map<String, JSONArray>>> children = new ArrayList<List<Map<String, JSONArray>>>();
+
+            AsyncTask <String, Void, String> call = new WebCallReturningAsyncTask(context).execute(SEARCHABLE_PLUGINS);
+
+            try {
+                JSONArray array = new JSONObject(call.get().toString()).getJSONObject("results").getJSONArray("items");
+
+                for (int i = 0; i < array.length(); i++) {
+                    String pluginString = ((JSONArray) array.get(i)).get(0).toString();
+                    groups.add(pluginString);
+
+                    JSONArray resultArray = null;
+
+                    AsyncTask <String, Void, String> pluginResults = new WebCallReturningAsyncTask(context,
+                            String.format(SEARCH_PLUGIN_FORMATTED, pluginString))
+                            .execute(JSONHandler.createRequestJSON("text", query));
+
+                    List<Map<String, JSONArray>> list = new ArrayList<Map<String, JSONArray>>();
+                    if (pluginResults.get() != null && pluginResults.get().toString().trim().length() > 0) {
+                        resultArray = new JSONObject(pluginResults.get().toString()).getJSONObject("results")
+                                .getJSONArray("items");
+                        for (int j = 0; j < resultArray.length(); j++) {
+                            Map<String, JSONArray> item = new HashMap<String, JSONArray>();
+                            item.put(pluginString, (JSONArray) resultArray.get(j));
+                            list.add(item);
+                        }
+                    }
+                    children.add(list);
+                }
+            }
+            catch (Exception e) {
+                Log.e(LOG_TAG, e.toString());
+                Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
+            }
+
+            SearchResults results = new SearchResults();
+            results.setGroups(groups);
+            results.setChildren(children);
+            return results;
+        }
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            progressDialog = ProgressDialog.show(context, null, getString(R.string.searching));
+        }
+
+        @Override
+        protected void onPostExecute(SearchResults results) {
+            super.onPostExecute(results);
+            listView.setAdapter(new GroupExpandableListAdapter(context, results.getGroups(), results.getChildren()));
+            progressDialog.dismiss();
+            Toast.makeText(context, String.format(getString(R.string.showingResults), query), Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    class SearchResults {
+        List<String> groups;
+        List<List<Map<String, JSONArray>>> children;
+
+        public List<String> getGroups() {
+            return groups;
+        }
+
+        public void setGroups(List<String> groups) {
+            this.groups = groups;
+        }
+
+        public List<List<Map<String, JSONArray>>> getChildren() {
+            return children;
+        }
+
+        public void setChildren(List<List<Map<String, JSONArray>>> children) {
+            this.children = children;
+        }
+    }
+    private final String LOG_TAG = this.getClass().getSimpleName();    
+}

=== added file 'src/org/openlp/android/activity/Service.java'
--- src/org/openlp/android/activity/Service.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/activity/Service.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,233 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.activity;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.Toast;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.openlp.android.R;
+import org.openlp.android.api.Api;
+import org.openlp.android.data.Slide;
+import org.openlp.android.utility.JSONHandler;
+import org.openlp.android.utility.OpenLPHttpClient;
+import org.openlp.android.utility.SlideAdapter;
+import org.openlp.android.utility.WebCallAsyncTask;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Activity for managing service objects.
+ */
+public class Service extends Activity implements Api {
+    private final Activity context = this;
+
+    private ListView listView;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(LOG_TAG, "onCreate");
+
+        setContentView(R.layout.service);
+        listView = (ListView) findViewById(R.id.list);
+        findViewById(R.id.prev).setOnClickListener(new Button.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    new WebCallAsyncTask(context).execute(SERVICE_PREVIOUS);
+                }
+                catch (Exception e) {
+                    Toast.makeText(getApplicationContext(),
+                            String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage()),
+                            Toast.LENGTH_SHORT).show();
+                }
+            }
+        });
+
+        findViewById(R.id.next).setOnClickListener(new Button.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    new WebCallAsyncTask(context).execute(SERVICE_NEXT);
+                }
+                catch (Exception e) {
+                    Toast.makeText(getApplicationContext(),
+                            String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage()),
+                            Toast.LENGTH_SHORT).show();
+                }
+            }
+        });
+
+        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
+                String service;
+                try {
+                    service = JSONHandler.createRequestJSON("id", Integer.toString(i));
+                    new WebCallAsyncTask(context, SERVICE_SET).execute(service);
+                    service = null;
+                }
+                catch (JSONHandler.JSONHandlerException e) {
+                    service = String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage());
+                }
+
+                if (service != null) {
+                    Toast.makeText(getApplicationContext(), service, Toast.LENGTH_LONG).show();
+                }
+            }
+        });
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log.d(LOG_TAG, "Resume");
+
+        new FetchServiceItemsTask(this).execute(SERVICE_LIST);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.menu, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.preferences:
+                startActivity(new Intent(this, Preferences.class));
+                return true;
+            case R.id.menuSearch:
+                onSearchRequested();
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+    /**
+     * Asynchronous task to fetch the service items.
+     */
+    class FetchServiceItemsTask extends AsyncTask<String, Void, Slide[]> {
+        Service serviceActivity;
+        ProgressDialog progressDialog;
+        String error;
+
+        FetchServiceItemsTask(Service serviceActivity) {
+            this.serviceActivity = serviceActivity;
+        }
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            progressDialog = ProgressDialog.show(Service.this, getString(R.string.loading),
+                    getString(R.string.loadingServiceItems));
+        }
+
+        @Override
+        protected Slide[] doInBackground(String... strings) {
+            OpenLPHttpClient httpClient = new OpenLPHttpClient(getApplicationContext());
+            HttpResponse response = null;
+            String returnString = "";
+
+            Log.d(LOG_TAG, "Processing:" + Arrays.asList(strings));
+            try {
+                httpClient.setUrl(strings[0]);
+                if (httpClient.getUrl().getHost().trim().length() <= 0) {
+                    startActivity(new Intent(serviceActivity, Preferences.class));
+                }
+                else {
+                    response = httpClient.execute();
+                }
+
+                if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                    HttpEntity entity = response.getEntity();
+
+                    if (entity != null) {
+                        List<Slide> serviceItemList = JSONHandler.parseServiceItemResponseJSON(entity);
+                        Log.i(LOG_TAG, String.format("Service Items: %s", serviceItemList));
+                        return serviceItemList.toArray(new Slide[]{});
+                    }
+                }
+                else {
+                    returnString = String.format("%s %s", getString(R.string.unable), response);
+                }
+            }
+            catch (Exception e) {
+                try {
+                    throw new FetchItemsException(e);
+                }
+                catch (FetchItemsException e1) {
+                    returnString = String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage());
+                }
+            }
+
+            if (returnString.trim().length() > 0) {
+                error = returnString;
+                Log.e(LOG_TAG, returnString);
+            }
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Slide[] slides) {
+            super.onPostExecute(slides);
+            if (slides == null) {
+                slides = new Slide[]{};
+            }
+            listView.setAdapter(new SlideAdapter(context, Arrays.asList(slides), false));
+            progressDialog.dismiss();
+            if (error != null && error.trim().length() > 0) {
+                Toast.makeText(context, error, Toast.LENGTH_LONG).show();
+            }
+        }
+
+        class FetchItemsException extends Exception {
+            /**
+			 * 
+			 */
+			private static final long serialVersionUID = -1527836134529641630L;
+
+			FetchItemsException(Throwable throwable) {
+                super(throwable);
+            }
+        }
+    }
+    private final String LOG_TAG = Service.class.getName();    
+}
\ No newline at end of file

=== added file 'src/org/openlp/android/activity/Slide.java'
--- src/org/openlp/android/activity/Slide.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/activity/Slide.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,232 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.activity;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.Toast;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.openlp.android.R;
+import org.openlp.android.api.Api;
+import org.openlp.android.utility.JSONHandler;
+import org.openlp.android.utility.OpenLPHttpClient;
+import org.openlp.android.utility.SlideAdapter;
+import org.openlp.android.utility.WebCallAsyncTask;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class Slide extends Activity implements Api {
+    private final Activity context = this;
+    private ListView slideList;
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.d(LOG_TAG, "onCreate");
+        setContentView(R.layout.slide);
+
+        slideList = (ListView) findViewById(R.id.list);
+
+        findViewById(R.id.prev).setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                try {
+                    new WebCallAsyncTask(context).execute(LIVE_PREVIOUS);
+                }
+                catch (Exception e) {
+                    Toast.makeText(getApplicationContext(),
+                            String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage()),
+                            Toast.LENGTH_SHORT).show();
+                    Log.e(LOG_TAG, e.toString(), e);
+                }
+            }
+        });
+
+        findViewById(R.id.next).setOnClickListener(new Button.OnClickListener() {
+            public void onClick(View v) {
+                try {
+                    new WebCallAsyncTask(context).execute(LIVE_NEXT);
+                }
+                catch (Exception e) {
+                    Toast.makeText(getApplicationContext(),
+                            String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage()),
+                            Toast.LENGTH_SHORT).show();
+                    Log.e(LOG_TAG, e.toString(), e);
+                }
+            }
+        });
+
+        slideList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
+                String alert;
+                try {
+                    alert = JSONHandler.createRequestJSON("id", Integer.toString(i));
+                    new WebCallAsyncTask(context, LIVE_SET).execute(alert);
+                    alert = null;
+                }
+                catch (Exception e) {
+                    try {
+                        throw new JSONHandler.JSONHandlerException(e);
+                    }
+                    catch (JSONHandler.JSONHandlerException e1) {
+                        alert = String.format("%s: %s", e1.getClass().getSimpleName(), e1.getMessage());
+                    }
+                }
+
+                if (alert != null) {
+                    Toast.makeText(getApplicationContext(), alert, Toast.LENGTH_LONG).show();
+                }
+            }
+        });
+
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log.d(LOG_TAG, "Resume");
+
+        new FetchSlideItemsTask(this).execute(LIVE_TEXT);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.menu, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.preferences:
+                startActivity(new Intent(this, Preferences.class));
+                return true;
+            case R.id.menuSearch:
+                onSearchRequested();
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+    class FetchSlideItemsTask extends AsyncTask<String, Void, org.openlp.android.data.Slide[]> {
+        Slide slideActivity;
+        ProgressDialog progressDialog;
+        String error;
+
+        FetchSlideItemsTask(Slide slideActivity) {
+            this.slideActivity = slideActivity;
+        }
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            progressDialog = ProgressDialog.show(Slide.this, getString(R.string.loading), getString(R.string.loadingSlideItems));
+        }
+
+        @Override
+        protected org.openlp.android.data.Slide[] doInBackground(String... strings) {
+            OpenLPHttpClient httpClient = new OpenLPHttpClient(getApplicationContext());
+            HttpResponse response = null;
+            String returnString = "";
+
+            Log.d(LOG_TAG, "Processing:" + Arrays.asList(strings));
+            try {
+                httpClient.setUrl(strings[0]);
+                if (httpClient.getUrl().getHost().trim().length() <= 0) {
+                    startActivity(new Intent(slideActivity, Preferences.class));
+                }
+                else {
+                    response = httpClient.execute();
+                }
+
+                if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                    HttpEntity entity = response.getEntity();
+
+                    if (entity != null) {
+                        List<org.openlp.android.data.Slide> slideItemList = JSONHandler.parseSlideItemResponseJSON(entity);
+                        Log.d(LOG_TAG, String.format("slides: %s", slideItemList));
+                        return slideItemList.toArray(new org.openlp.android.data.Slide[]{});
+                    }
+                }
+                else {
+                    returnString = String.format("%s %s", getString(R.string.unable), response);
+                }
+            }
+            catch (Exception ex) {
+                try {
+                    throw new FetchItemsException(ex);
+                }
+                catch (FetchItemsException e) {
+                	Log.d(LOG_TAG, String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage()));
+                    returnString = String.format("%s", getString(R.string.connectionTimedout));
+                }
+            }
+
+            if (returnString.trim().length() > 0) {
+                error = returnString;
+                Log.e(LOG_TAG, returnString);
+            }
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(org.openlp.android.data.Slide[] slides) {
+            super.onPostExecute(slides);
+            if (slides == null) {
+                slides = new org.openlp.android.data.Slide[]{};
+            }
+            slideList.setAdapter(new SlideAdapter(context, Arrays.asList(slides)));
+            progressDialog.dismiss();
+
+            if (error != null && error.trim().length() > 0) {
+                Toast.makeText(context, error, Toast.LENGTH_LONG).show();
+            }
+        }
+
+        class FetchItemsException extends Exception {
+            /**
+			 * 
+			 */
+			private static final long serialVersionUID = 5643837655316198262L;
+
+			FetchItemsException(Throwable throwable) {
+                super(throwable);
+            }
+        }
+    }
+    private final String LOG_TAG = Slide.class.getName();    
+}

=== added directory 'src/org/openlp/android/api'
=== added file 'src/org/openlp/android/api/Api.java'
--- src/org/openlp/android/api/Api.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/api/Api.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,121 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.api;
+
+/**
+ * <h1>Routes:</h1>
+ * <p/>
+ * <pre>
+ * ``/``
+ * Go to the web interface.
+ *
+ * ``/files/{filename}``
+ *
+ * ``/api/poll``
+ * {"results": {"type": "controller"}}
+ * Or, if there were no results, False::
+ * {"results": False}
+ *
+ * ``/api/display/{hide|show}``
+ * Blank or unblank the screen.
+ *
+ * ``/api/alert``
+ * {"request": {"text": "<your alert text>"}}
+ * ``/api/controller/{live|preview}/{action}``
+ * ``next``
+ * Load the next slide.
+ *
+ * ``previous``
+ * Load the previous slide.
+ *
+ * ``set``
+ * Set a specific slide. Requires an id return in a JSON-encoded dict like
+ * this::
+ *
+ * {"request": {"id": 1}}
+ *
+ * ``first``
+ * Load the first slide.
+ *
+ * ``last``
+ * Load the last slide.
+ *
+ * ``text``
+ * Fetches the text of the current song. The output is a JSON-encoded
+ * dict which looks like this::
+ *
+ * {"result": {"slides": ["...", "..."]}}
+ *
+ * ``/api/service/{action}``
+ * Perform ``{action}`` on the service manager (e.g. go live). Data is
+ * passed as a json-encoded ``data`` parameter. Valid actions are:
+ *
+ * ``next``
+ * Load the next item in the service.
+ *
+ * ``previous``
+ *
+ * ``set``
+ * Set a specific item in the service. Requires an id returned in a
+ * JSON-encoded dict like this::
+ *
+ * {"request": {"id": 1}}
+ *
+ * ``list``
+ * Request a list of items in the service. Returns a list of items in the
+ * current service in a JSON-encoded dict like this::
+ *
+ * {"results": {"items": [{...}, {...}]}}
+ * """
+ * </pre>
+ */
+
+public interface Api {
+
+    public final String LIVE_NEXT = "/api/controller/live/next";
+    public final String LIVE_PREVIOUS = "/api/controller/live/previous";
+    public final String LIVE_TEXT = "/api/controller/live/text";
+    public final String LIVE_SET = "/api/controller/live/set?data=";
+
+    public final String SERVICE_NEXT = "/api/service/next";
+    public final String SERVICE_PREVIOUS = "/api/service/previous";
+    public final String SERVICE_LIST = "/api/service/list";
+    public final String SERVICE_SET = "/api/service/set?data=";
+
+    public final String DISPLAY_HIDE_SCREEN = "/api/display/blank";
+    public final String DISPLAY_HIDE_THEME = "/api/display/theme";
+    public final String DISPLAY_HIDE_DESKTOP = "/api/display/desktop";
+    public final String DISPLAY_SHOW = "/api/display/show";
+    public final String POLL_STATUS = "/api/poll";
+
+    public final String ALERT = "/api/alert?data=";
+
+    public final String SEARCHABLE_PLUGINS = "/api/plugin/search";
+    /**
+     * This is a special string that uses the String.format() method.
+     * See {@link String#format(String, Object...)}
+     */
+    public final String SEARCH_PLUGIN_FORMATTED = "/api/%s/search?data=";
+    public final String SEARCH_PLUGIN_LIVE = "/api/%s/live?data=";
+    public final String SEARCH_PLUGIN_ADD = "/api/%s/add?data=";
+}

=== added directory 'src/org/openlp/android/data'
=== added file 'src/org/openlp/android/data/Poll.java'
--- src/org/openlp/android/data/Poll.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/data/Poll.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,101 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+
+package org.openlp.android.data;
+
+
+public class Poll {
+	
+	private int slide;
+	private String item;
+	private boolean twelveHourDisplay = false;;
+	private boolean blankedDisplayed = false;;
+	private boolean themeDisplayed = false;;
+	private boolean desktopDisplayed = false;
+	private boolean displayHidden = false;
+
+	public int getSlide() {
+		return slide;
+	}
+
+	public void setSlide(int slide) {
+		this.slide = slide;
+	}
+
+	public String getItem() {
+		return item;
+	}
+
+	public void setItem(String item) {
+		this.item = item;
+	}
+
+	public boolean isTwelveHourDisplay() {
+		return twelveHourDisplay;
+	}
+
+	public void setTwelveHourDisplay(boolean twelveHourDisplay) {
+		this.twelveHourDisplay = twelveHourDisplay;
+	}
+
+	public boolean isBlankedDisplayed() {
+		return blankedDisplayed;
+	}
+
+	public void setBlankedDisplayed(boolean blankedDisplayed) {
+		this.blankedDisplayed = blankedDisplayed;
+		if (blankedDisplayed){
+			this.displayHidden = true;
+		}
+	}
+
+	public boolean isThemeDisplayed() {
+		return themeDisplayed;
+	}
+
+	public void setThemeDisplayed(boolean themeDisplayed) {
+		this.themeDisplayed = themeDisplayed;
+		if (themeDisplayed){
+			this.displayHidden = true;
+		}		
+	}
+
+	public boolean isDesktopDisplayed() {
+		return desktopDisplayed;
+	}
+
+	public void setDesktopDisplayed(boolean desktopDisplayed) {
+		this.desktopDisplayed = desktopDisplayed;
+		if (desktopDisplayed){
+			this.displayHidden = true;
+		}		
+	}
+
+	public boolean isDisplayHidden() {
+		return displayHidden;
+	}
+
+	public void setDisplayHidden(boolean displayHidden) {
+		this.displayHidden = displayHidden;
+	}
+}

=== added file 'src/org/openlp/android/data/Slide.java'
--- src/org/openlp/android/data/Slide.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/data/Slide.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,72 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.data;
+
+public class Slide {
+    private String text;
+    private boolean selected;
+    private String tag;
+    private String html;
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public boolean isSelected() {
+        return selected;
+    }
+
+    public void setSelected(boolean selected) {
+        this.selected = selected;
+    }
+
+    public String getTag() {
+        return tag;
+    }
+
+    public void setTag(String tag) {
+        this.tag = tag;
+    }
+
+    public String getHtml() {
+        return html;
+    }
+
+    public void setHtml(String html) {
+        this.html = html;
+    }
+
+    @Override
+    public String toString() {
+        return "SlidePOJO{" +
+                "text='" + text + '\'' +
+                ", selected=" + selected +
+                ", tag='" + tag + '\'' +
+                ", html='" + html + '\'' +
+                '}';
+    }
+}

=== added directory 'src/org/openlp/android/service'
=== added file 'src/org/openlp/android/service/PingService.java'
--- src/org/openlp/android/service/PingService.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/service/PingService.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,16 @@
+package org.openlp.android.service;
+
+import android.os.Bundle;
+import org.openlp.android.activity.Service;
+
+public class PingService extends Service {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+    }
+}

=== added directory 'src/org/openlp/android/utility'
=== added file 'src/org/openlp/android/utility/GroupExpandableListAdapter.java'
--- src/org/openlp/android/utility/GroupExpandableListAdapter.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/utility/GroupExpandableListAdapter.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,124 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.utility;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.TextView;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.openlp.android.R;
+
+import java.util.List;
+import java.util.Map;
+
+public class GroupExpandableListAdapter extends BaseExpandableListAdapter {
+    List<String> groups;
+    List<List<Map<String, JSONArray>>> children;
+    LayoutInflater inflater;
+    Activity context;
+
+    public GroupExpandableListAdapter(Activity context, List<String> groups,
+                                      List<List<Map<String, JSONArray>>> children) {
+        this.context = context;
+        this.groups = groups;
+        this.children = children;
+        inflater = context.getLayoutInflater();
+    }
+
+    @Override
+    public int getGroupCount() {
+        return groups.size();
+    }
+
+    @Override
+    public int getChildrenCount(int position) {
+        return children.get(position).size();
+    }
+
+    @Override
+    public Object getGroup(int position) {
+        return groups.get(position);
+    }
+
+    @Override
+    public Object getChild(int rootPosition, int childPosition) {
+        return children.get(rootPosition).get(childPosition);
+    }
+
+    @Override
+    public long getGroupId(int position) {
+        return groups.indexOf(groups.get(position));
+    }
+
+    @Override
+    public long getChildId(int i, int i1) {
+        List<Map<String, JSONArray>> child = children.get(i);
+        return child.indexOf(child.get(i1));
+    }
+
+    @Override
+    public boolean hasStableIds() {
+        return false;
+    }
+
+    @Override
+    public View getGroupView(int position, boolean b, View view, ViewGroup viewGroup) {
+        if (view == null) {
+            view = inflater.inflate(R.layout.group_parent, null);
+            view.setClickable(false);
+        }
+        TextView textView = (TextView) view.findViewById(R.id.groupParentText);
+        TextView numberView = (TextView) view.findViewById(R.id.parentChildCount);
+        numberView.setText(String.format("%s", children.get(position).size()));
+        textView.setText(groups.get(position));
+        return view;
+    }
+
+    @Override
+    public View getChildView(int groupPosition, int childPosition, boolean b, View view, ViewGroup viewGroup) {
+        if (view == null) {
+            view = inflater.inflate(R.layout.group_child, null);
+            view.setClickable(false);
+        }
+        TextView childView = (TextView) view.findViewById(R.id.groupChildText);
+        List<Map<String, JSONArray>> childItem = children.get(groupPosition);
+        Map<String, JSONArray> mapItem = childItem.get(childPosition);
+        JSONArray jsonItem = mapItem.get(groups.get(groupPosition));
+        try {
+            childView.setText(String.format("%s", jsonItem.get(1)));
+        }
+        catch (JSONException e) {
+            e.printStackTrace();
+        }
+        return view;
+    }
+
+    @Override
+    public boolean isChildSelectable(int i, int i1) {
+        return true;
+    }
+}

=== added file 'src/org/openlp/android/utility/JSONHandler.java'
--- src/org/openlp/android/utility/JSONHandler.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/utility/JSONHandler.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,164 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.utility;
+
+import android.util.Log;
+import org.apache.http.HttpEntity;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONStringer;
+import org.openlp.android.data.Poll;
+import org.openlp.android.data.Slide;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JSONHandler {
+
+    public static String createRequestJSON(String key, String value) throws JSONHandlerException {
+        try {
+            String responseJSON;
+            JSONObject jo = new JSONObject();
+            jo.put(key, value);
+            responseJSON = new JSONStringer().object().key("request").value(jo).endObject().toString();
+            responseJSON = URLEncoder.encode(responseJSON, "UTF-8");
+            return responseJSON;
+        }
+        catch (JSONException e) {
+            throw new JSONHandlerException(e);
+        }
+        catch (UnsupportedEncodingException e) {
+            throw new JSONHandlerException(e);
+        }
+    }
+
+    public static List<Slide> parseServiceItemResponseJSON(HttpEntity entity) throws JSONHandlerException {
+        try {
+            List<Slide> serviceItemList = new ArrayList<Slide>();
+            InputStream inputStream = entity.getContent();
+            String result = StringHelper.convertStreamToString(inputStream);
+            Log.i(LOG_TAG, result);
+
+            JSONObject jObject = new JSONObject(result);
+            JSONObject results = jObject.getJSONObject("results");
+            JSONArray items = results.getJSONArray("items");
+
+            for (int i = 0; i < items.length(); i++) {
+                JSONObject item = items.getJSONObject(i);
+                Slide slide = new Slide();
+                slide.setTag("");
+                slide.setText(item.getString("title"));
+                slide.setSelected(item.getBoolean("selected"));
+                slide.setHtml("");
+                serviceItemList.add(slide);
+            }
+
+            inputStream.close();
+            return serviceItemList;
+        }
+        catch (IOException e) {
+            throw new JSONHandlerException(e);
+        }
+        catch (JSONException e) {
+            throw new JSONHandlerException(e);
+        }
+
+    }
+
+    public static List<Slide> parseSlideItemResponseJSON(HttpEntity entity) throws JSONHandlerException {
+        try {
+            List<Slide> serviceItemList = new ArrayList<Slide>();
+            InputStream inputStream = entity.getContent();
+            String result = StringHelper.convertStreamToString(inputStream);
+            Log.i(LOG_TAG, result);
+
+            JSONObject jObject = new JSONObject(result);
+            JSONObject results = jObject.getJSONObject("results");
+            JSONArray items = results.getJSONArray("slides");
+
+            for (int i = 0; i < items.length(); i++) {
+                JSONObject item = items.getJSONObject(i);
+                Slide slide = new Slide();
+                slide.setText(item.getString("text"));
+                slide.setTag(item.getString("tag"));
+                slide.setSelected(item.getBoolean("selected"));
+                slide.setHtml(item.getString("html"));
+                serviceItemList.add(slide);
+            }
+
+            inputStream.close();
+            return serviceItemList;
+        }
+        catch (IOException e) {
+            throw new JSONHandlerException(e);
+        }
+        catch (JSONException e) {
+            throw new JSONHandlerException(e);
+        }
+    }
+    
+    public static Poll parsePollResponseJSON(HttpEntity entity) throws JSONHandlerException {
+        try {
+            InputStream inputStream = entity.getContent();
+            String result = StringHelper.convertStreamToString(inputStream);
+            Log.i(LOG_TAG, result);
+
+            JSONObject jObject = new JSONObject(result);
+            JSONObject results = jObject.getJSONObject("results");
+            //JSONArray items = results.getJSONArray("slides");
+            Poll poll = new Poll();
+            poll.setSlide(results.getInt("slide"));
+            poll.setItem(results.getString("item"));
+            poll.setTwelveHourDisplay(results.getBoolean("twelve"));
+            poll.setBlankedDisplayed(results.getBoolean("blank"));
+            poll.setThemeDisplayed(results.getBoolean("theme"));
+            poll.setDesktopDisplayed(results.getBoolean("display"));  
+            Log.d(LOG_TAG, poll.toString());            
+            inputStream.close();
+            return poll;
+        }
+        catch (IOException e) {
+            throw new JSONHandlerException(e);
+        }
+        catch (JSONException e) {
+            throw new JSONHandlerException(e);
+        }
+    }
+    
+    public static class JSONHandlerException extends Exception {
+        /**
+		 * 
+		 */
+		private static final long serialVersionUID = -6772307308404816615L;
+
+		public JSONHandlerException(Throwable throwable) {
+            super(throwable);
+        }
+    }
+    private static String LOG_TAG = JSONHandler.class.getName();    
+}

=== added file 'src/org/openlp/android/utility/OpenLPHttpClient.java'
--- src/org/openlp/android/utility/OpenLPHttpClient.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/utility/OpenLPHttpClient.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,94 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.utility;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.openlp.android.R;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+/**
+ * Personalised HttpClient to be used throughout OpenLP with customisable parameters.
+ */
+public class OpenLPHttpClient extends DefaultHttpClient {
+
+    private HttpGet httpGet;
+    private URL url;
+    private final String urlBase;
+
+    public OpenLPHttpClient(Context context) {
+        SharedPreferences preferences = context.getSharedPreferences(context
+                .getString(R.string.keySharedPreferences), Context.MODE_PRIVATE);
+
+        Log.d(LOG_TAG, preferences.getAll().toString());
+        HttpParams httpParams = new BasicHttpParams();
+
+        urlBase = String.format("http://%s:%s";,
+                preferences.getString(context.getString(R.string.keyHost), context.getString(R.string.hostDefaultValue)),
+                preferences.getString(context.getString(R.string.keyPort), context.getString(R.string.portDefaultValue)));
+
+        int connectionTimeout = context.getResources().getInteger(R.integer.connectionTimeoutDefaultValue);
+        int socketTimeout = context.getResources().getInteger(R.integer.socketTimeoutDefaultValue);
+
+        if (preferences.getBoolean(context.getString(R.string.keyEnableCustomTimeout), false)) {
+            Log.d(LOG_TAG, String.format("Retrieving values for %s and %s...", context
+                    .getString(R.string.keyConnectionTimeout), context.getString(R.string.keySocketTimeout)));
+            connectionTimeout = Integer.parseInt(preferences.getString(context.getString(R.string.keyConnectionTimeout),
+                    String.valueOf(context.getResources().getInteger(R.integer.connectionTimeoutDefaultValue))));
+            socketTimeout = Integer.parseInt(preferences.getString(context.getString(R.string.keySocketTimeout),
+                    String.valueOf(context.getResources().getInteger(R.integer.socketTimeoutDefaultValue))));
+        }
+        HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeout);
+        HttpConnectionParams.setSoTimeout(httpParams, socketTimeout);
+
+        setParams(httpParams);
+
+        httpGet = new HttpGet();
+    }
+
+    public URL getUrl() {
+        return url;
+    }
+
+    public void setUrl(String apiPart) throws URISyntaxException, MalformedURLException {
+        url = new URL(urlBase.concat(apiPart));
+        Log.d(LOG_TAG, "URL set to: " + url);
+        httpGet.setURI(getUrl().toURI());
+    }
+
+    public HttpResponse execute() throws IOException {
+        return super.execute(httpGet);
+    }
+    private final String LOG_TAG = OpenLPHttpClient.class.getName();
+}

=== added file 'src/org/openlp/android/utility/SlideAdapter.java'
--- src/org/openlp/android/utility/SlideAdapter.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/utility/SlideAdapter.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.utility;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+import org.openlp.android.R;
+import org.openlp.android.data.Slide;
+
+import java.util.List;
+
+public class SlideAdapter extends BaseAdapter {
+    List<Slide> items;
+    Activity context;
+    LayoutInflater inflater;
+    boolean useTagDisplay = true;
+
+    public SlideAdapter(Activity context, List<Slide> items) {
+        this.context = context;
+        this.items = items;
+        inflater = context.getLayoutInflater();
+    }
+
+    public SlideAdapter(Activity context, List<Slide> items, boolean useTagDisplay) {
+        this.context = context;
+        this.items = items;
+        this.useTagDisplay = useTagDisplay;
+        inflater = context.getLayoutInflater();
+    }
+
+    @Override
+    public int getCount() {
+        return items.size();
+    }
+
+    @Override
+    public Object getItem(int i) {
+        return items.get(i);
+    }
+
+    @Override
+    public long getItemId(int i) {
+        return items.indexOf(items.get(i));
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        ViewHolder holder;
+        View view = convertView;
+
+        Slide item = items.get(position);
+
+        if (view == null) {
+            view = inflater.inflate(R.layout.slide_list_item, null);
+            holder = new ViewHolder();
+
+            holder.rowMarker = (TextView) view.findViewById(R.id.rowItemMarker);
+            holder.rowItem = (TextView) view.findViewById(R.id.rowItemText);
+
+            view.setTag(holder);
+        }
+        else {
+            holder = (ViewHolder) view.getTag();
+        }
+
+        holder.rowMarker.setText(item.getTag());
+        holder.rowItem.setText(item.getText());
+
+        if (useTagDisplay) {
+            holder.rowMarker.setMinWidth(40);
+        }
+        return view;
+    }
+
+    static class ViewHolder {
+        TextView rowMarker;
+        TextView rowItem;
+    }
+}

=== added file 'src/org/openlp/android/utility/StringHelper.java'
--- src/org/openlp/android/utility/StringHelper.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/utility/StringHelper.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,65 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.utility;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * String helper utility to do common string processing.
+ */
+public class StringHelper {
+    public synchronized static String convertStreamToString(InputStream is) {
+        /*
+            To convert the InputStream to String we use the
+            BufferedReader.readLine() method. We iterate until the BufferedReader
+            return null which means there's no more data to read. Each line will
+            appended to a StringBuilder and returned as String.
+        */
+
+        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+        StringBuilder sb = new StringBuilder();
+
+        String line = null;
+        try {
+            while ((line = reader.readLine()) != null) {
+                sb.append(line + "\n");
+            }
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+        }
+        finally {
+            try {
+                is.close();
+            }
+            catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return sb.toString();
+    }
+
+}

=== added file 'src/org/openlp/android/utility/WebCallAsyncTask.java'
--- src/org/openlp/android/utility/WebCallAsyncTask.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/utility/WebCallAsyncTask.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.utility;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.os.AsyncTask;
+import android.util.Log;
+import android.widget.Toast;
+import org.openlp.android.R;
+
+/**
+ * Call URL's using this task, which provides visual feedback.
+ */
+public class WebCallAsyncTask extends AsyncTask<String, Void, Void> {
+    private Context context;
+    private ProgressDialog progressDialog;
+    private String error;
+    private String apiPart;
+
+    public WebCallAsyncTask(Context context) {
+        this.context = context;
+    }
+
+    public WebCallAsyncTask(Context context, String apiPart) {
+        this.context = context;
+        this.apiPart = apiPart;
+    }
+
+    @Override
+    protected void onPreExecute() {
+        super.onPreExecute();
+        progressDialog = ProgressDialog.show(context, "", context.getString(R.string.loading));
+    }
+
+    @Override
+    protected Void doInBackground(String... apiCall) {
+        OpenLPHttpClient httpClient = new OpenLPHttpClient(context);
+        try {
+            if (apiPart == null) {
+                httpClient.setUrl(apiCall[0]);
+            }
+            else {
+                httpClient.setUrl(String.format("%s%s", apiPart, apiCall[0]));
+            }
+
+            Log.d(LOG_TAG, "Executing request: " + httpClient.getUrl().toString());
+            if (httpClient.getUrl().getHost() != null) {
+                httpClient.execute();
+            }
+        }
+        catch (Exception e) {
+            Log.e(LOG_TAG, e.toString());
+            error = String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage());
+        }
+        return null;
+    }
+
+    @Override
+    protected void onPostExecute(Void aVoid) {
+        super.onPostExecute(aVoid);
+        progressDialog.dismiss();
+        if (error != null && error.trim().length() > 0) {
+            Toast.makeText(context, error, Toast.LENGTH_LONG).show();
+        }
+    }
+    private final String LOG_TAG = WebCallAsyncTask.class.getName();    
+}

=== added file 'src/org/openlp/android/utility/WebCallReturningAsyncTask.java'
--- src/org/openlp/android/utility/WebCallReturningAsyncTask.java	1970-01-01 00:00:00 +0000
+++ src/org/openlp/android/utility/WebCallReturningAsyncTask.java	2012-01-07 20:53:27 +0000
@@ -0,0 +1,108 @@
+/******************************************************************************
+ * OpenLP - Open Source Lyrics Projection                                      *
+ * --------------------------------------------------------------------------- *
+ * Copyright (c) 2008-2012 Raoul Snyman                                        *
+ * Portions copyright (c) 2008-2012 Tim Bentley, Jonathan Corwin, Michael      *
+ * Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        *
+ * Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      *
+ * Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             *
+ * --------------------------------------------------------------------------- *
+ * This program 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; version 2 of the License.                              *
+ *                                                                             *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc., 59  *
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA                          *
+ *******************************************************************************/
+package org.openlp.android.utility;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.util.Log;
+import android.widget.Toast;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.openlp.android.activity.Preferences;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+public class WebCallReturningAsyncTask extends AsyncTask<String, Void, String> {
+    private Activity context;
+    private String apiPart;
+
+
+    public WebCallReturningAsyncTask(Activity context) {
+        this.context = context;
+    }
+
+    public WebCallReturningAsyncTask(Activity context, String apiPart) {
+        this.context = context;
+        this.apiPart = apiPart;
+    }
+
+
+    @Override
+    protected String doInBackground(String... apiCall) {
+        OpenLPHttpClient httpClient = new OpenLPHttpClient(context);
+        HttpResponse response = null;
+
+        try {
+            if (apiPart == null) {
+                httpClient.setUrl(apiCall[0]);
+            }
+            else {
+                httpClient.setUrl(String.format("%s%s", apiPart, apiCall[0]));
+            }
+
+            if (httpClient.getUrl().getHost().trim().length() <= 0) {
+                context.startActivity(new Intent(context, Preferences.class));
+            }
+            else {
+                response = httpClient.execute();
+            }
+
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                HttpEntity entity = response.getEntity();
+
+                if (entity != null) {
+                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
+                    StringBuilder stringBuilder = new StringBuilder();
+
+                    String line = bufferedReader.readLine();
+                    while (line != null) {
+                        stringBuilder.append(line);
+                        line = bufferedReader.readLine();
+                    }
+
+                    Log.i(LOG_TAG, String.format("entity: %s", stringBuilder.toString()));
+                    bufferedReader.close();
+                    return stringBuilder.toString();
+                }
+            }
+        }
+        catch (Exception e) {
+            Log.e(LOG_TAG, e.toString());
+            Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
+        }
+        return null;
+    }
+
+    @Override
+    protected void onPreExecute() {
+        super.onPreExecute();
+    }
+
+    @Override
+    protected void onPostExecute(String s) {
+        super.onPostExecute(s);
+    }
+    private final String LOG_TAG = this.getClass().getName();    
+}