mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-14 03:30:53 +00:00
Disentangle new-school and old-school disk selection and misc cleanup
This commit is contained in:
parent
2a263e2418
commit
dd0de51d64
@ -229,7 +229,24 @@ public class Apple2Activity extends Activity implements Apple2DiskChooserActivit
|
|||||||
|
|
||||||
if (sDisksChosen != null && mDisksMenu != null) {
|
if (sDisksChosen != null && mDisksMenu != null) {
|
||||||
if (sDisksChosen.pfd != null) {
|
if (sDisksChosen.pfd != null) {
|
||||||
mDisksMenu.showDiskInsertionAlertDialog("title", sDisksChosen);
|
String name = sDisksChosen.name;
|
||||||
|
|
||||||
|
final String[] prefices = {"content://com.android.externalstorage.documents/document", "content://com.android.externalstorage.documents", "content://com.android.externalstorage.documents", "content://"};
|
||||||
|
for (String prefix : prefices) {
|
||||||
|
if (name.startsWith(prefix)) {
|
||||||
|
name = name.substring(prefix.length());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip out URL-encoded '/' directory separators
|
||||||
|
String nameLower = name.toLowerCase();
|
||||||
|
int idx = nameLower.lastIndexOf("%2f", /*fromIndex:*/name.length()-3);
|
||||||
|
if (idx >= 0) {
|
||||||
|
name = name.substring(idx + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
mDisksMenu.showDiskInsertionAlertDialog(name, sDisksChosen);
|
||||||
}
|
}
|
||||||
sDisksChosen = null;
|
sDisksChosen = null;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,8 @@ public class Apple2DiskChooserActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public void finish() {
|
public void finish() {
|
||||||
sDiskChooserIsChoosing.set(false);
|
sDiskChooserIsChoosing.set(false);
|
||||||
sDisksCallback.onDisksChosen(new DiskArgs(chosenUri, chosenPfd));
|
String name = chosenUri == null ? "" : chosenUri.toString();
|
||||||
|
sDisksCallback.onDisksChosen(new DiskArgs(name, chosenUri, chosenPfd));
|
||||||
super.finish();
|
super.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,11 +172,13 @@ public class Apple2DiskChooserActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DiskArgs {
|
class DiskArgs {
|
||||||
|
public String name;
|
||||||
public String path;
|
public String path;
|
||||||
public Uri uri;
|
public Uri uri;
|
||||||
public ParcelFileDescriptor pfd;
|
public ParcelFileDescriptor pfd;
|
||||||
|
|
||||||
public DiskArgs(Uri uri, ParcelFileDescriptor pfd) {
|
public DiskArgs(String name, Uri uri, ParcelFileDescriptor pfd) {
|
||||||
|
this.name = name;
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
this.pfd = pfd;
|
this.pfd = pfd;
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,13 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckBox;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@ -155,6 +157,17 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
return "driveBInsertedDiskGZ";
|
return "driveBInsertedDiskGZ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getPrefDefault() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
USE_NEWSCHOOL_DISK_SELECTION {
|
||||||
|
@Override
|
||||||
|
public String getPrefKey() {
|
||||||
|
return "useNewSchoolDiskSelection";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getPrefDefault() {
|
public Object getPrefDefault() {
|
||||||
return true;
|
return true;
|
||||||
@ -201,6 +214,28 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
final Button ejectButton1 = (Button) mDisksView.findViewById(R.id.ejectButton1);
|
||||||
|
ejectButton1.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
ejectDisk(/*isDriveA:*/true);
|
||||||
|
dynamicSetup();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final Button ejectButton2 = (Button) mDisksView.findViewById(R.id.ejectButton2);
|
||||||
|
ejectButton2.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
ejectDisk(/*isDriveA:*/false);
|
||||||
|
dynamicSetup();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Apple2Utils.getExternalStorageDirectory(activity);
|
Apple2Utils.getExternalStorageDirectory(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +331,10 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (imageName.startsWith(EXTERNAL_CHOOSER_SENTINEL)) {
|
if (imageName.startsWith(EXTERNAL_CHOOSER_SENTINEL)) {
|
||||||
|
if (!Apple2Utils.isExternalStorageAccessible(activity)) {
|
||||||
|
// disallow access if we cannot access external storage
|
||||||
|
throw new Exception("External storage not accessible");
|
||||||
|
}
|
||||||
if (diskArgs.pfd == null) {
|
if (diskArgs.pfd == null) {
|
||||||
if (diskArgs.uri == null) {
|
if (diskArgs.uri == null) {
|
||||||
String uriString = imageName.substring(EXTERNAL_CHOOSER_SENTINEL.length());
|
String uriString = imageName.substring(EXTERNAL_CHOOSER_SENTINEL.length());
|
||||||
@ -304,7 +343,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
diskArgs.pfd = Apple2DiskChooserActivity.openFileDescriptorFromUri(activity, diskArgs.uri);
|
diskArgs.pfd = Apple2DiskChooserActivity.openFileDescriptorFromUri(activity, diskArgs.uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = diskArgs.pfd.getFd();
|
int fd = diskArgs.pfd.getFd(); // NPE thrown if diskArgs.pfd is null
|
||||||
map.put("fd", fd);
|
map.put("fd", fd);
|
||||||
} else {
|
} else {
|
||||||
File file = new File(imageName);
|
File file = new File(imageName);
|
||||||
@ -331,14 +370,12 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
|
|
||||||
String jsonString = nativeChooseDisk(map.toString());
|
String jsonString = nativeChooseDisk(map.toString());
|
||||||
|
|
||||||
if (diskArgs.pfd != null) {
|
try {
|
||||||
try {
|
diskArgs.pfd.close(); // at this point diskArgs.pfd !null
|
||||||
diskArgs.pfd.close();
|
} catch (IOException ioe) {
|
||||||
} catch (IOException ioe) {
|
Log.e(TAG, "Error attempting to close PFD : " + ioe);
|
||||||
Log.e(TAG, "Error attempting to close PFD : " + ioe);
|
|
||||||
}
|
|
||||||
diskArgs.pfd = null;
|
|
||||||
}
|
}
|
||||||
|
diskArgs.pfd = null;
|
||||||
|
|
||||||
map = new JSONObject(jsonString);
|
map = new JSONObject(jsonString);
|
||||||
boolean inserted = map.getBoolean("inserted");
|
boolean inserted = map.getBoolean("inserted");
|
||||||
@ -479,11 +516,136 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
private void dynamicSetup() {
|
private void dynamicSetup() {
|
||||||
|
|
||||||
final ListView disksList = (ListView) mDisksView.findViewById(R.id.listView_settings);
|
final ListView disksList = (ListView) mDisksView.findViewById(R.id.listView_settings);
|
||||||
disksList.setEnabled(true);
|
|
||||||
|
final boolean useNewschoolSelection = (boolean) Apple2Preferences.getJSONPref(SETTINGS.USE_NEWSCHOOL_DISK_SELECTION);
|
||||||
|
|
||||||
|
final CheckBox newschoolSelection = (CheckBox) mDisksView.findViewById(R.id.newschoolDiskSelectionButton);
|
||||||
|
newschoolSelection.setChecked(useNewschoolSelection);
|
||||||
|
newschoolSelection.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Apple2Preferences.setJSONPref(SETTINGS.USE_NEWSCHOOL_DISK_SELECTION, newschoolSelection.isChecked());
|
||||||
|
dynamicSetup();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final boolean isKitKatOrBetter = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT);
|
||||||
|
|
||||||
|
final boolean includeExternalFileChooser = Apple2Utils.isExternalStorageAccessible(mActivity) && isKitKatOrBetter;
|
||||||
|
|
||||||
|
final View newschoolChooser = mDisksView.findViewById(R.id.disk_selection_newschool_chooser);
|
||||||
|
newschoolChooser.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
final boolean alreadyChoosing = Apple2DiskChooserActivity.sDiskChooserIsChoosing.getAndSet(true);
|
||||||
|
if (alreadyChoosing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Intent chooserIntent = new Intent(mActivity, Apple2DiskChooserActivity.class);
|
||||||
|
chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION/* | Intent.FLAG_ACTIVITY_CLEAR_TOP */);
|
||||||
|
|
||||||
|
Apple2DiskChooserActivity.sDisksCallback = mActivity;
|
||||||
|
mActivity.startActivity(chooserIntent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final Button ejectButton1 = (Button) mDisksView.findViewById(R.id.ejectButton1);
|
||||||
|
final Button ejectButton2 = (Button) mDisksView.findViewById(R.id.ejectButton2);
|
||||||
|
|
||||||
|
if (!includeExternalFileChooser || !useNewschoolSelection) {
|
||||||
|
disksList.setEnabled(true);
|
||||||
|
disksList.setVisibility(View.VISIBLE);
|
||||||
|
newschoolChooser.setVisibility(View.INVISIBLE);
|
||||||
|
ejectButton1.setVisibility(View.VISIBLE);
|
||||||
|
ejectButton2.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
LinearLayout layout = (LinearLayout) mDisksView.findViewById((i == 0) ? R.id.a2_newschool_driveA_layout : R.id.a2_newschool_driveB_layout);
|
||||||
|
layout.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!includeExternalFileChooser) {
|
||||||
|
newschoolSelection.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
Apple2Preferences.setJSONPref(SETTINGS.USE_NEWSCHOOL_DISK_SELECTION, false);
|
||||||
|
oldschoolDynamicSetup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
disksList.setEnabled(false);
|
||||||
|
disksList.setVisibility(View.INVISIBLE);
|
||||||
|
newschoolChooser.setVisibility(View.VISIBLE);
|
||||||
|
ejectButton1.setVisibility(View.INVISIBLE);
|
||||||
|
ejectButton2.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
// new external file chooser activity can allow navigation to restricted external SD Card(s) ...
|
||||||
|
newschoolSelection.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
String imageName = null;
|
||||||
|
do {
|
||||||
|
String diskPath = (String) Apple2Preferences.getJSONPref((i == 0) ? SETTINGS.CURRENT_DISK_PATH_A : SETTINGS.CURRENT_DISK_PATH_B);
|
||||||
|
|
||||||
|
if (diskPath == null || diskPath.equals("")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri uri = Uri.parse(diskPath);
|
||||||
|
if (uri == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
diskPath = uri.getPath();
|
||||||
|
int idx = diskPath.lastIndexOf("/");
|
||||||
|
if (idx < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
imageName = diskPath.substring(idx + 1);
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
LinearLayout layout = (LinearLayout) mDisksView.findViewById((i == 0) ? R.id.a2_newschool_driveA_layout : R.id.a2_newschool_driveB_layout);
|
||||||
|
|
||||||
|
LinearLayout widgetLayout = (LinearLayout) mDisksView.findViewById((i == 0) ? R.id.a2_newschool_diskA_widget_frame : R.id.a2_newschool_diskB_widget_frame);
|
||||||
|
if (widgetLayout.getChildCount() > 0) {
|
||||||
|
// layout cells appear to be reused when scrolling into view ... make sure we start with clear hierarchy
|
||||||
|
widgetLayout.removeAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageName == null || imageName.equals("")) {
|
||||||
|
layout.setVisibility(View.INVISIBLE);
|
||||||
|
} else {
|
||||||
|
layout.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
boolean readOnly = (boolean) Apple2Preferences.getJSONPref((i == 0) ? SETTINGS.CURRENT_DISK_PATH_A_RO : SETTINGS.CURRENT_DISK_PATH_B_RO);
|
||||||
|
imageName = "(" + mActivity.getResources().getString((readOnly ? R.string.disk_read_only : R.string.disk_read_write)) + "): " + imageName;
|
||||||
|
TextView textView = (TextView) mDisksView.findViewById((i == 0) ? R.id.a2_newschool_diskA : R.id.a2_newschool_diskB);
|
||||||
|
textView.setText(imageName);
|
||||||
|
|
||||||
|
String eject = mActivity.getResources().getString(R.string.disk_eject);
|
||||||
|
Button ejectButton = new Button(mActivity);
|
||||||
|
ejectButton.setText(eject);
|
||||||
|
final boolean isDriveA = (i == 0);
|
||||||
|
ejectButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
ejectDisk(isDriveA);
|
||||||
|
dynamicSetup();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
widgetLayout.addView(ejectButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void oldschoolDynamicSetup() {
|
||||||
|
|
||||||
|
final ListView disksList = (ListView) mDisksView.findViewById(R.id.listView_settings);
|
||||||
|
|
||||||
String disksDir = pathStackAsDirectory();
|
String disksDir = pathStackAsDirectory();
|
||||||
final boolean isRootPath = (disksDir == null);
|
final boolean isRootPath = (disksDir == null);
|
||||||
final File extStorageDir = Apple2Utils.getExternalStorageDirectory(mActivity);
|
|
||||||
if (isRootPath) {
|
if (isRootPath) {
|
||||||
disksDir = Apple2Utils.getDataDir(mActivity) + File.separator + "disks"; // default path
|
disksDir = Apple2Utils.getDataDir(mActivity) + File.separator + "disks"; // default path
|
||||||
}
|
}
|
||||||
@ -532,31 +694,15 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int off = 0;
|
final boolean includeExternalStoragePath = (Apple2Utils.isExternalStorageAccessible(mActivity) && isRootPath);
|
||||||
final boolean includeExternalStoragePath = (extStorageDir != null && isRootPath);
|
|
||||||
if (includeExternalStoragePath) {
|
final int offset = includeExternalStoragePath ? 1 : 0;
|
||||||
++off;
|
|
||||||
}
|
|
||||||
final boolean includeExternalFileChooser = isRootPath && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT);
|
|
||||||
if (includeExternalFileChooser) {
|
|
||||||
++off;
|
|
||||||
}
|
|
||||||
final int offset = off;
|
|
||||||
final String[] fileNames = new String[files.length + offset];
|
final String[] fileNames = new String[files.length + offset];
|
||||||
final String[] filePaths = new String[files.length + offset];
|
final String[] filePaths = new String[files.length + offset];
|
||||||
final boolean[] isDirectory = new boolean[files.length + offset];
|
final boolean[] isDirectory = new boolean[files.length + offset];
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
// external file chooser can allow navigation to restricted external SD Card
|
|
||||||
if (includeExternalFileChooser) {
|
|
||||||
filePaths[idx] = EXTERNAL_CHOOSER_SENTINEL;
|
|
||||||
fileNames[idx] = mActivity.getResources().getString(R.string.file_chooser);
|
|
||||||
isDirectory[idx] = true;
|
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
// first external storage link should be /sdcard/apple2ix to encourage this form of organization
|
|
||||||
if (includeExternalStoragePath) {
|
if (includeExternalStoragePath) {
|
||||||
filePaths[idx] = Apple2Utils.getRealExternalStorageDirectory(mActivity).getAbsolutePath();
|
filePaths[idx] = Apple2Utils.getRealExternalStorageDirectory(mActivity).getAbsolutePath();
|
||||||
fileNames[idx] = mActivity.getResources().getString(R.string.storage);
|
fileNames[idx] = mActivity.getResources().getString(R.string.storage);
|
||||||
@ -636,21 +782,6 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
|
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
|
||||||
if (isDirectory[position]) {
|
if (isDirectory[position]) {
|
||||||
if (filePaths[position].equals(EXTERNAL_CHOOSER_SENTINEL)) {
|
|
||||||
final boolean alreadyChoosing = Apple2DiskChooserActivity.sDiskChooserIsChoosing.getAndSet(true);
|
|
||||||
if (alreadyChoosing) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent chooserIntent = new Intent(mActivity, Apple2DiskChooserActivity.class);
|
|
||||||
chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION/* | Intent.FLAG_ACTIVITY_CLEAR_TOP */);
|
|
||||||
|
|
||||||
Apple2DiskChooserActivity.sDisksCallback = mActivity;
|
|
||||||
mActivity.startActivity(chooserIntent);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(TAG, "Descending to path : " + filePaths[position]);
|
Log.d(TAG, "Descending to path : " + filePaths[position]);
|
||||||
if (parentIsRootPath && !new File(filePaths[position]).isAbsolute()) {
|
if (parentIsRootPath && !new File(filePaths[position]).isAbsolute()) {
|
||||||
pushPathStack(parentDisksDir + File.separator + filePaths[position]);
|
pushPathStack(parentDisksDir + File.separator + filePaths[position]);
|
||||||
|
@ -343,9 +343,10 @@ public class Apple2MainMenu {
|
|||||||
final String[] readOnlyKeys = new String[]{"readOnlyA", "readOnlyB"};
|
final String[] readOnlyKeys = new String[]{"readOnlyA", "readOnlyB"};
|
||||||
final String[] fdKeys = new String[]{"fdA", "fdB"};
|
final String[] fdKeys = new String[]{"fdA", "fdB"};
|
||||||
|
|
||||||
ParcelFileDescriptor[] pfds = { null, null };
|
ParcelFileDescriptor[] pfds = {null, null};
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
|
|
||||||
String diskPath = map.getString(diskPathKeys[i]);
|
String diskPath = map.getString(diskPathKeys[i]);
|
||||||
boolean readOnly = map.getBoolean(readOnlyKeys[i]);
|
boolean readOnly = map.getBoolean(readOnlyKeys[i]);
|
||||||
|
|
||||||
@ -362,13 +363,16 @@ public class Apple2MainMenu {
|
|||||||
Uri uri = Uri.parse(uriString);
|
Uri uri = Uri.parse(uriString);
|
||||||
|
|
||||||
pfds[i] = Apple2DiskChooserActivity.openFileDescriptorFromUri(mActivity, uri);
|
pfds[i] = Apple2DiskChooserActivity.openFileDescriptorFromUri(mActivity, uri);
|
||||||
int fd = pfds[i].getFd();
|
if (pfds[i] == null) {
|
||||||
|
Log.e(TAG, "Did not find URI for drive #" + i + " specified in emulator.state file : " + diskPath);
|
||||||
map.put(fdKeys[i], fd);
|
} else {
|
||||||
|
int fd = pfds[i].getFd();
|
||||||
|
map.put(fdKeys[i], fd);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
boolean exists = new File(diskPath).exists();
|
boolean exists = new File(diskPath).exists();
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
Log.e(TAG, "Did not find path(s) for drive #" + i + " specified in emulator.state file : " + diskPath);
|
Log.e(TAG, "Did not find path for drive #" + i + " specified in emulator.state file : " + diskPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,6 +188,11 @@ public class Apple2Utils {
|
|||||||
return sRealExternalFilesDir;
|
return sRealExternalFilesDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isExternalStorageAccessible(Apple2Activity activity) {
|
||||||
|
getExternalStorageDirectory(activity);
|
||||||
|
return (sRealExternalFilesDir != null) && (new File(sRealExternalFilesDir.getAbsolutePath()).listFiles() != null);
|
||||||
|
}
|
||||||
|
|
||||||
// HACK NOTE 2015/02/22 : Apparently native code cannot easily access stuff in the APK ... so copy various resources
|
// HACK NOTE 2015/02/22 : Apparently native code cannot easily access stuff in the APK ... so copy various resources
|
||||||
// out of the APK and into the /data/data/... for ease of access. Because this is FOSS software we don't care about
|
// out of the APK and into the /data/data/... for ease of access. Because this is FOSS software we don't care about
|
||||||
// security or DRM for these assets =)
|
// security or DRM for these assets =)
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/a2preference_title"
|
android:layout_below="@id/a2preference_title"
|
||||||
android:layout_alignLeft="@id/a2preference_title"
|
android:layout_alignLeft="@id/a2preference_title"
|
||||||
|
android:layout_alignStart="@id/a2preference_title"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:maxLines="4" />
|
android:maxLines="4" />
|
||||||
|
|
||||||
|
@ -1,39 +1,223 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:background="@color/black"
|
|
||||||
android:orientation="vertical"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:baselineAligned="false"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent" >
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_marginBottom="5dip"
|
||||||
|
android:layout_marginLeft="5dip"
|
||||||
|
android:layout_marginStart="5dip"
|
||||||
|
android:layout_marginRight="5dip"
|
||||||
|
android:layout_marginEnd="5dip"
|
||||||
|
android:layout_marginTop="5dip"
|
||||||
|
android:background="@color/black"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:background="@color/black"
|
android:id="@+id/disks_selection_header"
|
||||||
android:orientation="horizontal"
|
|
||||||
android:baselineAligned="false"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content" >
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/black"
|
||||||
<TextView
|
android:baselineAligned="false"
|
||||||
android:id="@+id/header_disks"
|
android:orientation="horizontal">
|
||||||
style="?android:attr/listSeparatorTextViewStyle"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/header_disks" />
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
android:id="@+id/ejectButton1"
|
||||||
style="?android:attr/buttonStyleSmall"
|
style="?android:attr/buttonStyleSmall"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
|
android:drawableLeft="@android:drawable/ic_menu_save"
|
||||||
android:drawableStart="@android:drawable/ic_menu_close_clear_cancel"
|
android:drawableStart="@android:drawable/ic_menu_save"
|
||||||
android:id="@+id/cancelButton" />
|
android:text="@string/header_eject_1" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/ejectButton2"
|
||||||
|
style="?android:attr/buttonStyleSmall"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawableLeft="@android:drawable/ic_menu_save"
|
||||||
|
android:drawableStart="@android:drawable/ic_menu_save"
|
||||||
|
android:text="@string/header_eject_2" />
|
||||||
|
|
||||||
|
<!-- FIXME : spacer, prolly a better way ... -->
|
||||||
|
<TextView
|
||||||
|
style="?android:attr/listSeparatorTextViewStyle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
style="?android:attr/buttonStyleSmall"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawableEnd="@android:drawable/ic_menu_close_clear_cancel"
|
||||||
|
android:drawableRight="@android:drawable/ic_menu_close_clear_cancel" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/newschoolDiskSelectionButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignLeft="@id/disks_selection_header"
|
||||||
|
android:layout_alignStart="@id/disks_selection_header"
|
||||||
|
android:layout_below="@id/disks_selection_header"
|
||||||
|
android:layout_marginTop="10dip"
|
||||||
|
android:text="@string/disk_selection_newschoool" />
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:id="@+id/listView_settings"
|
android:id="@+id/listView_settings"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_alignLeft="@id/disks_selection_header"
|
||||||
|
android:layout_alignStart="@id/disks_selection_header"
|
||||||
|
android:layout_below="@id/newschoolDiskSelectionButton"
|
||||||
|
android:visibility="invisible"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
</LinearLayout>
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/disk_selection_newschool_chooser"
|
||||||
|
android:layout_alignLeft="@id/disks_selection_header"
|
||||||
|
android:layout_alignStart="@id/disks_selection_header"
|
||||||
|
android:layout_below="@id/newschoolDiskSelectionButton"
|
||||||
|
android:layout_marginLeft="5dip"
|
||||||
|
android:layout_marginStart="5dip"
|
||||||
|
android:layout_marginRight="5dip"
|
||||||
|
android:layout_marginEnd="5dip"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="20dip"
|
||||||
|
android:layout_marginTop="20dip"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:fadingEdge="horizontal"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@+string/file_chooser"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
<!-- FIXME : spacer, prolly a better way ... -->
|
||||||
|
<TextView
|
||||||
|
style="?android:attr/listSeparatorTextViewStyle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:src="@android:drawable/ic_menu_save"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/a2_newschool_driveA_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignLeft="@id/disk_selection_newschool_chooser"
|
||||||
|
android:layout_alignStart="@id/disk_selection_newschool_chooser"
|
||||||
|
android:layout_below="@id/disk_selection_newschool_chooser"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
|
android:paddingRight="?android:attr/scrollbarSize">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="5dip"
|
||||||
|
android:layout_marginRight="5dip"
|
||||||
|
android:layout_marginTop="5dip"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/a2_newschool_driveA"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:fadingEdge="horizontal"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@+string/diskA"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/a2_newschool_diskA"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignLeft="@id/a2_newschool_driveA"
|
||||||
|
android:layout_alignStart="@id/a2_newschool_driveA"
|
||||||
|
android:layout_below="@id/a2_newschool_driveA"
|
||||||
|
android:maxLines="4"
|
||||||
|
android:text="someLongSelectedDiskName.dsk.gz"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<!-- Custom preference should place its actual preference widget here. -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/a2_newschool_diskA_widget_frame"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:descendantFocusability="blocksDescendants"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/a2_newschool_driveB_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignLeft="@id/a2_newschool_driveA_layout"
|
||||||
|
android:layout_alignStart="@id/a2_newschool_driveA_layout"
|
||||||
|
android:layout_below="@id/a2_newschool_driveA_layout"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
|
android:paddingRight="?android:attr/scrollbarSize">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="5dip"
|
||||||
|
android:layout_marginRight="5dip"
|
||||||
|
android:layout_marginTop="5dip"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/a2_newschool_driveB"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:fadingEdge="horizontal"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="@+string/diskB"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/a2_newschool_diskB"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignLeft="@id/a2_newschool_driveB"
|
||||||
|
android:layout_alignStart="@id/a2_newschool_driveB"
|
||||||
|
android:layout_below="@id/a2_newschool_driveB"
|
||||||
|
android:maxLines="4"
|
||||||
|
android:text="someLongSelectedDiskName.dsk.gz"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<!-- Custom preference should place its actual preference widget here. -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/a2_newschool_diskB_widget_frame"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:descendantFocusability="blocksDescendants"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
@ -40,12 +40,15 @@
|
|||||||
<string name="disk_insert_could_not_read">Sorry, could not read the disk image!</string>
|
<string name="disk_insert_could_not_read">Sorry, could not read the disk image!</string>
|
||||||
<string name="disk_read_only">Read only</string>
|
<string name="disk_read_only">Read only</string>
|
||||||
<string name="disk_read_write">Read/write</string>
|
<string name="disk_read_write">Read/write</string>
|
||||||
|
<string name="disk_selection_newschoool">Use system file chooser</string>
|
||||||
<string name="disk_show_operation">Show Disk ][ operations</string>
|
<string name="disk_show_operation">Show Disk ][ operations</string>
|
||||||
<string name="disk_show_operation_summary">Shows when disk drives are reading or writing</string>
|
<string name="disk_show_operation_summary">Shows when disk drives are reading or writing</string>
|
||||||
<string name="emulation_continue">Continue…</string>
|
<string name="emulation_continue">Continue…</string>
|
||||||
<string name="emulation_disks">Load disk image</string>
|
<string name="emulation_disks">Load disk image</string>
|
||||||
<string name="file_chooser">System choose disk…</string>
|
<string name="file_chooser">Choose disk…</string>
|
||||||
<string name="header_disks">Insert disk:</string>
|
<string name="header_disks">Insert disk:</string>
|
||||||
|
<string name="header_eject_1">Eject 1</string>
|
||||||
|
<string name="header_eject_2">Eject 2</string>
|
||||||
<string name="input_current">Current touch device</string>
|
<string name="input_current">Current touch device</string>
|
||||||
<string name="input_current_summary">Choose current touch device</string>
|
<string name="input_current_summary">Choose current touch device</string>
|
||||||
<string name="joystick">Joystick</string>
|
<string name="joystick">Joystick</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user