mirror of https://github.com/BOINC/boinc.git
AndroidBOINC: Sort attachable projects list alphabetically
This commit is contained in:
parent
845f90bb07
commit
6360b6ac5e
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file is part of BOINC.
|
* This file is part of BOINC.
|
||||||
* http://boinc.berkeley.edu
|
* http://boinc.berkeley.edu
|
||||||
* Copyright (C) 2012 University of California
|
* Copyright (C) 2016 University of California
|
||||||
*
|
*
|
||||||
* BOINC is free software; you can redistribute it and/or modify it
|
* BOINC is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU Lesser General Public License
|
* under the terms of the GNU Lesser General Public License
|
||||||
|
@ -19,12 +19,6 @@
|
||||||
|
|
||||||
package edu.berkeley.boinc.attach;
|
package edu.berkeley.boinc.attach;
|
||||||
|
|
||||||
import edu.berkeley.boinc.R;
|
|
||||||
import edu.berkeley.boinc.utils.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import edu.berkeley.boinc.client.IMonitor;
|
|
||||||
import edu.berkeley.boinc.client.Monitor;
|
|
||||||
import edu.berkeley.boinc.rpc.ProjectInfo;
|
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -41,6 +35,14 @@ import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import edu.berkeley.boinc.R;
|
||||||
|
import edu.berkeley.boinc.client.IMonitor;
|
||||||
|
import edu.berkeley.boinc.client.Monitor;
|
||||||
|
import edu.berkeley.boinc.rpc.ProjectInfo;
|
||||||
|
import edu.berkeley.boinc.utils.Logging;
|
||||||
|
import java.text.Collator;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public class SelectionListActivity extends FragmentActivity{
|
public class SelectionListActivity extends FragmentActivity{
|
||||||
|
|
||||||
|
@ -180,42 +182,71 @@ public class SelectionListActivity extends FragmentActivity{
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UpdateProjectListAsyncTask extends AsyncTask<Void, Void, ArrayList<ProjectInfo>> {
|
private class UpdateProjectListAsyncTask extends AsyncTask<Void, Void, ArrayList<ProjectInfo>> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArrayList<ProjectInfo> doInBackground(Void... arg0) {
|
protected ArrayList<ProjectInfo> doInBackground(Void... arg0) {
|
||||||
|
|
||||||
ArrayList<ProjectInfo> data = null;
|
ArrayList<ProjectInfo> data = null;
|
||||||
Boolean retry = true;
|
boolean retry = true;
|
||||||
while(retry) {
|
// Try to get the project list for as long as the AsyncTask has not been canceled
|
||||||
try{data = (ArrayList<ProjectInfo>) monitor.getAttachableProjects();} catch (RemoteException e){}
|
while (!super.isCancelled() && retry) {
|
||||||
if(data == null) {
|
try {
|
||||||
if(Logging.WARNING) Log.w(Logging.TAG,"UpdateProjectListAsyncTask: failed to retrieve data, retry....");
|
data = (ArrayList<ProjectInfo>)monitor.getAttachableProjects();
|
||||||
try{Thread.sleep(500);} catch(Exception e) {}
|
} catch (RemoteException e) {}
|
||||||
|
if (data == null) {
|
||||||
|
if (Logging.WARNING) Log.w(Logging.TAG, "UpdateProjectListAsyncTask: failed to retrieve data, retry....");
|
||||||
|
try {
|
||||||
|
Thread.sleep(500);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
if (Log.isLoggable(Logging.TAG, Log.DEBUG)) Log.d(Logging.TAG, e.getMessage(), e);
|
||||||
|
}
|
||||||
} else retry = false;
|
} else retry = false;
|
||||||
}
|
}
|
||||||
if(Logging.DEBUG) Log.d( Logging.TAG,"monitor.getAttachableProjects returned with " + data.size() + " elements");
|
if (Logging.DEBUG) Log.d(Logging.TAG, "monitor.getAttachableProjects returned with " + data.size() + " elements");
|
||||||
|
// Clear current ProjectListEntries since we successfully have got new ProjectInfos
|
||||||
|
SelectionListActivity.this.entries.clear();
|
||||||
|
// Transform ProjectInfos into ProjectListEntries
|
||||||
|
for (int i = data.size() - 1; !super.isCancelled() && i >= 0; i--) {
|
||||||
|
SelectionListActivity.this.entries.add(new ProjectListEntry(data.get(i)));
|
||||||
|
}
|
||||||
|
// Set preferred Collator for ProjectListEntries before sorting
|
||||||
|
if (SelectionListActivity.ProjectListEntry.collator == null) {
|
||||||
|
SelectionListActivity.ProjectListEntry.collator = SelectionListActivity.ProjectListEntry.getCollator();
|
||||||
|
}
|
||||||
|
// Sort ProjectListEntries off the UI thread
|
||||||
|
Collections.sort(SelectionListActivity.this.entries);
|
||||||
|
// Dispose Collator instance after sorting
|
||||||
|
SelectionListActivity.ProjectListEntry.collator = null;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onPostExecute(ArrayList<ProjectInfo> result) {
|
protected final void onPostExecute(final ArrayList<ProjectInfo> result) {
|
||||||
if (result != null) {
|
if (result == null) return;
|
||||||
entries.clear();
|
|
||||||
for(ProjectInfo tmp: result) {
|
|
||||||
entries.add(new ProjectListEntry(tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
entries.add(new ProjectListEntry()); // add account manager option to bottom of list
|
SelectionListActivity.this.entries.add(new ProjectListEntry()); // add account manager option to bottom of list
|
||||||
SelectionListAdapter listAdapter = new SelectionListAdapter(SelectionListActivity.this,R.id.listview,entries);
|
SelectionListAdapter listAdapter = new SelectionListAdapter(SelectionListActivity.this, R.id.listview,entries);
|
||||||
lv.setAdapter(listAdapter);
|
lv.setAdapter(listAdapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class ProjectListEntry {
|
static final class ProjectListEntry implements Comparable<SelectionListActivity.ProjectListEntry> {
|
||||||
public ProjectInfo info;
|
public ProjectInfo info;
|
||||||
public boolean checked;
|
public boolean checked;
|
||||||
public boolean am; //indicates that element is account manager entry
|
public boolean am; //indicates that element is account manager entry
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Collator} used when comparing {@code ProjectListEntry}s.
|
||||||
|
* This member is usually only set when performing comparison operations
|
||||||
|
* in bulk. Otherwise, it should be set to {@code null} to avoid having
|
||||||
|
* a {@link Collator} instance lingering around when not attaching
|
||||||
|
* projects (most of the time). Furthermore, when comparing
|
||||||
|
* {@code ProjectListEntry}s in bulk the {@link Collator} instance
|
||||||
|
* stored by this member does not need to get reallocated and setup on
|
||||||
|
* every comparison.
|
||||||
|
*
|
||||||
|
* @see SelectionListActivity.ProjectListEntry#getCollator()
|
||||||
|
* @see Collator
|
||||||
|
*/
|
||||||
|
static Collator collator;
|
||||||
|
|
||||||
public ProjectListEntry(ProjectInfo info) {
|
public ProjectListEntry(ProjectInfo info) {
|
||||||
this.info = info;
|
this.info = info;
|
||||||
this.checked = false;
|
this.checked = false;
|
||||||
|
@ -227,5 +258,36 @@ public class SelectionListActivity extends FragmentActivity{
|
||||||
public ProjectListEntry() {
|
public ProjectListEntry() {
|
||||||
this.am = true;
|
this.am = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares this {@code ProjectListEntry} instance to {@code p} based
|
||||||
|
* on {@link ProjectInfo#name}. The comparison is <i>case-insensitive</i>.
|
||||||
|
*
|
||||||
|
* @param p the {@code ProjectListEntry} to compare to
|
||||||
|
* @return {@code 0} if both {@link ProjectInfo#name}s are equal,<br>
|
||||||
|
* {@code -1} if {@code this} {@link ProjectInfo#name} comes before
|
||||||
|
* {@code p}'s {@link ProjectInfo#name} in the current locale's
|
||||||
|
* {@link Collator#getInstance() collation},<br>else {@code 1}
|
||||||
|
* @see SelectionListActivity.ProjectListEntry#info
|
||||||
|
* @see ProjectInfo#name
|
||||||
|
* @see Comparable#compareTo(T)
|
||||||
|
*/
|
||||||
|
public final int compareTo(final SelectionListActivity.ProjectListEntry p) {
|
||||||
|
return (SelectionListActivity.ProjectListEntry.collator == null ?
|
||||||
|
SelectionListActivity.ProjectListEntry.getCollator() :
|
||||||
|
SelectionListActivity.ProjectListEntry.collator).compare(this.info.name, p.info.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the preferred locale specific {@link Collator} for comparing {@code ProjectListEntry}s.
|
||||||
|
*
|
||||||
|
* @return the preferred {@link Collator}
|
||||||
|
*/
|
||||||
|
static final Collator getCollator() {
|
||||||
|
final Collator collator;
|
||||||
|
(collator = Collator.getInstance()).setStrength(Collator.SECONDARY);
|
||||||
|
collator.setDecomposition(Collator.NO_DECOMPOSITION);
|
||||||
|
return collator;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue