CreateRecipe.java
/*
* Copyright 2016 the Cook-E development team
*
* This file is part of Cook-E.
*
* Cook-E is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Cook-E 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cook-E. If not, see <http://www.gnu.org/licenses/>.
*/
package org.cook_e.cook_e;
import android.app.AlertDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import org.cook_e.data.Recipe;
import org.cook_e.data.Step;
import java.sql.SQLException;
import java.util.Collections;
/**
* An activity that lets the user create a recipe
*/
public class CreateRecipe extends AppCompatActivity {
/**
* The key used when saving and restoring the recipe image
*/
private static final String KEY_RECIPE_IMAGE = CreateRecipe.class.getName() + ".RECIPE_IMAGE";
/**
* Result code used when requesting images
*/
private static int RESULT_LOAD_IMAGE = 42;
/**
* The image view that displays the recipe image
*/
private ImageView mImageView;
/**
* The user-selected image for the new recipe, or null if none has been selected
*/
@Nullable
private Bitmap mRecipeImage = null;
/**
* Text field for title
*/
private EditText mTitleField;
/**
* Text field for description
*/
private EditText mAuthorField;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// must be call beforehand
setContentView(R.layout.activity_create_recipe);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setUpActionBar();
// Image view
mImageView = (ImageView) findViewById(R.id.recipe_image_view);
// Hide by default, until an image is selected
mImageView.setVisibility(View.GONE);
mTitleField = (EditText) findViewById(R.id.title_field);
mAuthorField = (EditText) findViewById(R.id.author_field);
// Continue button
final Button continueButton = (Button) findViewById(R.id.continue_button);
continueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
continueCreatingRecipe();
}
});
// Check for restored state
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_RECIPE_IMAGE)) {
final Bitmap restoredImage = savedInstanceState.getParcelable(KEY_RECIPE_IMAGE);
if (restoredImage != null) {
mImageView.setImageBitmap(restoredImage);
mImageView.setVisibility(View.VISIBLE);
mRecipeImage = restoredImage;
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Write the selected image
outState.putParcelable(KEY_RECIPE_IMAGE, mRecipeImage);
}
private void continueCreatingRecipe() {
final String title = mTitleField.getText().toString();
final String author = mAuthorField.getText().toString();
if (title.isEmpty()) {
new AlertDialog.Builder(this)
.setTitle("Empty title")
.setMessage("Please enter a recipe title")
.setPositiveButton(android.R.string.ok, null)
.show();
return;
}
// Create a recipe
final Recipe recipe = new Recipe(title, author, Collections.<Step>emptyList());
// TODO: If the recipe image is set, starting the next activity will fail because of
// the large image (see issue #7). Once a solution is found, set the image.
// Store the recipe
try {
App.getAccessor().persistRecipe(recipe);
} catch (SQLException e) {
new AlertDialog.Builder(this)
.setTitle("Failed to save recipe")
.setMessage(e.getLocalizedMessage())
.show();
return;
}
// Start editor activity
final Intent intent = new Intent(this, EditRecipeActivity.class);
intent.putExtra(EditRecipeActivity.EXTRA_RECIPE, recipe);
startActivity(intent);
// Close this activity, so that when the user goes back it will not appear again
finish();
}
private void setUpActionBar() {
final ActionBar bar = getSupportActionBar();
assert bar != null;
bar.setTitle(R.string.create_recipe);
}
/*
* This is a workaround for inconsistent behavior.
*
* Pressing the system back button or calling finish() returns a result to the parent activity,
* as expected. However, the default action when the up button is pressed does not send a result
* to the parent. This override ensures that a result is sent when the action bar up button is
* pressed.
*/
@Override
public boolean onSupportNavigateUp() {
finish();
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.create_recipe, menu);
final MenuItem addImageItem = menu.findItem(R.id.item_add_image);
addImageItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
requestImageSelect();
return true;
}
});
final MenuItem removeImageItem = menu.findItem(R.id.item_remove_image);
removeImageItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
mRecipeImage = null;
mImageView.setImageDrawable(null);
mImageView.setVisibility(View.GONE);
return true;
}
});
return true;
}
/**
* Starts an activity to ask the user to select an image
*/
private void requestImageSelect() {
Intent intent = new Intent(
Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RESULT_LOAD_IMAGE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check for a received image
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && data != null) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
final int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
final Bitmap loadedImage = BitmapFactory.decodeFile(picturePath);
if (loadedImage != null) {
mImageView.setImageBitmap(loadedImage);
mImageView.setVisibility(View.VISIBLE);
mRecipeImage = loadedImage;
}
else {
new AlertDialog.Builder(this)
.setTitle("Could not access image")
.setMessage("Please ensure that the selected image is valid and accessible.")
.setPositiveButton(android.R.string.ok, null)
.show();
}
}
}
}
}