FormulaRunner.java :  » UnTagged » moonblink » org » hermit » formula » Android Open Source

Android Open Source » UnTagged » moonblink 
moonblink » org » hermit » formula » FormulaRunner.java

/**
 * Formula: programmable custom computations.
 * <br>Copyright 2009 Ian Cameron Smith
 *
 * <p>This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation (see COPYING).
 * 
 * <p>This program 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.
 */


package org.hermit.formula;


import org.hermit.android.core.AppUtils;
import org.hermit.android.core.MainActivity;
import org.hermit.android.notice.EulaBox;
import org.hermit.android.notice.InfoBox;
import org.hermit.formula.provider.Formula;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;


/**
 * Main activity for Formula.
 */
public class FormulaRunner
  extends MainActivity
{
  
  // ******************************************************************** //
    // Activity Lifecycle.
    // ******************************************************************** //

  /**
   * Called when the activity is starting.  This is where most
   * initialization should go: calling setContentView(int) to inflate
   * the activity's UI, etc.
   * 
   * You can call finish() from within this function, in which case
   * onDestroy() will be immediately called without any of the rest of
   * the activity lifecycle executing.
   * 
   * Derived classes must call through to the super class's implementation
   * of this method.  If they do not, an exception will be thrown.
   * 
   * @param  icicle      If the activity is being re-initialized
   *               after previously being shut down then this
   *               Bundle contains the data it most recently
   *               supplied in onSaveInstanceState(Bundle).
   *               Note: Otherwise it is null.
   */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        
        // Get the URI of the formula we're running; this will be null
        // if we were started from the launcher.
        formulaUri = getIntent().getData();
        
        // Create the application GUI.
        setContentView(R.layout.formula_runner);
        
        // Get the formula view widget.
        formulaWidget = (FormulaView) findViewById(R.id.runner_view);

        // Create the EULA dialog.
        eulaDialog = new EulaBox(this, R.string.eula_title,
                     R.string.eula_text, R.string.button_close);
        
        // Create the dialog we use for help and about.
        AppUtils autils = AppUtils.getInstance(this);
        messageDialog = new InfoBox(this, R.string.button_close);
        String version = autils.getVersionString();
    messageDialog.setTitle(version);

        // Restore our preferences.
        updatePreferences();
    }
    

    /**
     * Called after {@link #onCreate} or {@link #onStop} when the current
     * activity is now being displayed to the user.  It will
     * be followed by {@link #onRestart}.
     */
    @Override
  protected void onStart() {
        Log.i(TAG, "onStart()");
        
        super.onStart();
    }


    /**
     * Called after onRestoreInstanceState(Bundle), onRestart(), or onPause(),
     * for your activity to start interacting with the user.  This is a good
     * place to begin animations, open exclusive-access devices (such as the
     * camera), etc.
   * 
   * Derived classes must call through to the super class's implementation
   * of this method.  If they do not, an exception will be thrown.
     */
    @Override
    protected void onResume() {
        Log.i(TAG, "onResume()");
        
        super.onResume();
        
        // First time round, show the EULA.
        eulaDialog.showFirstTime();
        
        // If we have a URI, get a cursor on the formula.  If we don't have
        // one, then query for any formula, in order of when used,
        // so we get the most recent one.
        if (formulaUri != null)
          formulaCursor = managedQuery(formulaUri, BODY_PROJECTION, null, null, null);
        else {
          formulaCursor = managedQuery(Formula.Formulae.CONTENT_URI,
                         BODY_PROJECTION,
                         Formula.Formulae.VALID + ">0",
                         null,
                         Formula.Formulae.USED_DATE + " DESC");
        }

        // If we have a matching formula, display it.  Otherwise
        // display a hint.
        if (formulaCursor != null && formulaCursor.moveToFirst()) {
          // If we don't have a URI, sort it out.
          if (formulaUri == null) {
                int iindex = formulaCursor.getColumnIndex(Formula.Formulae._ID);
                long rowId = formulaCursor.getLong(iindex);
              formulaUri = ContentUris.withAppendedId(Formula.Formulae.CONTENT_URI, rowId);
          }

            // Get the formula and display it.
            int tindex = formulaCursor.getColumnIndex(Formula.Formulae.TITLE);
            String title = formulaCursor.getString(tindex);
            int findex = formulaCursor.getColumnIndex(Formula.Formulae.FORMULA);
            String text = formulaCursor.getString(findex);
            setFormula(title, text);
            
          // Update the last-used date.
          ContentValues values = new ContentValues();
          values.put(Formula.Formulae.USED_DATE, System.currentTimeMillis());
          getContentResolver().update(formulaUri, values, null, null);
        } else {
          // TODO: inform the user.
            formulaWidget.clearFormula();
        }
    }


    /**
     * Called to retrieve per-instance state from an activity before being
     * killed so that the state can be restored in onCreate(Bundle) or
     * onRestoreInstanceState(Bundle) (the Bundle populated by this method
     * will be passed to both).
     * 
     * If called, this method will occur before onStop().  There are no
     * guarantees about whether it will occur before or after onPause().
   * 
   * @param  outState    A Bundle in which to place any state
   *               information you wish to save.
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        Log.i(TAG, "onSaveInstanceState()");
        
        super.onSaveInstanceState(outState);
    }

    
    /**
     * Called as part of the activity lifecycle when an activity is going
     * into the background, but has not (yet) been killed.  The counterpart
     * to onResume(). 
     * 
     * After receiving this call you will usually receive a following call
     * to onStop() (after the next activity has been resumed and displayed),
     * however in some cases there will be a direct call back to onResume()
     * without going through the stopped state. 
   * 
   * Derived classes must call through to the super class's implementation
   * of this method.  If they do not, an exception will be thrown.
     */
    @Override
    protected void onPause() {
        Log.i(TAG, "onPause()");
        
        super.onPause();
    }


    /**
     * Called when you are no longer visible to the user.  You will next
     * receive either {@link #onStart}, {@link #onDestroy}, or nothing,
     * depending on later user activity.
     * 
     * <p>Note that this method may never be called, in low memory situations
     * where the system does not have enough memory to keep your activity's
     * process running after its {@link #onPause} method is called.
     */
    @Override
  protected void onStop() {
        Log.i(TAG, "onStop()");
        
        super.onStop();
    }


  // ******************************************************************** //
    // Menu and Preferences Handling.
    // ******************************************************************** //

  /**
     * Initialize the contents of the options menu by adding items
     * to the given menu.
     * 
     * This is only called once, the first time the options menu is displayed.
     * To update the menu every time it is displayed, see
     * onPrepareOptionsMenu(Menu).
     * 
     * When we add items to the menu, we can either supply a Runnable to
     * receive notification of selection, or we can implement the Activity's
     * onOptionsItemSelected(Menu.Item) method to handle them there.
     * 
     * @param  menu      The options menu in which we should
     *               place our items.  We can safely hold on this
     *               (and any items created from it), making
     *               modifications to it as desired, until the next
     *               time onCreateOptionsMenu() is called.
     * @return          true for the menu to be displayed; false
     *               to suppress showing it.
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
      // We must call through to the base implementation.
      super.onCreateOptionsMenu(menu);
      
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);

        return true;
    }
    
    
    /**
     * Prepare the options menu to be displayed.  This is called right
     * before the menu is shown, every time it is shown.
     * 
     * @param  menu      The options menu as last shown or first
     *               initialized by onCreateOptionsMenu().
     * @return          You must return true for the menu to be
     *               displayed; if you return false it will
     *               not be shown.
     */
    @Override
  public boolean onPrepareOptionsMenu(Menu menu) {
      super.onPrepareOptionsMenu(menu);
      
      // Disable edit if we have nothing to edit.
      MenuItem edit = menu.findItem(R.id.menu_edit);
      edit.setEnabled(formulaUri != null);
       
      return true;
    }
    
    
    /**
     * This hook is called whenever an item in your options menu is selected.
     * Derived classes should call through to the base class for it to
     * perform the default menu handling.  (True?)
     *
     * @param  item      The menu item that was selected.
     * @return          false to have the normal processing happen.
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
        case R.id.menu_select:
          Intent pick = new Intent(Intent.ACTION_VIEW,
                      Formula.Formulae.CONTENT_URI);
        startActivity(pick);
          break;
        case R.id.menu_edit:
          if (formulaUri != null) {
            Intent edit = new Intent(Intent.ACTION_EDIT, formulaUri);
            startActivity(edit);
          }
          break;
        case R.id.menu_new:
          Intent insert = new Intent(Intent.ACTION_INSERT,
                         Formula.Formulae.CONTENT_URI);
          startActivity(insert);
          break;
        case R.id.menu_prefs:
          // Launch the preferences activity as a subactivity, so we
          // know when it returns.
          Intent pint = new Intent();
          pint.setClass(this, Preferences.class);
          startActivityForResult(pint, new MainActivity.ActivityListener() {
        @Override
        public void onActivityFinished(int resultCode, Intent data) {
                updatePreferences();
        }
          });
          break;
      case R.id.menu_help:
        messageDialog.setLinkButton(1, R.string.button_homepage,
                        R.string.url_homepage);
        messageDialog.setLinkButton(2, R.string.button_manual,
                      R.string.url_manual);
       messageDialog.show(R.string.help_text);
        break;
      case R.id.menu_about:
        messageDialog.setLinkButton(1, R.string.button_homepage,
                      R.string.url_homepage);
        messageDialog.setLinkButton(2, R.string.button_license,
                    R.string.url_license);
       messageDialog.show(R.string.about_text);
         break;
      case R.id.menu_eula:
            eulaDialog.showNow();
         break;
        case R.id.menu_exit:
          finish();
          break;
      default:
        return super.onOptionsItemSelected(item);
      }
      
      return true;
    }
    

    /**
     * Read our application preferences and configure ourself appropriately.
     */
    private void updatePreferences() {
      SharedPreferences prefs =
              PreferenceManager.getDefaultSharedPreferences(this);

      shadowSd = false;
      try {
        shadowSd = prefs.getBoolean("shadowSd", false);
      } catch (Exception e) {
        Log.i(TAG, "Pref: bad shadowSd");
      }
      Log.i(TAG, "Prefs: shadowSd " + shadowSd);
    }


  // ******************************************************************** //
  // Formula Handling.
  // ******************************************************************** //

    private void setFormula(String title, String formula) {
      String app = getString(R.string.app_name);
      setTitle(app + ": " + title);
      formulaWidget.setFormula(formula);
    }
    

  // ******************************************************************** //
  // Class Data.
  // ******************************************************************** //

    // Debugging tag.
  @SuppressWarnings("unused")
  private static final String TAG = "formula";

    // Projection to select the text of a formula.
    private static final String[] BODY_PROJECTION = new String[] {
            Formula.Formulae._ID,
            Formula.Formulae.TITLE,
            Formula.Formulae.FORMULA,
    };

    
  // ******************************************************************** //
  // Private Data.
  // ******************************************************************** //

    // The EULA dialog.
    private EulaBox eulaDialog;

  // Dialog used to display about etc.
  private InfoBox messageDialog;

    // The URI, cursor and text of the current formula.  If we don't have
    // one, these will all be blank.
  private Uri formulaUri;
    private Cursor formulaCursor = null;
    
    // The formula view widget.
    private FormulaView formulaWidget = null;
    
    // If true, shadow all formulae to the SD card.
    private boolean shadowSd = false;

}

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.