Browse Source

Added label picking/new label dialog in details fragment.

pull/11/head
Eric Kok 11 years ago
parent
commit
8321c2c91b
  1. 49
      core/res/layout/dialog_setlabel.xml
  2. 14
      core/res/layout/dialog_trackers.xml
  3. 5
      core/res/values/strings.xml
  4. 14
      core/src/org/transdroid/core/gui/DetailsActivity.java
  5. 28
      core/src/org/transdroid/core/gui/DetailsFragment.java
  6. 15
      core/src/org/transdroid/core/gui/TorrentsActivity.java
  7. 4
      core/src/org/transdroid/core/gui/navigation/Label.java
  8. 106
      core/src/org/transdroid/core/gui/navigation/SetLabelDialog.java
  9. 77
      core/src/org/transdroid/core/gui/navigation/SetTrackersDialog.java

49
core/res/layout/dialog_setlabel.xml

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/margin_half"
android:orientation="vertical" >
<TextView
android:id="@+id/pick_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/status_label_pick"
android:textAllCaps="true" />
<View
android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="#28000000" />
<ListView
android:id="@+id/labels_list"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:listSelector="?attr/selectable_background_transdroid" />
<View
android:id="@+id/line2"
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="#28000000" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_half"
android:text="@string/status_label_new"
android:textAllCaps="true" />
<EditText
android:id="@+id/newlabel_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:inputType="textFilter"
android:hint="@string/status_label_hint" />
</LinearLayout>

14
core/res/layout/dialog_trackers.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/margin_half" >
<EditText
android:id="@+id/trackers_edit"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minLines="5"
android:inputType="textUri|textMultiLine" />
</FrameLayout>

5
core/res/values/strings.xml

@ -100,6 +100,10 @@
<string name="status_maxspeed_unit">KB/S</string> <string name="status_maxspeed_unit">KB/S</string>
<string name="status_maxspeed_reset">Reset</string> <string name="status_maxspeed_reset">Reset</string>
<string name="status_update">Update</string> <string name="status_update">Update</string>
<string name="status_label_pick">PICK A LABEL</string>
<string name="status_label_new">NEW LABEL</string>
<string name="status_label_remove">Remove label</string>
<string name="status_label_hint">E.g. movies or linux</string>
<string name="labels_showall">All labels</string> <string name="labels_showall">All labels</string>
<string name="labels_unlabeled">Unlabeled</string> <string name="labels_unlabeled">Unlabeled</string>
@ -313,6 +317,7 @@
<string name="error_file_not_found">The settings file could not be found</string> <string name="error_file_not_found">The settings file could not be found</string>
<string name="error_cant_write_settings_file">Can\'t write to the settings file</string> <string name="error_cant_write_settings_file">Can\'t write to the settings file</string>
<string name="error_notanumber">Please enter a positive number</string> <string name="error_notanumber">Please enter a positive number</string>
<string name="error_notalabel">Please enter a valid label or pick from the list</string>
<string name="system_name" translatable="false">Transdroid</string> <string name="system_name" translatable="false">Transdroid</string>
<string name="system_developer" translatable="false">\u00A9 Eric Kok, 2312 development</string> <string name="system_developer" translatable="false">\u00A9 Eric Kok, 2312 development</string>

14
core/src/org/transdroid/core/gui/DetailsActivity.java

@ -17,6 +17,7 @@ import org.transdroid.core.R;
import org.transdroid.core.app.settings.*; import org.transdroid.core.app.settings.*;
import org.transdroid.core.gui.lists.LocalTorrent; import org.transdroid.core.gui.lists.LocalTorrent;
import org.transdroid.core.gui.log.Log; import org.transdroid.core.gui.log.Log;
import org.transdroid.core.gui.navigation.Label;
import org.transdroid.core.gui.navigation.NavigationHelper; import org.transdroid.core.gui.navigation.NavigationHelper;
import org.transdroid.daemon.Daemon; import org.transdroid.daemon.Daemon;
import org.transdroid.daemon.IDaemonAdapter; import org.transdroid.daemon.IDaemonAdapter;
@ -66,6 +67,9 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
@Extra @Extra
@InstanceState @InstanceState
protected Torrent torrent; protected Torrent torrent;
@Extra
@InstanceState
protected ArrayList<Label> currentLabels;
// Settings // Settings
@Bean @Bean
@ -92,7 +96,7 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
protected void init() { protected void init() {
// We require a torrent to be specified; otherwise close the activity // We require a torrent to be specified; otherwise close the activity
if (torrent == null) { if (torrent == null || currentLabels == null) {
finish(); finish();
return; return;
} }
@ -107,6 +111,7 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
// Show details and load fine stats and torrent files // Show details and load fine stats and torrent files
fragmentDetails.updateTorrent(torrent); fragmentDetails.updateTorrent(torrent);
fragmentDetails.updateLabels(currentLabels);
} }
@ -237,7 +242,8 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
@Override @Override
public void updateLabel(Torrent torrent, String newLabel) { public void updateLabel(Torrent torrent, String newLabel) {
torrent.mimicNewLabel(newLabel); torrent.mimicNewLabel(newLabel);
DaemonTaskResult result = SetLabelTask.create(currentConnection, torrent, newLabel).execute(); DaemonTaskResult result = SetLabelTask.create(currentConnection, torrent, newLabel == null ? "" : newLabel)
.execute();
if (result instanceof DaemonTaskResult) { if (result instanceof DaemonTaskResult) {
onTaskSucceeded((DaemonTaskSuccessResult) result, getString(R.string.result_labelset, newLabel)); onTaskSucceeded((DaemonTaskSuccessResult) result, getString(R.string.result_labelset, newLabel));
} else { } else {
@ -309,9 +315,11 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
@UiThread @UiThread
protected void onTorrentsRetrieved(List<Torrent> torrents, List<org.transdroid.daemon.Label> labels) { protected void onTorrentsRetrieved(List<Torrent> torrents, List<org.transdroid.daemon.Label> labels) {
// Update the details fragment // Update the details fragment accordingly
fragmentDetails.updateIsLoading(false); fragmentDetails.updateIsLoading(false);
fragmentDetails.perhapsUpdateTorrent(torrents); fragmentDetails.perhapsUpdateTorrent(torrents);
fragmentDetails.updateLabels(Label.convertToNavigationLabels(labels,
getResources().getString(R.string.labels_unlabeled)));
} }
} }

28
core/src/org/transdroid/core/gui/DetailsFragment.java

@ -6,7 +6,6 @@ import java.util.List;
import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment; import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.FragmentArg;
import org.androidannotations.annotations.InstanceState; import org.androidannotations.annotations.InstanceState;
import org.androidannotations.annotations.OptionsItem; import org.androidannotations.annotations.OptionsItem;
import org.androidannotations.annotations.OptionsMenu; import org.androidannotations.annotations.OptionsMenu;
@ -15,9 +14,12 @@ import org.transdroid.core.R;
import org.transdroid.core.app.settings.SystemSettings_; import org.transdroid.core.app.settings.SystemSettings_;
import org.transdroid.core.gui.lists.DetailsAdapter; import org.transdroid.core.gui.lists.DetailsAdapter;
import org.transdroid.core.gui.lists.SimpleListItemAdapter; import org.transdroid.core.gui.lists.SimpleListItemAdapter;
import org.transdroid.core.gui.navigation.Label;
import org.transdroid.core.gui.navigation.NavigationHelper; import org.transdroid.core.gui.navigation.NavigationHelper;
import org.transdroid.core.gui.navigation.NavigationHelper_; import org.transdroid.core.gui.navigation.NavigationHelper_;
import org.transdroid.core.gui.navigation.SelectionManagerMode; import org.transdroid.core.gui.navigation.SelectionManagerMode;
import org.transdroid.core.gui.navigation.SetLabelDialog;
import org.transdroid.core.gui.navigation.SetLabelDialog.OnLabelPickedListener;
import org.transdroid.core.gui.navigation.SetTrackersDialog; import org.transdroid.core.gui.navigation.SetTrackersDialog;
import org.transdroid.core.gui.navigation.SetTrackersDialog.OnTrackersUpdatedListener; import org.transdroid.core.gui.navigation.SetTrackersDialog.OnTrackersUpdatedListener;
import org.transdroid.daemon.Daemon; import org.transdroid.daemon.Daemon;
@ -47,17 +49,18 @@ import de.keyboardsurfer.android.widget.crouton.Crouton;
*/ */
@EFragment(resName = "fragment_details") @EFragment(resName = "fragment_details")
@OptionsMenu(resName = "fragment_details") @OptionsMenu(resName = "fragment_details")
public class DetailsFragment extends SherlockFragment implements OnTrackersUpdatedListener { public class DetailsFragment extends SherlockFragment implements OnTrackersUpdatedListener, OnLabelPickedListener {
// Local data // Local data
@InstanceState @InstanceState
@FragmentArg
protected Torrent torrent = null; protected Torrent torrent = null;
@InstanceState @InstanceState
protected TorrentDetails torrentDetails = null; protected TorrentDetails torrentDetails = null;
@InstanceState @InstanceState
protected ArrayList<TorrentFile> torrentFiles = null; protected ArrayList<TorrentFile> torrentFiles = null;
@InstanceState @InstanceState
protected ArrayList<Label> currentLabels = null;
@InstanceState
protected boolean isLoadingTorrent = false; protected boolean isLoadingTorrent = false;
// Views // Views
@ -162,6 +165,15 @@ public class DetailsFragment extends SherlockFragment implements OnTrackersUpdat
} }
} }
/**
* Updates the locally maintained list of labels that are active on the server. Used in the label picking dialog and
* should be updated every time after the list of torrents was retrieved to keep it updated.
* @param currentLabels The list of known server labels
*/
public void updateLabels(ArrayList<Label> currentLabels) {
this.currentLabels = new ArrayList<Label>(currentLabels);
}
/** /**
* Clear the screen by fully clearing the internal merge list (with header and other lists) * Clear the screen by fully clearing the internal merge list (with header and other lists)
*/ */
@ -253,13 +265,19 @@ public class DetailsFragment extends SherlockFragment implements OnTrackersUpdat
@OptionsItem(resName = "action_setlabel") @OptionsItem(resName = "action_setlabel")
protected void setLabel() { protected void setLabel() {
// TODO: Show label selection dialog new SetLabelDialog().setOnLabelPickedListener(this).setCurrentLabels(currentLabels)
.show(getFragmentManager(), "SetLabelDialog");
} }
@OptionsItem(resName = "action_updatetrackers") @OptionsItem(resName = "action_updatetrackers")
protected void updateTrackers() { protected void updateTrackers() {
new SetTrackersDialog().setOnTrackersUpdated(this).setCurrentTrackers(torrentDetails.getTrackersText()) new SetTrackersDialog().setOnTrackersUpdated(this).setCurrentTrackers(torrentDetails.getTrackersText())
.show(getActivity().getSupportFragmentManager(), "SetTrackersDialog"); .show(getFragmentManager(), "SetTrackersDialog");
}
@Override
public void onLabelPicked(String newLabel) {
getTasksExecutor().updateLabel(torrent, newLabel);
} }
@Override @Override

15
core/src/org/transdroid/core/gui/TorrentsActivity.java

@ -127,6 +127,8 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
protected NavigationFilter currentFilter = null; protected NavigationFilter currentFilter = null;
@InstanceState @InstanceState
protected boolean turleModeEnabled = false; protected boolean turleModeEnabled = false;
@InstanceState
protected ArrayList<Label> lastNavigationLabels;
// Contained torrent and details fragments // Contained torrent and details fragments
@FragmentById(resName = "torrent_list") @FragmentById(resName = "torrent_list")
@ -575,7 +577,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
if (fragmentDetails != null) { if (fragmentDetails != null) {
fragmentDetails.updateTorrent(torrent); fragmentDetails.updateTorrent(torrent);
} else { } else {
DetailsActivity_.intent(this).torrent(torrent).start(); DetailsActivity_.intent(this).torrent(torrent).currentLabels(lastNavigationLabels).start();
} }
} }
@ -816,7 +818,8 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
@Override @Override
public void updateLabel(Torrent torrent, String newLabel) { public void updateLabel(Torrent torrent, String newLabel) {
torrent.mimicNewLabel(newLabel); torrent.mimicNewLabel(newLabel);
DaemonTaskResult result = SetLabelTask.create(currentConnection, torrent, newLabel).execute(); DaemonTaskResult result = SetLabelTask.create(currentConnection, torrent, newLabel == null ? "" : newLabel)
.execute();
if (result instanceof DaemonTaskResult) { if (result instanceof DaemonTaskResult) {
onTaskSucceeded((DaemonTaskSuccessResult) result, getString(R.string.result_labelset, newLabel)); onTaskSucceeded((DaemonTaskSuccessResult) result, getString(R.string.result_labelset, newLabel));
} else { } else {
@ -899,15 +902,17 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
} }
// Update local list of labels in the navigation // Update local list of labels in the navigation
List<Label> navigationLabels = Label.convertToNavigationLabels(labels, lastNavigationLabels = Label.convertToNavigationLabels(labels,
getResources().getString(R.string.labels_unlabeled)); getResources().getString(R.string.labels_unlabeled));
if (navigationListAdapter != null) { if (navigationListAdapter != null) {
// Labels are shown in the dedicated side navigation // Labels are shown in the dedicated side navigation
navigationListAdapter.updateLabels(navigationLabels); navigationListAdapter.updateLabels(lastNavigationLabels);
} else { } else {
// Labels are shown in the action bar spinner // Labels are shown in the action bar spinner
navigationSpinnerAdapter.updateLabels(navigationLabels); navigationSpinnerAdapter.updateLabels(lastNavigationLabels);
} }
if (fragmentDetails != null)
fragmentDetails.updateLabels(lastNavigationLabels);
// Update the server status (counts and speeds) in the action bar // Update the server status (counts and speeds) in the action bar
serverStatusView.update(torrents); serverStatusView.update(torrents);

4
core/src/org/transdroid/core/gui/navigation/Label.java

@ -52,12 +52,12 @@ public class Label implements SimpleListItem, NavigationFilter {
* @param unnamedLabel The text to show for the empty label (i.e. the unnamed label) * @param unnamedLabel The text to show for the empty label (i.e. the unnamed label)
* @return A label items that can be used in a filter list such as the action bar spinner * @return A label items that can be used in a filter list such as the action bar spinner
*/ */
public static List<Label> convertToNavigationLabels(List<org.transdroid.daemon.Label> daemonLabels, public static ArrayList<Label> convertToNavigationLabels(List<org.transdroid.daemon.Label> daemonLabels,
String unnamedLabel) { String unnamedLabel) {
if (daemonLabels == null) if (daemonLabels == null)
return null; return null;
unnamedLabelText = unnamedLabel; unnamedLabelText = unnamedLabel;
List<Label> localLabels = new ArrayList<Label>(); ArrayList<Label> localLabels = new ArrayList<Label>();
for (org.transdroid.daemon.Label label : daemonLabels) { for (org.transdroid.daemon.Label label : daemonLabels) {
localLabels.add(new Label(label)); localLabels.add(new Label(label));
} }

106
core/src/org/transdroid/core/gui/navigation/SetLabelDialog.java

@ -0,0 +1,106 @@
package org.transdroid.core.gui.navigation;
import java.security.InvalidParameterException;
import java.util.List;
import org.transdroid.core.R;
import org.transdroid.core.gui.lists.SimpleListItem;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ListView;
import de.keyboardsurfer.android.widget.crouton.Crouton;
/**
* A dialog fragment that allows picking a label or entering a new label to set this new label to the torrent.
* @author Eric Kok
*/
public class SetLabelDialog extends DialogFragment {
private OnLabelPickedListener onLabelPickedListener = null;
private List<? extends SimpleListItem> currentLabels = null;
public SetLabelDialog() {
setRetainInstance(true);
}
/**
* Sets the callback for when the user is has picked a label for the target torrent.
* @param onLabelPickedListener The event listener to this dialog
* @return This dialog, for method chaining
*/
public SetLabelDialog setOnLabelPickedListener(OnLabelPickedListener onLabelPickedListener) {
this.onLabelPickedListener = onLabelPickedListener;
return this;
}
/**
* Sets the list of currently known labels as are active on the server. These are offered to the user to pick a new
* label for the target torrents.
* @param currentLabels The list of torrent labels
* @return This dialog, for method chaining
*/
public SetLabelDialog setCurrentLabels(List<? extends SimpleListItem> currentLabels) {
this.currentLabels = currentLabels;
return this;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
if (onLabelPickedListener == null)
throw new InvalidParameterException(
"Please first set the callback listener using setOnLabelPickedListener before opening the dialog.");
if (currentLabels == null)
throw new InvalidParameterException(
"Please first set the list of currently known labels before opening the dialog, even if the list is empty.");
final View setlabelFrame = getActivity().getLayoutInflater().inflate(R.layout.dialog_setlabel, null, false);
final ListView labelsList = (ListView) setlabelFrame.findViewById(R.id.labels_list);
final EditText newlabelEdit = (EditText) setlabelFrame.findViewById(R.id.newlabel_edit);
if (currentLabels.size() == 0) {
// Hide the list (and its label) if there are no labels yet
setlabelFrame.findViewById(R.id.pick_label).setVisibility(View.GONE);
setlabelFrame.findViewById(R.id.line1).setVisibility(View.GONE);
setlabelFrame.findViewById(R.id.line2).setVisibility(View.GONE);
labelsList.setVisibility(View.GONE);
} else {
labelsList.setAdapter(new FilterListItemAdapter(getActivity(), currentLabels));
labelsList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
onLabelPickedListener.onLabelPicked(((Label) labelsList.getItemAtPosition(position)).getName());
dismiss();
}
});
}
return new AlertDialog.Builder(getActivity()).setView(setlabelFrame)
.setPositiveButton(R.string.status_update, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// User should have provided a new label
if (newlabelEdit.getText().toString().equals("")) {
Crouton.showText(getActivity(), R.string.error_notalabel,
NavigationHelper.CROUTON_ERROR_STYLE);
}
onLabelPickedListener.onLabelPicked(newlabelEdit.getText().toString());
}
}).setNeutralButton(R.string.status_label_remove, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
onLabelPickedListener.onLabelPicked(null);
}
}).setNegativeButton(android.R.string.cancel, null).show();
}
public interface OnLabelPickedListener {
public void onLabelPicked(String newLabel);
}
}

77
core/src/org/transdroid/core/gui/navigation/SetTrackersDialog.java

@ -0,0 +1,77 @@
package org.transdroid.core.gui.navigation;
import java.security.InvalidParameterException;
import java.util.Arrays;
import java.util.List;
import org.transdroid.core.R;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.EditText;
/**
* A dialog fragment that allows changing the trackers of a torrent by editing the text directly.
* @author Eric Kok
*/
public class SetTrackersDialog extends DialogFragment {
private OnTrackersUpdatedListener onTrackersUpdatedListener = null;
private String currentTrackers = null;
public SetTrackersDialog() {
setRetainInstance(true);
}
/**
* Sets the callback for when the user is done updating the trackers list.
* @param onTrackersUpdatedListener The event listener to this dialog
* @return This dialog, for method chaining
*/
public SetTrackersDialog setOnTrackersUpdated(OnTrackersUpdatedListener onTrackersUpdatedListener) {
this.onTrackersUpdatedListener = onTrackersUpdatedListener;
return this;
}
/**
* Sets the current trackers text/list that will be available to the user to edit
* @param currentTrackers The current trackers for the target torrent
* @return This dialog, for method chaining
*/
public SetTrackersDialog setCurrentTrackers(String currentTrackers) {
this.currentTrackers = currentTrackers;
return this;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
if (currentTrackers == null)
throw new InvalidParameterException(
"Please first set the current trackers text using setCurrentTrackers before opening the dialog.");
if (onTrackersUpdatedListener == null)
throw new InvalidParameterException(
"Please first set the callback listener using setOnTrackersUpdated before opening the dialog.");
final View trackersFrame = getActivity().getLayoutInflater().inflate(R.layout.dialog_trackers, null, false);
final EditText trackersText = (EditText) trackersFrame.findViewById(R.id.trackers_edit);
trackersText.setText(currentTrackers);
return new AlertDialog.Builder(getActivity()).setView(trackersFrame)
.setPositiveButton(R.string.status_update, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// User is done editing and requested to update given the text input
onTrackersUpdatedListener.onTrackersUpdated(Arrays.asList(trackersText.getText().toString()
.split("\n")));
}
}).setNegativeButton(android.R.string.cancel, null).show();
}
public interface OnTrackersUpdatedListener {
public void onTrackersUpdated(List<String> updatedTrackers);
}
}
Loading…
Cancel
Save