All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.tidalwave.bluebill.mobile.android.observation.AndroidObservationUIController Maven / Gradle / Ivy

/***********************************************************************************************************************
 *
 * blueBill Mobile - open source birdwatching
 * ==========================================
 *
 * Copyright (C) 2009, 2010 by Tidalwave s.a.s. (http://www.tidalwave.it)
 * http://bluebill.tidalwave.it/mobile/
 *
 ***********************************************************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 ***********************************************************************************************************************
 *
 * $Id: AndroidObservationUIController.java,v 990e62920c21 2010/06/18 19:26:36 fabrizio $
 *
 **********************************************************************************************************************/
package it.tidalwave.bluebill.mobile.android.observation;

import java.io.IOException;
import javax.annotation.Nonnull;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.io.File;
import org.openide.util.NbBundle;
import it.tidalwave.util.logging.Logger;
import it.tidalwave.bluebill.observation.Observation;
import it.tidalwave.bluebill.observation.ObservationItem;
import it.tidalwave.bluebill.observation.ObservationManager;
import it.tidalwave.bluebill.observation.ObservationSet;
import it.tidalwave.mobile.ui.ActionEvent;
import it.tidalwave.mobile.ui.ActionListener;
import it.tidalwave.mobile.util.DateUpdater;
import it.tidalwave.bluebill.mobile.observation.DefaultObservationUIController;
import it.tidalwave.bluebill.mobile.observation.ObservationCountFormat;
import it.tidalwave.bluebill.mobile.observation.ObservationUI;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.DataSetObserver;
import android.net.Uri;
import android.view.MenuItem;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import it.tidalwave.bluebill.mobile.android.R;
import it.tidalwave.bluebill.mobile.android.taxonomy.factsheet.TaxonFactSheetControlFlow;
import it.tidalwave.bluebill.mobile.observation.share.Report;
import it.tidalwave.mobile.android.ui.AndroidUtilities;
import it.tidalwave.mobile.android.ui.ControlFlow;
import it.tidalwave.mobile.android.util.ProgressDialogController;
import it.tidalwave.mobile.io.FileSystem;
import it.tidalwave.netbeans.util.Locator;

/***********************************************************************************************************************
 *
 * @author  Fabrizio Giudici
 * @version $Id: $
 *
 **********************************************************************************************************************/
public class AndroidObservationUIController extends DefaultObservationUIController
  {
    private static final String CLASS = AndroidObservationUIController.class.getName();
    private static final Logger logger = Logger.getLogger(CLASS);

    private final ObservationListAdapter listAdapter;

    private final ObservationSet observationSet;

    private final ObservationUI ui;

    private FileSystem fileSystem;

    private Observation contextMenuObservation;

    private ObservationItem contextMenuObservationItem;
    
    private final ObservationCountFormat observationCountFormat = new ObservationCountFormat();

    private final ControlFlow controlFlow;

    private final static int PROGRESS_DIALOG = 171717;

    private final ProgressDialogController progressDialogController;

    /*******************************************************************************************************************
     *
     * FIXME: pull up, after using ActionListener and ActionEvent from the patched Swing stuff
     *
     ******************************************************************************************************************/
    private final ActionListener changeDateTimeListener = new ActionListener()
      {
        public void actionPerformed (final @Nonnull ActionEvent event)
          {
            final Date date = event.as(DateUpdater.class).update(contextMenuObservation.getDate());
            contextMenuObservation.change().at(date).apply();
          }
      };

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public AndroidObservationUIController (final @Nonnull ObservationUI ui)
      {
        super(ui);
        this.ui = ui;
        this.controlFlow = ControlFlow.forActivity((Activity)ui);
        this.progressDialogController = new ProgressDialogController((Activity)ui);

        fileSystem = Locator.find(FileSystem.class);

        observationSet = Locator.find(ObservationManager.class).findOrCreateObservationSetById(null);
        listAdapter = new ObservationListAdapter(observationSet);

        listAdapter.registerDataSetObserver(new DataSetObserver()
          {
            @Override
            public void onChanged()
              {
                ui.setFooterText(observationCountFormat.format(listAdapter.getGroupCount()));
              }
          });
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public void fireRefresh()
      {
        listAdapter.notifyDataSetChanged();
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public ObservationListAdapter getListAdapter()
      {
        return listAdapter;
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Override
    public void startNewObservationSequence()
      {
        logger.info("startNewObservationSequence()");
        super.startNewObservationSequence();
        controlFlow.start(AddObservationControlFlow.class);
      }

    /*******************************************************************************************************************
     *
     *
     *
     ******************************************************************************************************************/
    @Override
    public void browseToFactSheet()
      {
        logger.info("browseToFactSheet()");
        super.browseToFactSheet();
        controlFlow.start(TaxonFactSheetControlFlow.class);
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Override
    protected void shareObservations (final @Nonnull Report report)
      {
        logger.info("shareObservations(%s)", report);
        final String pickAService = NbBundle.getMessage(AndroidObservationUIController.class, "pickAService");
        final String[] recipients = report.getRecipients().toArray(new String[0]);
        final Intent sendIntent = new Intent(Intent.ACTION_SEND);
        sendIntent.putExtra(Intent.EXTRA_EMAIL, recipients);
        sendIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, recipients);
        sendIntent.putExtra(Intent.EXTRA_SUBJECT, report.getSubject());
        sendIntent.putExtra(Intent.EXTRA_TEXT, report.getBody());
        sendIntent.setType(report.getMimeType());

        if (!report.getAttachments().isEmpty())
          {
            try
              {
                final String attachmentsFileName = "spool/attachments.zip";
                final ZipOutputStream zos = new ZipOutputStream(fileSystem.openFileOutput(attachmentsFileName));
                
                for (final Report attachment : report.getAttachments())
                  {
                    logger.info(">>>> storing attachment: %s", attachment.getSubject());
                    final ZipEntry zipEntry = new ZipEntry(attachment.getSubject());
                    zos.putNextEntry(zipEntry);
                    zos.write(attachment.getBody().getBytes());
                    zos.closeEntry();
                  }
                
                zos.finish();
                zos.flush();
                zos.close();

//                final String path = fileSystem.getPath(attachmentsFileName);
//                logger.info(">>>> Attachment saved to %s", path);
//                sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+ path));
                final File path = fileSystem.getFile(attachmentsFileName);
                logger.info(">>>> Attachment saved to %s", path);
                sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(path));
//                sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+ path));
                sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                sendIntent.setType("application/zip");
                // FIXME: how to delete after sent?
              }
            catch (IOException e)
              {
                e.printStackTrace();
              }
          }

        ((Activity)ui).startActivity(Intent.createChooser(sendIntent, pickAService));
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public boolean onContextItemSelected (final @Nonnull MenuItem item)
      {
        final ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo)item.getMenuInfo();
        final int type = ExpandableListView.getPackedPositionType(info.packedPosition);
        final int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition);

        switch (type)
          {
            case ExpandableListView.PACKED_POSITION_TYPE_CHILD:
                final int childPosition = ExpandableListView.getPackedPositionChild(info.packedPosition);
                contextMenuObservationItem = listAdapter.getChild(groupPosition, childPosition);

                switch (item.getItemId())
                  {
                    case R.id.deleteObservationItem:
                      deleteObservationItem(contextMenuObservationItem);
                      break;
                  }

                return true;

            case ExpandableListView.PACKED_POSITION_TYPE_GROUP:
                contextMenuObservation = listAdapter.getGroup(groupPosition);

                switch (item.getItemId())
                  {
                    case R.id.editDate:
                    case R.id.editTime:
                      ui.getCommonUITasks().showDialog(item.getItemId());
                      break;
                  }

                return true;
          }

        return false;
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    protected Dialog onCreateDialog (final int id)
      {
        switch (id)
          {
            case R.id.editTime:
                return (Dialog)ui.getCommonUITasks().createTimePickerDialog(changeDateTimeListener);

            case R.id.editDate:
                return (Dialog)ui.getCommonUITasks().createDatePickerDialog(changeDateTimeListener);

            case R.id.share:
                return createShareDialog();

            case PROGRESS_DIALOG:
                return progressDialogController.getProgressDialog();
          }

        throw new RuntimeException("Unknown dialog id: " + id);
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    protected void onPrepareDialog (final int id, final @Nonnull Dialog dialog)
      {
        switch (id)
          {
            case R.id.editTime:
                AndroidUtilities.setDate((TimePickerDialog)dialog, contextMenuObservation.getDate());
                break;

            case R.id.editDate:
                AndroidUtilities.setDate((DatePickerDialog)dialog, contextMenuObservation.getDate());
                break;
          }
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public Dialog createShareDialog()
      {
        String shareOptions = NbBundle.getMessage(AndroidObservationUIController.class, "shareOptions");
        String attachKML = NbBundle.getMessage(AndroidObservationUIController.class, "attachKML");
        String ok = NbBundle.getMessage(AndroidObservationUIController.class, "ok");
        String cancel = NbBundle.getMessage(AndroidObservationUIController.class, "cancel");

        final CharSequence[] items = { attachKML };
        final boolean[] o = new boolean[1];

        final AlertDialog.Builder builder = new AlertDialog.Builder((Activity)ui);
        builder.setTitle(shareOptions);
        builder.setMultiChoiceItems(items, o, new DialogInterface.OnMultiChoiceClickListener()
          {
            public void onClick (DialogInterface di, int i, boolean bln)
              {
                o[i] = bln;
              }
          });
          
        builder.setPositiveButton(ok, new DialogInterface.OnClickListener()
          {
            public void onClick (final @Nonnull DialogInterface di, final int i)
              {
                final ShareOptions options = new ShareOptions();
                options.setKmlAttachment(o[0]);
                options.setProgressListener(progressDialogController);

                final Thread thread = new Thread()
                  {
                    @Override
                    public void run()
                      {
                        shareObservations(options);
                      }
                  };

                thread.start();
                ((Activity)ui).showDialog(PROGRESS_DIALOG);
              }
          });
          
        builder.setNegativeButton(cancel, null);

        return builder.create();
      }
  }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy