com.richtodd.android.quiltdesign.app.BlockEditActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.richtodd.android.quiltdesign.app.BlockEditActivity.java

Source

/* Copyright (c) 2013 Richard G. Todd.
 * Licensed under the terms of the GNU General Public License (GPL) Version 3.0.
 */

package com.richtodd.android.quiltdesign.app;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidParameterException;
import java.util.Date;

import org.json.JSONObject;

import android.app.ActionBar;
import android.app.Activity;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;

import com.richtodd.android.pdf.DocumentInformation;
import com.richtodd.android.pdf.DocumentWriter;
import com.richtodd.android.pdf.Rectangle;
import com.richtodd.android.quiltdesign.block.BlockContainer;
import com.richtodd.android.quiltdesign.block.JSONRepository;
import com.richtodd.android.quiltdesign.block.PaperPiecedBlock;
import com.richtodd.android.quiltdesign.block.PaperPiecedBlockDocumentFormatter;
import com.richtodd.android.quiltdesign.block.PaperPiecedBlockPiece;
import com.richtodd.android.quiltdesign.block.RenderFormats;
import com.richtodd.android.quiltdesign.block.RenderOptions;
import com.richtodd.android.quiltdesign.block.RenderStyles;
import com.richtodd.android.quiltdesign.block.Repository;
import com.richtodd.android.quiltdesign.block.Swatch;
import com.richtodd.android.quiltdesign.block.Theme;
import com.richtodd.android.quiltdesign.block.ThemeContainer;
import com.richtodd.android.quiltdesign.block.ThemeView;
import com.richtodd.android.repository.JSONUtility;
import com.richtodd.android.repository.RepositoryException;

public class BlockEditActivity extends Activity implements ColorPickerDialogFragment.ColorPickerDialogListener,
        ThemePickerDialogFragment.ThemePickerDialogListener, BlockEditFragment.BlockEditListener,
        AlertDialogFragment.AlertDialogListener, EditNameDialogFragment.EditNameDialogListener,
        ShareOptionsDialogFragment.ShareOptionsDialogListener,
        BlockOptionsDialogFragment.BlockOptionsDialogListener {
    // private static final String TAG = "BlockEditActivity";

    //
    // Fields
    //

    public static final String ARG_BLOCK_NAME = "com.richtodd.android.quiltdesign.app.BlockEditActivity.blockName";
    private static final String KEY_CONFIRM_DELETE = "confirmDelete";
    private static final String KEY_FILE_EXISTS = "fileExists";

    private String m_blockNameArgument;

    private Theme m_theme;

    private ThemeView m_themeView;
    private Button m_button_setColor;
    private Button m_button_addPiece;
    private Button m_button_deletePiece;

    private String m_saveAsBlockName;

    //
    // Overrides
    //

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_block_edit);
        getActionBar().setDisplayHomeAsUpEnabled(true);

        m_blockNameArgument = getIntent().getStringExtra(ARG_BLOCK_NAME);

        if (savedInstanceState != null) {
            m_saveAsBlockName = savedInstanceState.getString("saveAsBlockName");
            m_theme = (Theme) savedInstanceState.getParcelable("theme");
        }

        ActionBar ab = getActionBar();
        ab.setTitle("Edit Block");
        ab.setSubtitle(getCurrentBlockName());

        FragmentManager fm = getFragmentManager();

        // Create color settings fragment.
        {
            Fragment f = fm.findFragmentById(R.id.layout_blockEditFragment);
            if (f == null) {
                f = BlockEditFragment.create(m_blockNameArgument);
                fm.beginTransaction().add(R.id.layout_blockEditFragment, f).commit();
            }
        }

        m_themeView = (ThemeView) findViewById(R.id.themeView);
        m_themeView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Swatch swatch = (Swatch) m_themeView.getItemAtPosition(position);
                BlockEditFragment fragment = getBlockEditFragment();
                if (fragment != null) {
                    fragment.setColor(swatch.getColor());
                }

            }
        });
        m_themeView.setTheme(m_theme);

        m_button_setColor = (Button) findViewById(R.id.button_setColor);
        m_button_setColor.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                chooseColor();
            }
        });

        m_button_addPiece = (Button) findViewById(R.id.button_addPiece);
        m_button_addPiece.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BlockEditFragment fragment = getBlockEditFragment();
                int color = fragment.getColor();
                PaperPiecedBlockPiece piece = fragment.addPiece(color);
                onPieceSelected(fragment, piece);
            }
        });

        m_button_deletePiece = (Button) findViewById(R.id.button_deletePiece);
        m_button_deletePiece.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BlockEditFragment fragment = getBlockEditFragment();
                fragment.deletePiece();
                onPieceSelected(fragment, null);
            }
        });

        ImageView button_refreshTheme = (ImageView) findViewById(R.id.button_refreshTheme);
        button_refreshTheme.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                refreshTheme();
            }
        });

        ImageView button_selectTheme = (ImageView) findViewById(R.id.button_selectTheme);
        button_selectTheme.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                chooseTheme();
            }
        });
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString("saveAsBlockName", m_saveAsBlockName);
        outState.putParcelable("theme", m_theme);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.options_activity_block_edit, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        switch (itemId) {
        case android.R.id.home: {
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }
        case R.id.menu_blockOptions: {
            PaperPiecedBlock block = getBlockEditFragment().getBlock();
            BlockOptionsDialogFragment dialog = BlockOptionsDialogFragment.create((int) block.getWidth());
            dialog.show(getFragmentManager(), null);
            return true;
        }
        case R.id.menu_shareBlock: {
            ShareOptionsDialogFragment dialog = ShareOptionsDialogFragment.create(Intent.ACTION_SEND);
            dialog.show(getFragmentManager(), null);
            return true;
        }
        case R.id.menu_viewBlock: {
            ShareOptionsDialogFragment dialog = ShareOptionsDialogFragment.create(Intent.ACTION_VIEW);
            dialog.show(getFragmentManager(), null);
            return true;
        }
        case R.id.menu_renameBlock: {
            showEditNameDialog();
            return true;
        }
        case R.id.menu_deleteBlock: {
            AlertDialogFragment dialog = AlertDialogFragment.create(KEY_CONFIRM_DELETE,
                    getString(R.string.alert_message_confirmBlockDelete), getString(R.string.alert_button_yes),
                    getString(R.string.alert_button_no));
            dialog.show(getFragmentManager(), null);
            return true;
        }
        case R.id.menu_cancelChanges: {
            getBlockEditFragment().setSaveSuppressed(true);
            finish();
            return true;
        }
        case R.id.menu_settings: {
            Intent intent = new Intent(this, BlockPreferenceActivity.class);
            startActivity(intent);
            return true;
        }
        }

        return super.onOptionsItemSelected(item);
    }

    private void refreshTheme() {
        m_theme = getBlockEditFragment().getBlock()
                .createTheme(getResources().getInteger(R.integer.theme_swatch_count));
        m_themeView.setTheme(m_theme);
    }

    //
    // Overrides - Listeners
    //

    @Override
    public void onBlockLoaded(BlockEditFragment fragment, PaperPiecedBlock block) {

        if (m_theme == null) {
            if (block.getPieces().size() == 0 && block.getBackgroundColor() == 0) {
                m_theme = Theme.createColors(getResources().getInteger(R.integer.theme_swatch_count), 0.8f, 1f);

                fragment.setColor(m_theme.getSwatches().get(0).getColor());
                fragment.addPiece(m_theme.getSwatches().get(1).getColor());
                block.clearDirty();
            } else {
                m_theme = block.createTheme(getResources().getInteger(R.integer.theme_swatch_count));
            }

            if (m_themeView != null) {
                m_themeView.setTheme(m_theme);
            }
        }
    }

    @Override
    public void onPieceSelected(BlockEditFragment fragment, PaperPiecedBlockPiece piece) {
        enableDisableButtons();
    }

    @Override
    public void onColorPickerPositiveClick(DialogFragment dialog, int color) {
        BlockEditFragment fragment = getBlockEditFragment();
        if (fragment != null) {
            fragment.setColor(color);
        }
    }

    @Override
    public void onColorPickerNegativeClick(DialogFragment dialog) {
        // No action required.
    }

    @Override
    public void onThemePickerPositiveClick(DialogFragment dialog, String themeName) throws Exception {
        if (themeName != null) {
            Repository repository = Repository.getDefaultRepository(this);
            ThemeContainer themes = repository.getThemes();
            m_theme = themes.loadTheme(themeName);
            m_themeView.setTheme(m_theme);
        }
    }

    @Override
    public void onThemePickerNegativeClick(DialogFragment dialog) {
        // No action required.
    }

    @Override
    public void onAlertDialogPositiveClick(DialogFragment dialog, String key) throws Exception {

        if (key.equals(KEY_CONFIRM_DELETE)) {
            getBlockEditFragment().setSaveSuppressed(true);

            Repository repository = Repository.getDefaultRepository(this);
            BlockContainer blocks = repository.getBlocks();
            blocks.deleteBlock(m_blockNameArgument);

            finish();

        } else if (key.equals(KEY_FILE_EXISTS)) {
            showEditNameDialog();

        } else {
            throw new InvalidParameterException("Unknown key " + key);
        }
    }

    @Override
    public void onAlertDialogNegativeClick(DialogFragment dialog, String key) {
        // No action required.
    }

    @Override
    public void onEditNamePositiveClick(DialogFragment dialog, String name) throws Exception {

        Repository repository = Repository.getDefaultRepository(this);
        BlockContainer blocks = repository.getBlocks();
        if (blocks.blockExists(name)) {
            AlertDialogFragment alertDialog = AlertDialogFragment.create(KEY_FILE_EXISTS,
                    getString(R.string.alert_message_blockAlreadyExists),
                    getString(R.string.alert_button_acknowledge), null);
            alertDialog.show(getFragmentManager(), null);
        } else {
            m_saveAsBlockName = name;
            getBlockEditFragment().setSaveAsBlockName(m_saveAsBlockName);
        }

        ActionBar ab = getActionBar();
        ab.setSubtitle(getCurrentBlockName());
    }

    @Override
    public void onEditNameNegativeClick(DialogFragment dialog) {
        // No action required.
    }

    @Override
    public void onShareOptionsPositiveClick(DialogFragment dialog, RenderStyles renderStyle,
            RenderFormats renderFormat, String intentAction) throws Exception {

        Uri uriFile;
        String type;
        switch (renderFormat) {
        case Bitmap:
            uriFile = saveBitmap(renderStyle);
            type = "image/png";
            break;
        case PDF:
            uriFile = savePDF(renderStyle);
            type = "application/pdf";
            break;
        case QuiltDesign:
            uriFile = saveQuiltDesign();
            type = "application/vnd.richtodd.quiltdesign";
            break;
        default:
            throw new IllegalArgumentException("Unknown render format " + renderFormat);
        }

        Intent intent = new Intent(intentAction);
        if (intentAction.equals(Intent.ACTION_SEND)) {
            intent.putExtra(Intent.EXTRA_STREAM, uriFile);
            intent.setType(type);
            startActivity(Intent.createChooser(intent, "Share With"));
        } else {
            intent.setDataAndType(uriFile, type);
            startActivity(Intent.createChooser(intent, "View With"));
        }
    }

    @Override
    public void onShareOptionsNegativeClick(DialogFragment dialog) {
        // No action required.
    }

    @Override
    public void onBlockOptionsPositiveClick(DialogFragment dialog, int size) {
        BlockEditFragment fragment = getBlockEditFragment();
        fragment.setSize(size);
    }

    @Override
    public void onBlockOptionsNegativeClick(DialogFragment dialog) {
        // No action required.
    }

    //
    // Private
    //

    private String getCurrentBlockName() {
        if (m_saveAsBlockName != null) {
            return m_saveAsBlockName;
        } else {
            return m_blockNameArgument;
        }
    }

    private Uri saveBitmap(RenderStyles renderStyle) throws IOException {

        BlockEditFragment fragment = getBlockEditFragment();
        PaperPiecedBlock block = fragment.getBlock();

        File file = new File(StorageUtility.getPublicFolder(), getCurrentBlockName() + ".png");

        saveBitmap(block, file, renderStyle);

        Uri uri = Uri.fromFile(file);

        return uri;
    }

    private void saveBitmap(PaperPiecedBlock block, File file, RenderStyles renderStyle) throws IOException {
        int marginSize = getResources().getInteger(R.integer.block_margin_size);
        int shareDensity = Preferences.getEffectiveShareDensity(this,
                PreferenceManager.getDefaultSharedPreferences(this));

        float width = block.getWidth();
        float height = block.getHeight();

        RenderOptions renderOptions = new RenderOptions();
        renderOptions.setWidth((int) (shareDensity * width));
        renderOptions.setHeight((int) (shareDensity * height));
        renderOptions.setLeft(marginSize);
        renderOptions.setTop(marginSize);
        renderOptions.setStrokeWidth(2);
        renderOptions.setRenderStyle(renderStyle);

        Bitmap bitmap = renderOptions.createBitmap();

        block.draw(bitmap, renderOptions);

        FileOutputStream stream = new FileOutputStream(file);
        try {
            bitmap.compress(CompressFormat.JPEG, 100, stream);
        } finally {
            stream.close();
        }
    }

    private Uri savePDF(RenderStyles renderStyle) throws IOException {

        BlockEditFragment fragment = getBlockEditFragment();
        PaperPiecedBlock block = fragment.getBlock();

        File file = new File(StorageUtility.getPublicFolder(), getCurrentBlockName() + ".pdf");

        savePDF(block, file, renderStyle, getCurrentBlockName());

        Uri uri = Uri.fromFile(file);

        return uri;
    }

    private void savePDF(PaperPiecedBlock block, File file, RenderStyles renderStyle, String title)
            throws IOException {

        DocumentWriter writer = new DocumentWriter(new BufferedOutputStream(new FileOutputStream(file)));
        try {
            writer.beginDocument(Rectangle.getLetterPageBoundary(), Rectangle.getLetterContentBoundary());

            writer.beginPage();

            PaperPiecedBlockDocumentFormatter formatter = new PaperPiecedBlockDocumentFormatter();
            formatter.formatBlock(block, title, writer, renderStyle, false);

            writer.endPage();

            DocumentInformation documentInformation = new DocumentInformation();
            documentInformation.setTitle(title);
            documentInformation.setCreationDate(new Date());
            writer.endDocument(documentInformation);
        } finally {
            writer.close();
        }
    }

    private Uri saveQuiltDesign() throws IOException, RepositoryException {

        BlockEditFragment fragment = getBlockEditFragment();
        PaperPiecedBlock block = fragment.getBlock();

        File file = new File(StorageUtility.getPublicFolder(), getCurrentBlockName() + ".quiltdesign");

        saveQuiltDesign(block, file);

        Uri uri = Uri.fromFile(file);

        return uri;
    }

    private void saveQuiltDesign(PaperPiecedBlock block, File file) throws RepositoryException {
        JSONObject jsonRepository = new JSONObject();
        JSONRepository repository = new JSONRepository(jsonRepository, null);
        repository.getBlocks().savePaperPiecedBlock(getCurrentBlockName(), block, null);
        JSONUtility.saveJSONObject(file, jsonRepository);
    }

    private void showEditNameDialog() {
        String blockName = getCurrentBlockName();
        EditNameDialogFragment dialog = EditNameDialogFragment.create("Block", blockName);
        dialog.show(getFragmentManager(), null);
    }

    private void chooseColor() {
        BlockEditFragment fragment = getBlockEditFragment();
        int color = fragment.getColor();
        ColorPickerDialogFragment dialog = ColorPickerDialogFragment.create(color);
        dialog.show(getFragmentManager(), "ColorPickerDialogFragment");
    }

    private void chooseTheme() {
        ThemePickerDialogFragment dialog = ThemePickerDialogFragment.create();
        dialog.show(getFragmentManager(), "ThemePickerDialogFragment");
    }

    private void enableDisableButtons() {
        BlockEditFragment fragment = getBlockEditFragment();
        m_button_addPiece.setEnabled(fragment.canAddPiece());
        m_button_deletePiece.setEnabled(fragment.canDeletePiece());
    }

    private BlockEditFragment getBlockEditFragment() {
        return (BlockEditFragment) getFragmentManager().findFragmentById(R.id.layout_blockEditFragment);
    }
}