/**
* Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
* This file is part of CSipSimple.
*
* CSipSimple is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* If you own a pjsip commercial license you can also redistribute it
* and/or modify it under the terms of the GNU Lesser General Public License
* as an android library.
*
* CSipSimple 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.
*
* You should have received a copy of the GNU General Public License
* along with CSipSimple. If not, see <http://www.gnu.org/licenses/>.
*/
package com.csipsimple.ui.messages;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.net.Uri.Builder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockListFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.MenuItem.OnMenuItemClickListener;
import com.csipsimple.R;
import com.csipsimple.api.ISipService;
import com.csipsimple.api.SipMessage;
import com.csipsimple.api.SipProfile;
import com.csipsimple.api.SipUri;
import com.csipsimple.models.CallerInfo;
import com.csipsimple.service.SipNotifications;
import com.csipsimple.service.SipService;
import com.csipsimple.ui.PickupSipUri;
import com.csipsimple.utils.Log;
import com.csipsimple.utils.SmileyParser;
import com.csipsimple.utils.clipboard.ClipboardWrapper;
import com.csipsimple.utils.contacts.ContactsWrapper;
import com.csipsimple.widgets.AccountChooserButton;
public class MessageFragment extends SherlockListFragment implements LoaderManager.LoaderCallbacks<Cursor>, OnClickListener {
private static final String THIS_FILE = "ComposeMessage";
private String remoteFrom;
private TextView fromText;
private TextView fullFromText;
private EditText bodyInput;
private AccountChooserButton accountChooserButton;
private Button sendButton;
private SipNotifications notifications;
private MessageAdapter mAdapter;
public interface OnQuitListener {
public void onQuit();
}
private OnQuitListener quitListener;
private ClipboardWrapper clipboardManager;
public void setOnQuitListener(OnQuitListener l) {
quitListener = l;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
ListView lv = getListView();
lv.setOnCreateContextMenuListener(this);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SmileyParser.init(getActivity());
notifications = new SipNotifications(getActivity());
clipboardManager = ClipboardWrapper.getInstance(getActivity());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.compose_message_activity, container, false);
fullFromText = (TextView) v.findViewById(R.id.subject);
fromText = (TextView) v.findViewById(R.id.subjectLabel);
bodyInput = (EditText) v.findViewById(R.id.embedded_text_editor);
accountChooserButton = (AccountChooserButton) v.findViewById(R.id.accountChooserButton);
sendButton = (Button) v.findViewById(R.id.send_button);
accountChooserButton.setShowExternals(false);
return v;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getListView().setDivider(null);
fromText.setOnClickListener(this);
sendButton.setOnClickListener(this);
mAdapter = new MessageAdapter(getActivity(), null);
getListView().setAdapter(mAdapter);
// Setup from args
String from = getArguments().getString(SipMessage.FIELD_FROM);
String fullFrom = getArguments().getString(SipMessage.FIELD_FROM_FULL);
if (fullFrom == null) {
fullFrom = from;
}
setupFrom(from, fullFrom);
if (remoteFrom == null) {
chooseSipUri();
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
getActivity().bindService(new Intent(getActivity(), SipService.class), connection, Context.BIND_AUTO_CREATE);
}
@Override
public void onDetach() {
try {
getActivity().unbindService(connection);
} catch (Exception e) {
// Just ignore that
}
service = null;
super.onDetach();
}
@Override
public void onResume() {
Log.d(THIS_FILE, "Resume compose message act");
super.onResume();
notifications.setViewingMessageFrom(remoteFrom);
}
@Override
public void onPause() {
super.onPause();
notifications.setViewingMessageFrom(null);
}
private final static int PICKUP_SIP_URI = 0;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(THIS_FILE, "On activity result " + requestCode);
if (requestCode == PICKUP_SIP_URI) {
if (resultCode == Activity.RESULT_OK) {
String from = data.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
setupFrom(from, from);
}
if (TextUtils.isEmpty(remoteFrom)) {
if(quitListener != null) {
quitListener.onQuit();
}
}else {
loadMessageContent();
}
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
// Service connection
private ISipService service;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
service = ISipService.Stub.asInterface(arg1);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
service = null;
}
};
private void loadMessageContent() {
getLoaderManager().restartLoader(0, getArguments(), this);
String from = getArguments().getString(SipMessage.FIELD_FROM);
if (!TextUtils.isEmpty(from)) {
ContentValues args = new ContentValues();
args.put(SipMessage.FIELD_READ, true);
getActivity().getContentResolver().update(SipMessage.MESSAGE_URI, args,
SipMessage.FIELD_FROM + "=?", new String[] {
from
});
}
}
public static Bundle getArguments(String from, String fromFull) {
Bundle bundle = new Bundle();
if (from != null) {
bundle.putString(SipMessage.FIELD_FROM, from);
bundle.putString(SipMessage.FIELD_FROM_FULL, fromFull);
}
return bundle;
}
private void setupFrom(String from, String fullFrom) {
Log.d(THIS_FILE, "Setup from " + from);
if (from != null) {
if (remoteFrom != from) {
remoteFrom = from;
fromText.setText(remoteFrom);
CallerInfo callerInfo = CallerInfo.getCallerInfoFromSipUri(getActivity(), fullFrom);
if (callerInfo != null && callerInfo.contactExists) {
fullFromText.setText(callerInfo.name);
} else {
fullFromText.setText(SipUri.getDisplayedSimpleContact(fullFrom));
}
loadMessageContent();
notifications.setViewingMessageFrom(remoteFrom);
}
}
}
private void chooseSipUri() {
Intent pickupIntent = new Intent(getActivity(), PickupSipUri.class);
startActivityForResult(pickupIntent, PICKUP_SIP_URI);
}
private void sendMessage() {
if (service != null) {
SipProfile acc = accountChooserButton.getSelectedAccount();
if (acc != null && acc.id != SipProfile.INVALID_ID) {
try {
String textToSend = bodyInput.getText().toString();
if(!TextUtils.isEmpty(textToSend)) {
service.sendMessage(textToSend, remoteFrom, (int) acc.id);
bodyInput.getText().clear();
}
} catch (RemoteException e) {
Log.e(THIS_FILE, "Not able to send message");
}
}
}
}
@Override
public void onClick(View v) {
int clickedId = v.getId();
if (clickedId == R.id.subject) {
chooseSipUri();
} else if (clickedId == R.id.send_button) {
sendMessage();
}
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Builder toLoadUriBuilder = SipMessage.THREAD_ID_URI_BASE.buildUpon().appendEncodedPath(remoteFrom.replaceAll("/", "%2F"));
return new CursorLoader(getActivity(), toLoadUriBuilder.build(), null, null, null,
SipMessage.FIELD_DATE + " ASC");
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
// Options
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
int actionRoom = getResources().getBoolean(R.bool.menu_in_bar) ? MenuItem.SHOW_AS_ACTION_IF_ROOM : MenuItem.SHOW_AS_ACTION_NEVER;
MenuItem addContactMenu = menu.add(R.string.menu_add_to_contacts);
addContactMenu.setIcon(R.drawable.ic_add_contact_holo_dark).setShowAsAction(actionRoom);
addContactMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
Intent it = ContactsWrapper.getInstance().getAddContactIntent(null, remoteFrom);
startActivity(it);
return true;
}
});
}
// Context menu
public static final int MENU_COPY = ContextMenu.FIRST;
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
menu.add(0, MENU_COPY, 0, R.string.copy_message_text);
}
@Override
public boolean onContextItemSelected(android.view.MenuItem item) {
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
Cursor c = (Cursor) mAdapter.getItem(info.position);
if (c != null) {
SipMessage msg = new SipMessage(c);
switch (item.getItemId()) {
case MENU_COPY: {
clipboardManager.setText(msg.getDisplayName(), msg.getBody());
break;
}
default:
break;
}
}
return super.onContextItemSelected(item);
}
}