mirror of
https://github.com/jamessanford/kegs.git
synced 2025-01-07 22:32:56 +00:00
New DiskLoader with gzip and zip support.
Flow of disk image selection now goes through DiskLoader with onImageReady/onImageCancelled callbacks. DiskLoader handles downloading, ungzipping, and extracting from zipfile.
This commit is contained in:
parent
ee103891c5
commit
7bde7861c2
@ -20,41 +20,51 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:priority="999">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" android:pathPattern=".*\\.2mg" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="999">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" android:pathPattern=".*\\.dsk" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="999">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" android:pathPattern=".*\\.nib" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="999">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" android:pathPattern=".*\\.hdv" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="999">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" android:pathPattern=".*\\.po" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="999">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" android:pathPattern=".*\\.do" />
|
||||
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.zip" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.ZIP" />
|
||||
|
||||
<!-- Yeah, this is pretty much awful. Blame PatternMatcher -->
|
||||
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.2mg" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.dsk" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.nib" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.hdv" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.po" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.do" />
|
||||
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.2MG" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.DSK" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.NIB" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.HDV" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.PO" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.DO" />
|
||||
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.2mg.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.dsk.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.nib.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.hdv.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.po.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.do.gz" />
|
||||
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.2MG.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.DSK.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.NIB.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.HDV.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.PO.gz" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.DO.gz" />
|
||||
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.2MG.GZ" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.DSK.GZ" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.NIB.GZ" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.HDV.GZ" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.PO.GZ" />
|
||||
<data android:scheme="file" android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.DO.GZ" />
|
||||
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
@ -263,7 +263,7 @@ void android_config_init(char *output, int maxlen) {
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_froop_app_kegs_AssetImages_nativeSync( JNIEnv* env, jobject thiz) {
|
||||
Java_com_froop_app_kegs_DiskLoader_nativeSync( JNIEnv* env, jobject thiz) {
|
||||
sync();
|
||||
sync();
|
||||
}
|
||||
|
BIN
res/drawable-xhdpi/ic_dialog_alert_holo_dark.png
Normal file
BIN
res/drawable-xhdpi/ic_dialog_alert_holo_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -6,6 +6,9 @@
|
||||
<string name="rom_title">Checking for ROM</string>
|
||||
<string name="rom_check">Checking for ROM...</string>
|
||||
<string name="rom_error">Unable to obtain ROM. Find ROM.01 or ROM.03 and put it in /Android/data/com.froop.app.kegs/files/ on your SD Card.</string>
|
||||
<string name="image_error">Unable to load requested disk image.</string>
|
||||
<string name="error_title">Error</string>
|
||||
<string name="dialog_ok">OK</string>
|
||||
|
||||
<string-array name="rom_choices">
|
||||
<item>I have a ROM 01</item>
|
||||
@ -21,7 +24,8 @@
|
||||
</string-array>
|
||||
|
||||
<string name="diskimage_title">Choose a disk</string>
|
||||
<string name="asset_loading">Preparing disk image...</string>
|
||||
<string name="progress_message">Preparing disk image...</string>
|
||||
<string name="zipfile_nomatches">No disk images found</string>
|
||||
|
||||
<string-array name="swapdisk_choices">
|
||||
<item>Ignore this disk</item>
|
||||
|
@ -46,7 +46,6 @@ class AssetImages extends AsyncTask<Void, Void, Boolean> {
|
||||
mConfigFile.ensureAssetCopied(mConfigFile.getImagePath(),
|
||||
"System 6 Shareware.zip", "System 6.hdv");
|
||||
// TODO: could check to make sure they actually exist now.
|
||||
nativeSync();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -57,7 +56,4 @@ class AssetImages extends AsyncTask<Void, Void, Boolean> {
|
||||
protected void onPostExecute(final Boolean result) {
|
||||
mNotify.onAssetsReady(result);
|
||||
}
|
||||
|
||||
// See jni/android_driver.c:nativeSync()
|
||||
private native void nativeSync();
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ class ConfigFile {
|
||||
return mConfigPath + "/images";
|
||||
}
|
||||
|
||||
public String getCachePath() {
|
||||
return mContext.getExternalCacheDir().getPath();
|
||||
}
|
||||
|
||||
public void ensureAssetCopied(String destPath, String zipfile, String exampleFile) {
|
||||
// We only check for a local copy of a single file before unzipping...
|
||||
final File local_copy = new File(destPath, exampleFile);
|
||||
|
53
src/com/froop/app/kegs/ErrorDialogFragment.java
Normal file
53
src/com/froop/app/kegs/ErrorDialogFragment.java
Normal file
@ -0,0 +1,53 @@
|
||||
package com.froop.app.kegs;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||
|
||||
class ErrorDialogFragment extends SherlockDialogFragment {
|
||||
private int mMessage;
|
||||
private Runnable mRunnable;
|
||||
|
||||
public ErrorDialogFragment(int textId, Runnable runnable) {
|
||||
super();
|
||||
mMessage = textId;
|
||||
mRunnable = runnable; // ok if null
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.error_title);
|
||||
builder.setIcon(R.drawable.ic_dialog_alert_holo_dark);
|
||||
builder.setMessage(mMessage);
|
||||
builder.setPositiveButton(R.string.dialog_ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int button) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
final AlertDialog dialog = builder.create();
|
||||
dialog.setCanceledOnTouchOutside(false); // prevent accidental dismissal
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
super.onCancel(dialog);
|
||||
if (mRunnable != null) {
|
||||
mRunnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
if (mRunnable != null) {
|
||||
mRunnable.run();
|
||||
}
|
||||
}
|
||||
}
|
@ -26,14 +26,17 @@ import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||
import com.actionbarsherlock.view.Menu;
|
||||
import com.actionbarsherlock.view.MenuItem;
|
||||
|
||||
public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.StickyReset, AssetImages.AssetsReady, DownloadImage.DownloadReady {
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.StickyReset, AssetImages.AssetsReady, DiskLoader.ImageReady {
|
||||
private static final String FRAGMENT_ROM = "rom";
|
||||
private static final String FRAGMENT_DOWNLOAD = "download";
|
||||
private static final String FRAGMENT_ERROR = "error";
|
||||
private static final String FRAGMENT_SPEED = "speed";
|
||||
private static final String FRAGMENT_DISKIMAGE = "diskimage";
|
||||
private static final String FRAGMENT_ASSET = "asset";
|
||||
private static final String FRAGMENT_SWAPDISK = "swapdisk";
|
||||
private static final String FRAGMENT_ZIPDISK = "zipdisk";
|
||||
private static final String FRAGMENT_LOADING = "loading";
|
||||
|
||||
private ConfigFile mConfigFile;
|
||||
private KegsThread mKegsThread;
|
||||
@ -45,16 +48,27 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
|
||||
private KegsKeyboard mKegsKeyboard;
|
||||
private TouchJoystick mJoystick;
|
||||
|
||||
private boolean mAssetsReady = false;
|
||||
private boolean mDownloadReady = false;
|
||||
private boolean mDownloadStarted = false;
|
||||
private boolean mDownloadAborted = false;
|
||||
|
||||
private boolean mModeMouse = true;
|
||||
private boolean mHaveNewIntent = false;
|
||||
|
||||
private long mScreenSizeTime = 0;
|
||||
|
||||
private boolean mPaused = false;
|
||||
final ArrayDeque<Runnable> mResumeQueue = new ArrayDeque<Runnable>();
|
||||
|
||||
private DiskLoader mDiskLoader = null;
|
||||
|
||||
private void withUIActive(final Runnable runnable) {
|
||||
if(!mPaused) {
|
||||
runnable.run();
|
||||
} else {
|
||||
mResumeQueue.add(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
public void onAssetsReady(boolean result) {
|
||||
// TODO: deal with error conditions from assets as a warning.
|
||||
}
|
||||
|
||||
private View.OnClickListener mButtonClick = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
final int click_id = v.getId();
|
||||
@ -106,81 +120,109 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
|
||||
((ToggleButton)findViewById(R.id.key_closed_apple)).setChecked(false);
|
||||
}
|
||||
|
||||
public void onAssetsReady(boolean success) {
|
||||
// TODO FIXME: this needs to throw an error if it fails.
|
||||
mAssetsReady = success;
|
||||
}
|
||||
|
||||
public void onDownloadReady(boolean success) {
|
||||
// TODO FIXME: this needs to throw an error if it fails.
|
||||
mDownloadReady = success;
|
||||
protected void loadDiskImage(final DiskImage image) {
|
||||
if (image.action == DiskImage.BOOT) {
|
||||
getThread().doPowerOff();
|
||||
}
|
||||
loadDiskImageWhenReady(image);
|
||||
}
|
||||
|
||||
private void loadDiskImageWhenReady(final DiskImage image) {
|
||||
final AssetFragment frag = (AssetFragment)getSupportFragmentManager().findFragmentByTag(FRAGMENT_ASSET);
|
||||
|
||||
// Only start download when the assets are ready.
|
||||
if (mAssetsReady && !mDownloadStarted) {
|
||||
mDownloadStarted = true;
|
||||
final String imagePath = mConfigFile.getImagePath();
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
new DownloadImage(this, imagePath, image).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else {
|
||||
new DownloadImage(this, imagePath, image).execute();
|
||||
}
|
||||
}
|
||||
|
||||
// This code is lame.
|
||||
if (mDownloadAborted) {
|
||||
if (frag != null) {
|
||||
frag.dismiss();
|
||||
}
|
||||
if (image.primary) {
|
||||
getThread().allowPowerOn();
|
||||
}
|
||||
return; // don't schedule another pass.
|
||||
}
|
||||
|
||||
boolean nativeReady;
|
||||
if (image.primary) {
|
||||
if (image.action == DiskImage.BOOT) {
|
||||
nativeReady = getThread().nowWaitingForPowerOn();
|
||||
} else {
|
||||
nativeReady = true;
|
||||
}
|
||||
|
||||
if (!nativeReady || !mAssetsReady || !mDownloadReady) {
|
||||
if (frag == null && (!mAssetsReady || !mDownloadReady)) {
|
||||
// Only the asset part will take time, so only show the dialog
|
||||
// when waiting for the asset.
|
||||
final SherlockDialogFragment assetProgress = new AssetFragment();
|
||||
assetProgress.show(getSupportFragmentManager(), FRAGMENT_ASSET);
|
||||
}
|
||||
if (!nativeReady) {
|
||||
mKegsView.postDelayed(new Runnable() {
|
||||
public void run() { loadDiskImageWhenReady(image); }
|
||||
public void run() {
|
||||
loadDiskImageWhenReady(image);
|
||||
}
|
||||
}, 100);
|
||||
} else {
|
||||
if (frag != null) {
|
||||
frag.dismiss();
|
||||
}
|
||||
if (image.primary) {
|
||||
mConfigFile.setConfig(image);
|
||||
getThread().allowPowerOn();
|
||||
} else {
|
||||
getThread().getEventQueue().add(image.getDiskImageEvent());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
withUIActive(new Runnable() {
|
||||
public void run() {
|
||||
if (image.action == DiskImage.BOOT) {
|
||||
mConfigFile.setConfig(image);
|
||||
getThread().allowPowerOn();
|
||||
} else if (image.action == DiskImage.SWAP) {
|
||||
getThread().getEventQueue().add(image.getDiskImageEvent());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void loadDiskImage(DiskImage image) {
|
||||
if (image.primary) {
|
||||
getThread().doPowerOff();
|
||||
public void onImageReady(final boolean result, final DiskImage image) {
|
||||
mDiskLoader = null;
|
||||
withUIActive(new Runnable() {
|
||||
public void run() {
|
||||
dismissFragment(FRAGMENT_LOADING);
|
||||
if (!result) {
|
||||
// TODO: Consider not showing the error if it was cancelled.
|
||||
new ErrorDialogFragment(R.string.image_error, null).show(getSupportFragmentManager(), FRAGMENT_ERROR);
|
||||
} else if (image.action != DiskImage.ASK) {
|
||||
loadDiskImage(image);
|
||||
} else {
|
||||
new SwapDiskFragment(image).show(getSupportFragmentManager(),
|
||||
FRAGMENT_SWAPDISK);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void prepareDiskImage(DiskImage image) {
|
||||
dismissFragment(FRAGMENT_ROM); // Note: should probably bail if visible.
|
||||
dismissFragment(FRAGMENT_SPEED);
|
||||
dismissFragment(FRAGMENT_DISKIMAGE);
|
||||
dismissFragment(FRAGMENT_SWAPDISK);
|
||||
dismissFragment(FRAGMENT_ZIPDISK);
|
||||
|
||||
if (image.filename.endsWith(".zip") || image.filename.endsWith(".ZIP")) {
|
||||
final ZipDiskFragment zip = new ZipDiskFragment(image);
|
||||
if (zip.needsDialog()) {
|
||||
zip.show(getSupportFragmentManager(), FRAGMENT_ZIPDISK);
|
||||
return;
|
||||
} else {
|
||||
image = zip.getFirstImage();
|
||||
}
|
||||
}
|
||||
runDiskLoader(image);
|
||||
}
|
||||
|
||||
mDownloadStarted = false;
|
||||
mDownloadReady = false;
|
||||
mDownloadAborted = false;
|
||||
// So that other fragments can transition into the DiskLoader.
|
||||
public void runDiskLoader(final DiskImage image) {
|
||||
final Runnable cancel = new Runnable() {
|
||||
public void run() {
|
||||
if (mDiskLoader != null) {
|
||||
mDiskLoader.cancel(true);
|
||||
mDiskLoader = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
loadDiskImageWhenReady(image);
|
||||
final DiskLoader.ImageReady notify = this;
|
||||
withUIActive(new Runnable() {
|
||||
public void run() {
|
||||
// In case there was already another DiskLoader.
|
||||
cancel.run();
|
||||
dismissFragment(FRAGMENT_LOADING);
|
||||
|
||||
mDiskLoader = new DiskLoader(notify, mConfigFile, image);
|
||||
if (mDiskLoader.willBeSlow()) {
|
||||
new SpecialProgressDialog(cancel).show(getSupportFragmentManager(),
|
||||
FRAGMENT_LOADING);
|
||||
}
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
mDiskLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else {
|
||||
mDiskLoader.execute();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private DiskImage getBootDiskImage(Intent intent) {
|
||||
@ -200,14 +242,20 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
|
||||
private void boot() {
|
||||
final DiskImage image = getBootDiskImage(getIntent());
|
||||
if (image != null) {
|
||||
loadDiskImage(image);
|
||||
prepareDiskImage(image);
|
||||
} else {
|
||||
mConfigFile.defaultConfig();
|
||||
getThread().allowPowerOn();
|
||||
mKegsView.postDelayed(new Runnable() { public void run() {
|
||||
new DiskImageFragment().show(getSupportFragmentManager(),
|
||||
FRAGMENT_DISKIMAGE);
|
||||
} }, 1000);
|
||||
mKegsView.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
withUIActive(new Runnable() {
|
||||
public void run() {
|
||||
new DiskImageFragment().show(getSupportFragmentManager(),
|
||||
FRAGMENT_DISKIMAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,19 +277,23 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
|
||||
"http://jsan.co/KEGS/" + mRomfile,
|
||||
mConfigFile.getConfigPath() + "/" + mRomfile);
|
||||
}
|
||||
protected void onPostExecute(Boolean success) {
|
||||
final SherlockDialogFragment frag = (SherlockDialogFragment)getSupportFragmentManager().findFragmentByTag(FRAGMENT_DOWNLOAD);
|
||||
if (frag != null) {
|
||||
frag.dismiss();
|
||||
}
|
||||
if (!success) {
|
||||
if (!isCancelled()) {
|
||||
final SherlockDialogFragment dialog = new ErrorDialogFragment();
|
||||
dialog.show(getSupportFragmentManager(), FRAGMENT_ERROR);
|
||||
protected void onPostExecute(final Boolean success) {
|
||||
withUIActive(new Runnable() {
|
||||
public void run() {
|
||||
final SherlockDialogFragment frag = (SherlockDialogFragment)getSupportFragmentManager().findFragmentByTag(FRAGMENT_DOWNLOAD);
|
||||
if (frag != null) {
|
||||
frag.dismiss();
|
||||
}
|
||||
if (!success) {
|
||||
if (!isCancelled()) {
|
||||
final Runnable runnable = new Runnable() { public void run() { finish(); } };
|
||||
new ErrorDialogFragment(R.string.rom_error, runnable).show(getSupportFragmentManager(), FRAGMENT_ERROR);
|
||||
}
|
||||
} else {
|
||||
boot();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boot();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,53 +321,6 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
|
||||
}
|
||||
}
|
||||
|
||||
class ErrorDialogFragment extends SherlockDialogFragment {
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setMessage(getResources().getText(R.string.rom_error));
|
||||
final AlertDialog dialog = builder.create();
|
||||
dialog.setCanceledOnTouchOutside(false); // prevent accidental dismissal
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
super.onCancel(dialog);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
class AssetFragment extends SherlockDialogFragment {
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
ProgressDialog dialog = new ProgressDialog(getActivity());
|
||||
// TODO: should probably use an XML layout for this.
|
||||
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
dialog.setMessage(getResources().getText(R.string.asset_loading));
|
||||
dialog.setProgressNumberFormat(null);
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
dialog.setProgressPercentFormat(null);
|
||||
}
|
||||
dialog.setIndeterminate(true);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
super.onCancel(dialog);
|
||||
mDownloadAborted = true;
|
||||
}
|
||||
}
|
||||
|
||||
public KegsThread getThread() {
|
||||
return mKegsThread;
|
||||
}
|
||||
@ -447,22 +452,18 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
|
||||
if (image == null) {
|
||||
return; // Nothing to do.
|
||||
}
|
||||
dismissFragment(FRAGMENT_ROM); // Note: should probably bail if visible.
|
||||
dismissFragment(FRAGMENT_SPEED);
|
||||
dismissFragment(FRAGMENT_DISKIMAGE);
|
||||
dismissFragment(FRAGMENT_SWAPDISK);
|
||||
|
||||
// Ask the user what to do with this new disk image.
|
||||
new SwapDiskFragment(image).show(getSupportFragmentManager(),
|
||||
FRAGMENT_SWAPDISK);
|
||||
image.action = DiskImage.ASK;
|
||||
prepareDiskImage(image);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
protected void onNewIntent(final Intent intent) {
|
||||
// "An activity will always be paused before receiving a new intent."
|
||||
// Being paused means we can't show a dialog here. Tell onResume to do it.
|
||||
setIntent(intent);
|
||||
mHaveNewIntent = true;
|
||||
withUIActive(new Runnable() {
|
||||
public void run() {
|
||||
handleNewIntent(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -530,8 +531,7 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
|
||||
|
||||
final String romfile = mConfigFile.whichRomFile();
|
||||
if (romfile == null) {
|
||||
final SherlockDialogFragment chooseRom = new RomDialogFragment();
|
||||
chooseRom.show(getSupportFragmentManager(), FRAGMENT_ROM);
|
||||
new RomDialogFragment().show(getSupportFragmentManager(), FRAGMENT_ROM);
|
||||
} else {
|
||||
boot();
|
||||
}
|
||||
@ -544,6 +544,7 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
|
||||
if (mKegsView instanceof KegsViewGL) {
|
||||
mKegsView.onPause();
|
||||
}
|
||||
mPaused = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -553,15 +554,18 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
|
||||
if (mKegsView instanceof KegsViewGL) {
|
||||
mKegsView.onResume();
|
||||
}
|
||||
if (mHaveNewIntent) {
|
||||
mHaveNewIntent = false;
|
||||
handleNewIntent(getIntent());
|
||||
mPaused = false;
|
||||
|
||||
Runnable runnable;
|
||||
while ((runnable = mResumeQueue.poll()) != null) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mResumeQueue.clear();
|
||||
Log.w("kegs", "onDestroy called, halting");
|
||||
// Force process to exit. We cannot handle another onCreate
|
||||
// once a KegsView has been active. (JNI kegsmain has already run)
|
||||
|
42
src/com/froop/app/kegs/SpecialProgressDialog.java
Normal file
42
src/com/froop/app/kegs/SpecialProgressDialog.java
Normal file
@ -0,0 +1,42 @@
|
||||
package com.froop.app.kegs;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||
|
||||
// A predefined progress dialog that calls a Runner when it's cancelled.
|
||||
|
||||
public class SpecialProgressDialog extends SherlockDialogFragment {
|
||||
private Runnable mCancelRunnable;
|
||||
|
||||
public SpecialProgressDialog(Runnable runnable) {
|
||||
super();
|
||||
mCancelRunnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
ProgressDialog dialog = new ProgressDialog(getActivity());
|
||||
// TODO: should probably use an XML layout for this.
|
||||
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
dialog.setMessage(getResources().getText(R.string.progress_message));
|
||||
dialog.setProgressNumberFormat(null);
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
dialog.setProgressPercentFormat(null);
|
||||
}
|
||||
dialog.setIndeterminate(true);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
super.onCancel(dialog);
|
||||
mCancelRunnable.run();
|
||||
}
|
||||
}
|
@ -28,9 +28,10 @@ public class SwapDiskFragment extends SherlockDialogFragment {
|
||||
if (item == 0) {
|
||||
// ignore this image
|
||||
} else if (item == 1) {
|
||||
mImage.primary = false; // just a disk insert
|
||||
mImage.action = DiskImage.SWAP; // just a disk insert
|
||||
((KegsMain)getActivity()).loadDiskImage(mImage);
|
||||
} else if (item == 2) {
|
||||
mImage.action = DiskImage.BOOT; // was ASK
|
||||
((KegsMain)getActivity()).loadDiskImage(mImage);
|
||||
}
|
||||
}
|
||||
|
@ -5,24 +5,40 @@ import java.lang.Integer;
|
||||
import java.io.File;
|
||||
|
||||
class DiskImage {
|
||||
// template
|
||||
public static final String BOOT_SLOT_5 = "boot_slot_5";
|
||||
public static final String BOOT_SLOT_6 = "boot_slot_6";
|
||||
public static final String BOOT_SLOT_7 = "boot_slot_7";
|
||||
|
||||
public boolean primary = true;
|
||||
// origin
|
||||
public static final int ASSET = 0;
|
||||
public static final int DOWNLOAD = 1;
|
||||
public static final int LOCALFILE = 2;
|
||||
public static final int ERROR = 3;
|
||||
|
||||
// action
|
||||
public static final int BOOT = 0;
|
||||
public static final int SWAP = 1;
|
||||
public static final int ASK = 2;
|
||||
|
||||
public String filename;
|
||||
public String drive;
|
||||
public int speed;
|
||||
public String template;
|
||||
public int origin;
|
||||
public int action;
|
||||
public String extract_filename = null; // for extracting from zipfiles
|
||||
|
||||
// Example:
|
||||
// DiskImage("XMAS_DEMO.2MG", "s5d1", 2, "boot_slot_5");
|
||||
// DiskImage("XMAS_DEMO.2MG", "s5d1", 2, "boot_slot_5", LOCALFILE);
|
||||
public DiskImage(final String filename, final String drive,
|
||||
final int speed, final String template) {
|
||||
final int speed, final String template, final int origin) {
|
||||
this.filename = filename;
|
||||
this.drive = drive;
|
||||
this.speed = speed;
|
||||
this.template = template;
|
||||
this.origin = origin;
|
||||
this.action = BOOT;
|
||||
}
|
||||
|
||||
public static DiskImage fromPath(String path) {
|
||||
@ -32,19 +48,44 @@ class DiskImage {
|
||||
return null;
|
||||
} else if (length >= 1024 * 1024) {
|
||||
// TODO: should insert the disk and use the System 6 template
|
||||
return new DiskImage(path, "s7d1", 3, BOOT_SLOT_7);
|
||||
return new DiskImage(path, "s7d1", 3, BOOT_SLOT_7, LOCALFILE);
|
||||
} else if (length >= 400 * 1024) {
|
||||
return new DiskImage(path, "s5d1", 2, BOOT_SLOT_5);
|
||||
return new DiskImage(path, "s5d1", 2, BOOT_SLOT_5, LOCALFILE);
|
||||
} else if (length > 0) {
|
||||
return new DiskImage(path, "s6d1", 1, BOOT_SLOT_6);
|
||||
return new DiskImage(path, "s6d1", 1, BOOT_SLOT_6, LOCALFILE);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isDiskImageFilename(String filename) {
|
||||
if (filename.endsWith(".2mg") ||
|
||||
filename.endsWith(".dsk") ||
|
||||
filename.endsWith(".nib") ||
|
||||
filename.endsWith(".hdv") ||
|
||||
filename.endsWith(".po") ||
|
||||
filename.endsWith(".do") ||
|
||||
filename.endsWith(".bin") ||
|
||||
filename.endsWith(".2MG") ||
|
||||
filename.endsWith(".DSK") ||
|
||||
filename.endsWith(".NIB") ||
|
||||
filename.endsWith(".HDV") ||
|
||||
filename.endsWith(".PO") ||
|
||||
filename.endsWith(".DO") ||
|
||||
filename.endsWith(".BIN")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String getBaseFilename() {
|
||||
int pos = this.filename.lastIndexOf("/");
|
||||
return this.filename.substring(pos + 1);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
int pos = this.filename.lastIndexOf("/") + 1;
|
||||
return this.filename.substring(pos);
|
||||
return getBaseFilename();
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
|
@ -32,16 +32,16 @@ public class DiskImageFragment extends SherlockDialogFragment {
|
||||
DiskImage image = null;
|
||||
|
||||
if (item == 0) {
|
||||
image = new DiskImage("System 6.hdv", "s7d1", 3, DiskImage.BOOT_SLOT_7);
|
||||
image = new DiskImage("System 6.hdv", "s7d1", 3, DiskImage.BOOT_SLOT_7, DiskImage.ASSET);
|
||||
} else if (item == 1) {
|
||||
image = new DiskImage("XMAS_DEMO.2MG", "s5d1", 2, DiskImage.BOOT_SLOT_5);
|
||||
image = new DiskImage("XMAS_DEMO.2MG", "s5d1", 2, DiskImage.BOOT_SLOT_5, DiskImage.ASSET);
|
||||
} else if (item == 2) {
|
||||
// TODO: There should be an adapter on the ListView instead.
|
||||
image = new DiskImage("prince.2mg", "s5d1", 2, DiskImage.BOOT_SLOT_5);
|
||||
image = new DiskImage("prince.2mg", "s5d1", 2, DiskImage.BOOT_SLOT_5, DiskImage.DOWNLOAD);
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
((KegsMain)getActivity()).loadDiskImage(image);
|
||||
((KegsMain)getActivity()).prepareDiskImage(image);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
146
src/com/froop/app/kegs/diskimage/DiskLoader.java
Normal file
146
src/com/froop/app/kegs/diskimage/DiskLoader.java
Normal file
@ -0,0 +1,146 @@
|
||||
package com.froop.app.kegs;
|
||||
|
||||
import android.util.Log;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
class DiskLoader extends AsyncTask<Void, Void, Boolean> {
|
||||
interface ImageReady {
|
||||
void onImageReady(boolean result, DiskImage image);
|
||||
}
|
||||
|
||||
private ImageReady mNotify;
|
||||
private DiskImage mImage;
|
||||
|
||||
private boolean mSlow = false;
|
||||
private String mDestPath;
|
||||
|
||||
DiskLoader(final ImageReady notify, final ConfigFile config,
|
||||
final DiskImage image) {
|
||||
mNotify = notify;
|
||||
mImage = image;
|
||||
|
||||
if (image.filename.endsWith(".gz") ||
|
||||
image.filename.endsWith(".zip") ||
|
||||
image.filename.endsWith(".GZ") ||
|
||||
image.filename.endsWith(".ZIP") ||
|
||||
image.origin == DiskImage.ASSET ||
|
||||
image.origin == DiskImage.DOWNLOAD) {
|
||||
mSlow = true;
|
||||
}
|
||||
|
||||
if (image.origin == DiskImage.ASSET ||
|
||||
image.origin == DiskImage.DOWNLOAD) {
|
||||
mDestPath = config.getImagePath();
|
||||
|
||||
final File local_copy = new File(mDestPath, image.filename);
|
||||
if (local_copy != null && local_copy.exists()) {
|
||||
// Assume whatever is there will work.
|
||||
mSlow = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (image.origin == DiskImage.LOCALFILE) {
|
||||
// If we need to extract it, it will go here.
|
||||
mDestPath = config.getCachePath();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean willBeSlow() {
|
||||
return mSlow;
|
||||
}
|
||||
|
||||
protected void onPreExecute() {
|
||||
}
|
||||
|
||||
private Boolean extractImage() {
|
||||
if (mImage.origin == DiskImage.ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mImage.origin == DiskImage.ASSET) {
|
||||
// Just keep polling waiting for it, AssetImages is working on it.
|
||||
final File local_copy = new File(mDestPath, mImage.filename);
|
||||
while (!local_copy.exists()) {
|
||||
try { Thread.sleep(1000); } catch (InterruptedException e) {}
|
||||
if (isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mImage.origin == DiskImage.DOWNLOAD) {
|
||||
final File local_copy = new File(mDestPath, mImage.filename);
|
||||
if (local_copy != null && local_copy.exists()) {
|
||||
// Assume whatever is there will work.
|
||||
return true;
|
||||
} else {
|
||||
return new DownloadHelper().save(
|
||||
"http://jsan.co/KEGS/images/" + mImage.filename,
|
||||
local_copy.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
if (mImage.filename.endsWith(".gz") || mImage.filename.endsWith(".GZ")) {
|
||||
final String old_filename = mImage.getBaseFilename();
|
||||
final String filename = old_filename.substring(0, old_filename.lastIndexOf("."));
|
||||
try {
|
||||
GZIPInputStream zipStream = new GZIPInputStream(new BufferedInputStream(new FileInputStream(new File(mImage.filename))));
|
||||
new CopyHelper(zipStream, mDestPath, filename).copy();
|
||||
} catch (java.io.IOException e) {
|
||||
Log.e("kegs", Log.getStackTraceString(e));
|
||||
return false;
|
||||
}
|
||||
mImage.filename = new File(mDestPath, filename).getPath();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mImage.filename.endsWith(".zip") || mImage.filename.endsWith(".ZIP")) {
|
||||
final int pos = mImage.extract_filename.lastIndexOf("/");
|
||||
final String filename = mImage.extract_filename.substring(pos + 1);
|
||||
try {
|
||||
final ZipFile zip = new ZipFile(mImage.filename);
|
||||
final ZipEntry extract = zip.getEntry(mImage.extract_filename);
|
||||
if (extract == null) {
|
||||
zip.close();
|
||||
Log.e("kegs", mImage.filename + " has no " + mImage.extract_filename);
|
||||
return false;
|
||||
}
|
||||
new CopyHelper(zip.getInputStream(extract), mDestPath, filename).copy();
|
||||
zip.close();
|
||||
} catch (java.io.IOException e) {
|
||||
Log.e("kegs", Log.getStackTraceString(e));
|
||||
return false;
|
||||
}
|
||||
mImage.filename = new File(mDestPath, filename).getPath();
|
||||
return true;
|
||||
}
|
||||
|
||||
// No special handling required, finish up and run onImageReady.
|
||||
return true;
|
||||
}
|
||||
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
Boolean result = extractImage();
|
||||
nativeSync(); // Flush new disk images before claiming they are ready.
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void onCancelled(final Boolean result) {
|
||||
mNotify.onImageReady(result, mImage);
|
||||
}
|
||||
|
||||
protected void onPostExecute(final Boolean result) {
|
||||
mNotify.onImageReady(result, mImage);
|
||||
}
|
||||
|
||||
// See jni/android_driver.c:nativeSync()
|
||||
private native void nativeSync();
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.froop.app.kegs;
|
||||
|
||||
import android.util.Log;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
class DownloadImage extends AsyncTask<Void, Void, Boolean> {
|
||||
interface DownloadReady {
|
||||
void onDownloadReady(boolean result);
|
||||
}
|
||||
|
||||
private DownloadReady mNotify;
|
||||
private DiskImage mImage;
|
||||
private File mDest;
|
||||
private boolean mLocalPath = false;
|
||||
|
||||
DownloadImage(DownloadReady notify, String imagePath, DiskImage image) {
|
||||
mNotify = notify;
|
||||
mImage = image;
|
||||
|
||||
if (imagePath == null || image.filename.startsWith("/")) {
|
||||
mLocalPath = true;
|
||||
mDest = new File(image.filename);
|
||||
} else {
|
||||
mDest = new File(imagePath, image.filename);
|
||||
}
|
||||
|
||||
if (mLocalPath || mDest.exists()) {
|
||||
// Assume whatever is there will work.
|
||||
// So the caller will immediately see that it's already done.
|
||||
mNotify.onDownloadReady(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onPreExecute() {
|
||||
}
|
||||
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
if (mLocalPath || mDest.exists()) {
|
||||
// Assume whatever is there will work.
|
||||
return true;
|
||||
}
|
||||
|
||||
return new DownloadHelper().save(
|
||||
"http://jsan.co/KEGS/images/" + mImage.filename, mDest.getPath());
|
||||
}
|
||||
|
||||
protected void onCancelled(final Boolean result) {
|
||||
mNotify.onDownloadReady(false);
|
||||
}
|
||||
|
||||
protected void onPostExecute(final Boolean result) {
|
||||
mNotify.onDownloadReady(result);
|
||||
}
|
||||
}
|
105
src/com/froop/app/kegs/diskimage/ZipDiskFragment.java
Normal file
105
src/com/froop/app/kegs/diskimage/ZipDiskFragment.java
Normal file
@ -0,0 +1,105 @@
|
||||
package com.froop.app.kegs;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||
|
||||
public class ZipDiskFragment extends SherlockDialogFragment {
|
||||
private ArrayList<String> mFiles = new ArrayList<String>();
|
||||
private ArrayList<String> mTitles = new ArrayList<String>();
|
||||
private DiskImage mImage;
|
||||
|
||||
public ZipDiskFragment(DiskImage image) {
|
||||
super();
|
||||
mImage = image;
|
||||
|
||||
// NOTE: We extract the zipfile table of contents in the UI thread.
|
||||
getTableOfContents();
|
||||
}
|
||||
|
||||
private void getTableOfContents() {
|
||||
try {
|
||||
final ZipFile zip = new ZipFile(mImage.filename);
|
||||
Enumeration<? extends ZipEntry> entries = zip.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
final String filename = entry.getName();
|
||||
if (DiskImage.isDiskImageFilename(filename)) {
|
||||
mFiles.add(filename);
|
||||
int pos = filename.lastIndexOf("/");
|
||||
mTitles.add(filename.substring(pos + 1));
|
||||
}
|
||||
}
|
||||
zip.close();
|
||||
} catch (java.io.IOException e) {
|
||||
Log.e("kegs", Log.getStackTraceString(e));
|
||||
// Do not show any results.
|
||||
mFiles.clear();
|
||||
mTitles.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Caller may use getFirstImage when there is only one item
|
||||
public boolean needsDialog() {
|
||||
return mTitles.size() != 1;
|
||||
}
|
||||
|
||||
public DiskImage getFirstImage() {
|
||||
mImage.extract_filename = mFiles.get(0);
|
||||
return mImage;
|
||||
}
|
||||
|
||||
private void forceDiskLoaderError() {
|
||||
// TODO: Ick. All this just so that whoever opened this fragment
|
||||
// will get a DiskLoader callback.
|
||||
mImage.filename = "";
|
||||
mImage.origin = DiskImage.ERROR;
|
||||
((KegsMain)getActivity()).runDiskLoader(mImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
|
||||
// Force 3.5 inch disk icon instead of .getIconId()
|
||||
// TODO: Could also show a special zipfile icon...?
|
||||
builder.setIcon(R.drawable.ic_menu_save);
|
||||
builder.setTitle(mImage.getTitle());
|
||||
|
||||
if (mTitles.size() == 0) {
|
||||
builder.setMessage(R.string.zipfile_nomatches);
|
||||
builder.setPositiveButton(R.string.dialog_ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int button) {
|
||||
dismiss();
|
||||
forceDiskLoaderError();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
builder.setItems(mTitles.toArray(new String[0]), new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int item) {
|
||||
dismiss();
|
||||
mImage.extract_filename = mFiles.get(item);
|
||||
((KegsMain)getActivity()).runDiskLoader(mImage);
|
||||
}
|
||||
});
|
||||
}
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
super.onCancel(dialog);
|
||||
forceDiskLoaderError();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user