From e01555ae5ff7865ad89b2e93915a7164411e2173 Mon Sep 17 00:00:00 2001 From: Eric Kok Date: Mon, 4 Mar 2013 23:34:46 +0100 Subject: [PATCH] Creating new preferences screens. --- external/ColorPickerPreference/.classpath | 8 + external/ColorPickerPreference/.gitattributes | 2 + external/ColorPickerPreference/.gitignore | 4 + external/ColorPickerPreference/.project | 33 + .../ColorPickerPreference/AndroidManifest.xml | 18 + external/ColorPickerPreference/CHANGELOG.rst | 26 + external/ColorPickerPreference/LICENSE | 15 + external/ColorPickerPreference/README.rst | 47 + external/ColorPickerPreference/proguard.cfg | 34 + .../ColorPickerPreference/project.properties | 12 + .../res/drawable-hdpi/icon.png | Bin 0 -> 4147 bytes .../res/drawable-ldpi/icon.png | Bin 0 -> 1723 bytes .../res/drawable-mdpi/icon.png | Bin 0 -> 2574 bytes .../res/layout-land/dialog_color_picker.xml | 77 ++ .../res/layout/dialog_color_picker.xml | 78 ++ .../res/values/integer.xml | 5 + .../res/values/strings.xml | 21 + .../res/xml/settings.xml | 32 + external/ColorPickerPreference/screen_1.png | Bin 0 -> 124593 bytes external/ColorPickerPreference/screen_2.png | Bin 0 -> 68429 bytes .../colorpicker/AlphaPatternDrawable.java | 128 +++ .../colorpicker/ColorPickerDialog.java | 142 +++ .../colorpicker/ColorPickerPanelView.java | 171 ++++ .../colorpicker/ColorPickerPreference.java | 287 ++++++ .../colorpicker/ColorPickerView.java | 952 ++++++++++++++++++ .../preference/colorpicker/Test.java | 43 + lite/.factorypath | 2 +- lite/.project | 2 +- lite/AndroidManifest.xml | 17 +- lite/project.properties | 1 + lite/res/drawable-hdpi/ic_priority_high.png | Bin 0 -> 1194 bytes lite/res/drawable-hdpi/ic_priority_low.png | Bin 0 -> 848 bytes lite/res/drawable-hdpi/ic_priority_normal.png | Bin 0 -> 1206 bytes lite/res/drawable-hdpi/ic_priority_off.png | Bin 0 -> 1118 bytes lite/res/layout/list_item_torrent.xml | 89 ++ lite/res/values/attrs.xml | 7 + lite/res/values/colors.xml | 1 + lite/res/values/strings.xml | 141 ++- lite/res/xml/pref_about.xml | 20 + lite/res/xml/pref_main.xml | 52 + lite/res/xml/pref_notifications.xml | 47 + lite/res/xml/pref_rssfeed.xml | 21 + lite/res/xml/pref_server.xml | 108 ++ lite/res/xml/pref_websearch.xml | 16 + .../view/SherlockListView.java | 337 +++++++ .../widget/CheckableRelativeLayout.java | 100 ++ .../fr/marvinlabs/widget/InertCheckBox.java | 70 ++ .../lite/app/search/SearchHelper.java | 109 ++ .../lite/app/search/SearchResult.java | 64 ++ .../lite/app/search/SearchSite.java | 40 + .../lite/app/settings/AboutSettings.java | 30 + .../app/settings/ApplicationSettings.java | 140 +++ .../app/settings/NotificationSettings.java | 97 ++ .../lite/app/settings/RssfeedSetting.java | 67 ++ .../lite/app/settings/ServerSetting.java | 195 ++++ .../lite/app/settings/WebsearchSetting.java | 48 + .../transdroid/lite/gui/DetailsFagment.java | 2 +- .../transdroid/lite/gui/TorrentsActivity.java | 26 +- .../transdroid/lite/gui/TorrentsFragment.java | 2 +- .../lite/gui/lists/TorrentProgressBar.java | 110 ++ .../lite/gui/navigation/FilterAdapter.java | 14 +- .../lite/gui/navigation/FilterItemView.java | 2 +- .../gui/navigation/FilterSeparatorView.java | 2 +- .../transdroid/lite/gui/navigation/Label.java | 20 + .../lite/gui/navigation/StatusType.java | 75 ++ .../gui/settings/MainSettingsActivity.java | 164 +++ .../gui/settings/OtherSettingsActivity.java | 31 + .../lite/gui/settings/RssfeedPreference.java | 59 ++ .../gui/settings/RssfeedSettingsActivity.java | 46 + .../lite/gui/settings/ServerPreference.java | 59 ++ .../gui/settings/ServerSettingsActivity.java | 94 ++ .../gui/settings/WebsearchPreference.java | 59 ++ .../settings/WebsearchSettingsActivity.java | 45 + 73 files changed, 4740 insertions(+), 26 deletions(-) create mode 100644 external/ColorPickerPreference/.classpath create mode 100644 external/ColorPickerPreference/.gitattributes create mode 100644 external/ColorPickerPreference/.gitignore create mode 100644 external/ColorPickerPreference/.project create mode 100644 external/ColorPickerPreference/AndroidManifest.xml create mode 100644 external/ColorPickerPreference/CHANGELOG.rst create mode 100644 external/ColorPickerPreference/LICENSE create mode 100644 external/ColorPickerPreference/README.rst create mode 100644 external/ColorPickerPreference/proguard.cfg create mode 100644 external/ColorPickerPreference/project.properties create mode 100644 external/ColorPickerPreference/res/drawable-hdpi/icon.png create mode 100644 external/ColorPickerPreference/res/drawable-ldpi/icon.png create mode 100644 external/ColorPickerPreference/res/drawable-mdpi/icon.png create mode 100644 external/ColorPickerPreference/res/layout-land/dialog_color_picker.xml create mode 100644 external/ColorPickerPreference/res/layout/dialog_color_picker.xml create mode 100644 external/ColorPickerPreference/res/values/integer.xml create mode 100644 external/ColorPickerPreference/res/values/strings.xml create mode 100644 external/ColorPickerPreference/res/xml/settings.xml create mode 100644 external/ColorPickerPreference/screen_1.png create mode 100644 external/ColorPickerPreference/screen_2.png create mode 100644 external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java create mode 100644 external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerDialog.java create mode 100644 external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java create mode 100644 external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPreference.java create mode 100644 external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerView.java create mode 100644 external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/Test.java create mode 100644 lite/res/drawable-hdpi/ic_priority_high.png create mode 100644 lite/res/drawable-hdpi/ic_priority_low.png create mode 100644 lite/res/drawable-hdpi/ic_priority_normal.png create mode 100644 lite/res/drawable-hdpi/ic_priority_off.png create mode 100644 lite/res/layout/list_item_torrent.xml create mode 100644 lite/res/values/attrs.xml create mode 100644 lite/res/xml/pref_about.xml create mode 100644 lite/res/xml/pref_main.xml create mode 100644 lite/res/xml/pref_notifications.xml create mode 100644 lite/res/xml/pref_rssfeed.xml create mode 100644 lite/res/xml/pref_server.xml create mode 100644 lite/res/xml/pref_websearch.xml create mode 100644 lite/src/com/actionbarsherlock/view/SherlockListView.java create mode 100644 lite/src/fr/marvinlabs/widget/CheckableRelativeLayout.java create mode 100644 lite/src/fr/marvinlabs/widget/InertCheckBox.java create mode 100644 lite/src/org/transdroid/lite/app/search/SearchHelper.java create mode 100644 lite/src/org/transdroid/lite/app/search/SearchResult.java create mode 100644 lite/src/org/transdroid/lite/app/search/SearchSite.java create mode 100644 lite/src/org/transdroid/lite/app/settings/AboutSettings.java create mode 100644 lite/src/org/transdroid/lite/app/settings/ApplicationSettings.java create mode 100644 lite/src/org/transdroid/lite/app/settings/NotificationSettings.java create mode 100644 lite/src/org/transdroid/lite/app/settings/RssfeedSetting.java create mode 100644 lite/src/org/transdroid/lite/app/settings/ServerSetting.java create mode 100644 lite/src/org/transdroid/lite/app/settings/WebsearchSetting.java create mode 100644 lite/src/org/transdroid/lite/gui/lists/TorrentProgressBar.java create mode 100644 lite/src/org/transdroid/lite/gui/navigation/Label.java create mode 100644 lite/src/org/transdroid/lite/gui/navigation/StatusType.java create mode 100644 lite/src/org/transdroid/lite/gui/settings/MainSettingsActivity.java create mode 100644 lite/src/org/transdroid/lite/gui/settings/OtherSettingsActivity.java create mode 100644 lite/src/org/transdroid/lite/gui/settings/RssfeedPreference.java create mode 100644 lite/src/org/transdroid/lite/gui/settings/RssfeedSettingsActivity.java create mode 100644 lite/src/org/transdroid/lite/gui/settings/ServerPreference.java create mode 100644 lite/src/org/transdroid/lite/gui/settings/ServerSettingsActivity.java create mode 100644 lite/src/org/transdroid/lite/gui/settings/WebsearchPreference.java create mode 100644 lite/src/org/transdroid/lite/gui/settings/WebsearchSettingsActivity.java diff --git a/external/ColorPickerPreference/.classpath b/external/ColorPickerPreference/.classpath new file mode 100644 index 00000000..a4763d1e --- /dev/null +++ b/external/ColorPickerPreference/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/external/ColorPickerPreference/.gitattributes b/external/ColorPickerPreference/.gitattributes new file mode 100644 index 00000000..dfe07704 --- /dev/null +++ b/external/ColorPickerPreference/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/external/ColorPickerPreference/.gitignore b/external/ColorPickerPreference/.gitignore new file mode 100644 index 00000000..4b1a60ae --- /dev/null +++ b/external/ColorPickerPreference/.gitignore @@ -0,0 +1,4 @@ +/bin +/gen +.classpath +.project \ No newline at end of file diff --git a/external/ColorPickerPreference/.project b/external/ColorPickerPreference/.project new file mode 100644 index 00000000..b3e7744d --- /dev/null +++ b/external/ColorPickerPreference/.project @@ -0,0 +1,33 @@ + + + ColorPickerPreference + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/external/ColorPickerPreference/AndroidManifest.xml b/external/ColorPickerPreference/AndroidManifest.xml new file mode 100644 index 00000000..e09215a9 --- /dev/null +++ b/external/ColorPickerPreference/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/ColorPickerPreference/CHANGELOG.rst b/external/ColorPickerPreference/CHANGELOG.rst new file mode 100644 index 00000000..5342d2ac --- /dev/null +++ b/external/ColorPickerPreference/CHANGELOG.rst @@ -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 \ No newline at end of file diff --git a/external/ColorPickerPreference/LICENSE b/external/ColorPickerPreference/LICENSE new file mode 100644 index 00000000..da9cd5cb --- /dev/null +++ b/external/ColorPickerPreference/LICENSE @@ -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. + */ \ No newline at end of file diff --git a/external/ColorPickerPreference/README.rst b/external/ColorPickerPreference/README.rst new file mode 100644 index 00000000..bffa417a --- /dev/null +++ b/external/ColorPickerPreference/README.rst @@ -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 + +:: + + + alphaSlider="true" + /> + +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 \ No newline at end of file diff --git a/external/ColorPickerPreference/proguard.cfg b/external/ColorPickerPreference/proguard.cfg new file mode 100644 index 00000000..8ad7d335 --- /dev/null +++ b/external/ColorPickerPreference/proguard.cfg @@ -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 ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (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 *; +} diff --git a/external/ColorPickerPreference/project.properties b/external/ColorPickerPreference/project.properties new file mode 100644 index 00000000..616f300c --- /dev/null +++ b/external/ColorPickerPreference/project.properties @@ -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 diff --git a/external/ColorPickerPreference/res/drawable-hdpi/icon.png b/external/ColorPickerPreference/res/drawable-hdpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8074c4c571b8cd19e27f4ee5545df367420686d7 GIT binary patch literal 4147 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 literal 0 HcmV?d00001 diff --git a/external/ColorPickerPreference/res/drawable-ldpi/icon.png b/external/ColorPickerPreference/res/drawable-ldpi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1095584ec21f71cd0afc9e0993aa2209671b590c GIT binary patch literal 1723 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 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/ColorPickerPreference/res/layout/dialog_color_picker.xml b/external/ColorPickerPreference/res/layout/dialog_color_picker.xml new file mode 100644 index 00000000..00ee3753 --- /dev/null +++ b/external/ColorPickerPreference/res/layout/dialog_color_picker.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/ColorPickerPreference/res/values/integer.xml b/external/ColorPickerPreference/res/values/integer.xml new file mode 100644 index 00000000..e3626064 --- /dev/null +++ b/external/ColorPickerPreference/res/values/integer.xml @@ -0,0 +1,5 @@ + + + 0xff000000 + 0xff00ff00 + \ No newline at end of file diff --git a/external/ColorPickerPreference/res/values/strings.xml b/external/ColorPickerPreference/res/values/strings.xml new file mode 100644 index 00000000..251a66f4 --- /dev/null +++ b/external/ColorPickerPreference/res/values/strings.xml @@ -0,0 +1,21 @@ + + + + Hello World, Main! + ColorPickerPreference + + + Color Picker + Press on Color to apply + + + Category + Color 1 + black color by default, set by reference + Color 2 + not persistent color\nalpha slider added via code + Color 3 + picker with alpha slider + Color 4 + color set with HEX code in xml + diff --git a/external/ColorPickerPreference/res/xml/settings.xml b/external/ColorPickerPreference/res/xml/settings.xml new file mode 100644 index 00000000..0cd87af9 --- /dev/null +++ b/external/ColorPickerPreference/res/xml/settings.xml @@ -0,0 +1,32 @@ + + + + + + + + + \ No newline at end of file diff --git a/external/ColorPickerPreference/screen_1.png b/external/ColorPickerPreference/screen_1.png new file mode 100644 index 0000000000000000000000000000000000000000..4798dae717ac258baec0c388b218221f258415b7 GIT binary patch literal 124593 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∋XWxe#A7 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 literal 0 HcmV?d00001 diff --git a/external/ColorPickerPreference/screen_2.png b/external/ColorPickerPreference/screen_2.png new file mode 100644 index 0000000000000000000000000000000000000000..3bb2d671930d3c5e8557bcda386bb0f0146d3c24 GIT binary patch literal 68429 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 z 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 Z5vG4mEL+W+cOig(veHT~izJN${}25Pibwze literal 0 HcmV?d00001 diff --git a/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java new file mode 100644 index 00000000..ff9c3c84 --- /dev/null +++ b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java @@ -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; + + } + + } + +} \ No newline at end of file diff --git a/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerDialog.java b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerDialog.java new file mode 100644 index 00000000..a63d48c3 --- /dev/null +++ b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerDialog.java @@ -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); + } +} diff --git a/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java new file mode 100644 index 00000000..b0003662 --- /dev/null +++ b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java @@ -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; + } + +} \ No newline at end of file diff --git a/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPreference.java b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPreference.java new file mode 100644 index 00000000..8dded67a --- /dev/null +++ b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerPreference.java @@ -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 CREATOR = + new Parcelable.Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } +} \ No newline at end of file diff --git a/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerView.java b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerView.java new file mode 100644 index 00000000..c0ec0531 --- /dev/null +++ b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/ColorPickerView.java @@ -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; + } +} \ No newline at end of file diff --git a/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/Test.java b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/Test.java new file mode 100644 index 00000000..e5e167d9 --- /dev/null +++ b/external/ColorPickerPreference/src/net/margaritov/preference/colorpicker/Test.java @@ -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); + } +} \ No newline at end of file diff --git a/lite/.factorypath b/lite/.factorypath index 026446ed..d528d92e 100644 --- a/lite/.factorypath +++ b/lite/.factorypath @@ -1,3 +1,3 @@ - + diff --git a/lite/.project b/lite/.project index 0654bfb6..1b341fee 100644 --- a/lite/.project +++ b/lite/.project @@ -1,6 +1,6 @@ - TransdroidLite + Transdroid Core diff --git a/lite/AndroidManifest.xml b/lite/AndroidManifest.xml index 1b6f7500..e33579dd 100644 --- a/lite/AndroidManifest.xml +++ b/lite/AndroidManifest.xml @@ -1,13 +1,20 @@ + android:versionName="2.0-alpha1" > + + + + + + + + \ No newline at end of file diff --git a/lite/project.properties b/lite/project.properties index 5f7d115e..b8863ad3 100644 --- a/lite/project.properties +++ b/lite/project.properties @@ -13,3 +13,4 @@ # Project target. target=android-16 android.library.reference.1=../external/JakeWharton-ActionBarSherlock/library +android.library.reference.2=../external/ColorPickerPreference diff --git a/lite/res/drawable-hdpi/ic_priority_high.png b/lite/res/drawable-hdpi/ic_priority_high.png new file mode 100644 index 0000000000000000000000000000000000000000..43dd253bdeda94a1b5cbad49239b4591a03816e3 GIT binary patch literal 1194 zcmV;b1XcTqP)c5e|e! zygOM$9-$!2{F*bsGl)3iEk^>8=IhmqtP>LxfsKugA512bkWwnm&CM@{hldwuW@a8O zE-ro#ERPWP;dE+hYJMCU83{1~EeZ)tLqkKm=jZ3%Y&Khdd3h;LPEMWykM#HV|GBrf z=K)@3gkM}-h||;4=fGbgQXFZmTGQz0sIv$s8jZTlW^-F{aj{6HQm$k&8Et84x!&L3 zw}9!VM!4N>7l}l|eRg*CM|*qw`F|5g{*dhI>I&y@N=r)x{Rj!ar4oC3dX^r-T`rd> zDJc<0M@LUdZiJm*P1GYwkfbKHwzghcES6tUg>bvwA{LAJcXxN4b#--bQQ*1}j^Bu~ zvN8d=x+0NCl`erC1ze)J3lHH`0TRiTm6bu@MI35> zCEJX2OQ3nbL+4|XfaE}9zmCV_Imoe(8@(~Y6-7~#+}_^y-`w0-IDu75kmUsAWzsaP zu|?VL+1Xh?UF`LG7aqbL4u?RZ52mK3dRZnLRUz50g(~{``sTqdMr=vn!^6WMeIE=4 ze*+#j!l??I%_iWcL2fWrVUawU8O=>TpD$*$TIXR9^#`zE^V-_lM`&aQ>|Yt-m^ZaL zRP!hl3N`UoFl!0&x(O8Z_4TvRQqW{Ooldc}we^@-!T$^I!^vqoJ3E8iWGThJN73HE zh96?GMLL~UZv>tHA`-xT{|B$Csyb!Tg@q+qH+9)*}kH&u`$Gsqy!mF8g++YpA=tR zT?Of48Yr;c^ZWg8ps#}Hc?ieapvt1KZIoxKkU(Q^A0HnlSCkM->H+pVv9wH1PJRK_ z4kMfrkp5_Hn4Os5DzauyKtmyqkB`42jd|zX^!E0?CKhP=6C<3oC-z8mJuoovO3$8# zSZeIY#>PH_%|0QPbTe3R3HwEvo}O;NP}LgYl$0hL>-?q1<4Nk-YtIAKL9m)?O#KXBAJSYKZ+2a7MUCPYO=1vT<@Q&ZC=Bq&Ge0jzOD zoSp@cEz;T9NkbRY$x|4#?7_i-udS`^1zil55=~qJev1jM>*(m1$M_Q)c!p)U<4EW$_(y;N0Oit~VznlB0RR9107*qo IM6N<$f*+ME#{d8T literal 0 HcmV?d00001 diff --git a/lite/res/drawable-hdpi/ic_priority_low.png b/lite/res/drawable-hdpi/ic_priority_low.png new file mode 100644 index 0000000000000000000000000000000000000000..fa8e7bfb7096ff45090d417ee242cdd5999e3189 GIT binary patch literal 848 zcmV-W1F!svP)k7RCwB) zR!eIdQ53#2j_*gT!J>jBfyU5HCEaA9-AD_?EOa4Fmi-r9`U~7g7ug$z(hxTmq#Kh} z=*plF;zq1ekVslz<70ZxaHdR4X4G8x7`PYjcfRjDuAD5(?7w9KSOHFeo4#hi0x$yn zCX4}7+SgseBYPa}Tk`q*o2#pR%^_xsPiUM~xW!^~>6ZWRiJ12}V#je@}) zx&$bBM$t{;@wm8v1!T|z*+v!ckBY;?!_sIp8lnoQCf07Z zGZeXv8j*iYg%N?Qt)@^YG_+VOC2Tl{!@)q!t75VEk}iLe0$F1fg6;0^eg^Lub~g4# zy7W`RJUWz@yXMg>O!n8*fJtJN|XJ>~&=Z<0tP z&dEk~Cdun4;MJjri4;X~YcLobKpvDs=!Z%q61k^_)SasQlIYD;hSqYqe8ls-l3?g& zwzs!eqzapminSDQWQ{U&VE#CIyp}wb zACfDQ?_*M-JFDK zT)-PKSta^q3X}@EzP`=~f}jjJj1=DoihjJxi>CJ`E4aM8+=Qs#!kAFr0!VH(7K{CW zv!TYGwHl4nPSe}l+tB|0{ujI)8jA&k!4mBMB7&v%C>I+1ZL!ne7CR+et(pO0yo!Q9 a0t^6}Z64v69v9sJ0000Z!BR+B{h!i3#@|KaW+KSe#n{+bfB|Sxw1Bn@BO@bw=jZ3HOeRwqjYh@E$;or%!-Io^ zf9>z@S0i6>ad9C|PfveD{xu@WketSg~N^z`%uvsk62rNU;jiAW^!Jw4Rd z*SAc0fDk1mCF1Dl=o!h1u<_Nva^ESCV|oc{UPnhq6v%%w8jXSw$6_(>-rkAv6Z{~h@_v4ESz+1c4JBe(Jal{FUm1#)^f!Im+z*}Mefs2eGY(zd?7{skJG z2CKI;1&AHkJPZT^t-SeX8RT?QQHZ9drg>;A=wv&cPO-hc{e;lAx3|C1^5nGL-Q8i` z=29^RLN_|p1$%mMvPCMDQVT%;zX=5LZhgMCw)Qmt6c-v55*IaS!)|A1XPC|doJwC4 zKA-PbVz;%m^;G=<`Tz+Ny}iA!SYB-=O;x!7dK25tg6a8;G$uPzLrHgfZed~JJ1WTb6)i0-0d`)3 zSrlX-u{7#z!JM&QUS9fX6FO*MvG4VI-$Qo^(MNfV4Pq97Z6kbk^abuP(4)6aOiYkl zN(epm0P~;Fo2I9yzXBTv6(If5+#u_&FpFCw+n9%5JM!}J@$nC&Jgtw||Az|{lt)FL_qWBye_L$aaQ$qOb&+OSZa9=;4E_~h04tH% U;?bhnUH||907*qoM6N<$f-v$pApigX literal 0 HcmV?d00001 diff --git a/lite/res/drawable-hdpi/ic_priority_off.png b/lite/res/drawable-hdpi/ic_priority_off.png new file mode 100644 index 0000000000000000000000000000000000000000..e44ea25ab7e1d2755da9b4e84b41ee893bd678c9 GIT binary patch literal 1118 zcmV-k1flzhP)f-3#5{t#$+uPfs`Xd+&#)gN7|IkJR zu+PrUzRqT|Pw>Ai%S;r-4}m}+K{}keR|}wm7zPIiZz7S%+d`pW!wAFSuoVDSDFR_@ zYs++5Sjd|p-c zH#aw5f>FMsqk|!U!{PYU(9nRMmo=g+USn4#-q6cZPft%2LvLG=5A zc6oUjM8j4qrim3MCMLcRH6^l95ui*zQ87O?HFXHjU*Mf$=9m+kCLL#IXRlP_xI7+DnDp}mAXfuWX_9Ee z&G`8E1|+(KbbvwI!otEk@ZN=h7?sgzjE{_r9D#0*_DE!dRRbuKl0s8&Z*Q9C`S19n zrKN>6H8s7!#G-M?3+w9Y3RA@SO8i#?kTo<(ot>T0d_K=iCX-@V%?SV>`Fy@OabKW4 zvc4ku3RNm=b1^+V{R3!9p~qNNKoJuJ0jn!a`UQ>mtQLU(N*1`6LDnz|=nF*v@UPeF zT_-vv(v|h}RBbfq;DeKdvmA~07u`9G>V0TgM%Pc z46|4)N^((P4zXgf=viJ~_Rv^2Ya)3RKp?LydwYBJK*yNPW@9L=t*sjfgk6k4`}_ML zRhOLN^-=H@0Pg@+R#tqtvA(_@>B-H^%-~2)s!?Pz88IG@J9SZ11>iK?qeqxrKk|(N zUdP(n+Hx>9K4YRWBIpTYG#U+R0Pf|Y5`f}8BzFLk>qhUf_WSz!)=0F)9GXv7Z)K-1#%Ca$;z3qv$NASG&J-Lrl-8>p%x{f&LDUjDUBqh>QuQnFi kt6p0&bT-^wTmA_!0Qk+80bDP1`~Uy|07*qoM6N<$f-8Rf$^ZZW literal 0 HcmV?d00001 diff --git a/lite/res/layout/list_item_torrent.xml b/lite/res/layout/list_item_torrent.xml new file mode 100644 index 00000000..4041e535 --- /dev/null +++ b/lite/res/layout/list_item_torrent.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/lite/res/values/attrs.xml b/lite/res/values/attrs.xml new file mode 100644 index 00000000..a19eb9b9 --- /dev/null +++ b/lite/res/values/attrs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/lite/res/values/colors.xml b/lite/res/values/colors.xml index ba2e342f..f4cdf7fa 100644 --- a/lite/res/values/colors.xml +++ b/lite/res/values/colors.xml @@ -1,4 +1,5 @@ #8acc12 + #7dbb21 diff --git a/lite/res/values/strings.xml b/lite/res/values/strings.xml index ce8d9e9b..780a7fcf 100644 --- a/lite/res/values/strings.xml +++ b/lite/res/values/strings.xml @@ -1,7 +1,7 @@ - Transdroid Lite + Transdroid Add From file @@ -21,7 +21,6 @@ Ratio Filter list Settings - Start Stop Resume @@ -41,7 +40,143 @@ SERVERS STATUS LABELS + All + Downloading + Uploading + Active + Inactive Connected, but no torrent are active on the server Select a torrent to view its details - + Servers + Add new server + Search sites + Set default site + Add web search site + RSS feeds + Add RSS feed + Other settings + + Name + Optional personal name + Direct search URL + %s will be replaced by the search query + Feed URL + Requires authentication + Opens links in the webbrowser for user login + + Server type + IP or host name + Port number + User name + Password + Deluge web password + Advanced settings + Local IP or host + When connected to the specified local network + Local network + The server\'s local (wifi) network + Folder + Usually empty + SCGI mount point + Optional settings + Finished notification + Notify when a torrent finishes + New torrent notification + Nofity when a torrent was added + Server OS + Download directory + Manually set absolute path for remote connections + Connection timeout + Number of seconds before a connection attempt is aborted + Base (S)FTP url + For example ftp://me@server/downloads/ + (S)FTP password + Use SSL + Connect using https + Custom SSL thumbprint (SHA-1) + Permit only connections to this specific certificate + Accept all SSL certificates + Allow all connections from any thumbprint + + Background notifications + Enable notifications + Enables the background service + Interval + How often to check the server + Sound + Vibrate + LED colour + If supported by your device + Support AWD notifications + Show torrent counter in ADW Launcher + + About Transdroid + Check for updates + Check transdroidorg for latest app version + Import settings + Export settings + Send error log + Get support or report a bug + About + + + BitComet + Bitflu 1.2+ + BitTorrent 6+ + Buffalo NAS -1.31 + Deluge 1.2+ + DLink Router BT + Ktorrent + qBittorrent + rTorrent + Torrentflux-b4rt + Transmission + µTorrent + Vuze + + + daemon_bitcomet + daemon_bitflu + daemon_bittorrent + daemon_buffalonas + daemon_deluge + daemon_dlinkrouterbt + daemon_ktorrent + daemon_qbittorrent + daemon_rtorrent + daemon_tfb4rt + daemon_transmission + daemon_utorrent + daemon_vuze + + + Windows + Mac + Linux + + + type_windows + type_mac + type_linux + + + 1 minute + 10 minutes + 30 minutes + 1 hour + 3 hours + 12 hours + 1 day + + + 60 + 600 + 1800 + 3600 + 10800 + 43200 + 86400 + + + \ No newline at end of file diff --git a/lite/res/xml/pref_about.xml b/lite/res/xml/pref_about.xml new file mode 100644 index 00000000..eb4dad12 --- /dev/null +++ b/lite/res/xml/pref_about.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/lite/res/xml/pref_main.xml b/lite/res/xml/pref_main.xml new file mode 100644 index 00000000..19f3bf36 --- /dev/null +++ b/lite/res/xml/pref_main.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lite/res/xml/pref_notifications.xml b/lite/res/xml/pref_notifications.xml new file mode 100644 index 00000000..4a7a1a16 --- /dev/null +++ b/lite/res/xml/pref_notifications.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lite/res/xml/pref_rssfeed.xml b/lite/res/xml/pref_rssfeed.xml new file mode 100644 index 00000000..401c5aea --- /dev/null +++ b/lite/res/xml/pref_rssfeed.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lite/res/xml/pref_server.xml b/lite/res/xml/pref_server.xml new file mode 100644 index 00000000..9512a302 --- /dev/null +++ b/lite/res/xml/pref_server.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lite/res/xml/pref_websearch.xml b/lite/res/xml/pref_websearch.xml new file mode 100644 index 00000000..09674685 --- /dev/null +++ b/lite/res/xml/pref_websearch.xml @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/lite/src/com/actionbarsherlock/view/SherlockListView.java b/lite/src/com/actionbarsherlock/view/SherlockListView.java new file mode 100644 index 00000000..3b2df828 --- /dev/null +++ b/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 true if the item is now checked, false 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. + *

+ * (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(); + } +} diff --git a/lite/src/fr/marvinlabs/widget/CheckableRelativeLayout.java b/lite/src/fr/marvinlabs/widget/CheckableRelativeLayout.java new file mode 100644 index 00000000..e8e92e9a --- /dev/null +++ b/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 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(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)); + } + } + } +} diff --git a/lite/src/fr/marvinlabs/widget/InertCheckBox.java b/lite/src/fr/marvinlabs/widget/InertCheckBox.java new file mode 100644 index 00000000..5dd3080b --- /dev/null +++ b/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; + } +} diff --git a/lite/src/org/transdroid/lite/app/search/SearchHelper.java b/lite/src/org/transdroid/lite/app/search/SearchHelper.java new file mode 100644 index 00000000..11244a19 --- /dev/null +++ b/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 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 sites = new ArrayList(); + 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 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 results = new ArrayList(); + 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; + + } + +} diff --git a/lite/src/org/transdroid/lite/app/search/SearchResult.java b/lite/src/org/transdroid/lite/app/search/SearchResult.java new file mode 100644 index 00000000..77594909 --- /dev/null +++ b/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; + } + +} diff --git a/lite/src/org/transdroid/lite/app/search/SearchSite.java b/lite/src/org/transdroid/lite/app/search/SearchSite.java new file mode 100644 index 00000000..2d7910df --- /dev/null +++ b/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; + } + +} diff --git a/lite/src/org/transdroid/lite/app/settings/AboutSettings.java b/lite/src/org/transdroid/lite/app/settings/AboutSettings.java new file mode 100644 index 00000000..9dd745c7 --- /dev/null +++ b/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); + } + +} diff --git a/lite/src/org/transdroid/lite/app/settings/ApplicationSettings.java b/lite/src/org/transdroid/lite/app/settings/ApplicationSettings.java new file mode 100644 index 00000000..75a4c09e --- /dev/null +++ b/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 getServerSettings() { + List servers = new ArrayList(); + 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 getWebsearchSettings() { + List websearches = new ArrayList(); + 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 getRssfeedSettings() { + List rssfeeds = new ArrayList(); + 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)); + } + +} diff --git a/lite/src/org/transdroid/lite/app/settings/NotificationSettings.java b/lite/src/org/transdroid/lite/app/settings/NotificationSettings.java new file mode 100644 index 00000000..1a68aabd --- /dev/null +++ b/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); + } + +} diff --git a/lite/src/org/transdroid/lite/app/settings/RssfeedSetting.java b/lite/src/org/transdroid/lite/app/settings/RssfeedSetting.java new file mode 100644 index 00000000..69ee3823 --- /dev/null +++ b/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; + } + +} diff --git a/lite/src/org/transdroid/lite/app/settings/ServerSetting.java b/lite/src/org/transdroid/lite/app/settings/ServerSetting.java new file mode 100644 index 00000000..164be4ad --- /dev/null +++ b/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() : ""); + } + +} diff --git a/lite/src/org/transdroid/lite/app/settings/WebsearchSetting.java b/lite/src/org/transdroid/lite/app/settings/WebsearchSetting.java new file mode 100644 index 00000000..b4da7aed --- /dev/null +++ b/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(); + } + +} diff --git a/lite/src/org/transdroid/lite/gui/DetailsFagment.java b/lite/src/org/transdroid/lite/gui/DetailsFagment.java index 1b3c7e10..c43b8135 100644 --- a/lite/src/org/transdroid/lite/gui/DetailsFagment.java +++ b/lite/src/org/transdroid/lite/gui/DetailsFagment.java @@ -7,7 +7,7 @@ import org.androidannotations.annotations.InstanceState; import org.androidannotations.annotations.ViewById; import org.transdroid.daemon.Torrent; import org.transdroid.daemon.TorrentDetails; -import org.transdroid.lite.R; +import org.transdroid.core.R; import android.view.View; import android.widget.TextView; diff --git a/lite/src/org/transdroid/lite/gui/TorrentsActivity.java b/lite/src/org/transdroid/lite/gui/TorrentsActivity.java index f368bc94..1af298df 100644 --- a/lite/src/org/transdroid/lite/gui/TorrentsActivity.java +++ b/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.EActivity; import org.androidannotations.annotations.FragmentById; -import org.androidannotations.annotations.FragmentByTag; import org.androidannotations.annotations.ItemSelect; import org.androidannotations.annotations.OptionsMenu; 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.FilterItem; -import org.transdroid.lite.gui.navigation.FilterSeparatorView; import org.transdroid.lite.gui.navigation.NavigationHelper; +import org.transdroid.lite.gui.navigation.StatusType; import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar.OnNavigationListener; @@ -30,6 +30,10 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi protected SherlockListView filtersList; protected FilterAdapter navigationListAdapter = null; protected FilterAdapter navigationSpinnerAdapter = null; + + // Settings + @Bean + protected ApplicationSettings applicationSettings; // Torrents list components @FragmentById(R.id.torrent_list) @@ -42,17 +46,23 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi @AfterViews 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().setHomeButtonEnabled(false); navigationSpinnerAdapter = new FilterAdapter(this); + // Servers are always added to the action bar spinner + navigationSpinnerAdapter.updateServers(applicationSettings.getServerSettings()); getSupportActionBar().setListNavigationCallbacks(navigationSpinnerAdapter, this); if (filtersList != null) { + // There was room for a dedicated filter list; add the status types navigationListAdapter = new FilterAdapter(this); 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 - * @param selected True if - * @param item + * @param selected True if the filter item was selected, false if it was deselected + * @param item The touched filter item */ @ItemSelect(R.id.filters_list) protected void filterSelected(boolean selected, FilterItem item) { - // TODO: Update the view + // TODO: Update the torrent list view } } diff --git a/lite/src/org/transdroid/lite/gui/TorrentsFragment.java b/lite/src/org/transdroid/lite/gui/TorrentsFragment.java index f53a9e1d..5dd796bb 100644 --- a/lite/src/org/transdroid/lite/gui/TorrentsFragment.java +++ b/lite/src/org/transdroid/lite/gui/TorrentsFragment.java @@ -1,7 +1,7 @@ package org.transdroid.lite.gui; import org.androidannotations.annotations.EFragment; -import org.transdroid.lite.R; +import org.transdroid.core.R; import com.actionbarsherlock.app.SherlockFragment; diff --git a/lite/src/org/transdroid/lite/gui/lists/TorrentProgressBar.java b/lite/src/org/transdroid/lite/gui/lists/TorrentProgressBar.java new file mode 100644 index 00000000..0dbe8fc1 --- /dev/null +++ b/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))); + } + } + + } + +} diff --git a/lite/src/org/transdroid/lite/gui/navigation/FilterAdapter.java b/lite/src/org/transdroid/lite/gui/navigation/FilterAdapter.java index 0ffb0b8e..22f9dbe6 100644 --- a/lite/src/org/transdroid/lite/gui/navigation/FilterAdapter.java +++ b/lite/src/org/transdroid/lite/gui/navigation/FilterAdapter.java @@ -2,7 +2,7 @@ package org.transdroid.lite.gui.navigation; import java.util.List; -import org.transdroid.lite.R; +import org.transdroid.core.R; import android.content.Context; import android.view.View; @@ -31,7 +31,7 @@ public class FilterAdapter extends MergeAdapter { * Update the list of available servers. * @param servers The new list of available servers */ - public void updateServers(List servers) { + public void updateServers(List servers) { if (this.serverItems == null && servers != null) { addView(FilterSeparatorView_.build(context).setText(context.getString(R.string.navigation_servers)), false); this.serverItems = new FilterItemAdapter(context, servers); @@ -47,7 +47,7 @@ public class FilterAdapter extends MergeAdapter { * Update the list of available status types. * @param statusTypes The new list of available status types */ - public void updateStatusTypes(List statusTypes) { + public void updateStatusTypes(List statusTypes) { if (this.statusTypeItems == null && statusTypes != null) { addView(FilterSeparatorView_.build(context).setText(context.getString(R.string.navigation_status)), false); this.statusTypeItems = new FilterItemAdapter(context, statusTypes); @@ -63,7 +63,7 @@ public class FilterAdapter extends MergeAdapter { * Update the list of available labels. * @param labels The new list of available labels */ - public void updateLabels(List labels) { + public void updateLabels(List labels) { if (this.labelItems == null && labels != null) { addView(FilterSeparatorView_.build(context).setText(context.getString(R.string.navigation_labels)), false); this.labelItems = new FilterItemAdapter(context, labels); @@ -78,9 +78,9 @@ public class FilterAdapter extends MergeAdapter { protected class FilterItemAdapter extends BaseAdapter { private final Context context; - private List items; + private List items; - public FilterItemAdapter(Context context, List items) { + public FilterItemAdapter(Context context, List items) { this.context = context; 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 * @param newItems The new list of filter items to display */ - public void update(List newItems) { + public void update(List newItems) { this.items = newItems; notifyDataSetChanged(); } diff --git a/lite/src/org/transdroid/lite/gui/navigation/FilterItemView.java b/lite/src/org/transdroid/lite/gui/navigation/FilterItemView.java index e7f6dc82..532f85f3 100644 --- a/lite/src/org/transdroid/lite/gui/navigation/FilterItemView.java +++ b/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.ViewById; -import org.transdroid.lite.R; +import org.transdroid.core.R; import android.content.Context; import android.widget.LinearLayout; diff --git a/lite/src/org/transdroid/lite/gui/navigation/FilterSeparatorView.java b/lite/src/org/transdroid/lite/gui/navigation/FilterSeparatorView.java index 09368d89..ea6deaff 100644 --- a/lite/src/org/transdroid/lite/gui/navigation/FilterSeparatorView.java +++ b/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.ViewById; -import org.transdroid.lite.R; +import org.transdroid.core.R; import android.content.Context; import android.widget.LinearLayout; diff --git a/lite/src/org/transdroid/lite/gui/navigation/Label.java b/lite/src/org/transdroid/lite/gui/navigation/Label.java new file mode 100644 index 00000000..6da5d20a --- /dev/null +++ b/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; + } + +} diff --git a/lite/src/org/transdroid/lite/gui/navigation/StatusType.java b/lite/src/org/transdroid/lite/gui/navigation/StatusType.java new file mode 100644 index 00000000..2aaac124 --- /dev/null +++ b/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 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; + } + + } + +} diff --git a/lite/src/org/transdroid/lite/gui/settings/MainSettingsActivity.java b/lite/src/org/transdroid/lite/gui/settings/MainSettingsActivity.java new file mode 100644 index 00000000..5240fee5 --- /dev/null +++ b/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 servers = applicationSettings.getServerSettings(); + for (ServerSetting serverSetting : servers) { + getPreferenceScreen().addPreference( + new ServerPreference(this).setServerSetting(serverSetting).setOnServerClickedListener( + onServerClicked)); + } + + // Add existing websearch sites + List websearches = applicationSettings.getWebsearchSettings(); + for (WebsearchSetting websearchSetting : websearches) { + getPreferenceScreen().addPreference( + new WebsearchPreference(this).setWebsearchSetting(websearchSetting).setOnWebsearchClickedListener( + onWebsearchClicked)); + } + + // Add existing RSS feeds + List 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 searchsites = searchHelper.getAvailableSites(); + List siteNames = new ArrayList(websearches.size() + searchsites.size()); + List siteValues = new ArrayList(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

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(); + } + }; + +} diff --git a/lite/src/org/transdroid/lite/gui/settings/OtherSettingsActivity.java b/lite/src/org/transdroid/lite/gui/settings/OtherSettingsActivity.java new file mode 100644 index 00000000..5e23ee79 --- /dev/null +++ b/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); + + } + +} diff --git a/lite/src/org/transdroid/lite/gui/settings/RssfeedPreference.java b/lite/src/org/transdroid/lite/gui/settings/RssfeedPreference.java new file mode 100644 index 00000000..49a81046 --- /dev/null +++ b/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); + } + +} diff --git a/lite/src/org/transdroid/lite/gui/settings/RssfeedSettingsActivity.java b/lite/src/org/transdroid/lite/gui/settings/RssfeedSettingsActivity.java new file mode 100644 index 00000000..2b83f52f --- /dev/null +++ b/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); + + } + +} diff --git a/lite/src/org/transdroid/lite/gui/settings/ServerPreference.java b/lite/src/org/transdroid/lite/gui/settings/ServerPreference.java new file mode 100644 index 00000000..802873e3 --- /dev/null +++ b/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); + } + +} diff --git a/lite/src/org/transdroid/lite/gui/settings/ServerSettingsActivity.java b/lite/src/org/transdroid/lite/gui/settings/ServerSettingsActivity.java new file mode 100644 index 00000000..148a8b56 --- /dev/null +++ b/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); + + } + +} diff --git a/lite/src/org/transdroid/lite/gui/settings/WebsearchPreference.java b/lite/src/org/transdroid/lite/gui/settings/WebsearchPreference.java new file mode 100644 index 00000000..929f66a9 --- /dev/null +++ b/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); + } + +} diff --git a/lite/src/org/transdroid/lite/gui/settings/WebsearchSettingsActivity.java b/lite/src/org/transdroid/lite/gui/settings/WebsearchSettingsActivity.java new file mode 100644 index 00000000..d5daae2e --- /dev/null +++ b/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); + + } + +}