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 @@ |
|||||||
|
<?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 @@ |
|||||||
|
<?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 @@ |
|||||||
|
<?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 @@ |
|||||||
|
<?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 @@ |
|||||||
|
<?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 @@ |
|||||||
|
<!-- |
||||||
|
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 @@ |
|||||||
|
<?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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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 @@ |
|||||||
|
/* |
||||||
|
* 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; |
||||||
|
} |
||||||
|
|
||||||
|
} |