Rework the filebrowser some to add some functionality. A "hidden" preference now stores the default directory to open. This directory is marked with a gold star. To change the default directory, you touch on a star. Added icon for directories. Added preference to control if only ork files are shown in the file browser. Changed the sort order to do the fancy "logical" sort to compare number components numerically.

This commit is contained in:
Kevin Ruland 2012-02-14 18:33:31 +00:00
parent 4f090843b1
commit ff05c2b499
10 changed files with 341 additions and 31 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 993 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true" android:drawable="@drawable/ic_star_select"/>
<item android:drawable="@drawable/ic_star_unselected"/>
</selector>

View File

@ -0,0 +1,30 @@
<?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="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/filebrowser_list_item_typeicon"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:id="@+id/filebrowser_list_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="6dip"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ImageView
android:id="@+id/filebrowser_list_item_homeicon"
android:layout_width="48dp"
android:layout_height="48dp"
android:gravity="right"
android:paddingRight="15dp"
android:src="@drawable/filebrowser_home" />
</LinearLayout>

View File

@ -4,6 +4,8 @@
<string name="PreferenceMotorBrowserGroupingOption">PreferenceMotorBrowserGroupingOption</string>
<string name="PreferenceUseInternalFileBrowserOption">PreferenceUseInternalFileBrowserOpion</string>
<string name="PreferenceFileBrowserBaseDirectory">PreferenceFileBrowserBaseDirectory</string>
<string name="PreferenceShowOnlyOrkFiles">PreferenceShowOnlyOrkFiles</string>
<string-array name="PreferenceMotorBrowserGroupingValues">
<item>0</item>

View File

@ -93,9 +93,13 @@
<string name="simulationSeries2Label">Series 2</string>
<string name="motorbrowsergrouptitle">Motor Browser Grouping</string>
<string name="useinternalfilebrowsertitle">Use Internal File Browser</string>
<string name="useinternalfilebrowsersummary">Check to use built in file browser instead of external file browser</string>
<string name="showonlyorkfiles">Show only ORK files in Internal File Browser</string>
<string name="showonlyorkfilessummary">Check to show only .ork files in internal file browser</string>
<string-array name="PreferenceUnitLengthEntries">
<item>Millimeters</item>
<item>Centimeters</item>

View File

@ -17,7 +17,22 @@
android:key="@string/PreferenceUseInternalFileBrowserOption"
android:summary="@string/useinternalfilebrowsersummary"
/>
<CheckBoxPreference
android:defaultValue="false"
android:title="@string/showonlyorkfiles"
android:key="@string/PreferenceShowOnlyOrkFiles"
android:summary="@string/showonlyorkfilessummary"
android:dependency="@string/PreferenceUseInternalFileBrowserOption"
/>
<!-- This preference is hidden - not to be configured in the Preference screen
<Preference
android:defaultValue="/"
android:key="@string/PreferenceFileBrowserBaseDirectory"
/>
-->
<PreferenceScreen
android:key="UnitPrefences"
android:summary="Configure units"

View File

@ -0,0 +1,138 @@
/*
* The Alphanum Algorithm is an improved sorting algorithm for strings
* containing numbers. Instead of sorting numbers in ASCII order like
* a standard sort, this algorithm sorts numbers in numeric order.
*
* The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
* Subsequently this code had been hacked up to make it genericized and support
* folding upper/lower case.
*/
package net.sf.openrocket.android.filebrowser;
import java.text.Collator;
import java.util.Comparator;
/**
* This is an updated version with enhancements made by Daniel Migowski,
* Andre Bogus, and David Koelle
*
* To convert to use Templates (Java 1.5+):
* - Change "implements Comparator" to "implements Comparator<String>"
* - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)"
* - Remove the type checking and casting in compare().
*
* To use this class:
* Use the static "sort" method from the java.util.Collections class:
* Collections.sort(your list, new AlphanumComparator());
*/
public class AlphanumComparator implements Comparator<String>
{
private static final Collator sorter = Collator.getInstance();
static {
sorter.setStrength(Collator.TERTIARY);
sorter.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
}
private final boolean isDigit(char ch)
{
return ch >= 48 && ch <= 57;
}
/** Length of string is passed in for improved efficiency (only need to calculate it once) **/
private final String getChunk(String s, int slength, int marker)
{
StringBuilder chunk = new StringBuilder();
char c = s.charAt(marker);
chunk.append(c);
marker++;
if (isDigit(c))
{
while (marker < slength)
{
c = s.charAt(marker);
if (!isDigit(c))
break;
chunk.append(c);
marker++;
}
} else
{
while (marker < slength)
{
c = s.charAt(marker);
if (isDigit(c))
break;
chunk.append(c);
marker++;
}
}
return chunk.toString();
}
public int compare(String s1, String s2)
{
int thisMarker = 0;
int thatMarker = 0;
int s1Length = s1.length();
int s2Length = s2.length();
while (thisMarker < s1Length && thatMarker < s2Length)
{
String thisChunk = getChunk(s1, s1Length, thisMarker);
thisMarker += thisChunk.length();
String thatChunk = getChunk(s2, s2Length, thatMarker);
thatMarker += thatChunk.length();
// If both chunks contain numeric characters, sort them numerically
int result = 0;
if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))
{
// Simple chunk comparison by length.
int thisChunkLength = thisChunk.length();
result = thisChunkLength - thatChunk.length();
// If equal, the first different number counts
if (result == 0)
{
for (int i = 0; i < thisChunkLength; i++)
{
result = thisChunk.charAt(i) - thatChunk.charAt(i);
if (result != 0)
{
return result;
}
}
}
} else
{
result = sorter.compare(thisChunk, thatChunk);
}
if (result != 0)
return result;
}
return s1Length - s2Length;
}
}

View File

@ -13,32 +13,47 @@ import net.sf.openrocket.android.actionbarcompat.ActionBarListActivity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.ArrayAdapter;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class SimpleFileBrowser extends ActionBarListActivity {
private List<String> item = null;
private List<String> path = null;
private String root = "/";
private List<File> path = null;
private final static File root = new File("/");
private String baseDirPrefKey;
private String baseDirName;
private boolean showOnlyOrkFiles;
private static final OrkFileFilter filter = new OrkFileFilter();
private static final Collator sorter = Collator.getInstance();
static {
sorter.setStrength(Collator.TERTIARY);
sorter.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
}
private static final Comparator<String> sorter = new AlphanumComparator();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simplefilebrowser);
getDir( Environment.getExternalStorageDirectory().getAbsolutePath() );
Resources resources = this.getResources();
baseDirPrefKey = resources.getString(R.string.PreferenceFileBrowserBaseDirectory);
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
String showOnlyOrkFilesKey = resources.getString(R.string.PreferenceShowOnlyOrkFiles);
showOnlyOrkFiles = pref.getBoolean(showOnlyOrkFilesKey, false);
baseDirName = pref.getString(baseDirPrefKey, Environment.getExternalStorageDirectory().getAbsolutePath() );
getDir( new File(baseDirName) );
}
private static class OrkFileFilter implements FileFilter {
@ -51,12 +66,15 @@ public class SimpleFileBrowser extends ActionBarListActivity {
if ( arg0.isDirectory() ) {
return true;
}
return isOrk(arg0);
}
public boolean isOrk(File arg0) {
if ( arg0.getName().endsWith(".ork") ) {
return true;
}
return false;
}
}
private static class FileComparator implements Comparator<File> {
@ -84,39 +102,32 @@ public class SimpleFileBrowser extends ActionBarListActivity {
}
private void getDir(String dirPath) {
setTitle(dirPath);
item = new ArrayList<String>();
path = new ArrayList<String>();
private void getDir(File dirPath) {
setTitle(dirPath.getAbsolutePath());
path = new ArrayList<File>();
File f = new File(dirPath);
File[] files = f.listFiles(filter);
File[] files = dirPath.listFiles((showOnlyOrkFiles) ? filter : null );
if (!dirPath.equals(root)) {
item.add(root);
boolean hasUp = false;
if ( !dirPath.getAbsolutePath().equals("/")) {
path.add(root);
item.add("../");
path.add(f.getParent());
path.add( dirPath.getParentFile() );
hasUp = true;
}
Arrays.sort(files, new FileComparator() );
for (int i = 0; i < files.length; i++) {
File file = files[i];
path.add(file.getPath());
if (file.isDirectory())
item.add(file.getName() + "/");
else
item.add(file.getName());
for( File file : files ) {
path.add(file);
}
ArrayAdapter<String> fileList = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, item);
DirectoryList fileList = new DirectoryList(hasUp, path);
setListAdapter(fileList);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final File file = new File(path.get(position));
final File file = path.get(position);
if (file.isDirectory()) {
if (file.canRead())
getDir(path.get(position));
@ -140,4 +151,107 @@ public class SimpleFileBrowser extends ActionBarListActivity {
finish();
}
}
private class DirectoryList extends BaseAdapter {
List<File> listing;
boolean hasUp;
DirectoryList( boolean hasUp ,List<File> listing ) {
this.listing = listing;
this.hasUp = hasUp;
}
@Override
public int getCount() {
return listing.size();
}
@Override
public Object getItem(int arg0) {
return listing.get(arg0);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if ( convertView == null ) {
convertView = getLayoutInflater().inflate(R.layout.filebrowser_list_item, parent, false);
}
File file = (File) getItem(position);
// Set the name of the field.
{
String fileName = file.getName();
if ( hasUp ) {
if (position == 0 ) {
fileName = root.getAbsolutePath();
} else if (position == 1) {
fileName = "..";
}
}
((TextView) convertView.findViewById(R.id.filebrowser_list_item_name)).setText(fileName);
}
// Set the "type icon" directory, ork file, or none.
{
ImageView v = (ImageView) (convertView.findViewById(R.id.filebrowser_list_item_typeicon));
if ( file.isDirectory() ) {
v.setVisibility(View.VISIBLE);
v.setImageResource(R.drawable.ic_directory);
} else if ( filter.isOrk( file ) ) {
v.setVisibility(View.VISIBLE);
v.setImageResource(R.drawable.or_launcher);
} else {
v.setVisibility(View.INVISIBLE);
}
}
// Set the "base directory" thing.
{
ImageView v = (ImageView) (convertView.findViewById(R.id.filebrowser_list_item_homeicon));
if ( !file.isDirectory() ) {
v.setVisibility(View.INVISIBLE);
v.setClickable(false);
} else {
v.setVisibility(View.VISIBLE);
if ( baseDirName.equals( file.getAbsolutePath() ) ) {
v.setSelected(true);
} else {
v.setSelected(false);
v.setClickable(true);
v.setOnClickListener( new ChangeBaseDirectory(file.getAbsolutePath()));
}
}
}
return convertView;
}
}
private class ChangeBaseDirectory implements View.OnClickListener {
private final String dirname;
ChangeBaseDirectory ( String dirname ) {
this.dirname = dirname;
}
@Override
public void onClick(View v) {
if ( v.isSelected() == false ) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(SimpleFileBrowser.this);
baseDirName = dirname;
pref.edit().putString(baseDirPrefKey, dirname).apply();
SimpleFileBrowser.this.getDir(new File(dirname));
}
}
}
}