package com.odoo.addons.mail;
import java.util.ArrayList;
import java.util.List;
import odoo.OArguments;
import odoo.controls.OField;
import odoo.controls.OForm.OnViewClickListener;
import org.json.JSONArray;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.odoo.R;
import com.odoo.addons.mail.models.MailMessage;
import com.odoo.addons.mail.providers.mail.MailProvider;
import com.odoo.base.ir.Attachments;
import com.odoo.base.res.ResPartner;
import com.odoo.orm.OColumn;
import com.odoo.orm.ODataRow;
import com.odoo.orm.OSyncHelper;
import com.odoo.support.AppScope;
import com.odoo.support.fragment.AsyncTaskListener;
import com.odoo.support.fragment.BaseFragment;
import com.odoo.support.listview.OCursorListAdapter;
import com.odoo.support.listview.OCursorListAdapter.BeforeBindUpdateData;
import com.odoo.support.listview.OCursorListAdapter.OnRowViewClickListener;
import com.odoo.support.listview.OCursorListAdapter.OnViewBindListener;
import com.odoo.util.OControls;
import com.odoo.util.PreferenceManager;
import com.odoo.util.drawer.DrawerItem;
public class MailDetail extends BaseFragment implements
LoaderCallbacks<Cursor>, OnRowViewClickListener, OnViewBindListener,
OnClickListener, BeforeBindUpdateData, OnViewClickListener {
public static final String KEY_MESSAGE_ID = "mail_id";
public static final String KEY_SUBJECT = "mail_subject";
public static final String KEY_BODY = "mail_body";
public static final int KEY_MESSAGE_REPLY_ID = 125;
private Context mContext = null;
private Integer mMailId = null;
private String selection = null;
private String[] args;
private View mView = null;
private ListView mailList = null;
private OCursorListAdapter mAdapter;
private ImageView imgBtn_send_reply, btnStartFullComposeMode;
private Menu mMenu;
private PreferenceManager mPref;
private Attachments mAttachment;
private Cursor cr = null;
private List<Object> mBuilderitems = new ArrayList<Object>();
private List<ODataRow> mVoters = new ArrayList<ODataRow>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
scope = new AppScope(this);
mContext = getActivity();
mPref = new PreferenceManager(mContext);
mAttachment = new Attachments(mContext);
initArgs();
return inflater.inflate(R.layout.mail_detail_layout, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mView = view;
init();
imgBtn_send_reply.setOnClickListener(this);
btnStartFullComposeMode.setOnClickListener(this);
mailList = (ListView) view.findViewById(R.id.lstMessageDetail);
mAdapter = new OCursorListAdapter(mContext, null,
R.layout.mail_detail_parent_list_item);
mAdapter.setOnViewCreateListener(new OCursorListAdapter.OnViewCreateListener() {
@Override
public View onViewCreated(Context context, ViewGroup view,
Cursor cr, int position) {
int parent_id = cr.getInt(cr.getColumnIndex("parent_id"));
int resource = (parent_id == 0) ? mAdapter.getResource()
: R.layout.mail_detail_reply_list_item;
return mAdapter.inflate(resource, view);
}
});
mAdapter.setOnRowViewClickListener(R.id.imgBtn_mail_detail_starred,
this);
mAdapter.setBeforeBindUpdateData(this);
mAdapter.setOnRowViewClickListener(R.id.voteCounter, this);
mAdapter.setOnRowViewClickListener(R.id.voteCounter, this);
mAdapter.setOnViewBindListener(this);
mailList.setAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
private void initArgs() {
Bundle args = getArguments();
if (args.containsKey(OColumn.ROW_ID)) {
mMailId = args.getInt(OColumn.ROW_ID);
boolean autoArchive = mPref.getBoolean("mail_auto_archive", false);
if (autoArchive) {
archiveMail(false);
}
}
}
public void init() {
imgBtn_send_reply = (ImageView) mView
.findViewById(R.id.btnSendQuickReply);
btnStartFullComposeMode = (ImageView) mView
.findViewById(R.id.btnStartFullComposeMode);
if (mMailId != null) {
ODataRow parent = db().select(mMailId);
if (parent.getInt("id") == 0) {
OControls.setInvisible(mView, R.id.quickReplyBox);
}
if (parent.getString("message_title") != null
&& parent.getString("message_title") != "false")
OControls.setText(mView, R.id.txvDetailSubject,
parent.getString("message_title"));
}
}
private void toggleMailToRead(int mailId, boolean to_read) {
ContentValues values = new ContentValues();
values.put("to_read", (to_read) ? 1 : 0);
if (!inNetwork())
values.put("is_dirty", 1);
String selection = OColumn.ROW_ID + " = ? or parent_id = ?";
String[] args = new String[] { mailId + "", mailId + "" };
getActivity().getContentResolver().update(db().uri(), values,
selection, args);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Boolean to_read = false;
switch (item.getItemId()) {
case R.id.menu_mail_read:
to_read = false;
mMenu.findItem(R.id.menu_mail_unread).setVisible(true);
mMenu.findItem(R.id.menu_mail_read).setVisible(false);
break;
case R.id.menu_mail_unread:
to_read = true;
mMenu.findItem(R.id.menu_mail_unread).setVisible(false);
mMenu.findItem(R.id.menu_mail_read).setVisible(true);
break;
default:
break;
}
archiveMail(to_read);
return super.onOptionsItemSelected(item);
}
private void archiveMail(final Boolean to_read) {
toggleMailToRead(mMailId, to_read);
scope.main().newBackgroundTask(new AsyncTaskListener() {
@Override
public Object onPerformTask() {
if (inNetwork()) {
MailMessage mail = new MailMessage(getActivity());
mail.markMailReadUnread(mMailId, to_read);
}
return null;
}
@Override
public void onFinish(Object result) {
restartLoader();
}
}).execute();
}
@Override
public Object databaseHelper(Context context) {
return new MailMessage(context);
}
@Override
public List<DrawerItem> drawerMenus(Context context) {
return null;
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
List<String> argsList = new ArrayList<String>();
selection = "_id = ?";
selection += " or parent_id = ?";
argsList.add(mMailId + "");
argsList.add(mMailId + "");
args = argsList.toArray(new String[argsList.size()]);
Uri uri = ((MailMessage) db()).mailDetailUri();
return new CursorLoader(mContext, uri, new String[] { "message_title",
"author_name", "author_id", "total_childs", "parent_id",
"date", "to_read", "body", "starred" }, selection, args,
"date DESC");
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_mail_detail, menu);
mMenu = menu;
if (cr != null) {
updateMenuVisibility();
}
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
mAdapter.changeCursor(cursor);
cr = cursor;
updateMenuVisibility();
}
private void updateMenuVisibility() {
boolean to_read_flag = false;
if (cr.moveToFirst()) {
do {
int to_read = cr.getInt(cr.getColumnIndex("to_read"));
if (to_read == 1) {
to_read_flag = true;
break;
}
} while (cr.moveToNext());
int menu_id = R.id.menu_mail_unread;
if (!to_read_flag) {
menu_id = R.id.menu_mail_read;
}
if (mMenu != null)
mMenu.findItem(menu_id).setVisible(false);
}
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
mAdapter.changeCursor(null);
}
@Override
public void onRowViewClick(int position, Cursor cursor, final View view,
View parent) {
final MailMessage mail = new MailMessage(mContext);
final Cursor c = cursor;
switch (view.getId()) {
case R.id.voteCounter:
if (inNetwork()) {
final ImageView imgVote = (ImageView) view
.findViewById(R.id.imgBtn_mail_detail_rate);
final TextView voteCounter = (TextView) view
.findViewById(R.id.txv_voteCounter);
try {
final int mail_id = c.getInt(c.getColumnIndex("id"));
scope.main().newBackgroundTask(new AsyncTaskListener() {
boolean has_voted = false;
@Override
public Object onPerformTask() {
int votes = (!voteCounter.getText().equals("")) ? Integer
.parseInt(voteCounter.getText().toString())
: 0;
OSyncHelper helper = db().getSyncHelper();
OArguments args = new OArguments();
args.add(new JSONArray().put(mail_id));
Boolean response = (Boolean) helper.callMethod(
"vote_toggle", args);
if (response) {
// Vote up
mail.addManyToManyRecord(
"vote_user_ids",
c.getInt(c
.getColumnIndex(OColumn.ROW_ID)),
mail.author_id());
has_voted = true;
votes++;
} else {
// Vote down
mail.deleteManyToManyRecord(
"vote_user_ids",
c.getInt(c
.getColumnIndex(OColumn.ROW_ID)),
mail.author_id());
votes--;
}
return votes;
}
@Override
public void onFinish(Object result) {
int votes = (Integer) result;
voteCounter.setText((votes > 0) ? votes + "" : "");
imgVote.setColorFilter((has_voted) ? mContext
.getResources().getColor(
R.color.odoo_purple) : Color
.parseColor("#aaaaaa"));
}
}).execute();
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(mContext, _s(R.string.no_connection),
Toast.LENGTH_LONG).show();
}
break;
case R.id.imgBtn_mail_detail_starred:
String starred = "";
starred = c.getString(c.getColumnIndex("starred"));
final boolean is_fav = !starred.equals("1");
if (inNetwork()) {
ImageView imgStarred = (ImageView) view;
imgStarred.setColorFilter((is_fav) ? Color
.parseColor("#FF8800") : Color.parseColor("#aaaaaa"));
// markAsTodo
scope.main().newBackgroundTask(new AsyncTaskListener() {
@Override
public Object onPerformTask() {
MailMessage mail = (MailMessage) db();
mail.markAsTodo(c, is_fav);
return null;
}
@Override
public void onFinish(Object result) {
if (getActivity() != null)
restartLoader();
}
}).execute();
} else {
Toast.makeText(mContext, _s(R.string.no_connection),
Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
private void restartLoader() {
if (getActivity() != null)
getLoaderManager().restartLoader(0, null, this);
}
@Override
public void onViewBind(View view, Cursor cr, final ODataRow row) {
// Setting starred color
final ResPartner res = new ResPartner(mContext);
LinearLayout lvote_Counter = (LinearLayout) view
.findViewById(R.id.voteCounter);
ImageView imgStarred = (ImageView) view
.findViewById(R.id.imgBtn_mail_detail_starred);
String is_fav = cr.getString(cr.getColumnIndex("starred"));
imgStarred.setColorFilter((is_fav.equals("1")) ? Color
.parseColor("#FF8800") : Color.parseColor("#aaaaaa"));
List<Integer> voters_id = row.getM2MRecord("vote_user_ids").getRelIds();
int voters = voters_id.size();
if (voters > 0) {
int author_id = ((MailMessage) db()).author_id();
ImageView selfVoted = (ImageView) view
.findViewById(R.id.imgBtn_mail_detail_rate);
TextView txvVotes = (TextView) view
.findViewById(R.id.txv_voteCounter);
if (voters_id.indexOf(author_id) > -1) {
selfVoted.setColorFilter(_c(R.color.odoo_purple));
txvVotes.setTextColor(_c(R.color.odoo_purple));
} else {
selfVoted.setColorFilter(Color.parseColor("#aaaaaa"));
txvVotes.setTextColor(Color.parseColor("#aaaaaa"));
}
txvVotes.setText(voters + "");
}
if (view.findViewById(R.id.txvTotalChilds) != null) {
TextView totalChilds = (TextView) view
.findViewById(R.id.txvTotalChilds);
int replies = Integer.parseInt(cr.getString(cr
.getColumnIndex("total_childs")));
String childs = "No replies";
if (replies > 0) {
childs = replies + " replies";
}
totalChilds.setText(childs);
}
OField mfield = (OField) view.findViewById(R.id.msgAttachments);
if (row.getM2MRecord("attachment_ids").getRelIds().size() > 0) {
mfield.setOnItemClickListener(this);
mfield.reInit();
} else {
mfield.setVisibility(View.GONE);
}
String names = ((MailMessage) db()).getPartnersName(row);
OControls.setText(view, R.id.partner_names, names);
lvote_Counter.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mBuilderitems.clear();
mVoters = row.getM2MRecord("vote_user_ids").browseEach();
if (mVoters.size() > 0) {
for (ODataRow row : mVoters)
mBuilderitems.add(res.select(row.getInt("_id")));
}
new VoterDialog(mContext, mVoters, mBuilderitems).build()
.show();
return true;
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSendQuickReply:
if (getPref().getBoolean("confirm_send_mail", false)) {
AlertDialog.Builder builder = new AlertDialog.Builder(
getActivity());
builder.setTitle(_s(R.string.dialog_send_reply_title));
builder.setMessage(_s(R.string.dialog_send_reply_message));
builder.setPositiveButton(
_s(R.string.dialog_send_reply_positive_button_text),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
sendQuickMail();
}
});
builder.setNegativeButton(
_s(R.string.dialog_send_reply_negative_button_text),
null);
builder.show();
} else {
sendQuickMail();
}
break;
case R.id.btnStartFullComposeMode:
Bundle bundle = new Bundle();
bundle.putInt(KEY_MESSAGE_ID, mMailId);
bundle.putString(KEY_SUBJECT,
"Re: " + OControls.getText(mView, R.id.txvDetailSubject));
bundle.putString(KEY_BODY,
OControls.getText(mView, R.id.edtQuickReplyMessage));
Intent intent = new Intent(getActivity(), ComposeMail.class);
intent.putExtras(bundle);
startActivityForResult(intent, KEY_MESSAGE_REPLY_ID);
break;
default:
break;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == KEY_MESSAGE_REPLY_ID
&& resultCode == Activity.RESULT_OK) {
if (inNetwork()) {
scope.main().requestSync(MailProvider.AUTHORITY);
Toast.makeText(getActivity(), _s(R.string.message_sent),
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), _s(R.string.message_cant_sent),
Toast.LENGTH_LONG).show();
}
getLoaderManager().restartLoader(0, null, this);
OControls.setText(mView, R.id.edtQuickReplyMessage, "");
}
}
private void sendQuickMail() {
EditText edt = (EditText) mView.findViewById(R.id.edtQuickReplyMessage);
ODataRow parent = db().select(mMailId);
MailMessage mail = new MailMessage(mContext);
edt.setError(null);
if (TextUtils.isEmpty(edt.getText())) {
edt.setError("Message required");
} else {
String subject = parent.getString("message_title");
String mail_body = OControls.getText(mView,
R.id.edtQuickReplyMessage);
ContentValues values = new ContentValues();
values.put("message_title", subject);
values.put("body", mail_body);
mail.sendQuickReply(null, subject, mail_body, mMailId,
parent.getInt("total_childs"));
getLoaderManager().restartLoader(0, null, this);
if (inNetwork()) {
scope.main().requestSync(MailProvider.AUTHORITY);
Toast.makeText(mContext, _s(R.string.reply_sent),
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(mContext, _s(R.string.reply_cant_sent),
Toast.LENGTH_LONG).show();
}
OControls.setText(mView, R.id.edtQuickReplyMessage, "");
}
}
@Override
public ODataRow updateDataRow(Cursor cr) {
ODataRow row = new ODataRow();
ODataRow rec = db()
.selectRelRecord(
new String[] { "attachment_ids", "vote_user_ids",
"partner_ids" },
cr.getInt(cr.getColumnIndex(OColumn.ROW_ID)));
row.addAll(rec.getAll());
String author_image = "false";
if (!cr.getString(cr.getColumnIndex("author_id")).equals("false")) {
author_image = new ResPartner(getActivity()).select(
cr.getInt(cr.getColumnIndex("author_id"))).getString(
"image_small");
}
row.put("author_id_image_small", author_image);
return row;
}
@Override
public void onFormViewClick(View view, ODataRow row) {
mAttachment.downloadAttachment(row.getInt(OColumn.ROW_ID));
}
}