Implement actions

This commit is contained in:
Victor Shcherb 2011-08-20 18:56:34 +02:00
parent 5c16661dfb
commit cbc3cd5602
5 changed files with 459 additions and 192 deletions

View file

@ -4,17 +4,20 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical"> android:layout_height="fill_parent" android:orientation="vertical">
<LinearLayout android:id="@+id/LoadingPanel" android:layout_width="fill_parent" android:layout_height="wrap_content"> <LinearLayout android:id="@+id/LoadingPanel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="3dp">
<ProgressBar android:id="@+id/ProgressBar" android:paddingLeft="5dp" android:indeterminate="true" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/DownloadButton" android:layout_width="wrap_content" android:layout_gravity="right" android:layout_height="wrap_content" android:text="@string/local_index_download"
<CheckBox android:id="@+id/SelectionMode" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft = "3dp" android:layout_marginTop ="3dp" android:layout_marginRight = "3dp"/>
android:layout_marginLeft = "3dp" android:layout_marginRight = "3dp" android:visibility="gone"/> <TextView android:id="@+id/DescriptionText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"
<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/> android:text="@string/local_index_description"/>
<LinearLayout android:id="@+id/FillLayoutStart" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:visibility="gone"/>
<Button android:id="@+id/ActionButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/local_index_download" <Button android:id="@+id/ActionButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/local_index_download"
android:layout_marginLeft = "3dp" android:layout_marginTop ="3dp" android:layout_marginRight = "3dp" android:visibility="gone"/> android:layout_marginLeft = "3dp" android:layout_marginTop ="3dp" android:layout_marginRight = "3dp" android:visibility="gone"/>
<Button android:id="@+id/CancelButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/default_buttons_cancel" <Button android:id="@+id/CancelButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/default_buttons_cancel"
android:layout_marginLeft = "3dp" android:layout_marginTop ="3dp" android:layout_marginRight = "3dp" android:visibility="gone"/> android:layout_marginLeft = "3dp" android:layout_marginTop ="3dp" android:layout_marginRight = "3dp" android:visibility="gone"/>
<Button android:id="@+id/DownloadButton" android:layout_width="wrap_content" android:layout_gravity="right" android:layout_height="wrap_content" android:text="@string/local_index_download"
android:layout_marginLeft = "3dp" android:layout_marginTop ="3dp" android:layout_marginRight = "3dp"/> <LinearLayout android:id="@+id/FillLayoutEnd" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:visibility="gone"/>
<ProgressBar android:id="@+id/ProgressBar" android:layout_marginLeft="5dp" android:indeterminate="true" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="5dp"/>
</LinearLayout> </LinearLayout>

View file

@ -8,7 +8,7 @@ android:orientation="vertical">
android:gravity="center_vertical" android:focusable="false"/> android:gravity="center_vertical" android:focusable="false"/>
</LinearLayout> </LinearLayout>
<TextView android:id="@+id/local_index_name" android:gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" <TextView android:id="@+id/local_index_name" android:gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:textSize="20sp"></TextView> android:layout_weight="1" android:textSize="20sp" android:layout_marginLeft="8dp"></TextView>
<TextView android:id="@+id/local_index_size" android:layout_marginLeft="3dp" android:gravity="center_vertical" android:layout_width="75dp" <TextView android:id="@+id/local_index_size" android:layout_marginLeft="3dp" android:gravity="center_vertical" android:layout_width="75dp"
android:layout_height="wrap_content" android:textSize="16sp" ></TextView> android:layout_height="wrap_content" android:textSize="16sp" ></TextView>

View file

@ -1,5 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?> <?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources> <resources>
<string name="local_index_items_backuped">%1$d items of %2$d were succesfully backuped.</string>
<string name="local_index_items_deleted">%1$d items of %2$d were succesfully deleted.</string>
<string name="local_index_items_restored">%1$d items of %2$d were succesfully restored.</string>
<string name="local_index_no_items_to_do">No items to %1$s</string>
<string name="local_index_action_do">You are about to %1$s %2$s items. Are you sure?</string>
<string name="local_index_description">Offline data available on the phone.\n You can download new or backup and delete existing data.</string>
<string name="local_index_mi_restore">Restore</string> <string name="local_index_mi_restore">Restore</string>
<string name="local_index_mi_backup">Backup</string> <string name="local_index_mi_backup">Backup</string>
<string name="local_index_mi_delete">Delete</string> <string name="local_index_mi_delete">Delete</string>

View file

@ -239,6 +239,7 @@ public class LocalIndexHelper {
private boolean notSupported = false; private boolean notSupported = false;
private boolean loaded; private boolean loaded;
private String pathToData; private String pathToData;
private String fileName;
private boolean singleFile; private boolean singleFile;
private int kbSize = -1; private int kbSize = -1;
@ -247,6 +248,7 @@ public class LocalIndexHelper {
public LocalIndexInfo(LocalIndexType type, File f, boolean backuped){ public LocalIndexInfo(LocalIndexType type, File f, boolean backuped){
pathToData = f.getAbsolutePath(); pathToData = f.getAbsolutePath();
fileName = f.getName();
name = formatName(f.getName()); name = formatName(f.getName());
this.type = type; this.type = type;
singleFile = !f.isDirectory(); singleFile = !f.isDirectory();
@ -277,6 +279,10 @@ public class LocalIndexHelper {
} }
} }
public void setBackupedData(boolean backupedData) {
this.backupedData = backupedData;
}
public void setSize(int size) { public void setSize(int size) {
this.kbSize = size; this.kbSize = size;
} }
@ -345,6 +351,10 @@ public class LocalIndexHelper {
return description; return description;
} }
public String getFileName() {
return fileName;
}
} }

View file

@ -1,22 +1,32 @@
package net.osmand.plus.activities; package net.osmand.plus.activities;
import java.io.File;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.ProgressDialogImplementation; import net.osmand.plus.ProgressDialogImplementation;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.ResourceManager;
import net.osmand.plus.activities.LocalIndexHelper.LocalIndexInfo; import net.osmand.plus.activities.LocalIndexHelper.LocalIndexInfo;
import net.osmand.plus.activities.LocalIndexHelper.LocalIndexType;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.app.ExpandableListActivity; import android.app.ExpandableListActivity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.AsyncTask.Status;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@ -27,11 +37,9 @@ import android.view.View.OnClickListener;
import android.widget.BaseExpandableListAdapter; import android.widget.BaseExpandableListAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;
public class LocalIndexesActivity extends ExpandableListActivity { public class LocalIndexesActivity extends ExpandableListActivity {
@ -39,9 +47,14 @@ public class LocalIndexesActivity extends ExpandableListActivity {
private LocalIndexesAdapter listAdapter; private LocalIndexesAdapter listAdapter;
private ProgressDialog progressDlg; private ProgressDialog progressDlg;
private LoadLocalIndexDescriptionTask descriptionLoader; private LoadLocalIndexDescriptionTask descriptionLoader;
private LocalIndexOperationTask operationTask;
private boolean selectionMode = false; private boolean selectionMode = false;
private Set<LocalIndexInfo> selectedItems = new LinkedHashSet<LocalIndexInfo>(); private Set<LocalIndexInfo> selectedItems = new LinkedHashSet<LocalIndexInfo>();
protected static int DELETE_OPERATION = 1;
protected static int BACKUP_OPERATION = 2;
protected static int RESTORE_OPERATION = 3;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -62,14 +75,6 @@ public class LocalIndexesActivity extends ExpandableListActivity {
} }
}); });
((CheckBox)findViewById(R.id.SelectionMode)).setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
selectionMode = isChecked;
listAdapter.notifyDataSetInvalidated();
}
});
setListAdapter(listAdapter); setListAdapter(listAdapter);
} }
@ -78,7 +83,7 @@ public class LocalIndexesActivity extends ExpandableListActivity {
@Override @Override
protected List<LocalIndexInfo> doInBackground(Activity... params) { protected List<LocalIndexInfo> doInBackground(Activity... params) {
LocalIndexHelper helper = new LocalIndexHelper((OsmandApplication) params[0].getApplication()); LocalIndexHelper helper = new LocalIndexHelper((OsmandApplication) getApplication());
progress.clear(); progress.clear();
return helper.getAllLocalIndexData(this); return helper.getAllLocalIndexData(this);
} }
@ -87,6 +92,11 @@ public class LocalIndexesActivity extends ExpandableListActivity {
publishProgress(loaded); publishProgress(loaded);
} }
@Override
protected void onPreExecute() {
findViewById(R.id.ProgressBar).setVisibility(View.VISIBLE);
}
@Override @Override
protected void onProgressUpdate(LocalIndexInfo... values) { protected void onProgressUpdate(LocalIndexInfo... values) {
for (LocalIndexInfo v : values) { for (LocalIndexInfo v : values) {
@ -98,9 +108,114 @@ public class LocalIndexesActivity extends ExpandableListActivity {
@Override @Override
protected void onPostExecute(List<LocalIndexInfo> result) { protected void onPostExecute(List<LocalIndexInfo> result) {
findViewById(R.id.ProgressBar).setVisibility(View.GONE); findViewById(R.id.ProgressBar).setVisibility(View.GONE);
findViewById(R.id.SelectionMode).setVisibility(View.VISIBLE); }
}
public class LocalIndexOperationTask extends AsyncTask<LocalIndexInfo, LocalIndexInfo, String> {
private final int operation;
private OsmandSettings settings;
public LocalIndexOperationTask(int operation){
this.operation = operation;
settings = ((OsmandApplication) getApplication()).getSettings();
}
public File getFileToRestore(LocalIndexInfo i){
if(i.isBackupedData()){
File parent = new File(i.getPathToData()).getParentFile();
if(i.getType() == LocalIndexType.GPX_DATA){
parent = settings.extendOsmandPath(ResourceManager.GPX_PATH);
} else if(i.getType() == LocalIndexType.MAP_DATA){
parent = settings.extendOsmandPath(ResourceManager.MAPS_PATH);
} else if(i.getType() == LocalIndexType.POI_DATA){
parent = settings.extendOsmandPath(ResourceManager.POI_PATH);
} else if(i.getType() == LocalIndexType.TILES_DATA){
parent = settings.extendOsmandPath(ResourceManager.TILES_PATH);
} else if(i.getType() == LocalIndexType.VOICE_DATA){
parent = settings.extendOsmandPath(ResourceManager.VOICE_PATH);
} else if(i.getType() == LocalIndexType.TTS_VOICE_DATA){
parent = settings.extendOsmandPath(ResourceManager.VOICE_PATH);
}
return new File(parent, i.getFileName());
}
return new File(i.getPathToData());
}
private File getFileToBackup(LocalIndexInfo i) {
if(!i.isBackupedData()){
return new File(settings.extendOsmandPath(ResourceManager.BACKUP_PATH), i.getFileName());
}
return new File(i.getPathToData());
}
private boolean move(File from, File to){
return from.renameTo(to);
}
@Override
protected String doInBackground(LocalIndexInfo... params) {
int count = 0;
int total = 0;
for(LocalIndexInfo info : params) {
if(!isCancelled()){
boolean successfull = false;
if(operation == DELETE_OPERATION){
File f = new File(info.getPathToData());
successfull = f.delete();
} else if(operation == RESTORE_OPERATION){
successfull = move(new File(info.getPathToData()), getFileToRestore(info));
if(successfull){
info.setBackupedData(false);
}
} else if(operation == BACKUP_OPERATION){
successfull = move(new File(info.getPathToData()), getFileToBackup(info));
if(successfull){
info.setBackupedData(true);
}
}
total ++;
if(successfull){
count++;
publishProgress(info);
}
}
}
if(operation == DELETE_OPERATION){
return getString(R.string.local_index_items_deleted, count, total);
} else if(operation == BACKUP_OPERATION){
return getString(R.string.local_index_items_backuped, count, total);
} else if(operation == RESTORE_OPERATION){
return getString(R.string.local_index_items_restored, count, total);
}
return "";
}
@Override
protected void onProgressUpdate(LocalIndexInfo... values) {
if(operation == DELETE_OPERATION){
listAdapter.delete(values);
} else if(operation == BACKUP_OPERATION){
listAdapter.move(values, false);
} else if(operation == RESTORE_OPERATION){
listAdapter.move(values, true);
}
} }
@Override
protected void onPreExecute() {
findViewById(R.id.ProgressBar).setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(String result) {
findViewById(R.id.ProgressBar).setVisibility(View.GONE);
Toast.makeText(LocalIndexesActivity.this, result, Toast.LENGTH_LONG).show();
reloadIndexes();
}
} }
@ -108,7 +223,7 @@ public class LocalIndexesActivity extends ExpandableListActivity {
@Override @Override
protected LocalIndexInfo[] doInBackground(LocalIndexInfo... params) { protected LocalIndexInfo[] doInBackground(LocalIndexInfo... params) {
LocalIndexHelper helper = new LocalIndexHelper((OsmandApplication) LocalIndexesActivity.this.getApplication()); LocalIndexHelper helper = new LocalIndexHelper((OsmandApplication) getApplication());
for (LocalIndexInfo i : params) { for (LocalIndexInfo i : params) {
helper.updateDescription(i); helper.updateDescription(i);
} }
@ -142,6 +257,14 @@ public class LocalIndexesActivity extends ExpandableListActivity {
listAdapter.notifyDataSetInvalidated(); listAdapter.notifyDataSetInvalidated();
return true; return true;
} }
@Override
protected void onPause() {
super.onPause();
if(operationTask != null){
operationTask.cancel(true);
}
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {
@ -154,190 +277,79 @@ public class LocalIndexesActivity extends ExpandableListActivity {
descriptionLoader.cancel(true); descriptionLoader.cancel(true);
} }
private class SelectItemListener implements CompoundButton.OnCheckedChangeListener {
private final LocalIndexInfo child;
public SelectItemListener(LocalIndexInfo child) {
this.child = child;
}
@Override
public void onCheckedChanged(CompoundButton v, boolean isChecked) {
if(isChecked){
selectedItems.add(child);
} else {
selectedItems.remove(child);
}
}
}
protected class LocalIndexesAdapter extends BaseExpandableListAdapter {
List<List<LocalIndexInfo>> data = new ArrayList<List<LocalIndexInfo>>();
List<LocalIndexInfo> category = new ArrayList<LocalIndexInfo>();
private MessageFormat formatMb;
public LocalIndexesAdapter() {
formatMb = new MessageFormat("{0, number,##.#} MB");
}
public void addLocalIndexInfo(LocalIndexInfo info) {
int found = -1;
// search from end
for (int i = category.size() - 1; i >= 0; i--) {
LocalIndexInfo cat = category.get(i);
if (cat.getType() == info.getType() && info.isBackupedData() == cat.isBackupedData()) {
found = i;
break;
}
}
if (found == -1) {
found = category.size();
category.add(new LocalIndexInfo(info.getType(), info.isBackupedData()));
}
if (found >= data.size()) {
data.add(new ArrayList<LocalIndexInfo>());
}
data.get(found).add(info);
}
@Override
public LocalIndexInfo getChild(int groupPosition, int childPosition) {
return data.get(groupPosition).get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
// it would be unusable to have 10000 local indexes
return groupPosition * 10000 + childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View v = convertView;
LocalIndexInfo child = (LocalIndexInfo) getChild(groupPosition, childPosition);
if (v == null || selectionMode) {
LayoutInflater inflater = getLayoutInflater();
v = inflater.inflate(net.osmand.plus.R.layout.local_index_list_item, parent, false);
}
TextView viewName = ((TextView) v.findViewById(R.id.local_index_name));
viewName.setText(child.getName());
if (child.isNotSupported()) {
viewName.setTextColor(Color.RED);
} else if (child.isCorrupted()) {
viewName.setTextColor(Color.MAGENTA);
} else if (child.isLoaded()) {
viewName.setTextColor(Color.GREEN);
} else {
viewName.setTextColor(Color.LTGRAY);
}
if (child.getSize() >= 0) {
String size;
if (child.getSize() > 100) {
size = formatMb.format(new Object[] { (float) child.getSize() / (1 << 10) });
} else {
size = child.getSize() + " Kb";
}
((TextView) v.findViewById(R.id.local_index_size)).setText(size);
} else {
((TextView) v.findViewById(R.id.local_index_size)).setText("");
}
TextView descr = ((TextView) v.findViewById(R.id.local_index_descr));
if (child.isExpanded()) {
descr.setVisibility(View.VISIBLE);
descr.setText(child.getDescription());
} else {
descr.setVisibility(View.GONE);
}
CheckBox checkbox = (CheckBox) v.findViewById(R.id.check_local_index);
checkbox.setVisibility(selectionMode ? View.VISIBLE : View.GONE);
if (selectionMode) {
checkbox.setSelected(selectedItems.contains(child));
checkbox.setOnCheckedChangeListener(new SelectItemListener(child));
}
return v;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View v = convertView;
LocalIndexInfo group = getGroup(groupPosition);
if (v == null) {
LayoutInflater inflater = getLayoutInflater();
v = inflater.inflate(net.osmand.plus.R.layout.local_index_list_item_category, parent, false);
}
StringBuilder t = new StringBuilder(group.getType().getHumanString(LocalIndexesActivity.this));
if (group.isBackupedData()) {
t.append("* ");
}
TextView nameView = ((TextView) v.findViewById(R.id.local_index_category_name));
t.append(" [").append(getChildrenCount(groupPosition)).append(" ").append(getString(R.string.local_index_items)).append("]");
nameView.setText(t.toString());
if (!group.isBackupedData()) {
nameView.setTypeface(Typeface.DEFAULT, Typeface.NORMAL);
} else {
nameView.setTypeface(Typeface.DEFAULT, Typeface.ITALIC);
}
return v;
}
@Override
public int getChildrenCount(int groupPosition) {
return data.get(groupPosition).size();
}
@Override
public LocalIndexInfo getGroup(int groupPosition) {
return category.get(groupPosition);
}
@Override
public int getGroupCount() {
return category.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, R.string.local_index_mi_reload, 0, R.string.local_index_mi_reload);
menu.add(0, R.string.local_index_mi_delete, 0, R.string.local_index_mi_delete);
menu.add(0, R.string.local_index_mi_restore, 0, R.string.local_index_mi_restore);
menu.add(0, R.string.local_index_mi_backup, 0, R.string.local_index_mi_backup); menu.add(0, R.string.local_index_mi_backup, 0, R.string.local_index_mi_backup);
menu.add(0, R.string.local_index_mi_reload, 1, R.string.local_index_mi_reload);
menu.add(0, R.string.local_index_mi_delete, 2, R.string.local_index_mi_delete);
menu.add(0, R.string.local_index_mi_restore, 3, R.string.local_index_mi_restore);
return true; return true;
} }
private void openSelectionMode(String actionButton){ @Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(operationTask == null || operationTask.getStatus() == Status.FINISHED){
menu.setGroupVisible(0, true);
} else {
menu.setGroupVisible(0, false);
}
return true;
}
public void doAction(int actionResId){
if(actionResId == R.string.local_index_mi_backup){
operationTask = new LocalIndexOperationTask(BACKUP_OPERATION);
} else if(actionResId == R.string.local_index_mi_delete){
operationTask = new LocalIndexOperationTask(DELETE_OPERATION);
} else if(actionResId == R.string.local_index_mi_restore){
operationTask = new LocalIndexOperationTask(RESTORE_OPERATION);
} else {
operationTask = null;
}
if(operationTask != null){
operationTask.execute(selectedItems.toArray(new LocalIndexInfo[selectedItems.size()]));
}
closeSelectionMode();
}
private void openSelectionMode(final int actionResId){
final String actionButton = getString(actionResId);
if(listAdapter.getGroupCount() == 0){
listAdapter.cancelFilter();
Toast.makeText(LocalIndexesActivity.this, getString(R.string.local_index_no_items_to_do, actionButton.toLowerCase()), Toast.LENGTH_SHORT).show();
return;
}
selectionMode = true; selectionMode = true;
selectedItems.clear(); selectedItems.clear();
Button action = (Button) findViewById(R.id.ActionButton); Button action = (Button) findViewById(R.id.ActionButton);
action.setVisibility(View.VISIBLE); action.setVisibility(View.VISIBLE);
action.setText(actionButton);
action.setOnClickListener(new OnClickListener() { action.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if(selectedItems.isEmpty()){
Toast.makeText(LocalIndexesActivity.this, getString(R.string.local_index_no_items_to_do, actionButton.toLowerCase()), Toast.LENGTH_SHORT).show();
return;
}
Builder builder = new AlertDialog.Builder(LocalIndexesActivity.this);
builder.setMessage(getString(R.string.local_index_action_do, actionButton.toLowerCase(), selectedItems.size()));
builder.setPositiveButton(actionButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
doAction(actionResId);
}
});
builder.setNegativeButton(R.string.default_buttons_cancel, null);
builder.show();
} }
}); });
Button cancel = (Button) findViewById(R.id.CancelButton); Button cancel = (Button) findViewById(R.id.CancelButton);
@ -350,14 +362,21 @@ public class LocalIndexesActivity extends ExpandableListActivity {
} }
}); });
findViewById(R.id.DownloadButton).setVisibility(View.GONE); findViewById(R.id.DownloadButton).setVisibility(View.GONE);
findViewById(R.id.DescriptionText).setVisibility(View.GONE);
findViewById(R.id.FillLayoutStart).setVisibility(View.VISIBLE);
findViewById(R.id.FillLayoutEnd).setVisibility(View.VISIBLE);
listAdapter.notifyDataSetChanged(); listAdapter.notifyDataSetChanged();
} }
private void closeSelectionMode(){ private void closeSelectionMode(){
selectionMode = false; selectionMode = false;
findViewById(R.id.DownloadButton).setVisibility(View.VISIBLE); findViewById(R.id.DownloadButton).setVisibility(View.VISIBLE);
findViewById(R.id.DescriptionText).setVisibility(View.VISIBLE);
findViewById(R.id.FillLayoutStart).setVisibility(View.GONE);
findViewById(R.id.FillLayoutEnd).setVisibility(View.GONE);
findViewById(R.id.CancelButton).setVisibility(View.GONE); findViewById(R.id.CancelButton).setVisibility(View.GONE);
findViewById(R.id.ActionButton).setVisibility(View.GONE); findViewById(R.id.ActionButton).setVisibility(View.GONE);
listAdapter.cancelFilter();
listAdapter.notifyDataSetChanged(); listAdapter.notifyDataSetChanged();
} }
@ -366,11 +385,14 @@ public class LocalIndexesActivity extends ExpandableListActivity {
if(item.getItemId() == R.string.local_index_mi_reload){ if(item.getItemId() == R.string.local_index_mi_reload){
reloadIndexes(); reloadIndexes();
} else if(item.getItemId() == R.string.local_index_mi_delete){ } else if(item.getItemId() == R.string.local_index_mi_delete){
openSelectionMode(getString(R.string.local_index_mi_delete)); openSelectionMode(R.string.local_index_mi_delete);
} else if(item.getItemId() == R.string.local_index_mi_backup){ } else if(item.getItemId() == R.string.local_index_mi_backup){
openSelectionMode(getString(R.string.local_index_mi_backup)); listAdapter.filterCategories(false);
listAdapter.filterCategories(LocalIndexType.MAP_DATA, LocalIndexType.POI_DATA);
openSelectionMode(R.string.local_index_mi_backup);
} else if(item.getItemId() == R.string.local_index_mi_restore){ } else if(item.getItemId() == R.string.local_index_mi_restore){
openSelectionMode(getString(R.string.local_index_mi_restore)); listAdapter.filterCategories(true);
openSelectionMode(R.string.local_index_mi_restore);
} else { } else {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -418,4 +440,230 @@ public class LocalIndexesActivity extends ExpandableListActivity {
} }
} }
protected class LocalIndexesAdapter extends BaseExpandableListAdapter {
Map<LocalIndexInfo, List<LocalIndexInfo>> data = new LinkedHashMap<LocalIndexInfo, List<LocalIndexInfo>>();
List<LocalIndexInfo> category = new ArrayList<LocalIndexInfo>();
List<LocalIndexInfo> filterCategory = null;
private MessageFormat formatMb;
public LocalIndexesAdapter() {
formatMb = new MessageFormat("{0, number,##.#} MB");
}
public LocalIndexInfo findCategory(LocalIndexInfo val, boolean backuped){
for(LocalIndexInfo i : category){
if(i.isBackupedData() == backuped && val.getType() == i.getType() ){
return i;
}
}
LocalIndexInfo newCat = new LocalIndexInfo(val.getType(), backuped);
category.add(newCat);
data.put(newCat, new ArrayList<LocalIndexInfo>());
return newCat;
}
public void delete(LocalIndexInfo[] values) {
for(LocalIndexInfo i : values){
LocalIndexInfo c = findCategory(i, i.isBackupedData());
if(c != null){
data.get(c).remove(i);
}
}
listAdapter.notifyDataSetChanged();
}
public void move(LocalIndexInfo[] values, boolean oldBackupState) {
for(LocalIndexInfo i : values){
LocalIndexInfo c = findCategory(i, oldBackupState);
if(c != null){
data.get(c).remove(i);
}
c = findCategory(i, !oldBackupState);
if(c != null){
data.get(c).add(i);
}
}
listAdapter.notifyDataSetChanged();
}
public void cancelFilter(){
filterCategory = null;
notifyDataSetChanged();
}
public void filterCategories(LocalIndexType... types) {
List<LocalIndexInfo> filter = new ArrayList<LocalIndexInfo>();
List<LocalIndexInfo> source = filterCategory == null ? category : filterCategory;
for (LocalIndexInfo info : source) {
for (LocalIndexType ts : types) {
if (info.getType() == ts) {
filter.add(info);
}
}
}
filterCategory = filter;
notifyDataSetChanged();
}
public void filterCategories(boolean backup) {
List<LocalIndexInfo> filter = new ArrayList<LocalIndexInfo>();
List<LocalIndexInfo> source = filterCategory == null ? category : filterCategory;
for (LocalIndexInfo info : source) {
if (info.isBackupedData() == backup) {
filter.add(info);
}
}
filterCategory = filter;
notifyDataSetChanged();
}
public void addLocalIndexInfo(LocalIndexInfo info) {
int found = -1;
// search from end
for (int i = category.size() - 1; i >= 0; i--) {
LocalIndexInfo cat = category.get(i);
if (cat.getType() == info.getType() && info.isBackupedData() == cat.isBackupedData()) {
found = i;
break;
}
}
if (found == -1) {
found = category.size();
category.add(new LocalIndexInfo(info.getType(), info.isBackupedData()));
}
if (!data.containsKey(category.get(found))) {
data.put(category.get(found), new ArrayList<LocalIndexInfo>());
}
data.get(category.get(found)).add(info);
}
@Override
public LocalIndexInfo getChild(int groupPosition, int childPosition) {
LocalIndexInfo cat = filterCategory != null ? filterCategory.get(groupPosition) : category.get(groupPosition);
return data.get(cat).get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
// it would be unusable to have 10000 local indexes
return groupPosition * 10000 + childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View v = convertView;
final LocalIndexInfo child = (LocalIndexInfo) getChild(groupPosition, childPosition);
if (v == null ) {
LayoutInflater inflater = getLayoutInflater();
v = inflater.inflate(net.osmand.plus.R.layout.local_index_list_item, parent, false);
}
TextView viewName = ((TextView) v.findViewById(R.id.local_index_name));
viewName.setText(child.getName());
if (child.isNotSupported()) {
viewName.setTextColor(Color.RED);
} else if (child.isCorrupted()) {
viewName.setTextColor(Color.MAGENTA);
} else if (child.isLoaded()) {
viewName.setTextColor(Color.GREEN);
} else {
viewName.setTextColor(Color.LTGRAY);
}
if (child.getSize() >= 0) {
String size;
if (child.getSize() > 100) {
size = formatMb.format(new Object[] { (float) child.getSize() / (1 << 10) });
} else {
size = child.getSize() + " Kb";
}
((TextView) v.findViewById(R.id.local_index_size)).setText(size);
} else {
((TextView) v.findViewById(R.id.local_index_size)).setText("");
}
TextView descr = ((TextView) v.findViewById(R.id.local_index_descr));
if (child.isExpanded()) {
descr.setVisibility(View.VISIBLE);
descr.setText(child.getDescription());
} else {
descr.setVisibility(View.GONE);
}
final CheckBox checkbox = (CheckBox) v.findViewById(R.id.check_local_index);
checkbox.setVisibility(selectionMode ? View.VISIBLE : View.GONE);
if (selectionMode) {
checkbox.setChecked(selectedItems.contains(child));
checkbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(checkbox.isChecked()){
selectedItems.add(child);
} else {
selectedItems.remove(child);
}
}
});
}
return v;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View v = convertView;
LocalIndexInfo group = getGroup(groupPosition);
if (v == null) {
LayoutInflater inflater = getLayoutInflater();
v = inflater.inflate(net.osmand.plus.R.layout.local_index_list_item_category, parent, false);
}
StringBuilder t = new StringBuilder(group.getType().getHumanString(LocalIndexesActivity.this));
if (group.isBackupedData()) {
t.append("* ");
}
TextView nameView = ((TextView) v.findViewById(R.id.local_index_category_name));
t.append(" [").append(getChildrenCount(groupPosition)).append(" ").append(getString(R.string.local_index_items)).append("]");
nameView.setText(t.toString());
if (!group.isBackupedData()) {
nameView.setTypeface(Typeface.DEFAULT, Typeface.NORMAL);
} else {
nameView.setTypeface(Typeface.DEFAULT, Typeface.ITALIC);
}
return v;
}
@Override
public int getChildrenCount(int groupPosition) {
LocalIndexInfo cat = filterCategory != null ? filterCategory.get(groupPosition) : category.get(groupPosition);
return data.get(cat).size();
}
@Override
public LocalIndexInfo getGroup(int groupPosition) {
return filterCategory == null ? category.get(groupPosition) : filterCategory.get(groupPosition);
}
@Override
public int getGroupCount() {
return filterCategory == null ? category.size() : filterCategory.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
} }