After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- |
||||
Copyright 2010-2013 Eric Kok et al. |
||||
|
||||
Transdroid is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
Transdroid is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. |
||||
--> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:dividerPadding="@dimen/margin_default" |
||||
android:orientation="@integer/widget_config_orientation" > |
||||
|
||||
<FrameLayout |
||||
android:layout_width="@dimen/widget_preview_width" |
||||
android:layout_height="@dimen/widget_preview_height" |
||||
android:layout_gravity="center_horizontal" |
||||
android:background="@null" |
||||
android:padding="@dimen/widget_preview_padding" > |
||||
|
||||
<include layout="@layout/widget_torrents_light" /> |
||||
</FrameLayout> |
||||
|
||||
<ScrollView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/background_light" |
||||
android:fillViewport="true" |
||||
android:paddingLeft="@dimen/margin_default" |
||||
android:paddingRight="@dimen/margin_default" > |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="vertical" > |
||||
|
||||
<TextView |
||||
android:id="@+id/filterheader_text" |
||||
style="@style/SectionHeader" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/widget_filter" |
||||
android:textIsSelectable="false" /> |
||||
|
||||
<Spinner |
||||
android:id="@+id/server_spinner" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="@dimen/margin_half" /> |
||||
|
||||
<Spinner |
||||
android:id="@+id/filter_spinner" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="@dimen/margin_half" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/sortbyheader_text" |
||||
style="@style/SectionHeader" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/widget_sortby" |
||||
android:textIsSelectable="false" /> |
||||
|
||||
<Spinner |
||||
android:id="@+id/sort_spinner" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="@dimen/margin_half" /> |
||||
|
||||
<CheckBox |
||||
android:id="@+id/reverseorder_check_box" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="@dimen/margin_half" |
||||
android:text="@string/widget_reversesortorder" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/lookfeelheader_text" |
||||
style="@style/SectionHeader" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/widget_lookfeel" |
||||
android:textIsSelectable="false" /> |
||||
|
||||
<CheckBox |
||||
android:id="@+id/darktheme_check_box" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginBottom="@dimen/margin_half" |
||||
android:layout_marginTop="@dimen/margin_half" |
||||
android:text="@string/widget_usedarktheme" /> |
||||
</LinearLayout> |
||||
</ScrollView> |
||||
|
||||
</LinearLayout> |
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- |
||||
Copyright 2010-2013 Eric Kok et al. |
||||
|
||||
Transdroid is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
Transdroid is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. |
||||
--> |
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:id="@+id/widget_line_layout" |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="@dimen/widget_list_item_height" |
||||
android:background="@drawable/selectable_background_transdroid" |
||||
android:paddingRight="@dimen/widget_list_item_padding" > |
||||
|
||||
<TextView |
||||
android:id="@+id/status_view" |
||||
android:layout_width="6dp" |
||||
android:layout_height="@dimen/widget_list_item_height" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/name_text" |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="@dimen/widget_list_item_padding_left" |
||||
android:ellipsize="end" |
||||
android:fontFamily="sans-serif-condensed" |
||||
android:maxLines="1" |
||||
android:paddingTop="@dimen/widget_list_item_padding" |
||||
android:textColor="@color/text_bright_dark" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/text_enlarged" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/ratio_text" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_alignParentRight="true" |
||||
android:layout_below="@id/name_text" |
||||
android:layout_marginLeft="@dimen/widget_list_item_padding" |
||||
android:layout_marginTop="4dip" |
||||
android:maxLines="1" |
||||
android:paddingBottom="@dimen/widget_list_item_padding" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/text_small" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/progress_text" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_alignBaseline="@id/ratio_text" |
||||
android:layout_alignParentLeft="true" |
||||
android:layout_marginLeft="@dimen/widget_list_item_padding_left" |
||||
android:layout_toLeftOf="@id/ratio_text" |
||||
android:maxLines="1" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/text_small" /> |
||||
|
||||
</RelativeLayout> |
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- |
||||
Copyright 2010-2013 Eric Kok et al. |
||||
|
||||
Transdroid is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
Transdroid is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. |
||||
--> |
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:id="@+id/widget_line_layout" |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="@dimen/widget_list_item_height" |
||||
android:background="@drawable/selectable_background_transdroid2" |
||||
android:paddingRight="@dimen/widget_list_item_padding" > |
||||
|
||||
<TextView |
||||
android:id="@+id/status_view" |
||||
android:layout_width="6dp" |
||||
android:layout_height="@dimen/widget_list_item_height" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/name_text" |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginLeft="@dimen/widget_list_item_padding_left" |
||||
android:ellipsize="end" |
||||
android:fontFamily="sans-serif-condensed" |
||||
android:maxLines="1" |
||||
android:paddingTop="@dimen/widget_list_item_padding" |
||||
android:textColor="@color/text_bright_light" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/text_enlarged" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/ratio_text" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_alignParentRight="true" |
||||
android:layout_below="@id/name_text" |
||||
android:layout_marginLeft="@dimen/widget_list_item_padding" |
||||
android:layout_marginTop="4dip" |
||||
android:maxLines="1" |
||||
android:paddingBottom="@dimen/widget_list_item_padding" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/text_small" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/progress_text" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_alignBaseline="@id/ratio_text" |
||||
android:layout_alignParentLeft="true" |
||||
android:layout_marginLeft="@dimen/widget_list_item_padding_left" |
||||
android:layout_toLeftOf="@id/ratio_text" |
||||
android:maxLines="1" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/text_small" /> |
||||
|
||||
</RelativeLayout> |
@ -0,0 +1,116 @@
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- |
||||
Copyright 2010-2013 Eric Kok et al. |
||||
|
||||
Transdroid is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
Transdroid is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. |
||||
--> |
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/background_dark" |
||||
android:padding="@dimen/margin_widget" > |
||||
|
||||
<ImageButton |
||||
android:id="@+id/icon_image" |
||||
android:layout_width="@dimen/widget_header_height" |
||||
android:layout_height="@dimen/widget_header_height" |
||||
android:background="@drawable/selectable_background_transdroid" |
||||
android:contentDescription="@string/widget_opentransdroid" |
||||
android:padding="@dimen/widget_header_padding" |
||||
android:scaleType="fitXY" |
||||
android:src="@drawable/ic_launcher" /> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/refresh_button" |
||||
android:layout_width="@dimen/widget_header_height" |
||||
android:layout_height="@dimen/widget_header_height" |
||||
android:layout_alignParentRight="true" |
||||
android:background="@drawable/selectable_background_transdroid" |
||||
android:contentDescription="@string/action_refresh" |
||||
android:padding="@dimen/widget_header_padding" |
||||
android:scaleType="fitXY" |
||||
android:src="@drawable/ic_action_refresh_dark" /> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/navigation_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="@dimen/widget_header_height" |
||||
android:layout_toLeftOf="@id/refresh_button" |
||||
android:layout_toRightOf="@id/icon_image" |
||||
android:background="@drawable/selectable_background_transdroid" |
||||
android:clickable="true" |
||||
android:orientation="vertical" |
||||
android:paddingRight="@dimen/margin_half" |
||||
android:paddingTop="3dp" > |
||||
|
||||
<TextView |
||||
android:id="@+id/filter_text" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:ellipsize="marquee" |
||||
android:fontFamily="sans-serif-condensed" |
||||
android:maxLines="1" |
||||
android:textColor="@color/text_actionbar_dark" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/ui_navigation_filter" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/server_text" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="-4dip" |
||||
android:ellipsize="marquee" |
||||
android:fontFamily="sans-serif-light" |
||||
android:maxLines="1" |
||||
android:textColor="@color/text_actionbar_dark" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/ui_navigation_server" /> |
||||
</LinearLayout> |
||||
|
||||
<TextView |
||||
android:id="@+id/topline_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="2dp" |
||||
android:layout_below="@id/icon_image" |
||||
android:background="@color/green" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/bottomline_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="2dp" |
||||
android:layout_alignParentBottom="true" |
||||
android:background="@color/green" /> |
||||
|
||||
<ListView |
||||
android:id="@+id/torrents_list" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_above="@id/bottomline_view" |
||||
android:layout_below="@id/topline_view" |
||||
android:visibility="gone" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/error_text" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_above="@id/bottomline_view" |
||||
android:layout_below="@id/topline_view" |
||||
android:layout_gravity="center" |
||||
android:gravity="center" |
||||
android:maxWidth="400dip" |
||||
android:padding="@dimen/margin_default" |
||||
android:textIsSelectable="false" |
||||
android:visibility="gone" /> |
||||
|
||||
</RelativeLayout> |
@ -0,0 +1,115 @@
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- |
||||
Copyright 2010-2013 Eric Kok et al. |
||||
|
||||
Transdroid is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
Transdroid is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. |
||||
--> |
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/background_light" |
||||
android:padding="@dimen/margin_widget" > |
||||
|
||||
<ImageButton |
||||
android:id="@+id/icon_image" |
||||
android:layout_width="@dimen/widget_header_height" |
||||
android:layout_height="@dimen/widget_header_height" |
||||
android:background="@drawable/selectable_background_transdroid2" |
||||
android:contentDescription="@string/widget_opentransdroid" |
||||
android:padding="@dimen/widget_header_padding" |
||||
android:scaleType="fitXY" |
||||
android:src="@drawable/ic_launcher" /> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/refresh_button" |
||||
android:layout_width="@dimen/widget_header_height" |
||||
android:layout_height="@dimen/widget_header_height" |
||||
android:layout_alignParentRight="true" |
||||
android:background="@drawable/selectable_background_transdroid2" |
||||
android:contentDescription="@string/action_refresh" |
||||
android:padding="@dimen/widget_header_padding" |
||||
android:scaleType="fitXY" |
||||
android:src="@drawable/ic_action_refresh_light" /> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/navigation_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="@dimen/widget_header_height" |
||||
android:layout_toLeftOf="@id/refresh_button" |
||||
android:layout_toRightOf="@id/icon_image" |
||||
android:background="@drawable/selectable_background_transdroid2" |
||||
android:clickable="true" |
||||
android:orientation="vertical" |
||||
android:paddingRight="@dimen/margin_half" |
||||
android:paddingTop="3dp" > |
||||
|
||||
<TextView |
||||
android:id="@+id/filter_text" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:ellipsize="marquee" |
||||
android:fontFamily="sans-serif-condensed" |
||||
android:maxLines="1" |
||||
android:textColor="@color/text_actionbar_light" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/ui_navigation_filter" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/server_text" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="-4dip" |
||||
android:ellipsize="marquee" |
||||
android:fontFamily="sans-serif-light" |
||||
android:maxLines="1" |
||||
android:textColor="@color/text_actionbar_light" |
||||
android:textIsSelectable="false" |
||||
android:textSize="@dimen/ui_navigation_server" /> |
||||
</LinearLayout> |
||||
|
||||
<TextView |
||||
android:id="@+id/topline_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="2dp" |
||||
android:layout_below="@id/icon_image" |
||||
android:background="@color/green" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/bottomline_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="2dp" |
||||
android:layout_alignParentBottom="true" |
||||
android:background="@color/green" /> |
||||
|
||||
<ListView |
||||
android:id="@+id/torrents_list" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_above="@id/bottomline_view" |
||||
android:layout_below="@id/topline_view" |
||||
android:visibility="gone" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/error_text" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_above="@id/bottomline_view" |
||||
android:layout_below="@id/topline_view" |
||||
android:layout_gravity="center" |
||||
android:gravity="center" |
||||
android:padding="@dimen/margin_default" |
||||
android:textIsSelectable="false" |
||||
android:visibility="gone" /> |
||||
|
||||
</RelativeLayout> |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
<!-- |
||||
Copyright 2010-2013 Eric Kok et al. |
||||
|
||||
Transdroid is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
Transdroid is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. |
||||
--> |
||||
<resources> |
||||
|
||||
<dimen name="margin_widget">0dp</dimen> |
||||
|
||||
</resources> |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- |
||||
Copyright 2010-2013 Eric Kok et al. |
||||
|
||||
Transdroid is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
Transdroid is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. |
||||
--> |
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:configure="org.transdroid.core.widget.WidgetConfigActivity_" |
||||
android:initialKeyguardLayout="@layout/widget_torrents_light" |
||||
android:initialLayout="@layout/widget_torrents_light" |
||||
android:minHeight="110dip" |
||||
android:minResizeHeight="110dip" |
||||
android:minResizeWidth="110dp" |
||||
android:minWidth="180dp" |
||||
android:previewImage="@drawable/widget_preview" |
||||
android:resizeMode="horizontal|vertical" |
||||
android:updatePeriodMillis="3600000" |
||||
android:widgetCategory="home_screen|keyguard" /> |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
/* |
||||
* Copyright 2010-2013 Eric Kok et al. |
||||
* |
||||
* Transdroid is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* Transdroid is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
package org.transdroid.core.gui.lists; |
||||
|
||||
import java.util.List; |
||||
|
||||
import android.content.Context; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.widget.ArrayAdapter; |
||||
import android.widget.TextView; |
||||
|
||||
/** |
||||
* A wrapper around {@link ArrayAdapter} that contains {@link SimpleListItem}s which simply show their name in the |
||||
* Spinner. The standard Android spinner resources are used for the layout. |
||||
* @author Eric Kok |
||||
*/ |
||||
public class SimpleListItemSpinnerAdapter<T extends SimpleListItem> extends ArrayAdapter<T> { |
||||
|
||||
/** |
||||
* Constructs the adapter, supplying the {@link SimpleListItem}s to show in the spinner. The given resource will be |
||||
* ignored as the standard Android Spinner layout is used instead. |
||||
* @param context The UI context to inflate the layout in |
||||
* @param resource This is ignored; android.R.layout.simple_spinner_item is always used instead |
||||
* @param objects The items to show in the spinner, which can simply display some name |
||||
*/ |
||||
public SimpleListItemSpinnerAdapter(Context context, int resource, List<T> objects) { |
||||
super(context, android.R.layout.simple_spinner_item, objects); |
||||
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); |
||||
} |
||||
|
||||
@Override |
||||
public View getView(int position, View convertView, ViewGroup parent) { |
||||
// This relies on the ArrayAdapter implementation and the used standard xml layouts that simply return a
|
||||
// TextView; this can then be filled with the SimpleListItem's name instead of the standard toString()
|
||||
// implementation
|
||||
TextView text = (TextView) super.getView(position, convertView, parent); |
||||
text.setText(getItem(position).getName()); |
||||
return text; |
||||
} |
||||
|
||||
@Override |
||||
public View getDropDownView(int position, View convertView, ViewGroup parent) { |
||||
// This relies on the ArrayAdapter implementation and the used standard xml layouts that simply return a
|
||||
// TextView; this can then be filled with the SimpleListItem's name instead of the standard toString()
|
||||
// implementation
|
||||
TextView text = (TextView) super.getDropDownView(position, convertView, parent); |
||||
text.setText(getItem(position).getName()); |
||||
return text; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
/* |
||||
* Copyright 2010-2013 Eric Kok et al. |
||||
* |
||||
* Transdroid is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* Transdroid is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
package org.transdroid.core.gui.lists; |
||||
|
||||
import org.transdroid.core.R; |
||||
import org.transdroid.daemon.TorrentsSortBy; |
||||
|
||||
import android.content.Context; |
||||
|
||||
/** |
||||
* Represents a way in which a torrents list can be sorted. |
||||
* @author Eric Kok |
||||
*/ |
||||
public class SortByListItem implements SimpleListItem { |
||||
|
||||
private final TorrentsSortBy sortBy; |
||||
private final String name; |
||||
|
||||
public SortByListItem(Context context, TorrentsSortBy sortBy) { |
||||
this.sortBy = sortBy; |
||||
switch (sortBy) { |
||||
case DateAdded: |
||||
this.name = context.getString(R.string.action_sort_added); |
||||
break; |
||||
case DateDone: |
||||
this.name = context.getString(R.string.action_sort_done); |
||||
break; |
||||
case Ratio: |
||||
this.name = context.getString(R.string.action_sort_ratio); |
||||
break; |
||||
case Status: |
||||
this.name = context.getString(R.string.action_sort_status); |
||||
break; |
||||
case UploadSpeed: |
||||
this.name = context.getString(R.string.action_sort_upspeed); |
||||
break; |
||||
default: |
||||
this.name = context.getString(R.string.action_sort_alpha); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns the contained represented sort order. |
||||
* @return The sort by order as its enumeration value |
||||
*/ |
||||
public TorrentsSortBy getSortBy() { |
||||
return sortBy; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
/* |
||||
* Copyright 2010-2013 Eric Kok et al. |
||||
* |
||||
* Transdroid is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* Transdroid is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
package org.transdroid.core.widget; |
||||
|
||||
import org.transdroid.core.gui.navigation.StatusType; |
||||
import org.transdroid.daemon.TorrentsSortBy; |
||||
|
||||
/** |
||||
* Represents a set of settings that define how the user configured a specific app widget. |
||||
* @author Eric Kok |
||||
*/ |
||||
public class WidgetConfig { |
||||
|
||||
private final int serverId; |
||||
private final StatusType statusType; |
||||
private final TorrentsSortBy sortBy; |
||||
private final boolean reserveSort; |
||||
private final boolean useDarkTheme; |
||||
|
||||
public WidgetConfig(int serverId, StatusType statusType, TorrentsSortBy sortBy, boolean reverseSort, |
||||
boolean useDarkTheme) { |
||||
this.serverId = serverId; |
||||
this.statusType = statusType; |
||||
this.sortBy = sortBy; |
||||
this.reserveSort = reverseSort; |
||||
this.useDarkTheme = useDarkTheme; |
||||
} |
||||
|
||||
public int getServerId() { |
||||
return serverId; |
||||
} |
||||
|
||||
public StatusType getStatusType() { |
||||
return statusType; |
||||
} |
||||
|
||||
public TorrentsSortBy getSortBy() { |
||||
return sortBy; |
||||
} |
||||
|
||||
public boolean shouldReserveSort() { |
||||
return reserveSort; |
||||
} |
||||
|
||||
public boolean shouldUseDarkTheme() { |
||||
return useDarkTheme; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,262 @@
@@ -0,0 +1,262 @@
|
||||
/* |
||||
* Copyright 2010-2013 Eric Kok et al. |
||||
* |
||||
* Transdroid is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* Transdroid is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
package org.transdroid.core.widget; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.androidannotations.annotations.AfterViews; |
||||
import org.androidannotations.annotations.Background; |
||||
import org.androidannotations.annotations.Bean; |
||||
import org.androidannotations.annotations.EActivity; |
||||
import org.androidannotations.annotations.ItemSelect; |
||||
import org.androidannotations.annotations.UiThread; |
||||
import org.androidannotations.annotations.ViewById; |
||||
import org.transdroid.core.R; |
||||
import org.transdroid.core.app.settings.ApplicationSettings; |
||||
import org.transdroid.core.app.settings.ServerSetting; |
||||
import org.transdroid.core.gui.lists.SimpleListItemSpinnerAdapter; |
||||
import org.transdroid.core.gui.lists.SortByListItem; |
||||
import org.transdroid.core.gui.lists.TorrentsAdapter; |
||||
import org.transdroid.core.gui.navigation.StatusType; |
||||
import org.transdroid.core.gui.navigation.StatusType.StatusTypeFilter; |
||||
import org.transdroid.core.service.ConnectivityHelper; |
||||
import org.transdroid.daemon.Daemon; |
||||
import org.transdroid.daemon.IDaemonAdapter; |
||||
import org.transdroid.daemon.Label; |
||||
import org.transdroid.daemon.Torrent; |
||||
import org.transdroid.daemon.TorrentsComparator; |
||||
import org.transdroid.daemon.TorrentsSortBy; |
||||
import org.transdroid.daemon.task.DaemonTaskResult; |
||||
import org.transdroid.daemon.task.RetrieveTask; |
||||
import org.transdroid.daemon.task.RetrieveTaskSuccessResult; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.appwidget.AppWidgetManager; |
||||
import android.content.Intent; |
||||
import android.os.Build; |
||||
import android.os.Bundle; |
||||
import android.view.View; |
||||
import android.view.View.OnClickListener; |
||||
import android.widget.CheckBox; |
||||
import android.widget.CompoundButton; |
||||
import android.widget.CompoundButton.OnCheckedChangeListener; |
||||
import android.widget.ListView; |
||||
import android.widget.Spinner; |
||||
import android.widget.TextView; |
||||
|
||||
import com.actionbarsherlock.app.ActionBar; |
||||
import com.actionbarsherlock.app.SherlockActivity; |
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB) |
||||
@EActivity(resName = "activity_widgetconfig") |
||||
public class WidgetConfigActivity extends SherlockActivity { |
||||
|
||||
// Views and adapters
|
||||
@ViewById |
||||
protected Spinner serverSpinner, filterSpinner, sortSpinner; |
||||
@ViewById |
||||
protected CheckBox reverseorderCheckBox, darkthemeCheckBox; |
||||
@ViewById |
||||
protected TextView filterText, serverText, errorText; |
||||
@ViewById |
||||
protected ListView torrentsList; |
||||
@Bean |
||||
protected TorrentsAdapter previewTorrentsAdapter; |
||||
private List<Torrent> previewTorrents = null; |
||||
|
||||
// Settings and helpers
|
||||
@Bean |
||||
protected ConnectivityHelper connectivityHelper; |
||||
@Bean |
||||
protected ApplicationSettings applicationSettings; |
||||
private int appWidgetId; |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
|
||||
super.onCreate(savedInstanceState); |
||||
if (getIntent() == null || getIntent().getExtras() == null |
||||
|| !getIntent().hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { |
||||
// Invalid configuration; return canceled result
|
||||
setResult(RESULT_CANCELED, |
||||
new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)); |
||||
finish(); |
||||
} |
||||
|
||||
// Get the appwidget ID we are configuring
|
||||
appWidgetId = getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, |
||||
AppWidgetManager.INVALID_APPWIDGET_ID); |
||||
// Set preliminary canceled result and continue with the initialisation
|
||||
setResult(RESULT_CANCELED, new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)); |
||||
|
||||
} |
||||
|
||||
@AfterViews |
||||
protected void init() { |
||||
|
||||
// Populate the selection spinners with custom array adapters
|
||||
List<SortByListItem> sortOrders = new ArrayList<SortByListItem>(); |
||||
for (TorrentsSortBy order : TorrentsSortBy.values()) { |
||||
sortOrders.add(new SortByListItem(this, order)); |
||||
} |
||||
serverSpinner.setAdapter(new SimpleListItemSpinnerAdapter<ServerSetting>(this, 0, applicationSettings |
||||
.getServerSettings())); |
||||
filterSpinner.setAdapter(new SimpleListItemSpinnerAdapter<StatusTypeFilter>(this, 0, StatusType |
||||
.getAllStatusTypes(this))); |
||||
sortSpinner.setAdapter(new SimpleListItemSpinnerAdapter<SortByListItem>(this, 0, sortOrders)); |
||||
// TODO: Update to AndroidAnnotations 3.0 and use @CheckedChanged
|
||||
reverseorderCheckBox.setOnCheckedChangeListener(reverseorderCheckedChanged); |
||||
torrentsList.setAdapter(previewTorrentsAdapter); |
||||
torrentsList.setEmptyView(errorText); |
||||
|
||||
// Set up action bar with a done button
|
||||
// Inspired by NoNonsenseNotes's ListWidgetConfig.java (Apache License, Version 2.0)
|
||||
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, |
||||
ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE); |
||||
View doneButtonFrame = getLayoutInflater().inflate(R.layout.actionbar_donebutton, null); |
||||
doneButtonFrame.findViewById(R.id.actionbar_done).setOnClickListener(doneClicked); |
||||
getSupportActionBar().setCustomView(doneButtonFrame); |
||||
|
||||
} |
||||
|
||||
@ItemSelect |
||||
protected void serverSpinnerItemSelected(boolean selected, ServerSetting server) { |
||||
serverText.setText(server.getName()); |
||||
loadTorrents(); |
||||
} |
||||
|
||||
@ItemSelect |
||||
protected void filterSpinnerItemSelected(boolean selected, StatusTypeFilter statusTypeFilter) { |
||||
filterText.setText(statusTypeFilter.getName()); |
||||
filterTorrents(); |
||||
} |
||||
|
||||
@ItemSelect |
||||
protected void sortSpinnerItemSelected(boolean selected, SortByListItem sortByListItem) { |
||||
filterTorrents(); |
||||
} |
||||
|
||||
protected OnCheckedChangeListener reverseorderCheckedChanged = new OnCheckedChangeListener() { |
||||
@Override |
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { |
||||
filterTorrents(); |
||||
} |
||||
}; |
||||
|
||||
@Background |
||||
protected void loadTorrents() { |
||||
|
||||
if (serverSpinner.getSelectedItem() == null) |
||||
return; |
||||
|
||||
// Create a connection object and retrieve the live torrents
|
||||
IDaemonAdapter connection = ((ServerSetting) serverSpinner.getSelectedItem()) |
||||
.createServerAdapter(connectivityHelper.getConnectedNetworkName()); |
||||
DaemonTaskResult result = RetrieveTask.create(connection).execute(); |
||||
if (result instanceof RetrieveTaskSuccessResult) { |
||||
// Success; show the active torrents in the widget preview
|
||||
onTorrentsRetrieved(((RetrieveTaskSuccessResult) result).getTorrents(), |
||||
((RetrieveTaskSuccessResult) result).getLabels()); |
||||
} else { |
||||
// Can't connect right now; provide a nice error message
|
||||
showError(false); |
||||
} |
||||
|
||||
} |
||||
|
||||
@UiThread |
||||
protected void onTorrentsRetrieved(List<Torrent> torrents, List<Label> labels) { |
||||
previewTorrents = torrents; |
||||
filterTorrents(); |
||||
} |
||||
|
||||
protected void filterTorrents() { |
||||
|
||||
// All spinners have to be initialised already
|
||||
if (serverSpinner.getSelectedItem() == null) |
||||
return; |
||||
if (filterSpinner.getSelectedItem() == null) |
||||
return; |
||||
if (sortSpinner.getSelectedItem() == null) |
||||
return; |
||||
if (previewTorrents == null) |
||||
return; |
||||
|
||||
// Get the already loaded torrents and filter and sort them
|
||||
ArrayList<Torrent> filteredTorrents = new ArrayList<Torrent>(previewTorrents.size()); |
||||
StatusTypeFilter statusTypeFilter = (StatusTypeFilter) filterSpinner.getSelectedItem(); |
||||
for (Torrent torrent : previewTorrents) { |
||||
if (statusTypeFilter.matches(torrent)) |
||||
filteredTorrents.add(torrent); |
||||
} |
||||
if (filteredTorrents.size() == 0) { |
||||
showError(true); |
||||
return; |
||||
} |
||||
TorrentsSortBy sortBy = ((SortByListItem) sortSpinner.getSelectedItem()).getSortBy(); |
||||
Daemon serverType = filteredTorrents.get(0).getDaemon(); |
||||
Collections |
||||
.sort(filteredTorrents, new TorrentsComparator(serverType, sortBy, reverseorderCheckBox.isChecked())); |
||||
|
||||
// Finally update the widget preview with the live, filtered and sorted torrents list
|
||||
previewTorrentsAdapter.update(filteredTorrents); |
||||
torrentsList.setVisibility(View.VISIBLE); |
||||
errorText.setVisibility(View.GONE); |
||||
} |
||||
|
||||
@UiThread |
||||
protected void showError(boolean emptyResults) { |
||||
torrentsList.setVisibility(View.GONE); |
||||
errorText.setVisibility(View.VISIBLE); |
||||
errorText.setText(emptyResults ? R.string.navigation_emptytorrents : R.string.error_httperror); |
||||
} |
||||
|
||||
private OnClickListener doneClicked = new OnClickListener() { |
||||
@Override |
||||
public void onClick(View v) { |
||||
|
||||
// All spinner have to be initialised already
|
||||
if (serverSpinner.getSelectedItem() == null) |
||||
return; |
||||
if (filterSpinner.getSelectedItem() == null) |
||||
return; |
||||
if (sortSpinner.getSelectedItem() == null) |
||||
return; |
||||
|
||||
// Store these user preferences
|
||||
int server = ((ServerSetting) serverSpinner.getSelectedItem()).getOrder(); |
||||
StatusType statusType = ((StatusTypeFilter) filterSpinner.getSelectedItem()).getStatusType(); |
||||
TorrentsSortBy sortBy = ((SortByListItem) sortSpinner.getSelectedItem()).getSortBy(); |
||||
boolean reverseSort = reverseorderCheckBox.isChecked(); |
||||
boolean useDarkTheme = darkthemeCheckBox.isChecked(); |
||||
WidgetConfig config = new WidgetConfig(server, statusType, sortBy, reverseSort, useDarkTheme); |
||||
applicationSettings.setWidgetConfig(appWidgetId, config); |
||||
|
||||
// Return the widget configuration result
|
||||
AppWidgetManager manager = AppWidgetManager.getInstance(WidgetConfigActivity.this); |
||||
manager.updateAppWidget(appWidgetId, |
||||
WidgetProvider.buildRemoteViews(getApplicationContext(), appWidgetId, config)); |
||||
manager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.torrents_list); |
||||
setResult(RESULT_OK, new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)); |
||||
finish(); |
||||
|
||||
} |
||||
}; |
||||
|
||||
} |
@ -0,0 +1,143 @@
@@ -0,0 +1,143 @@
|
||||
/* |
||||
* Copyright 2010-2013 Eric Kok et al. |
||||
* |
||||
* Transdroid is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* Transdroid is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
package org.transdroid.core.widget; |
||||
|
||||
import org.androidannotations.annotations.Bean; |
||||
import org.androidannotations.annotations.EReceiver; |
||||
import org.transdroid.core.R; |
||||
import org.transdroid.core.app.settings.*; |
||||
import org.transdroid.core.gui.*; |
||||
import org.transdroid.core.gui.log.Log; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.app.PendingIntent; |
||||
import android.appwidget.AppWidgetManager; |
||||
import android.appwidget.AppWidgetProvider; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.net.Uri; |
||||
import android.os.Build; |
||||
import android.widget.RemoteViews; |
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB) |
||||
@EReceiver |
||||
public class WidgetProvider extends AppWidgetProvider { |
||||
|
||||
public static final String INTENT_STARTSERVER = "org.transdroid.START_SERVER"; |
||||
public static final String EXTRA_TORRENT = "extra_torrent"; |
||||
public static final String EXTRA_SERVER = "extra_server"; |
||||
public static final String EXTRA_REFRESH = "extra_refresh"; |
||||
|
||||
@Bean |
||||
protected ApplicationSettings applicationSettings; |
||||
|
||||
@Override |
||||
public void onReceive(Context context, Intent intent) { |
||||
if (intent != null && intent.hasExtra(EXTRA_REFRESH)) { |
||||
// Manually requested a refresh for the app widget of which the ID was supplied
|
||||
int appWidgetId = intent.getIntExtra(EXTRA_REFRESH, -1); |
||||
AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, |
||||
buildRemoteViews(context, appWidgetId, applicationSettings.getWidgetConfig(appWidgetId))); |
||||
AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.torrents_list); |
||||
return; |
||||
} |
||||
super.onReceive(context, intent); |
||||
} |
||||
|
||||
@Override |
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { |
||||
for (int appWidgetId : appWidgetIds) { |
||||
appWidgetManager.updateAppWidget(appWidgetId, |
||||
buildRemoteViews(context, appWidgetId, applicationSettings.getWidgetConfig(appWidgetId))); |
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.torrents_list); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onDeleted(Context context, int[] appWidgetIds) { |
||||
for (int appWidgetId : appWidgetIds) { |
||||
applicationSettings.removeWidgetConfig(appWidgetId); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Loads and sets up the layout for some specific app widget given the user's widget settings. Note that the views |
||||
* for the list view rows are loaded separately in the {@link WidgetViewsFactory}. |
||||
* @param context The app widget context, with access to resources |
||||
* @param appWidgetId The specific ID of the app widget to load |
||||
* @param config The user widget configuration, with filter and theme preferences |
||||
* @return A fully initialised set of remote views to update the widget with the AppWidgetManager |
||||
*/ |
||||
@SuppressWarnings("deprecation") |
||||
public static RemoteViews buildRemoteViews(Context context, int appWidgetId, WidgetConfig config) { |
||||
|
||||
// Does the server to show and its widget settings actually still exist?
|
||||
if (context == null || config == null) |
||||
return null; |
||||
ApplicationSettings appSettings = ApplicationSettings_.getInstance_(context); |
||||
if (config.getServerId() < 0 || config.getServerId() > appSettings.getMaxServer()) { |
||||
Log.e(context, "Tried to set up widget " + appWidgetId + " but the bound server ID " + config.getServerId() |
||||
+ " no longer exists."); |
||||
return null; |
||||
} |
||||
|
||||
// Load the dark or light widget layout xml
|
||||
RemoteViews rv = new RemoteViews(context.getPackageName(), |
||||
config.shouldUseDarkTheme() ? R.layout.widget_torrents_dark : R.layout.widget_torrents_light); |
||||
|
||||
// Set up the widget's list view loading service which refers to the WidgetViewsFactory
|
||||
Intent data = new Intent(context, WidgetService_.class); |
||||
data.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); |
||||
data.setData(Uri.parse(data.toUri(Intent.URI_INTENT_SCHEME))); |
||||
rv.setRemoteAdapter(appWidgetId, R.id.torrents_list, data); |
||||
Intent open = new Intent(context, TorrentsActivity_.class); |
||||
open.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); |
||||
rv.setPendingIntentTemplate(R.id.torrents_list, |
||||
PendingIntent.getActivity(context, appWidgetId, open, PendingIntent.FLAG_UPDATE_CURRENT)); |
||||
rv.setEmptyView(R.id.torrents_list, R.id.error_text); |
||||
rv.setTextViewText(R.id.error_text, context.getString(R.string.widget_loading)); |
||||
|
||||
// Show the server and status type filter from the widget configuration in the 'action bar'
|
||||
ServerSetting server = appSettings.getServerSetting(config.getServerId()); |
||||
rv.setTextViewText(R.id.server_text, server.getName()); |
||||
rv.setTextViewText(R.id.filter_text, config.getStatusType().getFilterItem(context).getName()); |
||||
|
||||
// Set up the START_SERVER intent for 'action bar' clicks to start Transdroid normally
|
||||
Intent start = new Intent(context, TorrentsActivity_.class); |
||||
//start.setData(Uri.parse("intent://widget/" + appWidgetId + "/start/" + config.getServerId()));
|
||||
start.setAction(INTENT_STARTSERVER); |
||||
start.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); |
||||
start.putExtra(EXTRA_SERVER, config.getServerId()); |
||||
rv.setOnClickPendingIntent(R.id.icon_image, |
||||
PendingIntent.getActivity(context, appWidgetId, start, PendingIntent.FLAG_UPDATE_CURRENT)); |
||||
rv.setOnClickPendingIntent(R.id.navigation_view, |
||||
PendingIntent.getActivity(context, appWidgetId, start, PendingIntent.FLAG_UPDATE_CURRENT)); |
||||
|
||||
// Set up the widgets refresh button pending intent (calling this WidgetProvider itself)
|
||||
// Make sure that the intent is unique using a custom data path (rather than just the extras)
|
||||
Intent refresh = new Intent(context, WidgetProvider_.class); |
||||
refresh.setData(Uri.parse("intent://widget/" + appWidgetId + "/refresh")); |
||||
refresh.putExtra(EXTRA_REFRESH, appWidgetId); |
||||
refresh.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); |
||||
rv.setOnClickPendingIntent(R.id.refresh_button, |
||||
PendingIntent.getBroadcast(context, appWidgetId, refresh, PendingIntent.FLAG_UPDATE_CURRENT)); |
||||
|
||||
return rv; |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,198 @@
@@ -0,0 +1,198 @@
|
||||
/* |
||||
* Copyright 2010-2013 Eric Kok et al. |
||||
* |
||||
* Transdroid is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* Transdroid is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
package org.transdroid.core.widget; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.androidannotations.annotations.EService; |
||||
import org.transdroid.core.R; |
||||
import org.transdroid.core.app.settings.*; |
||||
import org.transdroid.core.app.settings.ServerSetting; |
||||
import org.transdroid.core.gui.lists.LocalTorrent; |
||||
import org.transdroid.core.gui.log.Log; |
||||
import org.transdroid.core.service.*; |
||||
import org.transdroid.daemon.Daemon; |
||||
import org.transdroid.daemon.IDaemonAdapter; |
||||
import org.transdroid.daemon.Torrent; |
||||
import org.transdroid.daemon.TorrentsComparator; |
||||
import org.transdroid.daemon.task.DaemonTaskResult; |
||||
import org.transdroid.daemon.task.RetrieveTask; |
||||
import org.transdroid.daemon.task.RetrieveTaskSuccessResult; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.appwidget.AppWidgetManager; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.os.Build; |
||||
import android.widget.RemoteViews; |
||||
import android.widget.RemoteViewsService; |
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB) |
||||
@EService |
||||
public class WidgetService extends RemoteViewsService { |
||||
|
||||
@Override |
||||
public RemoteViewsFactory onGetViewFactory(Intent intent) { |
||||
return new WidgetViewsFactory(this.getApplicationContext(), intent); |
||||
} |
||||
|
||||
} |
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB) |
||||
class WidgetViewsFactory implements RemoteViewsService.RemoteViewsFactory { |
||||
|
||||
private final Context context; |
||||
private final int appWidgetId; |
||||
private List<Torrent> torrents = null; |
||||
private WidgetConfig config = null; |
||||
|
||||
public WidgetViewsFactory(Context applicationContext, Intent intent) { |
||||
this.context = applicationContext; |
||||
this.appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, |
||||
AppWidgetManager.INVALID_APPWIDGET_ID); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate() { |
||||
// Nothing to do here (wait for onDataSetChanged)
|
||||
} |
||||
|
||||
@Override |
||||
public void onDataSetChanged() { |
||||
|
||||
// Load the widget settings
|
||||
ApplicationSettings settings = ApplicationSettings_.getInstance_(context); |
||||
config = settings.getWidgetConfig(appWidgetId); |
||||
if (config == null || config.getServerId() < 0) { |
||||
Log.e(context, "Looking for widget data while the widget wasn't yet configured"); |
||||
return; |
||||
} |
||||
ServerSetting server = settings.getServerSetting(config.getServerId()); |
||||
if (server == null) { |
||||
// TODO: Show error text some how in the remote view, perhaps via the EmptyView's text?
|
||||
Log.e(context, "The server for which this widget was created no longer exists"); |
||||
if (torrents != null) |
||||
torrents.clear(); |
||||
return; |
||||
} |
||||
|
||||
// Load the torrents; synchronously
|
||||
IDaemonAdapter connection = server.createServerAdapter(ConnectivityHelper_.getInstance_(context) |
||||
.getConnectedNetworkName()); |
||||
DaemonTaskResult result = RetrieveTask.create(connection).execute(); |
||||
if (!(result instanceof RetrieveTaskSuccessResult)) { |
||||
// TODO: Show error text somehow in the remote view, perhaps via the EmptyView's text?
|
||||
Log.e(context, "The torrents could not be retrieved at this time; probably a connection issue"); |
||||
if (torrents != null) |
||||
torrents.clear(); |
||||
return; |
||||
} |
||||
|
||||
// We have data; filter, sort and store it to use later when getViewAt gets called
|
||||
ArrayList<Torrent> filteredTorrents = new ArrayList<Torrent>(); |
||||
for (Torrent torrent : ((RetrieveTaskSuccessResult) result).getTorrents()) { |
||||
if (config.getStatusType().getFilterItem(context).matches(torrent)) |
||||
filteredTorrents.add(torrent); |
||||
} |
||||
if (filteredTorrents.size() > 0) { |
||||
// Only sort when there are actually torrents left after filtering
|
||||
Daemon serverType = filteredTorrents.get(0).getDaemon(); |
||||
Collections.sort(filteredTorrents, |
||||
new TorrentsComparator(serverType, config.getSortBy(), config.shouldReserveSort())); |
||||
} |
||||
torrents = filteredTorrents; |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public RemoteViews getViewAt(int position) { |
||||
|
||||
// Load the dark or light widget list item layout xml
|
||||
RemoteViews rv = new RemoteViews(context.getPackageName(), |
||||
config.shouldUseDarkTheme() ? R.layout.list_item_widget_dark : R.layout.list_item_widget_light); |
||||
|
||||
// Bind the torrent details texts and status colour
|
||||
Torrent torrent = torrents.get(position); |
||||
LocalTorrent local = LocalTorrent.fromTorrent(torrent); |
||||
rv.setTextViewText(R.id.name_text, torrent.getName()); |
||||
rv.setTextViewText(R.id.progress_text, local.getProgressSizeText(context.getResources(), false)); |
||||
rv.setTextViewText(R.id.ratio_text, local.getProgressEtaRatioText(context.getResources())); |
||||
int statusColour; |
||||
switch (torrent.getStatusCode()) { |
||||
case Downloading: |
||||
statusColour = R.color.torrent_downloading; |
||||
break; |
||||
case Paused: |
||||
statusColour = R.color.torrent_paused; |
||||
break; |
||||
case Seeding: |
||||
statusColour = R.color.torrent_seeding; |
||||
break; |
||||
case Error: |
||||
statusColour = R.color.torrent_error; |
||||
break; |
||||
default: // Checking, Waiting, Queued, Unknown
|
||||
statusColour = R.color.torrent_other; |
||||
break; |
||||
} |
||||
rv.setInt(R.id.status_view, "setBackgroundColor", context.getResources().getColor(statusColour)); |
||||
Intent startIntent = new Intent(); |
||||
startIntent.putExtra(WidgetProvider.EXTRA_SERVER, config.getServerId()); |
||||
startIntent.putExtra(WidgetProvider.EXTRA_TORRENT, torrent); |
||||
rv.setOnClickFillInIntent(R.id.widget_line_layout, startIntent); |
||||
|
||||
return rv; |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public RemoteViews getLoadingView() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
if (torrents != null) |
||||
torrents.clear(); |
||||
torrents = null; |
||||
} |
||||
|
||||
@Override |
||||
public int getViewTypeCount() { |
||||
return 1; |
||||
} |
||||
|
||||
@Override |
||||
public boolean hasStableIds() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public int getCount() { |
||||
if (torrents == null) |
||||
return 0; |
||||
return torrents.size(); |
||||
} |
||||
|
||||
@Override |
||||
public long getItemId(int position) { |
||||
return position; |
||||
} |
||||
|
||||
} |