Browse Source

Creating new preferences screens.

pull/11/head
Eric Kok 12 years ago
parent
commit
e01555ae5f
  1. 8
      external/ColorPickerPreference/.classpath
  2. 2
      external/ColorPickerPreference/.gitattributes
  3. 4
      external/ColorPickerPreference/.gitignore
  4. 33
      external/ColorPickerPreference/.project
  5. 18
      external/ColorPickerPreference/AndroidManifest.xml
  6. 26
      external/ColorPickerPreference/CHANGELOG.rst
  7. 15
      external/ColorPickerPreference/LICENSE
  8. 47
      external/ColorPickerPreference/README.rst
  9. 34
      external/ColorPickerPreference/proguard.cfg
  10. 12
      external/ColorPickerPreference/project.properties
  11. BIN
      external/ColorPickerPreference/res/drawable-hdpi/icon.png
  12. BIN
      external/ColorPickerPreference/res/drawable-ldpi/icon.png
  13. BIN
      external/ColorPickerPreference/res/drawable-mdpi/icon.png
  14. 77
      external/ColorPickerPreference/res/layout-land/dialog_color_picker.xml
  15. 78
      external/ColorPickerPreference/res/layout/dialog_color_picker.xml
  16. 5
      external/ColorPickerPreference/res/values/integer.xml
  17. 21
      external/ColorPickerPreference/res/values/strings.xml
  18. 32
      external/ColorPickerPreference/res/xml/settings.xml
  19. BIN
      external/ColorPickerPreference/screen_1.png
  20. BIN
      external/ColorPickerPreference/screen_2.png
  21. 128
      external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
  22. 142
      external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerDialog.java
  23. 171
      external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
  24. 287
      external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPreference.java
  25. 952
      external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerView.java
  26. 43
      external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/Test.java
  27. 2
      lite/.factorypath
  28. 2
      lite/.project
  29. 17
      lite/AndroidManifest.xml
  30. 1
      lite/project.properties
  31. BIN
      lite/res/drawable-hdpi/ic_priority_high.png
  32. BIN
      lite/res/drawable-hdpi/ic_priority_low.png
  33. BIN
      lite/res/drawable-hdpi/ic_priority_normal.png
  34. BIN
      lite/res/drawable-hdpi/ic_priority_off.png
  35. 89
      lite/res/layout/list_item_torrent.xml
  36. 7
      lite/res/values/attrs.xml
  37. 1
      lite/res/values/colors.xml
  38. 139
      lite/res/values/strings.xml
  39. 20
      lite/res/xml/pref_about.xml
  40. 52
      lite/res/xml/pref_main.xml
  41. 47
      lite/res/xml/pref_notifications.xml
  42. 21
      lite/res/xml/pref_rssfeed.xml
  43. 108
      lite/res/xml/pref_server.xml
  44. 16
      lite/res/xml/pref_websearch.xml
  45. 337
      lite/src/com/actionbarsherlock/view/SherlockListView.java
  46. 100
      lite/src/fr/marvinlabs/widget/CheckableRelativeLayout.java
  47. 70
      lite/src/fr/marvinlabs/widget/InertCheckBox.java
  48. 109
      lite/src/org/transdroid/lite/app/search/SearchHelper.java
  49. 64
      lite/src/org/transdroid/lite/app/search/SearchResult.java
  50. 40
      lite/src/org/transdroid/lite/app/search/SearchSite.java
  51. 30
      lite/src/org/transdroid/lite/app/settings/AboutSettings.java
  52. 140
      lite/src/org/transdroid/lite/app/settings/ApplicationSettings.java
  53. 97
      lite/src/org/transdroid/lite/app/settings/NotificationSettings.java
  54. 67
      lite/src/org/transdroid/lite/app/settings/RssfeedSetting.java
  55. 195
      lite/src/org/transdroid/lite/app/settings/ServerSetting.java
  56. 48
      lite/src/org/transdroid/lite/app/settings/WebsearchSetting.java
  57. 2
      lite/src/org/transdroid/lite/gui/DetailsFagment.java
  58. 26
      lite/src/org/transdroid/lite/gui/TorrentsActivity.java
  59. 2
      lite/src/org/transdroid/lite/gui/TorrentsFragment.java
  60. 110
      lite/src/org/transdroid/lite/gui/lists/TorrentProgressBar.java
  61. 14
      lite/src/org/transdroid/lite/gui/navigation/FilterAdapter.java
  62. 2
      lite/src/org/transdroid/lite/gui/navigation/FilterItemView.java
  63. 2
      lite/src/org/transdroid/lite/gui/navigation/FilterSeparatorView.java
  64. 20
      lite/src/org/transdroid/lite/gui/navigation/Label.java
  65. 75
      lite/src/org/transdroid/lite/gui/navigation/StatusType.java
  66. 164
      lite/src/org/transdroid/lite/gui/settings/MainSettingsActivity.java
  67. 31
      lite/src/org/transdroid/lite/gui/settings/OtherSettingsActivity.java
  68. 59
      lite/src/org/transdroid/lite/gui/settings/RssfeedPreference.java
  69. 46
      lite/src/org/transdroid/lite/gui/settings/RssfeedSettingsActivity.java
  70. 59
      lite/src/org/transdroid/lite/gui/settings/ServerPreference.java
  71. 94
      lite/src/org/transdroid/lite/gui/settings/ServerSettingsActivity.java
  72. 59
      lite/src/org/transdroid/lite/gui/settings/WebsearchPreference.java
  73. 45
      lite/src/org/transdroid/lite/gui/settings/WebsearchSettingsActivity.java

8
external/ColorPickerPreference/.classpath vendored

@ -0,0 +1,8 @@
<?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="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

2
external/ColorPickerPreference/.gitattributes vendored

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

4
external/ColorPickerPreference/.gitignore vendored

@ -0,0 +1,4 @@
/bin
/gen
.classpath
.project

33
external/ColorPickerPreference/.project vendored

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ColorPickerPreference</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>

18
external/ColorPickerPreference/AndroidManifest.xml vendored

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.margaritov.preference.colorpicker"
android:versionCode="0111"
android:versionName="1.11">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="net.margaritov.preference.colorpicker.Test"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="7" />
</manifest>

26
external/ColorPickerPreference/CHANGELOG.rst vendored

@ -0,0 +1,26 @@
================================
ColorPickerPreference Change Log
================================
2011-02-11 v1.11:
----------------
fix: color controls not visible in landscape orientation
fix: colorPickerDialog constructor was protected
2011-01-25 v1.1:
----------------
* new: Alpha Slider is disabled by default
* new: Alpha Slider can be enabled:
* with preference XML using attribute alphaSlider="true"
* with function setAlphaSliderEnabled(true)
* new: defaultValue in preference XML now accepts HEX color code:
* #FF00FF, rgb
* #FF00FF00, argb
2011-01-20 v1.01:
-----------------
fix: sometimes preview color disappear
2011-01-19 v1.0:
----------------
release

15
external/ColorPickerPreference/LICENSE vendored

@ -0,0 +1,15 @@
/*
* Copyright (C) 2011 Sergey Margaritov & Daniel Nilsson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

47
external/ColorPickerPreference/README.rst vendored

@ -0,0 +1,47 @@
=====================
ColorPickerPreference
=====================
Generally used classes by Daniel Nilsson.
ColorPickerPreference class by Sergey Margaritov.
Packed by Sergey Margaritov.
Features
========
* Color Area
* Hue Slider
* Alpha Slider (disabled by default)
* Old & New Color
* Color Preview in Preferences List
Requirements
============
Tested with APIv7, but maybe will work with early versions
Usage
=====
You can see some tests inside
::
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color1"
android:title="@string/color1_title"
android:summary="@string/color1_summary"
android:defaultValue="@color/pumpkin_orange" <!-- integer resources are also accepted -->
alphaSlider="true" <!-- enable alpha slider via XML -->
/>
To enable Alpha Slider in your code use function:
::
setAlphaSliderEnabled(boolean enable)
Screens
=======
* .. image:: https://github.com/attenzione/android-ColorPickerPreference/raw/master/screen_1.png
* .. image:: https://github.com/attenzione/android-ColorPickerPreference/raw/master/screen_2.png

34
external/ColorPickerPreference/proguard.cfg vendored

@ -0,0 +1,34 @@
-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 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 *;
}

12
external/ColorPickerPreference/project.properties vendored

@ -0,0 +1,12 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
android.library=true
# Project target.
target=android-16

BIN
external/ColorPickerPreference/res/drawable-hdpi/icon.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
external/ColorPickerPreference/res/drawable-ldpi/icon.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
external/ColorPickerPreference/res/drawable-mdpi/icon.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

77
external/ColorPickerPreference/res/layout-land/dialog_color_picker.xml vendored

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Daniel Nilsson
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:orientation="horizontal">
<net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="landscape"
android:layerType="software"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/press_color_to_apply"
android:gravity="center"
android:layout_marginTop="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="↓"
android:textSize="20sp"
android:gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5"
/>
</LinearLayout>
</LinearLayout>

78
external/ColorPickerPreference/res/layout/dialog_color_picker.xml vendored

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Daniel Nilsson
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:orientation="vertical">
<net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:tag="portrait"
android:layerType="software"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/press_color_to_apply"
android:gravity="left"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:orientation="horizontal"
android:layout_below="@id/color_picker_view"
android:layout_marginBottom="10dp">
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_weight="0.5"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="→"
android:textSize="20sp"
android:gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.5"
/>
</LinearLayout>
</LinearLayout>

5
external/ColorPickerPreference/res/values/integer.xml vendored

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<integer name="COLOR_BLACK">0xff000000</integer>
<integer name="COLOR_GREEN">0xff00ff00</integer>
</resources>

21
external/ColorPickerPreference/res/values/strings.xml vendored

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- App -->
<string name="hello">Hello World, Main!</string>
<string name="app_name">ColorPickerPreference</string>
<!-- Color Picker -->
<string name="dialog_color_picker">Color Picker</string>
<string name="press_color_to_apply">Press on Color to apply</string>
<!-- Preferences -->
<string name="pref_category">Category</string>
<string name="color1_title">Color 1</string>
<string name="color1_summary">black color by default, set by reference</string>
<string name="color2_title">Color 2</string>
<string name="color2_summary">not persistent color\nalpha slider added via code</string>
<string name="color3_title">Color 3</string>
<string name="color3_summary">picker with alpha slider</string>
<string name="color4_title">Color 4</string>
<string name="color4_summary">color set with HEX code in xml</string>
</resources>

32
external/ColorPickerPreference/res/xml/settings.xml vendored

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/pref_category">
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color1"
android:title="@string/color1_title"
android:summary="@string/color1_summary"
android:defaultValue="@integer/COLOR_BLACK"
/>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color2"
android:persistent="false"
android:title="@string/color2_title"
android:summary="@string/color2_summary"
android:defaultValue="@integer/COLOR_GREEN"
/>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color3"
android:title="@string/color3_title"
android:summary="@string/color3_summary"
android:defaultValue="@integer/COLOR_GREEN"
alphaSlider="true"
/>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color4"
android:persistent="false"
android:title="@string/color4_title"
android:summary="@string/color4_summary"
android:defaultValue="#0000FF"
/>
</PreferenceCategory>
</PreferenceScreen>

BIN
external/ColorPickerPreference/screen_1.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

BIN
external/ColorPickerPreference/screen_2.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

128
external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java vendored

@ -0,0 +1,128 @@
/*
* Copyright (C) 2010 Daniel Nilsson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.margaritov.preference.colorpicker;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
/**
* This drawable that draws a simple white and gray chessboard pattern.
* It's pattern you will often see as a background behind a
* partly transparent image in many applications.
* @author Daniel Nilsson
*/
public class AlphaPatternDrawable extends Drawable {
private int mRectangleSize = 10;
private Paint mPaint = new Paint();
private Paint mPaintWhite = new Paint();
private Paint mPaintGray = new Paint();
private int numRectanglesHorizontal;
private int numRectanglesVertical;
/**
* Bitmap in which the pattern will be cahched.
*/
private Bitmap mBitmap;
public AlphaPatternDrawable(int rectangleSize) {
mRectangleSize = rectangleSize;
mPaintWhite.setColor(0xffffffff);
mPaintGray.setColor(0xffcbcbcb);
}
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
}
@Override
public int getOpacity() {
return 0;
}
@Override
public void setAlpha(int alpha) {
throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
}
@Override
public void setColorFilter(ColorFilter cf) {
throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
int height = bounds.height();
int width = bounds.width();
numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
generatePatternBitmap();
}
/**
* This will generate a bitmap with the pattern
* as big as the rectangle we were allow to draw on.
* We do this to chache the bitmap so we don't need to
* recreate it each time draw() is called since it
* takes a few milliseconds.
*/
private void generatePatternBitmap(){
if(getBounds().width() <= 0 || getBounds().height() <= 0){
return;
}
mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmap);
Rect r = new Rect();
boolean verticalStartWhite = true;
for (int i = 0; i <= numRectanglesVertical; i++) {
boolean isWhite = verticalStartWhite;
for (int j = 0; j <= numRectanglesHorizontal; j++) {
r.top = i * mRectangleSize;
r.left = j * mRectangleSize;
r.bottom = r.top + mRectangleSize;
r.right = r.left + mRectangleSize;
canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
isWhite = !isWhite;
}
verticalStartWhite = !verticalStartWhite;
}
}
}

142
external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerDialog.java vendored

@ -0,0 +1,142 @@
/*
* Copyright (C) 2010 Daniel Nilsson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.margaritov.preference.colorpicker;
import android.app.Dialog;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
public class ColorPickerDialog
extends
Dialog
implements
ColorPickerView.OnColorChangedListener,
View.OnClickListener {
private ColorPickerView mColorPicker;
private ColorPickerPanelView mOldColor;
private ColorPickerPanelView mNewColor;
private OnColorChangedListener mListener;
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerDialog(Context context, int initialColor) {
super(context);
init(initialColor);
}
private void init(int color) {
// To fight color banding.
getWindow().setFormat(PixelFormat.RGBA_8888);
setUp(color);
}
private void setUp(int color) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.dialog_color_picker, null);
setContentView(layout);
setTitle(R.string.dialog_color_picker);
mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
((LinearLayout) mOldColor.getParent()).setPadding(
Math.round(mColorPicker.getDrawingOffset()),
0,
Math.round(mColorPicker.getDrawingOffset()),
0
);
mOldColor.setOnClickListener(this);
mNewColor.setOnClickListener(this);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
@Override
public void onColorChanged(int color) {
mNewColor.setColor(color);
/*
if (mListener != null) {
mListener.onColorChanged(color);
}
*/
}
public void setAlphaSliderVisible(boolean visible) {
mColorPicker.setAlphaSliderVisible(visible);
}
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener){
mListener = listener;
}
public int getColor() {
return mColorPicker.getColor();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.new_color_panel) {
if (mListener != null) {
mListener.onColorChanged(mNewColor.getColor());
}
}
dismiss();
}
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
state.putInt("old_color", mOldColor.getColor());
state.putInt("new_color", mNewColor.getColor());
return state;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mOldColor.setColor(savedInstanceState.getInt("old_color"));
mColorPicker.setColor(savedInstanceState.getInt("new_color"), true);
}
}

171
external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java vendored

@ -0,0 +1,171 @@
/*
* Copyright (C) 2010 Daniel Nilsson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.margaritov.preference.colorpicker;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* This class draws a panel which which will be filled with a color which can be set.
* It can be used to show the currently selected color which you will get from
* the {@link ColorPickerView}.
* @author Daniel Nilsson
*
*/
public class ColorPickerPanelView extends View {
/**
* The width in pixels of the border
* surrounding the color panel.
*/
private final static float BORDER_WIDTH_PX = 1;
private float mDensity = 1f;
private int mBorderColor = 0xff6E6E6E;
private int mColor = 0xff000000;
private Paint mBorderPaint;
private Paint mColorPaint;
private RectF mDrawingRect;
private RectF mColorRect;
private AlphaPatternDrawable mAlphaPattern;
public ColorPickerPanelView(Context context){
this(context, null);
}
public ColorPickerPanelView(Context context, AttributeSet attrs){
this(context, attrs, 0);
}
public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
mBorderPaint = new Paint();
mColorPaint = new Paint();
mDensity = getContext().getResources().getDisplayMetrics().density;
}
@Override
protected void onDraw(Canvas canvas) {
final RectF rect = mColorRect;
if(BORDER_WIDTH_PX > 0){
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(mDrawingRect, mBorderPaint);
}
if(mAlphaPattern != null){
mAlphaPattern.draw(canvas);
}
mColorPaint.setColor(mColor);
canvas.drawRect(rect, mColorPaint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mDrawingRect = new RectF();
mDrawingRect.left = getPaddingLeft();
mDrawingRect.right = w - getPaddingRight();
mDrawingRect.top = getPaddingTop();
mDrawingRect.bottom = h - getPaddingBottom();
setUpColorRect();
}
private void setUpColorRect(){
final RectF dRect = mDrawingRect;
float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
mColorRect = new RectF(left,top, right, bottom);
mAlphaPattern = new AlphaPatternDrawable((int)(5 * mDensity));
mAlphaPattern.setBounds(
Math.round(mColorRect.left),
Math.round(mColorRect.top),
Math.round(mColorRect.right),
Math.round(mColorRect.bottom)
);
}
/**
* Set the color that should be shown by this view.
* @param color
*/
public void setColor(int color){
mColor = color;
invalidate();
}
/**
* Get the color currently show by this view.
* @return
*/
public int getColor(){
return mColor;
}
/**
* Set the color of the border surrounding the panel.
* @param color
*/
public void setBorderColor(int color){
mBorderColor = color;
invalidate();
}
/**
* Get the color of the border surrounding the panel.
*/
public int getBorderColor(){
return mBorderColor;
}
}

287
external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPreference.java vendored

@ -0,0 +1,287 @@
/*
* Copyright (C) 2011 Sergey Margaritov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.margaritov.preference.colorpicker;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
* A preference type that allows a user to choose a time
* @author Sergey Margaritov
*/
public class ColorPickerPreference
extends
Preference
implements
Preference.OnPreferenceClickListener,
ColorPickerDialog.OnColorChangedListener {
View mView;
ColorPickerDialog mDialog;
private int mValue = Color.BLACK;
private float mDensity = 0;
private boolean mAlphaSliderEnabled = false;
public ColorPickerPreference(Context context) {
super(context);
init(context, null);
}
public ColorPickerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getColor(index, Color.BLACK);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
onColorChanged(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue);
}
private void init(Context context, AttributeSet attrs) {
mDensity = getContext().getResources().getDisplayMetrics().density;
setOnPreferenceClickListener(this);
if (attrs != null) {
mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false);
}
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
mView = view;
setPreviewColor();
}
private void setPreviewColor() {
if (mView == null) return;
ImageView iView = new ImageView(getContext());
LinearLayout widgetFrameView = ((LinearLayout)mView.findViewById(android.R.id.widget_frame));
if (widgetFrameView == null) return;
widgetFrameView.setVisibility(View.VISIBLE);
widgetFrameView.setPadding(
widgetFrameView.getPaddingLeft(),
widgetFrameView.getPaddingTop(),
(int)(mDensity * 8),
widgetFrameView.getPaddingBottom()
);
// remove already create preview image
int count = widgetFrameView.getChildCount();
if (count > 0) {
widgetFrameView.removeViews(0, count);
}
widgetFrameView.addView(iView);
widgetFrameView.setMinimumWidth(0);
iView.setBackgroundDrawable(new AlphaPatternDrawable((int)(5 * mDensity)));
iView.setImageBitmap(getPreviewBitmap());
}
private Bitmap getPreviewBitmap() {
int d = (int) (mDensity * 31); //30dip
int color = mValue;
Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
int w = bm.getWidth();
int h = bm.getHeight();
int c = color;
for (int i = 0; i < w; i++) {
for (int j = i; j < h; j++) {
c = (i <= 1 || j <= 1 || i >= w-2 || j >= h-2) ? Color.GRAY : color;
bm.setPixel(i, j, c);
if (i != j) {
bm.setPixel(j, i, c);
}
}
}
return bm;
}
@Override
public void onColorChanged(int color) {
if (isPersistent()) {
persistInt(color);
}
mValue = color;
setPreviewColor();
try {
getOnPreferenceChangeListener().onPreferenceChange(this, color);
} catch (NullPointerException e) {
}
}
public boolean onPreferenceClick(Preference preference) {
showDialog(null);
return false;
}
protected void showDialog(Bundle state) {
mDialog = new ColorPickerDialog(getContext(), mValue);
mDialog.setOnColorChangedListener(this);
if (mAlphaSliderEnabled) {
mDialog.setAlphaSliderVisible(true);
}
if (state != null) {
mDialog.onRestoreInstanceState(state);
}
mDialog.show();
}
/**
* Toggle Alpha Slider visibility (by default it's disabled)
* @param enable
*/
public void setAlphaSliderEnabled(boolean enable) {
mAlphaSliderEnabled = enable;
}
/**
* For custom purposes. Not used by ColorPickerPreferrence
* @param color
* @author Unknown
*/
public static String convertToARGB(int color) {
String alpha = Integer.toHexString(Color.alpha(color));
String red = Integer.toHexString(Color.red(color));
String green = Integer.toHexString(Color.green(color));
String blue = Integer.toHexString(Color.blue(color));
if (alpha.length() == 1) {
alpha = "0" + alpha;
}
if (red.length() == 1) {
red = "0" + red;
}
if (green.length() == 1) {
green = "0" + green;
}
if (blue.length() == 1) {
blue = "0" + blue;
}
return "#" + alpha + red + green + blue;
}
/**
* For custom purposes. Not used by ColorPickerPreferrence
* @param argb
* @throws NumberFormatException
* @author Unknown
*/
public static int convertToColorInt(String argb) throws NumberFormatException {
if (argb.startsWith("#")) {
argb = argb.replace("#", "");
}
int alpha = -1, red = -1, green = -1, blue = -1;
if (argb.length() == 8) {
alpha = Integer.parseInt(argb.substring(0, 2), 16);
red = Integer.parseInt(argb.substring(2, 4), 16);
green = Integer.parseInt(argb.substring(4, 6), 16);
blue = Integer.parseInt(argb.substring(6, 8), 16);
}
else if (argb.length() == 6) {
alpha = 255;
red = Integer.parseInt(argb.substring(0, 2), 16);
green = Integer.parseInt(argb.substring(2, 4), 16);
blue = Integer.parseInt(argb.substring(4, 6), 16);
}
return Color.argb(alpha, red, green, blue);
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (mDialog == null || !mDialog.isShowing()) {
return superState;
}
final SavedState myState = new SavedState(superState);
myState.dialogBundle = mDialog.onSaveInstanceState();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !(state instanceof SavedState)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
showDialog(myState.dialogBundle);
}
private static class SavedState extends BaseSavedState {
Bundle dialogBundle;
public SavedState(Parcel source) {
super(source);
dialogBundle = source.readBundle();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeBundle(dialogBundle);
}
public SavedState(Parcelable superState) {
super(superState);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

952
external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerView.java vendored

@ -0,0 +1,952 @@
/*
* Copyright (C) 2010 Daniel Nilsson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.margaritov.preference.colorpicker;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposeShader;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/**
* Displays a color picker to the user and allow them
* to select a color. A slider for the alpha channel is
* also available. Enable it by setting
* setAlphaSliderVisible(boolean) to true.
* @author Daniel Nilsson
*/
public class ColorPickerView extends View {
private final static int PANEL_SAT_VAL = 0;
private final static int PANEL_HUE = 1;
private final static int PANEL_ALPHA = 2;
/**
* The width in pixels of the border
* surrounding all color panels.
*/
private final static float BORDER_WIDTH_PX = 1;
/**
* The width in dp of the hue panel.
*/
private float HUE_PANEL_WIDTH = 30f;
/**
* The height in dp of the alpha panel
*/
private float ALPHA_PANEL_HEIGHT = 20f;
/**
* The distance in dp between the different
* color panels.
*/
private float PANEL_SPACING = 10f;
/**
* The radius in dp of the color palette tracker circle.
*/
private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
/**
* The dp which the tracker of the hue or alpha panel
* will extend outside of its bounds.
*/
private float RECTANGLE_TRACKER_OFFSET = 2f;
private float mDensity = 1f;
private OnColorChangedListener mListener;
private Paint mSatValPaint;
private Paint mSatValTrackerPaint;
private Paint mHuePaint;
private Paint mHueTrackerPaint;
private Paint mAlphaPaint;
private Paint mAlphaTextPaint;
private Paint mBorderPaint;
private Shader mValShader;
private Shader mSatShader;
private Shader mHueShader;
private Shader mAlphaShader;
private int mAlpha = 0xff;
private float mHue = 360f;
private float mSat = 0f;
private float mVal = 0f;
private String mAlphaSliderText = "";
private int mSliderTrackerColor = 0xff1c1c1c;
private int mBorderColor = 0xff6E6E6E;
private boolean mShowAlphaPanel = false;
/*
* To remember which panel that has the "focus" when
* processing hardware button data.
*/
private int mLastTouchedPanel = PANEL_SAT_VAL;
/**
* Offset from the edge we must have or else
* the finger tracker will get clipped when
* it is drawn outside of the view.
*/
private float mDrawingOffset;
/*
* Distance form the edges of the view
* of where we are allowed to draw.
*/
private RectF mDrawingRect;
private RectF mSatValRect;
private RectF mHueRect;
private RectF mAlphaRect;
private AlphaPatternDrawable mAlphaPattern;
private Point mStartTouchPoint = null;
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerView(Context context){
this(context, null);
}
public ColorPickerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
mDensity = getContext().getResources().getDisplayMetrics().density;
PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
RECTANGLE_TRACKER_OFFSET *= mDensity;
HUE_PANEL_WIDTH *= mDensity;
ALPHA_PANEL_HEIGHT *= mDensity;
PANEL_SPACING = PANEL_SPACING * mDensity;
mDrawingOffset = calculateRequiredOffset();
initPaintTools();
//Needed for receiving trackball motion events.
setFocusable(true);
setFocusableInTouchMode(true);
}
private void initPaintTools(){
mSatValPaint = new Paint();
mSatValTrackerPaint = new Paint();
mHuePaint = new Paint();
mHueTrackerPaint = new Paint();
mAlphaPaint = new Paint();
mAlphaTextPaint = new Paint();
mBorderPaint = new Paint();
mSatValTrackerPaint.setStyle(Style.STROKE);
mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
mSatValTrackerPaint.setAntiAlias(true);
mHueTrackerPaint.setColor(mSliderTrackerColor);
mHueTrackerPaint.setStyle(Style.STROKE);
mHueTrackerPaint.setStrokeWidth(2f * mDensity);
mHueTrackerPaint.setAntiAlias(true);
mAlphaTextPaint.setColor(0xff1c1c1c);
mAlphaTextPaint.setTextSize(14f * mDensity);
mAlphaTextPaint.setAntiAlias(true);
mAlphaTextPaint.setTextAlign(Align.CENTER);
mAlphaTextPaint.setFakeBoldText(true);
}
private float calculateRequiredOffset(){
float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
return offset * 1.5f;
}
private int[] buildHueColorArray(){
int[] hue = new int[361];
int count = 0;
for(int i = hue.length -1; i >= 0; i--, count++){
hue[count] = Color.HSVToColor(new float[]{i, 1f, 1f});
}
return hue;
}
@Override
protected void onDraw(Canvas canvas) {
if(mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) return;
drawSatValPanel(canvas);
drawHuePanel(canvas);
drawAlphaPanel(canvas);
}
private void drawSatValPanel(Canvas canvas){
final RectF rect = mSatValRect;
if(BORDER_WIDTH_PX > 0){
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
}
if (mValShader == null) {
mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
0xffffffff, 0xff000000, TileMode.CLAMP);
}
int rgb = Color.HSVToColor(new float[]{mHue,1f,1f});
mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
0xffffffff, rgb, TileMode.CLAMP);
ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);
mSatValPaint.setShader(mShader);
canvas.drawRect(rect, mSatValPaint);
Point p = satValToPoint(mSat, mVal);
mSatValTrackerPaint.setColor(0xff000000);
canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);
mSatValTrackerPaint.setColor(0xffdddddd);
canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
}
private void drawHuePanel(Canvas canvas){
final RectF rect = mHueRect;
if(BORDER_WIDTH_PX > 0){
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(rect.left - BORDER_WIDTH_PX,
rect.top - BORDER_WIDTH_PX,
rect.right + BORDER_WIDTH_PX,
rect.bottom + BORDER_WIDTH_PX,
mBorderPaint);
}
if (mHueShader == null) {
mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);
mHuePaint.setShader(mHueShader);
}
canvas.drawRect(rect, mHuePaint);
float rectHeight = 4 * mDensity / 2;
Point p = hueToPoint(mHue);
RectF r = new RectF();
r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
r.top = p.y - rectHeight;
r.bottom = p.y + rectHeight;
canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
}
private void drawAlphaPanel(Canvas canvas){
if(!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) return;
final RectF rect = mAlphaRect;
if(BORDER_WIDTH_PX > 0){
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(rect.left - BORDER_WIDTH_PX,
rect.top - BORDER_WIDTH_PX,
rect.right + BORDER_WIDTH_PX,
rect.bottom + BORDER_WIDTH_PX,
mBorderPaint);
}
mAlphaPattern.draw(canvas);
float[] hsv = new float[]{mHue,mSat,mVal};
int color = Color.HSVToColor(hsv);
int acolor = Color.HSVToColor(0, hsv);
mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
color, acolor, TileMode.CLAMP);
mAlphaPaint.setShader(mAlphaShader);
canvas.drawRect(rect, mAlphaPaint);
if(mAlphaSliderText != null && mAlphaSliderText!= ""){
canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint);
}
float rectWidth = 4 * mDensity / 2;
Point p = alphaToPoint(mAlpha);
RectF r = new RectF();
r.left = p.x - rectWidth;
r.right = p.x + rectWidth;
r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
}
private Point hueToPoint(float hue){
final RectF rect = mHueRect;
final float height = rect.height();
Point p = new Point();
p.y = (int) (height - (hue * height / 360f) + rect.top);
p.x = (int) rect.left;
return p;
}
private Point satValToPoint(float sat, float val){
final RectF rect = mSatValRect;
final float height = rect.height();
final float width = rect.width();
Point p = new Point();
p.x = (int) (sat * width + rect.left);
p.y = (int) ((1f - val) * height + rect.top);
return p;
}
private Point alphaToPoint(int alpha){
final RectF rect = mAlphaRect;
final float width = rect.width();
Point p = new Point();
p.x = (int) (width - (alpha * width / 0xff) + rect.left);
p.y = (int) rect.top;
return p;
}
private float[] pointToSatVal(float x, float y){
final RectF rect = mSatValRect;
float[] result = new float[2];
float width = rect.width();
float height = rect.height();
if (x < rect.left){
x = 0f;
}
else if(x > rect.right){
x = width;
}
else{
x = x - rect.left;
}
if (y < rect.top){
y = 0f;
}
else if(y > rect.bottom){
y = height;
}
else{
y = y - rect.top;
}
result[0] = 1.f / width * x;
result[1] = 1.f - (1.f / height * y);
return result;
}
private float pointToHue(float y){
final RectF rect = mHueRect;
float height = rect.height();
if (y < rect.top){
y = 0f;
}
else if(y > rect.bottom){
y = height;
}
else{
y = y - rect.top;
}
return 360f - (y * 360f / height);
}
private int pointToAlpha(int x){
final RectF rect = mAlphaRect;
final int width = (int) rect.width();
if(x < rect.left){
x = 0;
}
else if(x > rect.right){
x = width;
}
else{
x = x - (int)rect.left;
}
return 0xff - (x * 0xff / width);
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
boolean update = false;
if(event.getAction() == MotionEvent.ACTION_MOVE){
switch(mLastTouchedPanel){
case PANEL_SAT_VAL:
float sat, val;
sat = mSat + x/50f;
val = mVal - y/50f;
if(sat < 0f){
sat = 0f;
}
else if(sat > 1f){
sat = 1f;
}
if(val < 0f){
val = 0f;
}
else if(val > 1f){
val = 1f;
}
mSat = sat;
mVal = val;
update = true;
break;
case PANEL_HUE:
float hue = mHue - y * 10f;
if(hue < 0f){
hue = 0f;
}
else if(hue > 360f){
hue = 360f;
}
mHue = hue;
update = true;
break;
case PANEL_ALPHA:
if(!mShowAlphaPanel || mAlphaRect == null){
update = false;
}
else{
int alpha = (int) (mAlpha - x*10);
if(alpha < 0){
alpha = 0;
}
else if(alpha > 0xff){
alpha = 0xff;
}
mAlpha = alpha;
update = true;
}
break;
}
}
if(update){
if(mListener != null){
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
}
invalidate();
return true;
}
return super.onTrackballEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean update = false;
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
mStartTouchPoint = new Point((int)event.getX(), (int)event.getY());
update = moveTrackersIfNeeded(event);
break;
case MotionEvent.ACTION_MOVE:
update = moveTrackersIfNeeded(event);
break;
case MotionEvent.ACTION_UP:
mStartTouchPoint = null;
update = moveTrackersIfNeeded(event);
break;
}
if(update){
if(mListener != null){
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
}
invalidate();
return true;
}
return super.onTouchEvent(event);
}
private boolean moveTrackersIfNeeded(MotionEvent event){
if(mStartTouchPoint == null) return false;
boolean update = false;
int startX = mStartTouchPoint.x;
int startY = mStartTouchPoint.y;
if(mHueRect.contains(startX, startY)){
mLastTouchedPanel = PANEL_HUE;
mHue = pointToHue(event.getY());
update = true;
}
else if(mSatValRect.contains(startX, startY)){
mLastTouchedPanel = PANEL_SAT_VAL;
float[] result = pointToSatVal(event.getX(), event.getY());
mSat = result[0];
mVal = result[1];
update = true;
}
else if(mAlphaRect != null && mAlphaRect.contains(startX, startY)){
mLastTouchedPanel = PANEL_ALPHA;
mAlpha = pointToAlpha((int)event.getX());
update = true;
}
return update;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = 0;
int height = 0;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
widthAllowed = chooseWidth(widthMode, widthAllowed);
heightAllowed = chooseHeight(heightMode, heightAllowed);
if(!mShowAlphaPanel){
height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
//If calculated height (based on the width) is more than the allowed height.
if(height > heightAllowed || getTag().equals("landscape")) {
height = heightAllowed;
width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
}
else{
width = widthAllowed;
}
}
else{
width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
if(width > widthAllowed){
width = widthAllowed;
height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
}
else{
height = heightAllowed;
}
}
setMeasuredDimension(width, height);
}
private int chooseWidth(int mode, int size){
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else { // (mode == MeasureSpec.UNSPECIFIED)
return getPrefferedWidth();
}
}
private int chooseHeight(int mode, int size){
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else { // (mode == MeasureSpec.UNSPECIFIED)
return getPrefferedHeight();
}
}
private int getPrefferedWidth(){
int width = getPrefferedHeight();
if(mShowAlphaPanel){
width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
}
return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
}
private int getPrefferedHeight(){
int height = (int)(200 * mDensity);
if(mShowAlphaPanel){
height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
}
return height;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mDrawingRect = new RectF();
mDrawingRect.left = mDrawingOffset + getPaddingLeft();
mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
mDrawingRect.top = mDrawingOffset + getPaddingTop();
mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
setUpSatValRect();
setUpHueRect();
setUpAlphaRect();
}
private void setUpSatValRect(){
final RectF dRect = mDrawingRect;
float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
if(mShowAlphaPanel){
panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
}
float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = top + panelSide;
float right = left + panelSide;
mSatValRect = new RectF(left,top, right, bottom);
}
private void setUpHueRect(){
final RectF dRect = mDrawingRect;
float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
float right = dRect.right - BORDER_WIDTH_PX;
mHueRect = new RectF(left, top, right, bottom);
}
private void setUpAlphaRect() {
if(!mShowAlphaPanel) return;
final RectF dRect = mDrawingRect;
float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
mAlphaRect = new RectF(left, top, right, bottom);
mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
mAlphaPattern.setBounds(
Math.round(mAlphaRect.left),
Math.round(mAlphaRect.top),
Math.round(mAlphaRect.right),
Math.round(mAlphaRect.bottom)
);
}
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener){
mListener = listener;
}
/**
* Set the color of the border surrounding all panels.
* @param color
*/
public void setBorderColor(int color){
mBorderColor = color;
invalidate();
}
/**
* Get the color of the border surrounding all panels.
*/
public int getBorderColor(){
return mBorderColor;
}
/**
* Get the current color this view is showing.
* @return the current color.
*/
public int getColor(){
return Color.HSVToColor(mAlpha, new float[]{mHue,mSat,mVal});
}
/**
* Set the color the view should show.
* @param color The color that should be selected.
*/
public void setColor(int color){
setColor(color, false);
}
/**
* Set the color this view should show.
* @param color The color that should be selected.
* @param callback If you want to get a callback to
* your OnColorChangedListener.
*/
public void setColor(int color, boolean callback){
int alpha = Color.alpha(color);
int red = Color.red(color);
int blue = Color.blue(color);
int green = Color.green(color);
float[] hsv = new float[3];
Color.RGBToHSV(red, green, blue, hsv);
mAlpha = alpha;
mHue = hsv[0];
mSat = hsv[1];
mVal = hsv[2];
if(callback && mListener != null){
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
}
invalidate();
}
/**
* Get the drawing offset of the color picker view.
* The drawing offset is the distance from the side of
* a panel to the side of the view minus the padding.
* Useful if you want to have your own panel below showing
* the currently selected color and want to align it perfectly.
* @return The offset in pixels.
*/
public float getDrawingOffset(){
return mDrawingOffset;
}
/**
* Set if the user is allowed to adjust the alpha panel. Default is false.
* If it is set to false no alpha will be set.
* @param visible
*/
public void setAlphaSliderVisible(boolean visible){
if(mShowAlphaPanel != visible){
mShowAlphaPanel = visible;
/*
* Reset all shader to force a recreation.
* Otherwise they will not look right after
* the size of the view has changed.
*/
mValShader = null;
mSatShader = null;
mHueShader = null;
mAlphaShader = null;;
requestLayout();
}
}
public void setSliderTrackerColor(int color){
mSliderTrackerColor = color;
mHueTrackerPaint.setColor(mSliderTrackerColor);
invalidate();
}
public int getSliderTrackerColor(){
return mSliderTrackerColor;
}
/**
* Set the text that should be shown in the
* alpha slider. Set to null to disable text.
* @param res string resource id.
*/
public void setAlphaSliderText(int res){
String text = getContext().getString(res);
setAlphaSliderText(text);
}
/**
* Set the text that should be shown in the
* alpha slider. Set to null to disable text.
* @param text Text that should be shown.
*/
public void setAlphaSliderText(String text){
mAlphaSliderText = text;
invalidate();
}
/**
* Get the current value of the text
* that will be shown in the alpha
* slider.
* @return
*/
public String getAlphaSliderText(){
return mAlphaSliderText;
}
}

43
external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/Test.java vendored

@ -0,0 +1,43 @@
/*
* Copyright (C) 2011 Sergey Margaritov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.margaritov.preference.colorpicker;
import net.margaritov.preference.colorpicker.R;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceActivity;
public class Test extends PreferenceActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
((ColorPickerPreference)findPreference("color2")).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
preference.setSummary(ColorPickerPreference.convertToARGB(Integer.valueOf(String.valueOf(newValue))));
return true;
}
});
((ColorPickerPreference)findPreference("color2")).setAlphaSliderEnabled(true);
}
}

2
lite/.factorypath

@ -1,3 +1,3 @@
<factorypath> <factorypath>
<factorypathentry kind="WKSPJAR" id="/TransdroidLite/compile-libs/androidannotations-3.0-SNAPSHOT.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="WKSPJAR" id="/Transdroid Core/compile-libs/androidannotations-3.0-SNAPSHOT.jar" enabled="true" runInBatchMode="false"/>
</factorypath> </factorypath>

2
lite/.project

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>TransdroidLite</name> <name>Transdroid Core</name>
<comment></comment> <comment></comment>
<projects> <projects>
</projects> </projects>

17
lite/AndroidManifest.xml

@ -1,13 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.transdroid.lite" package="org.transdroid.core"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0" > android:versionName="2.0-alpha1" >
<uses-sdk <uses-sdk
android:minSdkVersion="7" android:minSdkVersion="7"
android:targetSdkVersion="17" /> android:targetSdkVersion="17" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
@ -20,9 +27,15 @@
android:uiOptions="splitActionBarWhenNarrow" > android:uiOptions="splitActionBarWhenNarrow" >
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="org.transdroid.lite.gui.settings.MainSettingsActivity_" />
<activity android:name="org.transdroid.lite.gui.settings.ServerSettingsActivity_" />
<activity android:name="org.transdroid.lite.gui.settings.WebsearchSettingsActivity_" />
<activity android:name="org.transdroid.lite.gui.settings.RssfeedSettingsActivity_" />
<activity android:name="org.transdroid.lite.gui.settings.OtherSettingsActivity_" />
</application> </application>
</manifest> </manifest>

1
lite/project.properties

@ -13,3 +13,4 @@
# Project target. # Project target.
target=android-16 target=android-16
android.library.reference.1=../external/JakeWharton-ActionBarSherlock/library android.library.reference.1=../external/JakeWharton-ActionBarSherlock/library
android.library.reference.2=../external/ColorPickerPreference

BIN
lite/res/drawable-hdpi/ic_priority_high.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
lite/res/drawable-hdpi/ic_priority_low.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

BIN
lite/res/drawable-hdpi/ic_priority_normal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
lite/res/drawable-hdpi/ic_priority_off.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

89
lite/res/layout/list_item_torrent.xml

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<fr.marvinlabs.widget.CheckableRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="@dimen/margin_half"
android:layout_marginBottom="@dimen/margin_half"
android:layout_marginLeft="@dimen/margin_half"
android:layout_marginRight="@dimen/margin_default">
<ImageView
android:id="@+id/priority_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_half"
android:layout_marginTop="@dimen/margin_half"
android:src="@drawable/ic_priority_normal" />
<fr.marvinlabs.widget.InertCheckBox
android:id="@+id/torrent_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/priority_image" />
<TextView
android:id="@+id/name_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/torrent_checkbox"
android:textColor="#fff"
android:textSize="15sp"
android:text="CSI.Miami.Title-That_is_long.S13E16.HDTV.x264-LOL.mp4"
android:textIsSelectable="true" />
<TextView
android:id="@+id/ratio_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/name_text"
android:layout_alignParentRight="true"
android:layout_marginLeft="@dimen/margin_half"
android:layout_marginTop="4dip"
android:text="UNKNOWN ETA"
android:textSize="12sp"
android:textIsSelectable="false" />
<TextView
android:id="@+id/progress_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/ratio_text"
android:layout_toLeftOf="@id/ratio_text"
android:layout_toRightOf="@id/torrent_checkbox"
android:text="325.6MB OF 388.8MB (0%)"
android:textSize="12sp"
android:textIsSelectable="false" />
<org.transdroid.lite.gui.TorrentProgressBar
android:id="@+id/torrent_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ratio_text"
android:layout_marginTop="@dimen/margin_half"
android:layout_marginBottom="@dimen/margin_half" />
<TextView
android:id="@+id/speed_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/torrent_progressbar"
android:layout_alignParentRight="true"
android:layout_marginLeft="@dimen/margin_half"
android:text="↓400.8KB/s ↑1.4MB/s"
android:textSize="12sp"
android:textIsSelectable="false" />
<TextView
android:id="@+id/peers_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/speed_text"
android:layout_toLeftOf="@id/speed_text"
android:layout_toRightOf="@id/torrent_checkbox"
android:text="246 (288) LEECHERS"
android:textSize="12sp"
android:textIsSelectable="false" />
</fr.marvinlabs.widget.CheckableRelativeLayout>

7
lite/res/values/attrs.xml

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TorrentProgressBar">
<attr name="progress" format="integer" />
<attr name="isActive" format="boolean" />
</declare-styleable>
</resources>

1
lite/res/values/colors.xml

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="green">#8acc12</color> <color name="green">#8acc12</color>
<color name="ledgreen">#7dbb21</color>
</resources> </resources>

139
lite/res/values/strings.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" translatable="false">Transdroid Lite</string> <string name="app_name" translatable="false">Transdroid</string>
<string name="action_add">Add</string> <string name="action_add">Add</string>
<string name="action_addfromfile">From file</string> <string name="action_addfromfile">From file</string>
@ -21,7 +21,6 @@
<string name="action_sort_ratio">Ratio</string> <string name="action_sort_ratio">Ratio</string>
<string name="action_filter">Filter list</string> <string name="action_filter">Filter list</string>
<string name="action_settings">Settings</string> <string name="action_settings">Settings</string>
<string name="action_start">Start</string> <string name="action_start">Start</string>
<string name="action_stop">Stop</string> <string name="action_stop">Stop</string>
<string name="action_resume">Resume</string> <string name="action_resume">Resume</string>
@ -41,7 +40,143 @@
<string name="navigation_servers">SERVERS</string> <string name="navigation_servers">SERVERS</string>
<string name="navigation_status">STATUS</string> <string name="navigation_status">STATUS</string>
<string name="navigation_labels">LABELS</string> <string name="navigation_labels">LABELS</string>
<string name="navigation_status_showall">All</string>
<string name="navigation_status_onlydown">Downloading</string>
<string name="navigation_status_onlyup">Uploading</string>
<string name="navigation_status_onlyactive">Active</string>
<string name="navigation_status_onlyinactive">Inactive</string>
<string name="navigation_emptytorrents">Connected, but no torrent are active on the server</string> <string name="navigation_emptytorrents">Connected, but no torrent are active on the server</string>
<string name="navigation_emptydetails">Select a torrent to view its details</string> <string name="navigation_emptydetails">Select a torrent to view its details</string>
<string name="pref_servers">Servers</string>
<string name="pref_addserver">Add new server</string>
<string name="pref_searchsites">Search sites</string>
<string name="pref_setsearchsite">Set default site</string>
<string name="pref_addwebsearch">Add web search site</string>
<string name="pref_rssfeeds">RSS feeds</string>
<string name="pref_addrssfeed">Add RSS feed</string>
<string name="pref_others">Other settings</string>
<string name="pref_name">Name</string>
<string name="pref_name_optional">Optional personal name</string>
<string name="pref_searchurl">Direct search URL</string>
<string name="pref_searchurl_info">%s will be replaced by the search query</string>
<string name="pref_feedurl">Feed URL</string>
<string name="pref_reqauth">Requires authentication</string>
<string name="pref_reqauth_info">Opens links in the webbrowser for user login</string>
<string name="pref_servertype">Server type</string>
<string name="pref_address">IP or host name</string>
<string name="pref_port">Port number</string>
<string name="pref_user">User name</string>
<string name="pref_pass">Password</string>
<string name="pref_extrapass">Deluge web password</string>
<string name="pref_advanced">Advanced settings</string>
<string name="pref_localaddress">Local IP or host</string>
<string name="pref_localaddress_info">When connected to the specified local network</string>
<string name="pref_localnetwork">Local network</string>
<string name="pref_localnetwork_info">The server\'s local (wifi) network</string>
<string name="pref_folder">Folder</string>
<string name="pref_folder_info">Usually empty</string>
<string name="pref_scgifolder">SCGI mount point</string>
<string name="pref_optional">Optional settings</string>
<string name="pref_alarmdone">Finished notification</string>
<string name="pref_alarmdone_info">Notify when a torrent finishes</string>
<string name="pref_alarmnew">New torrent notification</string>
<string name="pref_alarmnew_info">Nofity when a torrent was added</string>
<string name="pref_os">Server OS</string>
<string name="pref_downdir">Download directory</string>
<string name="pref_downdir_info">Manually set absolute path for remote connections</string>
<string name="pref_timeout">Connection timeout</string>
<string name="pref_timeout_info">Number of seconds before a connection attempt is aborted</string>
<string name="pref_ftpurl">Base (S)FTP url</string>
<string name="pref_ftpurl_into">For example ftp://me@server/downloads/</string>
<string name="pref_ftppass">(S)FTP password</string>
<string name="pref_sslenable">Use SSL</string>
<string name="pref_sslenable_info">Connect using https</string>
<string name="pref_sslkey">Custom SSL thumbprint (SHA-1)</string>
<string name="pref_sslkey_info">Permit only connections to this specific certificate</string>
<string name="pref_sslacceptall">Accept all SSL certificates</string>
<string name="pref_sslacceptall_info">Allow all connections from any thumbprint</string>
<string name="pref_background">Background notifications</string>
<string name="pref_notifications">Enable notifications</string>
<string name="pref_notifications_info">Enables the background service</string>
<string name="pref_notifyinterval">Interval</string>
<string name="pref_notifyinterval_info">How often to check the server</string>
<string name="pref_notifysound">Sound</string>
<string name="pref_notifyvibrate">Vibrate</string>
<string name="pref_notifyled">LED colour</string>
<string name="pref_notifyled_info">If supported by your device</string>
<string name="pref_awdnotify">Support AWD notifications</string>
<string name="pref_awdnotify_info">Show torrent counter in ADW Launcher</string>
<string name="pref_system">About Transdroid</string>
<string name="pref_checkupdates">Check for updates</string>
<string name="pref_checkupdates_info">Check transdroidorg for latest app version</string>
<string name="pref_import">Import settings</string>
<string name="pref_export">Export settings</string>
<string name="pref_sendlog">Send error log</string>
<string name="pref_sendlog_info">Get support or report a bug</string>
<string name="pref_about">About</string>
<string-array name="pref_daemon_types" translatable="false">
<item>BitComet</item>
<item>Bitflu 1.2+</item>
<item>BitTorrent 6+</item>
<item>Buffalo NAS -1.31</item>
<item>Deluge 1.2+</item>
<item>DLink Router BT</item>
<item>Ktorrent</item>
<item>qBittorrent</item>
<item>rTorrent</item>
<item>Torrentflux-b4rt</item>
<item>Transmission</item>
<item>µTorrent</item>
<item>Vuze</item>
</string-array>
<string-array name="pref_daemon_values" translatable="false">
<item>daemon_bitcomet</item>
<item>daemon_bitflu</item>
<item>daemon_bittorrent</item>
<item>daemon_buffalonas</item>
<item>daemon_deluge</item>
<item>daemon_dlinkrouterbt</item>
<item>daemon_ktorrent</item>
<item>daemon_qbittorrent</item>
<item>daemon_rtorrent</item>
<item>daemon_tfb4rt</item>
<item>daemon_transmission</item>
<item>daemon_utorrent</item>
<item>daemon_vuze</item>
</string-array>
<string-array name="pref_os_types" translatable="false">
<item>Windows</item>
<item>Mac</item>
<item>Linux</item>
</string-array>
<string-array name="pref_os_values" translatable="false">
<item>type_windows</item>
<item>type_mac</item>
<item>type_linux</item>
</string-array>
<string-array name="pref_notifyinterval_types">
<item>1 minute</item>
<item>10 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>3 hours</item>
<item>12 hours</item>
<item>1 day</item>
</string-array>
<string-array name="pref_notifyinterval_values" translatable="false">
<item>60</item>
<item>600</item>
<item>1800</item>
<item>3600</item>
<item>10800</item>
<item>43200</item>
<item>86400</item>
</string-array>
</resources> </resources>

20
lite/res/xml/pref_about.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<CheckBoxPreference
android:key="about_checkupdates"
android:title="@string/pref_checkupdates"
android:summary="@string/pref_checkupdates_info"
android:defaultValue="true" />
<Preference
android:key="about_sendlog"
android:title="@string/pref_sendlog"
android:summary="@string/pref_sendlog_info">
</Preference>
<Preference
android:key="about_about"
android:title="@string/pref_about" />
</PreferenceScreen>

52
lite/res/xml/pref_main.xml

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:key="header_servers"
android:title="@string/pref_servers"
android:order="0">
<Preference
android:key="header_addserver"
android:title="@string/pref_addserver"
android:order="99" />
</PreferenceCategory>
<PreferenceCategory
android:key="header_searchsites"
android:title="@string/pref_servers"
android:order="100">
<ListPreference
android:key="header_setsearchsite"
android:title="@string/pref_setsearchsite"
android:order="101" />
<Preference
android:key="header_addwebsearch"
android:title="@string/pref_addwebsearch"
android:order="199"/>
</PreferenceCategory>
<PreferenceCategory
android:key="header_rssfeeds"
android:title="@string/pref_rssfeeds"
android:order="200">
<Preference
android:key="header_addrssfeed"
android:title="@string/pref_addrssfeed"
android:order="199"/>
</PreferenceCategory>
<PreferenceCategory
android:key="header_other"
android:title="@string/pref_others"
android:order="300">
<Preference
android:key="header_background"
android:title="@string/pref_background"
android:order="301" />
<Preference
android:key="header_system"
android:title="@string/pref_system"
android:order="302" />
</PreferenceCategory>
</PreferenceScreen>

47
lite/res/xml/pref_notifications.xml

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<CheckBoxPreference
android:key="notifications_enabled"
android:title="@string/pref_notifications"
android:summary="@string/pref_notifications_info"
android:defaultValue="true" />
<ListPreference
android:key="notifications_interval"
android:title="@string/pref_notifyinterval"
android:summary="@string/pref_notifyinterval_info"
android:entries="@array/pref_notifyinterval_types"
android:entryValues="@array/pref_notifyinterval_values"
android:defaultValue="10800"
android:dependency="notifications_enabled" />
<RingtonePreference
android:key="notifications_sound"
android:title="@string/pref_notifysound"
android:ringtoneType="notification"
android:showDefault="true"
android:showSilent="true"
android:dependency="notifications_enabled" />
<CheckBoxPreference
android:key="notifications_vibrate"
android:title="@string/pref_notifyvibrate"
android:defaultValue="false" />
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="notifications_ledcolour"
android:title="@string/pref_notifyled"
android:summary="@string/pref_notifyled_info"
android:defaultValue="@color/ledgreen"
android:dependency="notifications_enabled"
alphaSlider="false" />
<CheckBoxPreference
android:key="notifications_adwnotify"
android:title="@string/pref_notifyled"
android:summary="@string/pref_notifyled_info"
android:defaultValue="false"
android:dependency="notifications_enabled" />
</PreferenceScreen>

21
lite/res/xml/pref_rssfeed.xml

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<EditTextPreference
android:key="rssfeed_name"
android:title="@string/pref_name"
android:summary="@string/pref_name_optional"
android:inputType="textNoSuggestions" />
<EditTextPreference
android:key="rssfeed_url"
android:title="@string/pref_feedurl"
android:inputType="textUri" />
<CheckBoxPreference
android:key="rssfeed_reqauth"
android:title="@string/pref_reqauth"
android:summary="@string/pref_reqauth_info"
android:defaultValue="false" />
</PreferenceScreen>

108
lite/res/xml/pref_server.xml

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<EditTextPreference
android:key="server_name"
android:title="@string/pref_name"
android:summary="@string/pref_name_optional"
android:inputType="textNoSuggestions" />
<ListPreference
android:key="server_type"
android:title="@string/pref_servertype"
android:entries="@array/pref_daemon_types"
android:entryValues="@array/pref_daemon_values" />
<EditTextPreference
android:key="server_address"
android:title="@string/pref_address"
android:summary="@string/pref_searchurl_info"
android:inputType="textUri" />
<EditTextPreference
android:key="server_port"
android:title="@string/pref_address"
android:summary="@string/pref_searchurl_info"
android:inputType="numberSigned" />
<EditTextPreference
android:key="server_user"
android:title="@string/pref_user"
android:inputType="textNoSuggestions" />
<EditTextPreference
android:key="server_pass"
android:title="@string/pref_pass"
android:inputType="textPassword" />
<EditTextPreference
android:key="server_extrapass"
android:title="@string/pref_extrapass"
android:inputType="textPassword" />
<PreferenceScreen android:title="@string/pref_advanced" >
<EditTextPreference
android:key="server_localaddress"
android:title="@string/pref_localaddress"
android:summary="@string/pref_localaddress_info"
android:inputType="textUri" />
<ListPreference
android:key="server_localnetwork"
android:title="@string/pref_localnetwork"
android:summary="@string/pref_localnetwork_info" />
<EditTextPreference
android:key="server_folder"
android:title="@string/pref_folder"
android:summary="@string/pref_folder_info"
android:inputType="textUri" />
<EditTextPreference
android:key="server_timeout"
android:title="@string/pref_timeout"
android:summary="@string/pref_timeout_info"
android:inputType="numberSigned" />
<CheckBoxPreference
android:key="server_sslenabled"
android:title="@string/pref_sslenable"
android:summary="@string/pref_sslenable_info"
android:defaultValue="false" />
<CheckBoxPreference
android:key="server_trustall"
android:title="@string/pref_sslacceptall"
android:summary="@string/pref_sslacceptall_info"
android:defaultValue="false"
android:dependency="server_sslenabled" />
<EditTextPreference
android:key="server_ssltrustkey"
android:title="@string/pref_sslkey"
android:summary="@string/pref_sslkey_info"
android:inputType="textNoSuggestions"
android:dependency="server_sslenabled" />
</PreferenceScreen>
<PreferenceScreen android:title="@string/pref_optional" >
<CheckBoxPreference
android:key="server_alarmfinished"
android:title="@string/pref_alarmdone"
android:summary="@string/pref_alarmdone_info"
android:defaultValue="true" />
<CheckBoxPreference
android:key="server_alarmnew"
android:title="@string/pref_alarmnew"
android:summary="@string/pref_alarmnew_info"
android:defaultValue="false" />
<ListPreference
android:key="server_os"
android:title="@string/pref_os"
android:entries="@array/pref_os_types"
android:entryValues="@array/pref_os_values" />
<EditTextPreference
android:key="server_downloaddir"
android:title="@string/pref_downdir"
android:summary="@string/pref_downdir_info"
android:inputType="textUri" />
<EditTextPreference
android:key="server_ftpurl"
android:title="@string/pref_ftpurl"
android:summary="@string/pref_ftpurl_into"
android:inputType="textUri" />
<EditTextPreference
android:key="server_ftppass"
android:title="@string/pref_ftppass"
android:inputType="textPassword" />
</PreferenceScreen>
</PreferenceScreen>

16
lite/res/xml/pref_websearch.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<EditTextPreference
android:key="websearch_name"
android:title="@string/pref_name"
android:summary="@string/pref_name_optional"
android:inputType="textNoSuggestions" />
<EditTextPreference
android:key="websearch_url"
android:title="@string/pref_searchurl"
android:summary="@string/pref_searchurl_info"
android:inputType="textUri" />
</PreferenceScreen>

337
lite/src/com/actionbarsherlock/view/SherlockListView.java

@ -0,0 +1,337 @@
package com.actionbarsherlock.view;
import android.annotation.TargetApi;
import android.content.Context;
import android.util.AttributeSet;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Checkable;
import android.widget.ListView;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
/**
* Provides backwards compatible multiple choice ActionMode support on Froyo+ using ActionBarSherlock.
*/
public class SherlockListView extends ListView {
// API 11+ reference, but ok because the value will be inlined.
public static final int CHOICE_MODE_MULTIPLE_MODAL_COMPAT = CHOICE_MODE_MULTIPLE_MODAL;
/**
* Wrapper to intercept delegation of long click events, and pass to {@link #doLongPress}
*/
class OnItemLongClickListenerWrapper implements OnItemLongClickListener {
private OnItemLongClickListener wrapped;
public void setWrapped(OnItemLongClickListener listener) {
this.wrapped = listener;
}
@Override
public boolean onItemLongClick(AdapterView<?> view, View child, int position, long id) {
// this would be easier if AbsListView.performLongPress wasn't package
// protected :-(
boolean handled = doLongPress(child, position, id);
if (!handled && wrapped != null) {
return wrapped.onItemLongClick(view, child, position, id);
}
return true;
}
}
/**
* Hijack the onLongClickListener so we can intercept delegation.
*/
@Override
public void setOnItemLongClickListener(OnItemLongClickListener listener) {
if (longClickListenerWrapper == null) {
longClickListenerWrapper = new OnItemLongClickListenerWrapper();
}
longClickListenerWrapper.setWrapped(listener);
super.setOnItemLongClickListener(longClickListenerWrapper);
}
/**
* A MultiChoiceModeListener receives events for {@link AbsListView#CHOICE_MODE_MULTIPLE_MODAL}. It acts as the
* {@link ActionMode.Callback} for the selection mode and also receives
* {@link #onItemCheckedStateChanged(ActionMode, int, long, boolean)} events when the user selects and deselects
* list items.
*/
@SuppressWarnings("javadoc")
public interface MultiChoiceModeListenerCompat extends ActionMode.Callback {
/**
* Called when an item is checked or unchecked during selection mode.
* @param mode The {@link ActionMode} providing the selection mode
* @param position Adapter position of the item that was checked or unchecked
* @param id Adapter ID of the item that was checked or unchecked
* @param checked <code>true</code> if the item is now checked, <code>false</code> if the item is now unchecked.
*/
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked);
}
class MultiChoiceModeWrapper implements MultiChoiceModeListenerCompat {
private MultiChoiceModeListenerCompat wrapped;
public void setWrapped(MultiChoiceModeListenerCompat wrapped) {
this.wrapped = wrapped;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
if (wrapped == null) {
return false;
}
if (wrapped.onCreateActionMode(mode, menu)) {
// Initialize checked graphic state?
setLongClickable(false);
return true;
}
return false;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
if (wrapped == null) {
return false;
}
return wrapped.onPrepareActionMode(mode, menu);
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (wrapped == null) {
return false;
}
return wrapped.onActionItemClicked(mode, item);
}
@Override
public void onDestroyActionMode(ActionMode mode) {
if (wrapped == null) {
return;
}
wrapped.onDestroyActionMode(mode);
actionMode = null;
// Ending selection mode means deselecting everything.
clearChoices();
checkedItemCount = 0;
updateOnScreenCheckedViews();
invalidateViews();
setLongClickable(true);
requestLayout();
invalidate();
}
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
if (wrapped == null) {
return;
}
wrapped.onItemCheckedStateChanged(mode, position, id, checked);
// If there are no items selected we no longer need the selection mode.
if (checkedItemCount == 0) {
mode.finish();
}
}
}
private com.actionbarsherlock.view.ActionMode actionMode;
private OnItemLongClickListenerWrapper longClickListenerWrapper;
private MultiChoiceModeWrapper choiceModeListener;
private int choiceMode;
private int checkedItemCount;
public SherlockListView(Context context) {
super(context);
init(context);
}
public SherlockListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SherlockListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
void init(Context context) {
if (isInEditMode()) {
// Ignore when viewing in the UI designer
return;
}
if (!(context instanceof SherlockActivity || context instanceof SherlockFragmentActivity)) {
throw new IllegalStateException(
"This view must be hosted in a SherlockActivity or SherlockFragmentActivity");
}
setOnItemLongClickListener(null);
}
@Override
public void setChoiceMode(int mode) {
choiceMode = mode;
if (actionMode != null) {
actionMode.finish();
actionMode = null;
}
if (choiceMode != CHOICE_MODE_NONE) {
if (mode == CHOICE_MODE_MULTIPLE_MODAL_COMPAT) {
clearChoices();
checkedItemCount = 0;
setLongClickable(true);
updateOnScreenCheckedViews();
requestLayout();
invalidate();
mode = CHOICE_MODE_MULTIPLE;
}
super.setChoiceMode(mode);
}
}
@Override
public int getChoiceMode() {
return choiceMode;
}
public void setMultiChoiceModeListener(MultiChoiceModeListenerCompat listener) {
if (choiceModeListener == null) {
choiceModeListener = new MultiChoiceModeWrapper();
}
choiceModeListener.setWrapped(listener);
}
@Override
public boolean performItemClick(View view, int position, long id) {
boolean handled = false;
boolean dispatchItemClick = true;
boolean checkStateChanged = false;
if (choiceMode != CHOICE_MODE_NONE) {
handled = true;
if (choiceMode == CHOICE_MODE_MULTIPLE
|| (choiceMode == CHOICE_MODE_MULTIPLE_MODAL_COMPAT && actionMode != null)) {
boolean newValue = !getCheckedItemPositions().get(position);
setItemChecked(position, newValue);
if (actionMode != null) {
choiceModeListener.onItemCheckedStateChanged(actionMode, position, id, newValue);
dispatchItemClick = false;
}
checkStateChanged = true;
return false;
} else if (choiceMode == CHOICE_MODE_SINGLE) {
boolean newValue = !getCheckedItemPositions().get(position);
setItemChecked(position, newValue);
checkStateChanged = true;
}
if (checkStateChanged) {
updateOnScreenCheckedViews();
}
}
if (dispatchItemClick) {
handled |= super.performItemClick(view, position, id);
}
return handled;
}
/**
* Perform a quick, in-place update of the checked or activated state on all visible item views. This should only be
* called when a valid choice mode is active.
* <p>
* (Taken verbatim from AbsListView.java)
*/
@TargetApi(11)
private void updateOnScreenCheckedViews() {
final int firstPos = getFirstVisiblePosition();
final int count = getChildCount();
final boolean useActivated = getContext().getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.HONEYCOMB;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
final int position = firstPos + i;
if (child instanceof Checkable) {
((Checkable) child).setChecked(getCheckedItemPositions().get(position));
} else if (useActivated) {
child.setActivated(getCheckedItemPositions().get(position));
}
}
}
public ActionMode startActionMode(ActionMode.Callback callback) {
if (actionMode != null) {
return actionMode;
}
Context context = getContext();
if (context instanceof SherlockActivity) {
actionMode = ((SherlockActivity) getContext()).startActionMode(callback);
} else if (context instanceof SherlockFragmentActivity) {
actionMode = ((SherlockFragmentActivity) context).startActionMode(callback);
} else {
throw new IllegalStateException(
"This view must be hosted in a SherlockActivity or SherlockFragmentActivity");
}
return actionMode;
}
boolean doLongPress(final View child, final int longPressPosition, final long longPressId) {
if (choiceMode == CHOICE_MODE_MULTIPLE_MODAL_COMPAT) {
if (actionMode == null && (actionMode = startActionMode(choiceModeListener)) != null) {
setItemChecked(longPressPosition, true);
}
return true;
}
return false;
}
/**
* Sets the checked state of the specified position. The is only valid if the choice mode has been set to
* {@link #CHOICE_MODE_SINGLE} or {@link #CHOICE_MODE_MULTIPLE}.
* @param position The item whose checked state is to be checked
* @param value The new checked state for the item
*/
@Override
public void setItemChecked(int position, boolean value) {
if (choiceMode == CHOICE_MODE_NONE) {
return;
}
SparseBooleanArray checkStates = getCheckedItemPositions();
// Start selection mode if needed. We don't need to if we're unchecking
// something.
if (value && choiceMode == CHOICE_MODE_MULTIPLE_MODAL_COMPAT && actionMode == null) {
actionMode = startActionMode(choiceModeListener);
}
if (choiceMode == CHOICE_MODE_MULTIPLE || choiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
// boolean oldValue = checkStates.get(position);
checkStates.put(position, value);
if (value) {
checkedItemCount++;
} else {
checkedItemCount--;
}
if (actionMode != null) {
final long id = getAdapter().getItemId(position);
choiceModeListener.onItemCheckedStateChanged(actionMode, position, id, value);
}
} else {
if (value || isItemChecked(position)) {
checkStates.clear();
}
// this may end up selecting the value we just cleared but this way
// we ensure length of checkStates is 1, a fact getCheckedItemPosition
// relies on
if (value) {
checkStates.put(position, true);
}
}
requestLayout();
invalidate();
}
}

100
lite/src/fr/marvinlabs/widget/CheckableRelativeLayout.java

@ -0,0 +1,100 @@
package fr.marvinlabs.widget;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Checkable;
import android.widget.RelativeLayout;
/**
* Extension of a relative layout to provide a checkable behaviour
*
* @author marvinlabs
*/
public class CheckableRelativeLayout extends RelativeLayout implements Checkable {
private boolean isChecked;
private List<Checkable> checkableViews;
public CheckableRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialise(attrs);
}
public CheckableRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initialise(attrs);
}
public CheckableRelativeLayout(Context context, int checkableId) {
super(context);
initialise(null);
}
/*
* @see android.widget.Checkable#isChecked()
*/
public boolean isChecked() {
return isChecked;
}
/*
* @see android.widget.Checkable#setChecked(boolean)
*/
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
for (Checkable c : checkableViews) {
c.setChecked(isChecked);
}
}
/*
* @see android.widget.Checkable#toggle()
*/
public void toggle() {
this.isChecked = !this.isChecked;
for (Checkable c : checkableViews) {
c.toggle();
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
final int childCount = this.getChildCount();
for (int i = 0; i < childCount; ++i) {
findCheckableChildren(this.getChildAt(i));
}
}
/**
* Read the custom XML attributes
*/
private void initialise(AttributeSet attrs) {
this.isChecked = false;
this.checkableViews = new ArrayList<Checkable>(5);
}
/**
* Add to our checkable list all the children of the view that implement the
* interface Checkable
*/
private void findCheckableChildren(View v) {
if (v instanceof Checkable) {
this.checkableViews.add((Checkable) v);
}
if (v instanceof ViewGroup) {
final ViewGroup vg = (ViewGroup) v;
final int childCount = vg.getChildCount();
for (int i = 0; i < childCount; ++i) {
findCheckableChildren(vg.getChildAt(i));
}
}
}
}

70
lite/src/fr/marvinlabs/widget/InertCheckBox.java

@ -0,0 +1,70 @@
package fr.marvinlabs.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.CheckBox;
/**
* CheckBox that does not react to any user event in order to let the container handle them.
*/
public class InertCheckBox extends CheckBox {
// Provide the same constructors as the superclass
public InertCheckBox(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// Provide the same constructors as the superclass
public InertCheckBox(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Provide the same constructors as the superclass
public InertCheckBox(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Make the checkbox not respond to any user event
return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Make the checkbox not respond to any user event
return false;
}
@Override
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
// Make the checkbox not respond to any user event
return false;
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
// Make the checkbox not respond to any user event
return false;
}
@Override
public boolean onKeyShortcut(int keyCode, KeyEvent event) {
// Make the checkbox not respond to any user event
return false;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// Make the checkbox not respond to any user event
return false;
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
// Make the checkbox not respond to any user event
return false;
}
}

109
lite/src/org/transdroid/lite/app/search/SearchHelper.java

@ -0,0 +1,109 @@
package org.transdroid.lite.app.search;
import java.util.ArrayList;
import java.util.List;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.EBean.Scope;
import org.androidannotations.annotations.RootContext;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
@EBean(scope = Scope.Singleton)
public class SearchHelper {
static final int CURSOR_SEARCH_ID = 0;
static final int CURSOR_SEARCH_NAME = 1;
static final int CURSOR_SEARCH_TORRENTURL = 2;
static final int CURSOR_SEARCH_DETAILSURL = 3;
static final int CURSOR_SEARCH_SIZE = 4;
static final int CURSOR_SEARCH_ADDED = 5;
static final int CURSOR_SEARCH_SEEDERS = 6;
static final int CURSOR_SEARCH_LEECHERS = 7;
static final int CURSOR_SITE_ID = 0;
static final int CURSOR_SITE_CODE = 1;
static final int CURSOR_SITE_NAME = 2;
static final int CURSOR_SITE_RSSURL = 3;
@RootContext
protected Context context;
public enum SearchSortOrder {
Combined, BySeeders
}
/**
* Return whether the Torrent Search package is installed and available to query against
* @return True if the available sites can be retrieved from the content provider, false otherwise
*/
public boolean isTorrentSearchInstalled() {
return getAvailableSites() != null;
}
/**
* Queries the Torrent Search package for all available in-app search sites. This method is synchronous.
* @return A list of available search sites as POJOs, or null if the Torrent Search package is not installed
*/
public List<SearchSite> getAvailableSites() {
// Try to access the TorrentSitesProvider to retrieve all available in-app torrent search sites
Uri uri = Uri.parse("content://org.transdroid.search.torrentsitesprovider/sites");
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
if (cursor.moveToFirst()) {
List<SearchSite> sites = new ArrayList<SearchSite>();
do {
// Read the cursor fields into the SearchSite object
sites.add(new SearchSite(cursor.getInt(CURSOR_SITE_ID), cursor.getString(CURSOR_SITE_CODE), cursor
.getString(CURSOR_SITE_NAME), cursor.getString(CURSOR_SITE_RSSURL)));
} while (cursor.moveToNext());
cursor.close();
return sites;
}
// Torrent Search package is not yet installed
return null;
}
/**
* Queries the Torrent Search module to search for torrents on the web. This method is synchornous and should always
* be called in a background thread.
* @param query The search query to pass to the torrent site
* @param site The site to search, as retrieved from the TorrentSitesProvider, or null if the Torrent Search package
* @param sortBy.name() The sort order to request from the torrent site, if supported
* @return A list of torrent search results as POJOs, or null if the Torrent Search package is not installed
*/
public List<SearchResult> search(String query, SearchSite site, SearchSortOrder sortBy) {
// Try to query the TorrentSearchProvider to search for torrents on the web
Uri uri = Uri.parse("content://org.transdroid.search.torrentsearchprovider/search/" + query);
Cursor cursor;
if (site == null) {
// If no explicit site was supplied, rely on the Torrent Search package's default
cursor = context.getContentResolver().query(uri, null, null, null, sortBy.name());
} else {
cursor = context.getContentResolver().query(uri, null, "SITE = ?", new String[] { site.getKey() },
sortBy.name());
}
if (cursor.moveToFirst()) {
List<SearchResult> results = new ArrayList<SearchResult>();
do {
// Read the cursor fields into the SearchResult object
results.add(new SearchResult(cursor.getInt(CURSOR_SEARCH_ID), cursor.getString(CURSOR_SEARCH_NAME),
cursor.getString(CURSOR_SEARCH_TORRENTURL), cursor.getString(CURSOR_SEARCH_DETAILSURL), cursor
.getString(CURSOR_SEARCH_SIZE), cursor.getLong(CURSOR_SEARCH_ADDED), cursor
.getString(CURSOR_SEARCH_SEEDERS), cursor.getString(CURSOR_SEARCH_LEECHERS)));
} while (cursor.moveToNext());
cursor.close();
return results;
}
// Torrent Search package is not yet installed
return null;
}
}

64
lite/src/org/transdroid/lite/app/search/SearchResult.java

@ -0,0 +1,64 @@
package org.transdroid.lite.app.search;
import java.util.Date;
/**
* Represents a search result as retrieved by querying the Torrent Search package.
* @author Eric Kok
*/
public class SearchResult {
private final int id;
private final String name;
private final String torrentUrl;
private final String detailsUrl;
private final String size;
private final Date addedOn;
private final String seeders;
private final String leechers;
public SearchResult(int id, String name, String torrentUrl, String detailsUrl, String size, long addedOnTime,
String seeders, String leechers) {
this.id = id;
this.name = name;
this.torrentUrl = torrentUrl;
this.detailsUrl = detailsUrl;
this.size = size;
this.addedOn = (addedOnTime == -1L) ? null : new Date(addedOnTime);
this.seeders = seeders;
this.leechers = leechers;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getTorrentUrl() {
return torrentUrl;
}
public String getDetailsUrl() {
return detailsUrl;
}
public String getSize() {
return size;
}
public Date getAddedOn() {
return addedOn;
}
public String getSeeders() {
return seeders;
}
public String getLeechers() {
return leechers;
}
}

40
lite/src/org/transdroid/lite/app/search/SearchSite.java

@ -0,0 +1,40 @@
package org.transdroid.lite.app.search;
import org.transdroid.lite.gui.navigation.FilterItem;
/**
* Represents an available torrent site that can be searched using the Torrent Search package.
* @author Eric Kok
*/
public class SearchSite implements FilterItem {
private final int id;
private final String key;
private final String name;
private final String rssFeedUrl;
public SearchSite(int id, String key, String name, String rssFeedUrl) {
this.id = id;
this.key = key;
this.name = name;
this.rssFeedUrl = rssFeedUrl;
}
public int getId() {
return id;
}
public String getKey() {
return key;
}
@Override
public String getName() {
return name;
}
public String getRssFeedUrl() {
return rssFeedUrl;
}
}

30
lite/src/org/transdroid/lite/app/settings/AboutSettings.java

@ -0,0 +1,30 @@
package org.transdroid.lite.app.settings;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;
import org.androidannotations.annotations.EBean.Scope;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
/**
* Allows instantiation of the settings specified in R.xml.pref_about.
* @author Eric Kok
*/
@EBean(scope = Scope.Singleton)
public class AboutSettings {
@RootContext
protected Context context;
private SharedPreferences prefs;
protected AboutSettings(Context context) {
prefs = PreferenceManager.getDefaultSharedPreferences(context);
}
public boolean checkForUpdates() {
return prefs.getBoolean("about_checkupdates", true);
}
}

140
lite/src/org/transdroid/lite/app/settings/ApplicationSettings.java

@ -0,0 +1,140 @@
package org.transdroid.lite.app.settings;
import java.util.ArrayList;
import java.util.List;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.EBean.Scope;
import org.androidannotations.annotations.RootContext;
import org.transdroid.daemon.Daemon;
import org.transdroid.daemon.OS;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
/**
* Singleton object to access all application settings, including stored servers, web search sites and RSS feeds.
* @author Eric Kok
*/
@EBean(scope = Scope.Singleton)
public class ApplicationSettings {
@RootContext
protected Context context;
private SharedPreferences prefs;
protected ApplicationSettings(Context context) {
prefs = PreferenceManager.getDefaultSharedPreferences(context);
}
/**
* Returns all available user-configured servers
* @return A list of all stored server settings objects
*/
public List<ServerSetting> getServerSettings() {
List<ServerSetting> servers = new ArrayList<ServerSetting>();
for (int i = 0; i <= getMaxServer(); i++) {
servers.add(getServerSetting(i));
}
return servers;
}
/**
* Returns the order number/identifying key of the last server
* @return The zero-based order number (index) of the last stored server settings
*/
public int getMaxServer() {
for (int i = 0; true; i++) {
if (prefs.getString("server_type_" + i, null) == null)
return i - 1;
}
}
/**
* Returns the user-specified server settings for a specific server
* @param order The order number/identifying key of the settings to retrieve
* @return The server settings object, loaded from shared preferences
*/
public ServerSetting getServerSetting(int order) {
return new ServerSetting(order, prefs.getString("server_name_" + order, null), Daemon.fromCode(prefs.getString(
"server_type_" + order, null)), prefs.getString("server_address_" + order, null), prefs.getString(
"server_localaddress_" + order, null), prefs.getString("server_localnetwork_" + order, null),
prefs.getInt("server_port_" + order, -1), prefs.getBoolean("server_sslenabled_" + order, false),
prefs.getBoolean("server_ssltrustall_" + order, false), prefs.getString("server_ssltrustkey_" + order,
null), prefs.getString("server_folder_" + order, null), prefs.getBoolean("server_useauth_"
+ order, true), prefs.getString("server_user_" + order, null), prefs.getString("server_pass_"
+ order, null), prefs.getString("server_extrapass_" + order, null), OS.fromCode(prefs
.getString("server_os_" + order, null)), prefs.getString("server_downloaddir_" + order, null),
prefs.getString("server_ftpurl_" + order, null), prefs.getString("server_ftppass_" + order, null),
prefs.getInt("server_timeout_" + order, -1), prefs.getBoolean("server_alarmfinished_" + order, true),
prefs.getBoolean("server_alarmnew_" + order, false), false);
}
/**
* Returns all available user-configured web-based (as opped to in-app) search sites
* @return A list of all stored web search site settings objects
*/
public List<WebsearchSetting> getWebsearchSettings() {
List<WebsearchSetting> websearches = new ArrayList<WebsearchSetting>();
for (int i = 0; i <= getMaxWebsearch(); i++) {
websearches.add(getWebsearchSetting(i));
}
return websearches;
}
/**
* Returns the order number/identifying key of the last web search site
* @return The zero-based order number (index) of the last stored web search site
*/
public int getMaxWebsearch() {
for (int i = 0; true; i++) {
if (prefs.getString("websearch_url_" + i, null) == null)
return i - 1;
}
}
/**
* Returns the user-specified web-based search site setting for a specific site
* @param order The order number/identifying key of the settings to retrieve
* @return The web search site settings object, loaded from shared preferences
*/
public WebsearchSetting getWebsearchSetting(int order) {
return new WebsearchSetting(order, prefs.getString("websearch_name_" + order, null), prefs.getString(
"websearch_url_" + order, null));
}
/**
* Returns all available user-configured RSS feeds
* @return A list of all stored RSS feed settings objects
*/
public List<RssfeedSetting> getRssfeedSettings() {
List<RssfeedSetting> rssfeeds = new ArrayList<RssfeedSetting>();
for (int i = 0; i <= getMaxRssfeed(); i++) {
rssfeeds.add(getRssfeedSetting(i));
}
return rssfeeds;
}
/**
* Returns the order number/identifying key of the last stored RSS feed
* @return The zero-based order number (index) of the last stored RSS feed
*/
public int getMaxRssfeed() {
for (int i = 0; true; i++) {
if (prefs.getString("rssfeed_feedurl_" + i, null) == null)
return i - 1;
}
}
/**
* Returns the user-specified RSS feed setting for a specific feed
* @param order The order number/identifying key of the settings to retrieve
* @return The RSS feed settings object, loaded from shared preferences
*/
public RssfeedSetting getRssfeedSetting(int order) {
return new RssfeedSetting(order, prefs.getString("rssfeed_name_" + order, null), prefs.getString(
"rssfeed_feedurl_" + order, null), prefs.getBoolean("rssfeed_reqauth_" + order, false));
}
}

97
lite/src/org/transdroid/lite/app/settings/NotificationSettings.java

@ -0,0 +1,97 @@
package org.transdroid.lite.app.settings;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.EBean.Scope;
import org.androidannotations.annotations.RootContext;
import org.transdroid.core.R;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.provider.Settings;
/**
* Allows instantiation of the settings specified in R.xml.pref_notifications.
* @author Eric Kok
*/
@EBean(scope = Scope.Singleton)
public class NotificationSettings {
@RootContext
protected Context context;
private SharedPreferences prefs;
protected NotificationSettings(Context context) {
prefs = PreferenceManager.getDefaultSharedPreferences(context);
}
/**
* Whether the background service is enabled, i.e. whether the user want to receive notifications
* @return True if the server should be checked for torrent status updates
*/
public boolean isEnabled() {
return prefs.getBoolean("notifications_enabled", true);
}
private String getRawInverval() {
return prefs.getString("notifications_interval", "10800");
}
/**
* Returns the interval between two server checks
* @return The interval, in milliseconds
*/
public Long getInvervalInMilliseconds() {
return Long.parseLong(getRawInverval()) * 1000L;
}
private String getRawSound() {
return prefs.getString("notifications_sound", null);
}
/**
* Returns the sound (ring tone) to play on a new notification, or null if it should not play any
* @return Either the user-specified sound, null if the user specified 'Silent' or the system default notification sound
*/
public Uri getSound() {
String raw = getRawSound();
if (raw == null)
return null;
if (raw.equals(""))
return Settings.System.DEFAULT_NOTIFICATION_URI;
return Uri.parse(raw);
}
/**
* Whether the device should vibrate on a new notification
* @return
*/
public boolean shouldVibrate() {
return prefs.getBoolean("notifications_vibrate", false);
}
private int getRawLedColour() {
return prefs.getInt("notifications_ledcolour", -1);
}
/**
* Returns the LED colour to use on a new notification
* @return The integer value of the user-specified or default colour
*/
public int getDesiredLedColour() {
int raw = getRawLedColour();
if (raw <= 0)
return context.getResources().getColor(R.color.ledgreen);
return raw;
}
/**
* Whether the background service should report to ADW Launcher
* @return True if the user want Transdroid to report to ADW Launcher
*/
public boolean shouldReportToAdwLauncher() {
return prefs.getBoolean("notifications_adwnotify", false);
}
}

67
lite/src/org/transdroid/lite/app/settings/RssfeedSetting.java

@ -0,0 +1,67 @@
package org.transdroid.lite.app.settings;
import org.transdroid.lite.gui.navigation.FilterItem;
import android.net.Uri;
import android.text.TextUtils;
/**
* Represents a user-specified RSS feed.
* @author Eric Kok
*/
public class RssfeedSetting implements FilterItem {
private static final String DEFAULT_NAME = "Default";
private final int order;
private final String name;
private final String url;
private final boolean requiresAuth;
private String lastNew;
public RssfeedSetting(int order, String name, String baseUrl, boolean needsAuth) {
this.order = order;
this.name = name;
this.url = baseUrl;
this.requiresAuth = needsAuth;
this.lastNew = null;
}
public int getOrder() {
return order;
}
@Override
public String getName() {
if (!TextUtils.isEmpty(name))
return name;
if (!TextUtils.isEmpty(url))
return Uri.parse(url).getHost();
return DEFAULT_NAME;
}
public String getUrl() {
return url;
}
public boolean requiresExternalAuthentication() {
return requiresAuth;
}
/**
* Returns the URL of the item that was the newest last time we checked this feed
* @return The last new item's URL as URL-encoded string
*/
public String getLastNew() {
return this.lastNew;
}
/**
* Record the URL of what is now the last item we retrieved
* @param lastNew The URL of the last new item as URL-encoded string
*/
public void setLastNew(String lastNew) {
this.lastNew = lastNew;
}
}

195
lite/src/org/transdroid/lite/app/settings/ServerSetting.java

@ -0,0 +1,195 @@
package org.transdroid.lite.app.settings;
import org.transdroid.daemon.Daemon;
import org.transdroid.daemon.OS;
import org.transdroid.lite.gui.navigation.FilterItem;
import android.text.TextUtils;
/**
* Represents a user-configured remote server.
* @author Eric Kok
*/
public class ServerSetting implements FilterItem {
private static final String DEFAULT_NAME = "Default";
private final int key;
private final String name;
private final Daemon type;
private final String address;
private final String localAddress;
private final String localNetwork;
private final int port;
private final String folder;
private final boolean useAuthentication;
private final String username;
private final String password;
private final String extraPass;
private final OS os;
private final String downloadDir;
private final String ftpUrl;
private final String ftpPassword;
private final int timeout;
private final boolean alarmOnFinishedDownload;
private final boolean alarmOnNewTorrent;
private final boolean ssl;
private final boolean sslTrustAll;
private final String sslTrustKey;
private final boolean isAutoGenerated;
/**
* Creates a daemon settings instance, providing full connection details
* @param name A name used to identify this server to the user
* @param type The server daemon type
* @param address The server domain name or IP address
* @param localAddress The server domain or IP address when connected to the server's local network
* @param localNetwork The server's local network SSID
* @param port The port on which the server daemon is running
* @param sslTrustKey The specific key that will be accepted.
* @param folder The server folder (like a virtual sub-folder or an SCGI mount point)
* @param useAuthentication Whether to use basic authentication
* @param username The user name to provide during authentication
* @param password The password to provide during authentication
* @param extraPass The Deluge web interface password
* @param downloadDir The default download directory (which may also be used as base directory for file paths)
* @param ftpUrl The partial URL to connect to when requesting FTP-style transfers
* @param timeout The number of seconds to wait before timing out a connection attempt
* @param isAutoGenerated Whether this setting was generated rather than manually inputed by the user
*/
public ServerSetting(int key, String name, Daemon type, String address, String localAddress, String localNetwork,
int port, boolean ssl, boolean sslTrustAll, String sslTrustKey, String folder, boolean useAuthentication,
String username, String password, String extraPass, OS os, String downloadDir, String ftpUrl,
String ftpPassword, int timeout, boolean alarmOnFinishedDownload, boolean alarmOnNewTorrent,
boolean isAutoGenerated) {
this.key = key;
this.name = name;
this.type = type;
this.address = address;
this.localAddress = localAddress;
this.localNetwork = localNetwork;
this.port = port;
this.ssl = ssl;
this.sslTrustAll = sslTrustAll;
this.sslTrustKey = sslTrustKey;
this.folder = folder;
this.useAuthentication = useAuthentication;
this.username = username;
this.password = password;
this.extraPass = extraPass;
this.os = os;
this.downloadDir = downloadDir;
this.ftpUrl = ftpUrl;
this.ftpPassword = ftpPassword;
this.timeout = timeout;
this.alarmOnFinishedDownload = alarmOnFinishedDownload;
this.alarmOnNewTorrent = alarmOnNewTorrent;
this.isAutoGenerated = isAutoGenerated;
}
@Override
public String getName() {
return (name == null || name.equals("") ? DEFAULT_NAME : name);
}
public Daemon getType() {
return type;
}
public String getAddress() {
return address;
}
public String getLocalAddress() {
return localAddress;
}
public String getLocalNetwork() {
return localNetwork;
}
public int getPort() {
return port;
}
public boolean getSsl() {
return ssl;
}
public boolean getSslTrustAll() {
return sslTrustAll;
}
public String getSslTrustKey() {
return sslTrustKey;
}
public String getFolder() {
return folder;
}
public boolean shouldUseAuthentication() {
return useAuthentication;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getExtraPassword() {
return extraPass;
}
public OS getOS() {
return os;
}
public String getDownloadDir() {
return downloadDir;
}
public String getFtpUrl() {
return ftpUrl;
}
public String getFtpPassword() {
return ftpPassword;
}
public int getTimeoutInMilliseconds() {
return timeout * 1000;
}
public boolean shouldAlarmOnFinishedDownload() {
return alarmOnFinishedDownload;
}
public boolean shouldAlarmOnNewTorrent() {
return alarmOnNewTorrent;
}
public boolean isAutoGenerated() {
return isAutoGenerated;
}
public int getOrder() {
return this.key;
}
public String getHumanReadableIdentifier() {
if (isAutoGenerated) {
// Hide the 'implementation details'; just give the username and server
return (this.shouldUseAuthentication() && !TextUtils.isEmpty(this.getUsername()) ? this.getUsername() + "@"
: "") + getAddress();
}
return (this.ssl ? "https://" : "http://")
+ (this.shouldUseAuthentication() && !TextUtils.isEmpty(this.getUsername()) ? this.getUsername() + "@"
: "") + getAddress() + ":" + getPort()
+ (Daemon.supportsCustomFolder(getType()) && getFolder() != null ? getFolder() : "");
}
}

48
lite/src/org/transdroid/lite/app/settings/WebsearchSetting.java

@ -0,0 +1,48 @@
package org.transdroid.lite.app.settings;
import org.transdroid.lite.gui.navigation.FilterItem;
import android.net.Uri;
import android.text.TextUtils;
/**
* Represents a user-specified website that can be searched (by starting the browser, rather than in-app)
* @author Eric Kok
*/
public class WebsearchSetting implements FilterItem {
private static final String DEFAULT_NAME = "Default";
private static final String KEY_PREFIX = "websearch_";
private final int order;
private final String name;
private final String baseUrl;
public WebsearchSetting(int order, String name, String baseUrl) {
this.order = order;
this.name = name;
this.baseUrl = baseUrl;
}
public int getOrder() {
return order;
}
@Override
public String getName() {
if (!TextUtils.isEmpty(name))
return name;
if (!TextUtils.isEmpty(baseUrl))
return Uri.parse(baseUrl).getHost();
return DEFAULT_NAME;
}
public String getBaseUrl() {
return baseUrl;
}
public String getKey() {
return KEY_PREFIX + getOrder();
}
}

2
lite/src/org/transdroid/lite/gui/DetailsFagment.java

@ -7,7 +7,7 @@ import org.androidannotations.annotations.InstanceState;
import org.androidannotations.annotations.ViewById; import org.androidannotations.annotations.ViewById;
import org.transdroid.daemon.Torrent; import org.transdroid.daemon.Torrent;
import org.transdroid.daemon.TorrentDetails; import org.transdroid.daemon.TorrentDetails;
import org.transdroid.lite.R; import org.transdroid.core.R;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;

26
lite/src/org/transdroid/lite/gui/TorrentsActivity.java

@ -4,15 +4,15 @@ import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity; import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.FragmentById; import org.androidannotations.annotations.FragmentById;
import org.androidannotations.annotations.FragmentByTag;
import org.androidannotations.annotations.ItemSelect; import org.androidannotations.annotations.ItemSelect;
import org.androidannotations.annotations.OptionsMenu; import org.androidannotations.annotations.OptionsMenu;
import org.androidannotations.annotations.ViewById; import org.androidannotations.annotations.ViewById;
import org.transdroid.lite.R; import org.transdroid.core.R;
import org.transdroid.lite.app.settings.ApplicationSettings;
import org.transdroid.lite.gui.navigation.FilterAdapter; import org.transdroid.lite.gui.navigation.FilterAdapter;
import org.transdroid.lite.gui.navigation.FilterItem; import org.transdroid.lite.gui.navigation.FilterItem;
import org.transdroid.lite.gui.navigation.FilterSeparatorView;
import org.transdroid.lite.gui.navigation.NavigationHelper; import org.transdroid.lite.gui.navigation.NavigationHelper;
import org.transdroid.lite.gui.navigation.StatusType;
import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.OnNavigationListener; import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
@ -31,6 +31,10 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
protected FilterAdapter navigationListAdapter = null; protected FilterAdapter navigationListAdapter = null;
protected FilterAdapter navigationSpinnerAdapter = null; protected FilterAdapter navigationSpinnerAdapter = null;
// Settings
@Bean
protected ApplicationSettings applicationSettings;
// Torrents list components // Torrents list components
@FragmentById(R.id.torrent_list) @FragmentById(R.id.torrent_list)
protected TorrentsFragment fragmentTorrents; protected TorrentsFragment fragmentTorrents;
@ -42,17 +46,23 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
@AfterViews @AfterViews
protected void init() { protected void init() {
// Set up navigation // Set up navigation, with an action bar spinner and possibly (if room) with a filter list
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
getSupportActionBar().setHomeButtonEnabled(false); getSupportActionBar().setHomeButtonEnabled(false);
navigationSpinnerAdapter = new FilterAdapter(this); navigationSpinnerAdapter = new FilterAdapter(this);
// Servers are always added to the action bar spinner
navigationSpinnerAdapter.updateServers(applicationSettings.getServerSettings());
getSupportActionBar().setListNavigationCallbacks(navigationSpinnerAdapter, this); getSupportActionBar().setListNavigationCallbacks(navigationSpinnerAdapter, this);
if (filtersList != null) { if (filtersList != null) {
// There was room for a dedicated filter list; add the status types
navigationListAdapter = new FilterAdapter(this); navigationListAdapter = new FilterAdapter(this);
filtersList.setAdapter(navigationListAdapter); filtersList.setAdapter(navigationListAdapter);
navigationListAdapter.updateStatusTypes(StatusType.getAllStatusTypes(this));
} else {
// Add status types directly to the action bar spinner
navigationSpinnerAdapter.updateStatusTypes(StatusType.getAllStatusTypes(this));
} }
// Load settings
} }
@ -73,12 +83,12 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
/** /**
* A new filter was selected; update the view over the current data * A new filter was selected; update the view over the current data
* @param selected True if * @param selected True if the filter item was selected, false if it was deselected
* @param item * @param item The touched filter item
*/ */
@ItemSelect(R.id.filters_list) @ItemSelect(R.id.filters_list)
protected void filterSelected(boolean selected, FilterItem item) { protected void filterSelected(boolean selected, FilterItem item) {
// TODO: Update the view // TODO: Update the torrent list view
} }
} }

2
lite/src/org/transdroid/lite/gui/TorrentsFragment.java

@ -1,7 +1,7 @@
package org.transdroid.lite.gui; package org.transdroid.lite.gui;
import org.androidannotations.annotations.EFragment; import org.androidannotations.annotations.EFragment;
import org.transdroid.lite.R; import org.transdroid.core.R;
import com.actionbarsherlock.app.SherlockFragment; import com.actionbarsherlock.app.SherlockFragment;

110
lite/src/org/transdroid/lite/gui/lists/TorrentProgressBar.java

@ -0,0 +1,110 @@
package org.transdroid.lite.gui.lists;
import org.transdroid.core.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* Draws a progress bar indicating the download progress as well as the torrent status.
*
* @author Eric Kok
*/
public class TorrentProgressBar extends View {
private final float scale = getContext().getResources().getDisplayMetrics().density;
private final int MINIMUM_HEIGHT = (int) (2 * scale + 0.5f);
// private final int RIGHT_MARGIN = (int)(3 * scale + 0.5f);
private int progress;
private boolean isActive;
private boolean isError;
private final Paint notdonePaint = new Paint();
private final Paint inactiveDonePaint = new Paint();
private final Paint inactivePaint = new Paint();
private final Paint progressPaint = new Paint();
private final Paint donePaint = new Paint();
private final Paint errorPaint = new Paint();
private final RectF fullRect = new RectF();
private final RectF progressRect = new RectF();
public void setProgress(int progress) {
this.progress = progress;
this.invalidate();
}
public void setActive(boolean isActive) {
this.isActive = isActive;
this.invalidate();
}
public void setError(boolean isError) {
this.isError = isError;
this.invalidate();
}
public TorrentProgressBar(Context context) {
super(context);
initPaints();
}
public TorrentProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
initPaints();
// Parse any set attributes from XML
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TorrentProgressBar);
if (a.hasValue(R.styleable.TorrentProgressBar_progress)) {
this.progress = a.getIndex(R.styleable.TorrentProgressBar_progress);
this.isActive = a.getBoolean(R.styleable.TorrentProgressBar_isActive, false);
}
a.recycle();
}
private void initPaints() {
notdonePaint.setColor(0xFFEEEEEE);
inactiveDonePaint.setColor(0xFFA759D4);
inactivePaint.setColor(0xFF9E9E9E);
progressPaint.setColor(0xFF42A8FA);
donePaint.setColor(0xFF8CCF29);
errorPaint.setColor(0xFFDE3939);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int ws = MeasureSpec.getSize(widthMeasureSpec);// - RIGHT_MARGIN;
int hs = Math.max(getHeight(), MINIMUM_HEIGHT);
setMeasuredDimension(ws, hs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height = getHeight();
int width = getWidth();
fullRect.set(0, 0, width, height);
// Error?
if (isError) {
canvas.drawRect(fullRect, errorPaint);
} else {
// Background rounded rectangle
canvas.drawRect(fullRect, notdonePaint);
// Foreground progress indicator
if (progress > 0) {
progressRect.set(0, 0, width * ((float) progress / 100), height);
canvas.drawRect(progressRect, (isActive ? (progress == 100 ? donePaint : progressPaint)
: (progress == 100 ? inactiveDonePaint : inactivePaint)));
}
}
}
}

14
lite/src/org/transdroid/lite/gui/navigation/FilterAdapter.java

@ -2,7 +2,7 @@ package org.transdroid.lite.gui.navigation;
import java.util.List; import java.util.List;
import org.transdroid.lite.R; import org.transdroid.core.R;
import android.content.Context; import android.content.Context;
import android.view.View; import android.view.View;
@ -31,7 +31,7 @@ public class FilterAdapter extends MergeAdapter {
* Update the list of available servers. * Update the list of available servers.
* @param servers The new list of available servers * @param servers The new list of available servers
*/ */
public void updateServers(List<FilterItem> servers) { public void updateServers(List<? extends FilterItem> servers) {
if (this.serverItems == null && servers != null) { if (this.serverItems == null && servers != null) {
addView(FilterSeparatorView_.build(context).setText(context.getString(R.string.navigation_servers)), false); addView(FilterSeparatorView_.build(context).setText(context.getString(R.string.navigation_servers)), false);
this.serverItems = new FilterItemAdapter(context, servers); this.serverItems = new FilterItemAdapter(context, servers);
@ -47,7 +47,7 @@ public class FilterAdapter extends MergeAdapter {
* Update the list of available status types. * Update the list of available status types.
* @param statusTypes The new list of available status types * @param statusTypes The new list of available status types
*/ */
public void updateStatusTypes(List<FilterItem> statusTypes) { public void updateStatusTypes(List<? extends FilterItem> statusTypes) {
if (this.statusTypeItems == null && statusTypes != null) { if (this.statusTypeItems == null && statusTypes != null) {
addView(FilterSeparatorView_.build(context).setText(context.getString(R.string.navigation_status)), false); addView(FilterSeparatorView_.build(context).setText(context.getString(R.string.navigation_status)), false);
this.statusTypeItems = new FilterItemAdapter(context, statusTypes); this.statusTypeItems = new FilterItemAdapter(context, statusTypes);
@ -63,7 +63,7 @@ public class FilterAdapter extends MergeAdapter {
* Update the list of available labels. * Update the list of available labels.
* @param labels The new list of available labels * @param labels The new list of available labels
*/ */
public void updateLabels(List<FilterItem> labels) { public void updateLabels(List<? extends FilterItem> labels) {
if (this.labelItems == null && labels != null) { if (this.labelItems == null && labels != null) {
addView(FilterSeparatorView_.build(context).setText(context.getString(R.string.navigation_labels)), false); addView(FilterSeparatorView_.build(context).setText(context.getString(R.string.navigation_labels)), false);
this.labelItems = new FilterItemAdapter(context, labels); this.labelItems = new FilterItemAdapter(context, labels);
@ -78,9 +78,9 @@ public class FilterAdapter extends MergeAdapter {
protected class FilterItemAdapter extends BaseAdapter { protected class FilterItemAdapter extends BaseAdapter {
private final Context context; private final Context context;
private List<FilterItem> items; private List<? extends FilterItem> items;
public FilterItemAdapter(Context context, List<FilterItem> items) { public FilterItemAdapter(Context context, List<? extends FilterItem> items) {
this.context = context; this.context = context;
this.items = items; this.items = items;
} }
@ -89,7 +89,7 @@ public class FilterAdapter extends MergeAdapter {
* Allows updating of the full data list underlying this adapter, replacing all items * Allows updating of the full data list underlying this adapter, replacing all items
* @param newItems The new list of filter items to display * @param newItems The new list of filter items to display
*/ */
public void update(List<FilterItem> newItems) { public void update(List<? extends FilterItem> newItems) {
this.items = newItems; this.items = newItems;
notifyDataSetChanged(); notifyDataSetChanged();
} }

2
lite/src/org/transdroid/lite/gui/navigation/FilterItemView.java

@ -2,7 +2,7 @@ package org.transdroid.lite.gui.navigation;
import org.androidannotations.annotations.EViewGroup; import org.androidannotations.annotations.EViewGroup;
import org.androidannotations.annotations.ViewById; import org.androidannotations.annotations.ViewById;
import org.transdroid.lite.R; import org.transdroid.core.R;
import android.content.Context; import android.content.Context;
import android.widget.LinearLayout; import android.widget.LinearLayout;

2
lite/src/org/transdroid/lite/gui/navigation/FilterSeparatorView.java

@ -2,7 +2,7 @@ package org.transdroid.lite.gui.navigation;
import org.androidannotations.annotations.EViewGroup; import org.androidannotations.annotations.EViewGroup;
import org.androidannotations.annotations.ViewById; import org.androidannotations.annotations.ViewById;
import org.transdroid.lite.R; import org.transdroid.core.R;
import android.content.Context; import android.content.Context;
import android.widget.LinearLayout; import android.widget.LinearLayout;

20
lite/src/org/transdroid/lite/gui/navigation/Label.java

@ -0,0 +1,20 @@
package org.transdroid.lite.gui.navigation;
/**
* Represents some label that is active or available on the server.
* @author Eric Kok
*/
public class Label implements FilterItem {
private final String name;
public Label(String name) {
this.name = name;
}
@Override
public String getName() {
return this.name;
}
}

75
lite/src/org/transdroid/lite/gui/navigation/StatusType.java

@ -0,0 +1,75 @@
package org.transdroid.lite.gui.navigation;
import java.util.Arrays;
import java.util.List;
import org.transdroid.core.R;
import android.content.Context;
/**
* Enumeration of all status types, which filter the list of shown torrents based on transfer activity.
* @author Eric Kok
*/
public enum StatusType {
ShowAll {
StatusTypeFilter getFilterItem(Context context) {
return new StatusTypeFilter(context.getString(R.string.navigation_status_showall));
}
},
OnlyDownloading {
StatusTypeFilter getFilterItem(Context context) {
return new StatusTypeFilter(context.getString(R.string.navigation_status_onlydown));
}
},
OnlyUploading {
StatusTypeFilter getFilterItem(Context context) {
return new StatusTypeFilter(context.getString(R.string.navigation_status_onlyup));
}
},
OnlyActive {
StatusTypeFilter getFilterItem(Context context) {
return new StatusTypeFilter(context.getString(R.string.navigation_status_onlyactive));
}
},
OnlyInactive {
StatusTypeFilter getFilterItem(Context context) {
return new StatusTypeFilter(context.getString(R.string.navigation_status_onlyinactive));
}
};
/**
* Returns a list with all status types, represented as filter item that can be shown in the GUI.
* @param context The Android UI context, to access translations
* @return A list of filter items for all available status types
*/
public static List<StatusTypeFilter> getAllStatusTypes(Context context) {
return Arrays.asList(ShowAll.getFilterItem(context), OnlyDownloading.getFilterItem(context),
OnlyUploading.getFilterItem(context), OnlyActive.getFilterItem(context),
OnlyInactive.getFilterItem(context));
}
/**
* Every status type can return a filter item that represents it in the navigation
* @param context The Android UI context, to access translations
* @return A filter item object to show in the GUI
*/
abstract StatusTypeFilter getFilterItem(Context context);
public static class StatusTypeFilter implements FilterItem {
private final String name;
StatusTypeFilter(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}
}

164
lite/src/org/transdroid/lite/gui/settings/MainSettingsActivity.java

@ -0,0 +1,164 @@
package org.transdroid.lite.gui.settings;
import java.util.ArrayList;
import java.util.List;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.transdroid.core.R;
import org.transdroid.lite.app.search.SearchHelper;
import org.transdroid.lite.app.search.SearchSite;
import org.transdroid.lite.app.settings.ApplicationSettings;
import org.transdroid.lite.app.settings.RssfeedSetting;
import org.transdroid.lite.app.settings.ServerSetting;
import org.transdroid.lite.app.settings.WebsearchSetting;
import org.transdroid.lite.gui.settings.RssfeedPreference.OnRssfeedClickedListener;
import org.transdroid.lite.gui.settings.ServerPreference.OnServerClickedListener;
import org.transdroid.lite.gui.settings.WebsearchPreference.OnWebsearchClickedListener;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
/**
* The main activity that provides access to all application settings. It shows the configured serves, web search sites
* and RSS feeds along with other general settings.
* @author Eric Kok
*/
@EActivity
public class MainSettingsActivity extends SherlockPreferenceActivity {
@Bean
protected ApplicationSettings applicationSettings;
@Bean
protected SearchHelper searchHelper;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preference menu and attack actions
addPreferencesFromResource(R.xml.pref_main);
findPreference("header_addserver").setOnPreferenceClickListener(onAddServer);
findPreference("header_addwebsearch").setOnPreferenceClickListener(onAddWebsearch);
findPreference("header_rssfeed").setOnPreferenceClickListener(onAddRssfeed);
findPreference("header_background").setOnPreferenceClickListener(onBackgroundSettings);
findPreference("header_system").setOnPreferenceClickListener(onSystemSettings);
// Add existing servers
List<ServerSetting> servers = applicationSettings.getServerSettings();
for (ServerSetting serverSetting : servers) {
getPreferenceScreen().addPreference(
new ServerPreference(this).setServerSetting(serverSetting).setOnServerClickedListener(
onServerClicked));
}
// Add existing websearch sites
List<WebsearchSetting> websearches = applicationSettings.getWebsearchSettings();
for (WebsearchSetting websearchSetting : websearches) {
getPreferenceScreen().addPreference(
new WebsearchPreference(this).setWebsearchSetting(websearchSetting).setOnWebsearchClickedListener(
onWebsearchClicked));
}
// Add existing RSS feeds
List<RssfeedSetting> rssfeeds = applicationSettings.getRssfeedSettings();
for (RssfeedSetting rssfeedSetting : rssfeeds) {
getPreferenceScreen().addPreference(
new RssfeedPreference(this).setRssfeedSetting(rssfeedSetting).setOnRssfeedClickedListener(
onRssfeedClicked));
}
// Construct list of all available search sites, in-app and web
ListPreference setSite = (ListPreference) findPreference("header_setsearchsite");
// Retrieve the available in-app search sites (using the Torrent Search package)
List<SearchSite> searchsites = searchHelper.getAvailableSites();
List<String> siteNames = new ArrayList<String>(websearches.size() + searchsites.size());
List<String> siteValues = new ArrayList<String>(websearches.size() + searchsites.size());
for (SearchSite searchSite : searchsites) {
siteNames.add(searchSite.getName());
siteValues.add(searchSite.getKey());
}
for (WebsearchSetting websearch : websearches) {
siteNames.add(websearch.getName());
siteValues.add(websearch.getKey());
}
// Supply the Preference list names and values
setSite.setEntries(siteNames.toArray(new String[siteNames.size()]));
setSite.setEntryValues(siteValues.toArray(new String[siteValues.size()]));
}
@Override
public void onBuildHeaders(List<Header> target) {
// TODO: Add two-pane support in settings
super.onBuildHeaders(target);
}
private OnPreferenceClickListener onAddServer = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
ServerSettingsActivity_.intent(MainSettingsActivity.this).start();
return true;
}
};
private OnPreferenceClickListener onAddWebsearch = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
WebsearchSettingsActivity_.intent(MainSettingsActivity.this).start();
return true;
}
};
private OnPreferenceClickListener onAddRssfeed = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
RssfeedSettingsActivity_.intent(MainSettingsActivity.this).start();
return true;
}
};
private OnPreferenceClickListener onBackgroundSettings = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
OtherSettingsActivity_.intent(MainSettingsActivity.this).preferencesResourceID(R.xml.pref_notifications)
.start();
return true;
}
};
private OnPreferenceClickListener onSystemSettings = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
OtherSettingsActivity_.intent(MainSettingsActivity.this).preferencesResourceID(R.xml.pref_about).start();
return true;
}
};
private OnServerClickedListener onServerClicked = new OnServerClickedListener() {
@Override
public void onServerClicked(ServerSetting serverSetting) {
ServerSettingsActivity_.intent(MainSettingsActivity.this).key(serverSetting.getOrder()).start();
}
};
private OnWebsearchClickedListener onWebsearchClicked = new OnWebsearchClickedListener() {
@Override
public void onWebsearchClicked(WebsearchSetting websearchSetting) {
WebsearchSettingsActivity_.intent(MainSettingsActivity.this).key(websearchSetting.getOrder()).start();
}
};
private OnRssfeedClickedListener onRssfeedClicked = new OnRssfeedClickedListener() {
@Override
public void onRssfeedClicked(RssfeedSetting rssfeedSetting) {
RssfeedSettingsActivity_.intent(MainSettingsActivity.this).key(rssfeedSetting.getOrder()).start();
}
};
}

31
lite/src/org/transdroid/lite/gui/settings/OtherSettingsActivity.java

@ -0,0 +1,31 @@
package org.transdroid.lite.gui.settings;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.transdroid.lite.app.settings.ApplicationSettings;
import android.os.Bundle;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
@EActivity
public class OtherSettingsActivity extends SherlockPreferenceActivity {
@Extra
protected int preferencesResourceID;
@Bean
protected ApplicationSettings applicationSettings;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Just load the preferences from XML, of which the ID is supplied as extra
addPreferencesFromResource(preferencesResourceID);
}
}

59
lite/src/org/transdroid/lite/gui/settings/RssfeedPreference.java

@ -0,0 +1,59 @@
package org.transdroid.lite.gui.settings;
import org.transdroid.lite.app.settings.RssfeedSetting;
import android.content.Context;
import android.preference.Preference;
/**
* Represents a {@link RssfeedSetting} in a preferences screen.
* @author Eric Kok
*/
public class RssfeedPreference extends Preference {
private static final int ORDER_START = 201;
private RssfeedSetting rssfeedSetting;
private OnRssfeedClickedListener onRssfeedClickedListener = null;
public RssfeedPreference(Context context) {
super(context);
setOnPreferenceClickListener(onPreferenceClicked);
}
/**
* Set the RSS feed settings object that is bound to this preference item
* @param rssfeedSetting The RSS feed settings
* @return Itself, for method chaining
*/
public RssfeedPreference setRssfeedSetting(RssfeedSetting rssfeedSetting) {
this.rssfeedSetting = rssfeedSetting;
setTitle(rssfeedSetting.getName());
setOrder(ORDER_START + rssfeedSetting.getOrder());
return this;
}
/**
* Set a listener that will be notified of click events on this preference
* @param onRssfeedClickedListener The click listener to register
* @return Itself, for method chaining
*/
public RssfeedPreference setOnRssfeedClickedListener(OnRssfeedClickedListener onRssfeedClickedListener) {
this.onRssfeedClickedListener = onRssfeedClickedListener;
return this;
}
private OnPreferenceClickListener onPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onRssfeedClickedListener != null)
onRssfeedClickedListener.onRssfeedClicked(rssfeedSetting);
return true;
}
};
public interface OnRssfeedClickedListener {
public void onRssfeedClicked(RssfeedSetting rssfeedSetting);
}
}

46
lite/src/org/transdroid/lite/gui/settings/RssfeedSettingsActivity.java

@ -0,0 +1,46 @@
package org.transdroid.lite.gui.settings;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.transdroid.core.R;
import org.transdroid.lite.app.settings.ApplicationSettings;
import android.os.Bundle;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
/**
* Activity that allows for a configuration of some RSS feed. The key can be supplied to update an
* existing RSS feed setting instead of creating a new one.
* @author Eric Kok
*/
@EActivity
public class RssfeedSettingsActivity extends SherlockPreferenceActivity {
@Extra
protected int key = -1;
@Bean
protected ApplicationSettings applicationSettings;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the raw preferences to show in this screen
addPreferencesFromResource(R.xml.pref_rssfeed);
// Bind the preferences to the correct storage key, e.g. the first RSS feed setting stores its URL in the
// 'rssfeed_url_0' shared preferences field
if (key < 0) {
key = applicationSettings.getMaxRssfeed() + 1;
}
findPreference("rssfeed_name").setKey("rssfeed_name_" + key);
findPreference("rssfeed_url").setKey("rssfeed_url_" + key);
findPreference("rssfeed_reqauth").setKey("rssfeed_reqauth_" + key);
}
}

59
lite/src/org/transdroid/lite/gui/settings/ServerPreference.java

@ -0,0 +1,59 @@
package org.transdroid.lite.gui.settings;
import org.transdroid.lite.app.settings.ServerSetting;
import android.content.Context;
import android.preference.Preference;
/**
* Represents a {@link ServerSetting} in a preferences screen.
* @author Eric Kok
*/
public class ServerPreference extends Preference {
private static final int ORDER_START = 1;
private ServerSetting serverSetting;
private OnServerClickedListener onServerClickedListener = null;
public ServerPreference(Context context) {
super(context);
setOnPreferenceClickListener(onPreferenceClicked);
}
/**
* Set the server settings object that is bound to this preference item
* @param serverSetting The server settings
* @return Itself, for method chaining
*/
public ServerPreference setServerSetting(ServerSetting serverSetting) {
this.serverSetting = serverSetting;
setTitle(serverSetting.getHumanReadableIdentifier());
setOrder(ORDER_START + serverSetting.getOrder());
return this;
}
/**
* Set a listener that will be notified of click events on this preference
* @param onServerClickedListener The click listener to register
* @return Itself, for method chaining
*/
public ServerPreference setOnServerClickedListener(OnServerClickedListener onServerClickedListener) {
this.onServerClickedListener = onServerClickedListener;
return this;
}
private OnPreferenceClickListener onPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onServerClickedListener != null)
onServerClickedListener.onServerClicked(serverSetting);
return true;
}
};
public interface OnServerClickedListener {
public void onServerClicked(ServerSetting serverSetting);
}
}

94
lite/src/org/transdroid/lite/gui/settings/ServerSettingsActivity.java

@ -0,0 +1,94 @@
package org.transdroid.lite.gui.settings;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.transdroid.daemon.Daemon;
import org.transdroid.core.R;
import org.transdroid.lite.app.settings.ApplicationSettings;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceManager;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
/**
* Activity that allows for a configuration of a server. The key can be supplied to update an existing server setting
* instead of creating a new one.
* @author Eric Kok
*/
@EActivity
public class ServerSettingsActivity extends SherlockPreferenceActivity {
@Extra
protected int key = -1;
@Bean
protected ApplicationSettings applicationSettings;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the raw preferences to show in this screen
addPreferencesFromResource(R.xml.pref_server);
// Bind the preferences to the correct storage key, e.g. the first server setting stores its address in the
// 'server_address_0' shared preferences field
if (key < 0) {
key = applicationSettings.getMaxWebsearch() + 1;
}
findPreference("server_name").setKey("server_name_" + key);
findPreference("server_type").setKey("server_type_" + key);
findPreference("server_address").setKey("server_address_" + key);
findPreference("server_port").setKey("server_port_" + key);
findPreference("server_user").setKey("server_user_" + key);
findPreference("server_pass").setKey("server_pass_" + key);
findPreference("server_extrapass").setKey("server_extrapass_" + key);
findPreference("server_localaddress").setKey("server_localaddress_" + key);
findPreference("server_localnetwork").setKey("server_localnetwork_" + key);
findPreference("server_folder").setKey("server_folder_" + key);
findPreference("server_timeout").setKey("server_timeout_" + key);
findPreference("server_alamrfinished").setKey("server_alamrfinished_" + key);
findPreference("server_alarnew").setKey("server_alarnew_" + key);
findPreference("server_os").setKey("server_os_" + key);
findPreference("server_downloaddir").setKey("server_downloaddir_" + key);
findPreference("server_ftpurl").setKey("server_ftpurl_" + key);
findPreference("server_ftppass").setKey("server_ftppass_" + key);
findPreference("server_sslenabled").setKey("server_sslenabled_" + key);
findPreference("server_ssltrustall").setKey("server_ssltrustall_" + key);
findPreference("server_ssltrustkey").setKey("server_ssltrustkey_" + key);
// Monitor preference changes
getPreferenceScreen().setOnPreferenceChangeListener(onPreferenceChangeListener);
}
private OnPreferenceChangeListener onPreferenceChangeListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
updatePreferenceAvailability();
return true;
}
};
@SuppressWarnings("deprecation")
private void updatePreferenceAvailability() {
// Use daemon factory to see if the newly selected daemon supports the feature
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
Daemon daemonType = Daemon.fromCode(prefs.getString("server_type_" + key, null));
findPreference("server_extrapass_" + key).setEnabled(Daemon.supportsExtraPassword(daemonType));
findPreference("server_folder_" + key).setEnabled(daemonType == null? false: Daemon.supportsCustomFolder(daemonType));
findPreference("server_downloaddir_" + key).setEnabled(daemonType == null? false: Daemon.needsManualPathSpecified(daemonType));
//findPreference("server_ssltrustkey_" + key).setEnabled(sslValue && !sslTAValue);
// Adjust title texts accordingly
findPreference("server_folder_" + key).setTitle(daemonType == Daemon.rTorrent? R.string.pref_scgifolder: R.string.pref_folder);
}
}

59
lite/src/org/transdroid/lite/gui/settings/WebsearchPreference.java

@ -0,0 +1,59 @@
package org.transdroid.lite.gui.settings;
import org.transdroid.lite.app.settings.WebsearchSetting;
import android.content.Context;
import android.preference.Preference;
/**
* Represents a {@link WebsearchSetting} in a preferences screen.
* @author Eric Kok
*/
public class WebsearchPreference extends Preference {
private static final int ORDER_START = 102;
private WebsearchSetting websearchSetting;
private OnWebsearchClickedListener onWebsearchClickedListener = null;
public WebsearchPreference(Context context) {
super(context);
setOnPreferenceClickListener(onPreferenceClicked);
}
/**
* Set the websearch settings object that is bound to this preference item
* @param websearchSetting The websearch settings
* @return Itself, for method chaining
*/
public WebsearchPreference setWebsearchSetting(WebsearchSetting websearchSetting) {
this.websearchSetting = websearchSetting;
setTitle(websearchSetting.getName());
setOrder(ORDER_START + websearchSetting.getOrder());
return this;
}
/**
* Set a listener that will be notified of click events on this preference
* @param onWebsearchClickedListener The click listener to register
* @return Itself, for method chaining
*/
public WebsearchPreference setOnWebsearchClickedListener(OnWebsearchClickedListener onWebsearchClickedListener) {
this.onWebsearchClickedListener = onWebsearchClickedListener;
return this;
}
private OnPreferenceClickListener onPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onWebsearchClickedListener != null)
onWebsearchClickedListener.onWebsearchClicked(websearchSetting);
return true;
}
};
public interface OnWebsearchClickedListener {
public void onWebsearchClicked(WebsearchSetting serverSetting);
}
}

45
lite/src/org/transdroid/lite/gui/settings/WebsearchSettingsActivity.java

@ -0,0 +1,45 @@
package org.transdroid.lite.gui.settings;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.transdroid.core.R;
import org.transdroid.lite.app.settings.ApplicationSettings;
import android.os.Bundle;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
/**
* Activity that allows for a configuration of a web search site. The key can be supplied to update an existing web
* search site setting instead of creating a new one.
* @author Eric Kok
*/
@EActivity
public class WebsearchSettingsActivity extends SherlockPreferenceActivity {
@Extra
protected int key = -1;
@Bean
protected ApplicationSettings applicationSettings;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the raw preferences to show in this screen
addPreferencesFromResource(R.xml.pref_websearch);
// Bind the preferences to the correct storage key, e.g. the first site setting stores its URL in the
// 'websearch_baseurl_0' shared preferences field
if (key < 0) {
key = applicationSettings.getMaxWebsearch() + 1;
}
findPreference("websearch_name").setKey("websearch_name_" + key);
findPreference("websearch_baseurl").setKey("websearch_baseurl_" + key);
}
}
Loading…
Cancel
Save