All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
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 d808b6cb5d50 2010/07/10 21:19:33 fabrizio $
*
**********************************************************************************************************************/
package it.tidalwave.bluebill.mobile.android.observation;
import javax.annotation.Nonnull;
import javax.inject.Provider;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.io.File;
import java.io.IOException;
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.os.Bundle;
import android.view.MenuItem;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import it.tidalwave.netbeans.util.Locator;
import it.tidalwave.mobile.io.FileSystem;
import it.tidalwave.mobile.io.MasterFileSystem;
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 java.io.FileOutputStream;
/***********************************************************************************************************************
*
* @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 static final String ATTACHMENTS_FILE_NAME = "spool/attachments.zip";
private final ObservationListAdapter listAdapter;
private final ObservationSet observationSet;
private final ObservationUI ui;
@Nonnull
private Provider masterFileSystem = Locator.createProviderFor(MasterFileSystem.class);
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);
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);
// It seems that using the internal file system it doesn't work
final FileSystem fileSystem = masterFileSystem.get().getExternalFileSystem();
// final FileSystem fileSystem = masterFileSystem.get().getInternalFileSystem();
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 File attachmentFile = fileSystem.getFile(ATTACHMENTS_FILE_NAME);
saveAttachment(attachmentFile, report);
sendIntent.setType("application/zip");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(attachmentFile));
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// FIXME: how to delete after sent? We could listen for Activity completion notification,
// but the user might decide to store the document as draft.
}
catch (IOException e)
{
logger.warning("Error while preparing the report: %s", e);
logger.throwing(CLASS, "shareObservations()", e);
}
}
((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();
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private void saveAttachment (final @Nonnull File file, final @Nonnull Report report)
throws IOException
{
final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file));
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();
logger.info(">>>> Attachment saved to %s, %d bytes", file, file.length());
}
}