Skip to content

Commit

Permalink
front: Updated PathPreference to follow standard pattern more closely.
Browse files Browse the repository at this point in the history
TODO: Still a bug on rotation with the dialog open. Previously,
rotating the screen produced an empty dialog.  Now the dialog is pop-
ulated, but always returns to the initial directory.
  • Loading branch information
littleguy77 committed Jan 18, 2013
1 parent dafc4f8 commit 8cb7f9d
Showing 1 changed file with 71 additions and 79 deletions.
150 changes: 71 additions & 79 deletions src/paulscode/android/mupen64plusae/persistent/PathPreference.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import java.util.ArrayList;
import java.util.List;

import android.text.TextUtils;
import paulscode.android.mupen64plusae.R;
import paulscode.android.mupen64plusae.util.FileUtil;
import android.app.AlertDialog.Builder;
Expand All @@ -33,9 +32,8 @@
import android.content.res.TypedArray;
import android.os.Environment;
import android.preference.DialogPreference;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class PathPreference extends DialogPreference
{
Expand All @@ -54,7 +52,7 @@ public class PathPreference extends DialogPreference
private boolean mDoReclick = false;
private List<CharSequence> mEntries = new ArrayList<CharSequence>();
private List<String> mValues = new ArrayList<String>();
private CharSequence mEntry;
private String mNewValue;
private String mValue;

public PathPreference( Context context, AttributeSet attrs )
Expand All @@ -67,81 +65,44 @@ public PathPreference( Context context, AttributeSet attrs )
a.recycle();
}

public int getSelectionMode()
public void setValue( String value )
{
return mSelectionMode;
mValue = validate( value );
if( shouldPersist() )
persistString( mValue );

// Summary always reflects the true/persisted value, does not track the temporary/new value
setSummary( mSelectionMode == SELECTION_MODE_FILE ? new File( mValue ).getName() : mValue );

// Reset the dialog info
populate( mValue );
}

public void setSelectionMode( int value )
{
mSelectionMode = value;
}

@Override
protected View onCreateView( ViewGroup parent )
public String getValue()
{
// Restore the persisted value
mValue = getPersistedString( "" );
populate( new File( mValue ) );
setSummary( mSelectionMode == SELECTION_MODE_FILE ? mEntry : mValue );

return super.onCreateView( parent );
return mValue;
}

public int getSelectionMode()
{
return mSelectionMode;
}

@Override
protected Object onGetDefaultValue( TypedArray a, int index )
{
String value = a.getString( index );

if( TextUtils.isEmpty( value ) )
{
// Use storage directory if no default provided in XML file
value = STORAGE_DIR;
}
else
{
// Default value was provided in XML file
// Prefixes encode additional information:
// ! means path is relative to storage dir, and parent dirs should be created if path does not exist
// ~ means path is relative to storage dir, and that storage dir should be used if path does not exist
boolean isRelativePath = value.startsWith( "!" ) || value.startsWith( "~" );
boolean forceParentDirs = value.startsWith( "!" );

// Build the absolute path if necessary
if( isRelativePath )
value = STORAGE_DIR + "/" + value.substring( 1 );

// Ensure the parent directories exist if requested
if( forceParentDirs )
( new File( value ) ).mkdirs();
else if( !new File( value ).exists() )
value = STORAGE_DIR;
}

return value;
return a.getString( index );
}

@Override
protected void onSetInitialValue( boolean restorePersistedValue, Object defaultValue )
{
if( restorePersistedValue )
{
// Restore persisted value
mValue = this.getPersistedString( STORAGE_DIR );

// Fall back to storage directory if path no longer exists
if( !( new File( mValue ) ).exists() )
{
mValue = STORAGE_DIR;
persistString( mValue );
}
}
else
{
// Set default state from the XML attribute
mValue = (String) defaultValue;
persistString( mValue );
}
setValue( restorePersistedValue ? getPersistedString( mValue ) : (String) defaultValue );
}

@Override
Expand All @@ -160,41 +121,37 @@ protected void onPrepareDialogBuilder( Builder builder )
@Override
public void onClick( DialogInterface dialog, int which )
{
super.onClick( dialog, which );

// If the user clicked a list item...
if( mValues != null && which >= 0 && which < mValues.size() )
{
mValue = mValues.get( which );
File path = new File( mValue );
mNewValue = mValues.get( which );
File path = new File( mNewValue );
if( path.isDirectory() )
{
// ...navigate into...
populate( path );
populate( mNewValue );
mDoReclick = true;
}
else
{
// ...or close dialog positively
onClick( dialog, DialogInterface.BUTTON_POSITIVE );
dialog.dismiss();
which = DialogInterface.BUTTON_POSITIVE;
}
}

// Call super last, parameters may have changed above
super.onClick( dialog, which );
}

@Override
protected void onDialogClosed( boolean positiveResult )
{
super.onDialogClosed( positiveResult );

// Clicking Cancel or Ok returns us to the parent preference menu. For these cases we return
// to a clean state by persisting or restoring the value.
if( positiveResult )
if( positiveResult && callChangeListener( mNewValue ) )
{
// User clicked Ok: clean the state by persisting value
persistString( mValue );
notifyChanged();
callChangeListener( mValue );
setValue( mNewValue );
}
else if( mDoReclick )
{
Expand All @@ -204,18 +161,22 @@ else if( mDoReclick )
}
else
{
// User clicked Cancel/Back: clean state by restoring value
mValue = getPersistedString( "" );
populate( new File( mValue ) );
// User clicked Cancel/Back: clean state by restoring persisted value
populate( mValue );
}
}

private void populate( File startPath )
private void populate( String path )
{
// Refresh the currently selected entry
mEntry = startPath.getName();
// Cache the path to persist on Ok
mNewValue = path;

// Quick exit if null
if( path == null )
return;

// If start path is a file, list it and its siblings in the parent directory
File startPath = new File( path );
if( startPath.isFile() )
startPath = startPath.getParentFile();

Expand All @@ -238,4 +199,35 @@ private void populate( File startPath )
boolean isFilesIncluded = mSelectionMode != SELECTION_MODE_DIRECTORY;
FileUtil.populate( startPath, true, true, isFilesIncluded, mEntries, mValues );
}

private static String validate( String value )
{
if( TextUtils.isEmpty( value ) )
{
// Use storage directory if value is empty
value = STORAGE_DIR;
}
else
{
// Non-empty string provided
// Prefixes encode additional information:
// ! and ~ mean path is relative to storage dir
// ! means parent dirs should be created if path does not exist
// ~ means storage dir should be used if path does not exist
boolean isRelativePath = value.startsWith( "!" ) || value.startsWith( "~" );
boolean forceParentDirs = value.startsWith( "!" );

// Build the absolute path if necessary
if( isRelativePath )
value = STORAGE_DIR + "/" + value.substring( 1 );

// Ensure the parent directories exist if requested
File file = new File( value );
if( forceParentDirs )
file.mkdirs();
else if( !file.exists() )
value = STORAGE_DIR;
}
return value;
}
}

0 comments on commit 8cb7f9d

Please sign in to comment.